greybus: gbuf: cport in buffer stream logic

This commit is contained in:
Greg Kroah-Hartman 2014-09-14 11:40:35 -07:00
parent 80e04f0994
commit 45f3678bcf
4 changed files with 79 additions and 16 deletions

View file

@ -14,7 +14,7 @@
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/kthread.h>
#include <linux/workqueue.h>
#include <linux/device.h>
#include "svc_msg.h"
#include "greybus_manifest.h"
@ -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);
int gb_thread_init(void)
int gb_ap_init(void)
{
ap_workqueue = alloc_workqueue("greybus_ap", 0, 1);
if (!ap_workqueue)
@ -261,7 +261,7 @@ int gb_thread_init(void)
return 0;
}
void gb_thread_destroy(void)
void gb_ap_exit(void)
{
destroy_workqueue(ap_workqueue);
}

View file

@ -527,13 +527,17 @@ static int __init gb_init(void)
goto error_bus;
}
retval = gb_thread_init();
retval = gb_ap_init();
if (retval) {
pr_err("gb_thread_init failed\n");
goto error_thread;
pr_err("gb_ap_init failed\n");
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();
if (retval) {
@ -544,9 +548,12 @@ static int __init gb_init(void)
return 0;
error_tty:
gb_thread_destroy();
gb_gbuf_exit();
error_thread:
error_gbuf:
gb_ap_exit();
error_ap:
bus_unregister(&greybus_bus_type);
error_bus:
@ -558,6 +565,8 @@ static int __init gb_init(void)
static void __exit gb_exit(void)
{
gb_tty_exit();
gb_gbuf_exit();
gb_ap_exit();
bus_unregister(&greybus_bus_type);
gb_debugfs_cleanup();
}

View file

@ -15,6 +15,7 @@
#include <linux/kref.h>
#include <linux/device.h>
#include <linux/slab.h>
#include <linux/workqueue.h>
#include "greybus.h"
@ -155,16 +156,42 @@ int gb_register_cport_complete(struct greybus_device *gdev,
return 0;
}
void gb_deregister_cport_handler(int cport)
void gb_deregister_cport_complete(int cport)
{
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,
size_t length)
{
struct gb_cport_handler *ch;
struct gbuf *gbuf;
struct cport_msg *cm;
/* first check to see if we have a cport handler for this cport */
ch = &cport_handler[cport];
@ -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");
return;
}
/* Set the data pointers */
gbuf->hdpriv = hd;
// FIXME - implement...
/*
* 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;
/* 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);
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;
}
void greybus_gbuf_exit(void)
void gb_gbuf_exit(void)
{
destroy_workqueue(cport_workqueue);
}

View file

@ -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. */
int gb_new_ap_msg(u8 *data, int length, struct greybus_host_device *hd);
int gb_thread_init(void);
void gb_thread_destroy(void);
int gb_ap_init(void);
void gb_ap_exit(void);
int gb_debugfs_init(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,
gbuf_complete_t handler, int cport,