summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Lockwood <lockwood@android.com>2010-06-27 20:05:55 -0400
committerColin Cross <ccross@android.com>2011-06-14 09:09:08 -0700
commit8da4cc8f77b0d291fa33a5474d69b12b534cb5f4 (patch)
tree8237fea6200b5920e80a02d3f6dd2bab6d92f0a5
parentba83b0158e1e7ae0a0169d523c3ed5084a360233 (diff)
USB: gadget: composite: Move switch_set_state calls to a work queue
Signed-off-by: Mike Lockwood <lockwood@android.com>
-rw-r--r--drivers/usb/gadget/composite.c18
-rw-r--r--include/linux/usb/composite.h1
2 files changed, 17 insertions, 2 deletions
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index 03b02876ba18..bf555327937f 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -545,7 +545,7 @@ static int set_config(struct usb_composite_dev *cdev,
done:
usb_gadget_vbus_draw(gadget, power);
- switch_set_state(&cdev->sdev, number);
+ schedule_work(&cdev->switch_work);
if (result >= 0 && cdev->delayed_status)
result = USB_GADGET_DELAYED_STATUS;
@@ -1118,7 +1118,7 @@ static void composite_disconnect(struct usb_gadget *gadget)
composite->disconnect(cdev);
spin_unlock_irqrestore(&cdev->lock, flags);
- switch_set_state(&cdev->sdev, 0);
+ schedule_work(&cdev->switch_work);
}
/*-------------------------------------------------------------------------*/
@@ -1199,6 +1199,19 @@ static u8 override_id(struct usb_composite_dev *cdev, u8 *desc)
return *desc;
}
+static void
+composite_switch_work(struct work_struct *data)
+{
+ struct usb_composite_dev *cdev =
+ container_of(data, struct usb_composite_dev, switch_work);
+ struct usb_configuration *config = cdev->config;
+
+ if (config)
+ switch_set_state(&cdev->sdev, config->bConfigurationValue);
+ else
+ switch_set_state(&cdev->sdev, 0);
+}
+
static int composite_bind(struct usb_gadget *gadget)
{
struct usb_composite_dev *cdev;
@@ -1252,6 +1265,7 @@ static int composite_bind(struct usb_gadget *gadget)
status = switch_dev_register(&cdev->sdev);
if (status < 0)
goto fail;
+ INIT_WORK(&cdev->switch_work, composite_switch_work);
cdev->desc = *composite->dev;
cdev->desc.bMaxPacketSize0 = gadget->ep0->maxpacket;
diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h
index 0b2d2919edb2..4cc46801652b 100644
--- a/include/linux/usb/composite.h
+++ b/include/linux/usb/composite.h
@@ -372,6 +372,7 @@ struct usb_composite_dev {
spinlock_t lock;
struct switch_dev sdev;
+ struct work_struct switch_work;
};
extern int usb_string_id(struct usb_composite_dev *c);