| From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
| From: Badhri Jagan Sridharan <Badhri@google.com> |
| Date: Tue, 14 Jul 2015 15:46:11 -0700 |
| Subject: ANDROID: usb: gadget: configfs: Add "state" attribute to |
| android_device |
| |
| Added a device attribute to android_device to |
| determine USB_GADGET's state |
| |
| Bug: 68755607 |
| Bug: 120441124 |
| Change-Id: I17f8903120df96bf2f4bf441940b53a87b818230 |
| [badhri: Migrate to using udc uevents from upstream sysfs.] |
| Signed-off-by: Badhri Jagan Sridharan <badhri@google.com> |
| --- |
| drivers/usb/gadget/configfs.c | 66 ++++++++++++++++++++++++++++++++++- |
| 1 file changed, 65 insertions(+), 1 deletion(-) |
| |
| diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c |
| index 1b2c6b0ba1c2..195f67999f12 100644 |
| --- a/drivers/usb/gadget/configfs.c |
| +++ b/drivers/usb/gadget/configfs.c |
| @@ -1676,11 +1676,49 @@ static const struct usb_gadget_driver configfs_driver_template = { |
| .match_existing_only = 1, |
| }; |
| |
| +#ifdef CONFIG_USB_CONFIGFS_UEVENT |
| +static ssize_t state_show(struct device *pdev, struct device_attribute *attr, |
| + char *buf) |
| +{ |
| + struct gadget_info *dev = dev_get_drvdata(pdev); |
| + struct usb_composite_dev *cdev; |
| + char *state = "DISCONNECTED"; |
| + unsigned long flags; |
| + |
| + if (!dev) |
| + goto out; |
| + |
| + cdev = &dev->cdev; |
| + |
| + if (!cdev) |
| + goto out; |
| + |
| + spin_lock_irqsave(&cdev->lock, flags); |
| + if (cdev->config) |
| + state = "CONFIGURED"; |
| + else if (dev->connected) |
| + state = "CONNECTED"; |
| + spin_unlock_irqrestore(&cdev->lock, flags); |
| +out: |
| + return sprintf(buf, "%s\n", state); |
| +} |
| + |
| +static DEVICE_ATTR(state, S_IRUGO, state_show, NULL); |
| + |
| +static struct device_attribute *android_usb_attributes[] = { |
| + &dev_attr_state, |
| + NULL |
| +}; |
| +#endif |
| + |
| static struct config_group *gadgets_make( |
| struct config_group *group, |
| const char *name) |
| { |
| struct gadget_info *gi; |
| + struct device_attribute **attrs; |
| + struct device_attribute *attr; |
| + int err; |
| |
| gi = kzalloc(sizeof(*gi), GFP_KERNEL); |
| if (!gi) |
| @@ -1731,12 +1769,31 @@ static struct config_group *gadgets_make( |
| MKDEV(0, 0), NULL, "android0"); |
| if (IS_ERR(android_device)) |
| goto err; |
| + |
| + dev_set_drvdata(android_device, gi); |
| + |
| + attrs = android_usb_attributes; |
| + while ((attr = *attrs++)) { |
| + err = device_create_file(android_device, attr); |
| + if (err) |
| + goto err1; |
| + } |
| #endif |
| |
| if (!gi->composite.gadget_driver.function) |
| - goto err; |
| + goto err1; |
| |
| return &gi->group; |
| + |
| +err1: |
| +#ifdef CONFIG_USB_CONFIGFS_UEVENT |
| + attrs = android_usb_attributes; |
| + while ((attr = *attrs++)) |
| + device_remove_file(android_device, attr); |
| + |
| + device_destroy(android_device->class, |
| + android_device->devt); |
| +#endif |
| err: |
| kfree(gi); |
| return ERR_PTR(-ENOMEM); |
| @@ -1744,8 +1801,15 @@ static struct config_group *gadgets_make( |
| |
| static void gadgets_drop(struct config_group *group, struct config_item *item) |
| { |
| + struct device_attribute **attrs; |
| + struct device_attribute *attr; |
| + |
| config_item_put(item); |
| + |
| #ifdef CONFIG_USB_CONFIGFS_UEVENT |
| + attrs = android_usb_attributes; |
| + while ((attr = *attrs++)) |
| + device_remove_file(android_device, attr); |
| device_destroy(android_device->class, android_device->devt); |
| #endif |
| } |