summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBadhri Jagan Sridharan <Badhri@google.com>2015-03-27 14:15:19 -0700
committerJohn Stultz <john.stultz@linaro.org>2016-02-16 13:52:09 -0800
commitdbaad39b68c88745a59d53e45403332bd1761462 (patch)
tree6c21ed39a35a8f163ec283e9b53567df4f0ffaa3
parent795b676102b66700581daed20c3fe6961d09563a (diff)
usb: gadget: Add function devices to the parent
Added create_function_device to create child function devices for USB gadget functions. Android UsbDeviceManager relies on communicating to the devices created by the gadget functions to implement functions such as audio_source. Signed-off-by: Badhri Jagan Sridharan <Badhri@google.com> Change-Id: I0df9ad86ac32d8cdacdea164e9fed49891b45fc2
-rw-r--r--drivers/usb/gadget/configfs.c35
1 files changed, 29 insertions, 6 deletions
diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c
index 8c527eb2289c..38077becbf2c 100644
--- a/drivers/usb/gadget/configfs.c
+++ b/drivers/usb/gadget/configfs.c
@@ -13,7 +13,6 @@
#include <linux/platform_device.h>
#include <linux/kdev_t.h>
#include <linux/usb/ch9.h>
-#include "u_fs.h"
#ifdef CONFIG_USB_CONFIGFS_F_ACC
extern int acc_ctrlrequest(struct usb_composite_dev *cdev,
@@ -21,6 +20,18 @@ extern int acc_ctrlrequest(struct usb_composite_dev *cdev,
void acc_disconnect(void);
#endif
static struct class *android_class;
+static struct device *android_device;
+static int index;
+
+struct device *create_function_device(char *name)
+{
+ if (android_device && !IS_ERR(android_device))
+ return device_create(android_class, android_device,
+ MKDEV(0, index++), NULL, name);
+ else
+ return ERR_PTR(-EINVAL);
+}
+EXPORT_SYMBOL_GPL(create_function_device);
#endif
int check_user_usb_string(const char *name,
@@ -1420,19 +1431,22 @@ static void android_work(struct work_struct *data)
spin_unlock_irqrestore(&cdev->lock, flags);
if (status[0]) {
- kobject_uevent_env(&gi->dev->kobj, KOBJ_CHANGE, connected);
+ kobject_uevent_env(&android_device->kobj,
+ KOBJ_CHANGE, connected);
pr_info("%s: sent uevent %s\n", __func__, connected[0]);
uevent_sent = true;
}
if (status[1]) {
- kobject_uevent_env(&gi->dev->kobj, KOBJ_CHANGE, configured);
+ kobject_uevent_env(&android_device->kobj,
+ KOBJ_CHANGE, configured);
pr_info("%s: sent uevent %s\n", __func__, configured[0]);
uevent_sent = true;
}
if (status[2]) {
- kobject_uevent_env(&gi->dev->kobj, KOBJ_CHANGE, disconnected);
+ kobject_uevent_env(&android_device->kobj,
+ KOBJ_CHANGE, disconnected);
pr_info("%s: sent uevent %s\n", __func__, disconnected[0]);
uevent_sent = true;
}
@@ -1554,7 +1568,6 @@ static struct config_group *gadgets_make(
gi = kzalloc(sizeof(*gi), GFP_KERNEL);
if (!gi)
return ERR_PTR(-ENOMEM);
-
gi->group.default_groups = gi->default_groups;
gi->group.default_groups[0] = &gi->functions_group;
gi->group.default_groups[1] = &gi->configs_group;
@@ -1592,8 +1605,10 @@ static struct config_group *gadgets_make(
#ifdef CONFIG_USB_CONFIGFS_UEVENT
INIT_WORK(&gi->work, android_work);
- gi->dev = device_create(android_class, NULL,
+ android_device = device_create(android_class, NULL,
MKDEV(0, 0), NULL, "android0");
+ if (IS_ERR(android_device))
+ goto err;
#endif
if (!gi->composite.gadget_driver.function)
@@ -1610,6 +1625,9 @@ err:
static void gadgets_drop(struct config_group *group, struct config_item *item)
{
config_item_put(item);
+#ifdef CONFIG_USB_CONFIGFS_UEVENT
+ device_destroy(android_device->class, android_device->devt);
+#endif
}
static struct configfs_group_operations gadgets_ops = {
@@ -1661,5 +1679,10 @@ module_init(gadget_cfs_init);
static void __exit gadget_cfs_exit(void)
{
configfs_unregister_subsystem(&gadget_subsys);
+#ifdef CONFIG_USB_CONFIGFS_UEVENT
+ if (!IS_ERR(android_class))
+ class_destroy(android_class);
+#endif
+
}
module_exit(gadget_cfs_exit);