Commit 45f3678b authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

greybus: gbuf: cport in buffer stream logic

parent 80e04f09
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <linux/kthread.h> #include <linux/workqueue.h>
#include <linux/device.h> #include <linux/device.h>
#include "svc_msg.h" #include "svc_msg.h"
#include "greybus_manifest.h" #include "greybus_manifest.h"
...@@ -252,7 +252,7 @@ int gb_new_ap_msg(u8 *data, int size, struct greybus_host_device *hd) ...@@ -252,7 +252,7 @@ int gb_new_ap_msg(u8 *data, int size, struct greybus_host_device *hd)
} }
EXPORT_SYMBOL_GPL(gb_new_ap_msg); EXPORT_SYMBOL_GPL(gb_new_ap_msg);
int gb_thread_init(void) int gb_ap_init(void)
{ {
ap_workqueue = alloc_workqueue("greybus_ap", 0, 1); ap_workqueue = alloc_workqueue("greybus_ap", 0, 1);
if (!ap_workqueue) if (!ap_workqueue)
...@@ -261,7 +261,7 @@ int gb_thread_init(void) ...@@ -261,7 +261,7 @@ int gb_thread_init(void)
return 0; return 0;
} }
void gb_thread_destroy(void) void gb_ap_exit(void)
{ {
destroy_workqueue(ap_workqueue); destroy_workqueue(ap_workqueue);
} }
......
...@@ -527,13 +527,17 @@ static int __init gb_init(void) ...@@ -527,13 +527,17 @@ static int __init gb_init(void)
goto error_bus; goto error_bus;
} }
retval = gb_thread_init(); retval = gb_ap_init();
if (retval) { if (retval) {
pr_err("gb_thread_init failed\n"); pr_err("gb_ap_init failed\n");
goto error_thread; goto error_ap;
} }
// FIXME - more gb core init goes here retval = gb_gbuf_init();
if (retval) {
pr_err("gb_gbuf_init failed\n");
goto error_gbuf;
}
retval = gb_tty_init(); retval = gb_tty_init();
if (retval) { if (retval) {
...@@ -544,9 +548,12 @@ static int __init gb_init(void) ...@@ -544,9 +548,12 @@ static int __init gb_init(void)
return 0; return 0;
error_tty: error_tty:
gb_thread_destroy(); gb_gbuf_exit();
error_gbuf:
gb_ap_exit();
error_thread: error_ap:
bus_unregister(&greybus_bus_type); bus_unregister(&greybus_bus_type);
error_bus: error_bus:
...@@ -558,6 +565,8 @@ static int __init gb_init(void) ...@@ -558,6 +565,8 @@ static int __init gb_init(void)
static void __exit gb_exit(void) static void __exit gb_exit(void)
{ {
gb_tty_exit(); gb_tty_exit();
gb_gbuf_exit();
gb_ap_exit();
bus_unregister(&greybus_bus_type); bus_unregister(&greybus_bus_type);
gb_debugfs_cleanup(); gb_debugfs_cleanup();
} }
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include <linux/kref.h> #include <linux/kref.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/workqueue.h>
#include "greybus.h" #include "greybus.h"
...@@ -155,16 +156,42 @@ int gb_register_cport_complete(struct greybus_device *gdev, ...@@ -155,16 +156,42 @@ int gb_register_cport_complete(struct greybus_device *gdev,
return 0; return 0;
} }
void gb_deregister_cport_handler(int cport) void gb_deregister_cport_complete(int cport)
{ {
cport_handler[cport].handler = NULL; cport_handler[cport].handler = NULL;
} }
struct cport_msg {
struct gbuf *gbuf;
struct work_struct event;
};
static struct workqueue_struct *cport_workqueue;
static void cport_process_event(struct work_struct *work)
{
struct cport_msg *cm;
struct gbuf *gbuf;
cm = container_of(work, struct cport_msg, event);
gbuf = cm->gbuf;
/* call the gbuf handler */
gbuf->complete(gbuf);
/* free all the memory */
kfree(gbuf->transfer_buffer);
kfree(gbuf);
kfree(cm);
}
void greybus_cport_in_data(struct greybus_host_device *hd, int cport, u8 *data, void greybus_cport_in_data(struct greybus_host_device *hd, int cport, u8 *data,
size_t length) size_t length)
{ {
struct gb_cport_handler *ch; struct gb_cport_handler *ch;
struct gbuf *gbuf; struct gbuf *gbuf;
struct cport_msg *cm;
/* first check to see if we have a cport handler for this cport */ /* first check to see if we have a cport handler for this cport */
ch = &cport_handler[cport]; ch = &cport_handler[cport];
...@@ -183,17 +210,42 @@ void greybus_cport_in_data(struct greybus_host_device *hd, int cport, u8 *data, ...@@ -183,17 +210,42 @@ void greybus_cport_in_data(struct greybus_host_device *hd, int cport, u8 *data,
pr_err("can't allocate gbuf???\n"); pr_err("can't allocate gbuf???\n");
return; return;
} }
/* Set the data pointers */ gbuf->hdpriv = hd;
/*
* FIXME:
* Very dumb copy data method for now, if this is slow (odds are it will
* be, we should move to a model where the hd "owns" all buffers, but we
* want something up and working first for now.
*/
gbuf->transfer_buffer = kmalloc(length, GFP_ATOMIC);
if (!gbuf->transfer_buffer) {
kfree(gbuf);
return;
}
memcpy(gbuf->transfer_buffer, data, length);
gbuf->transfer_buffer_length = length;
// FIXME - implement... /* Again with the slow allocate... */
cm = kmalloc(sizeof(*cm), GFP_ATOMIC);
/* Queue up the cport message to be handled in user context */
cm->gbuf = gbuf;
INIT_WORK(&cm->event, cport_process_event);
queue_work(cport_workqueue, &cm->event);
} }
EXPORT_SYMBOL_GPL(greybus_cport_in_data); EXPORT_SYMBOL_GPL(greybus_cport_in_data);
int greybus_gbuf_init(void) int gb_gbuf_init(void)
{ {
cport_workqueue = alloc_workqueue("greybus_gbuf", 0, 1);
if (!cport_workqueue)
return -ENOMEM;
return 0; return 0;
} }
void greybus_gbuf_exit(void) void gb_gbuf_exit(void)
{ {
destroy_workqueue(cport_workqueue);
} }
...@@ -229,10 +229,12 @@ const u8 *greybus_string(struct greybus_device *gdev, int id); ...@@ -229,10 +229,12 @@ const u8 *greybus_string(struct greybus_device *gdev, int id);
/* Internal functions to gb module, move to internal .h file eventually. */ /* Internal functions to gb module, move to internal .h file eventually. */
int gb_new_ap_msg(u8 *data, int length, struct greybus_host_device *hd); int gb_new_ap_msg(u8 *data, int length, struct greybus_host_device *hd);
int gb_thread_init(void); int gb_ap_init(void);
void gb_thread_destroy(void); void gb_ap_exit(void);
int gb_debugfs_init(void); int gb_debugfs_init(void);
void gb_debugfs_cleanup(void); void gb_debugfs_cleanup(void);
int gb_gbuf_init(void);
void gb_gbuf_exit(void);
int gb_register_cport_complete(struct greybus_device *gdev, int gb_register_cport_complete(struct greybus_device *gdev,
gbuf_complete_t handler, int cport, gbuf_complete_t handler, int cport,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment