USB: gadget: composite: Move switch_set_state calls to a work queue
authorMike Lockwood <lockwood@android.com>
Mon, 28 Jun 2010 00:05:55 +0000 (20:05 -0400)
committerColin Cross <ccross@android.com>
Tue, 14 Jun 2011 16:09:08 +0000 (09:09 -0700)
Signed-off-by: Mike Lockwood <lockwood@android.com>
drivers/usb/gadget/composite.c
include/linux/usb/composite.h

index 03b02876ba18dd22702c6fc190700bb0f4e44d37..bf555327937f29f7d7eb4814a46291a358318f44 100644 (file)
@@ -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;
index 0b2d2919edb266358d27d68cbadd40b6a35e3fe8..4cc46801652b2ee0a7f8da29d6da5f9952bdf61a 100644 (file)
@@ -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);