greybus: gbuf: cport in buffer stream logic
This commit is contained in:
parent
80e04f0994
commit
45f3678bcf
@ -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);
|
||||
}
|
||||
|
@ -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 @@ error_bus:
|
||||
static void __exit gb_exit(void)
|
||||
{
|
||||
gb_tty_exit();
|
||||
gb_gbuf_exit();
|
||||
gb_ap_exit();
|
||||
bus_unregister(&greybus_bus_type);
|
||||
gb_debugfs_cleanup();
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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,
|
||||
|
Loading…
x
Reference in New Issue
Block a user