aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/core
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2011-02-08 17:25:48 -0500
committerRafael J. Wysocki <rjw@sisk.pl>2011-03-14 19:43:14 -0400
commit4681b17154b3fd81f898802262985f662344e6ed (patch)
tree5670e6668fe43dad7bb19dd91e227d2d09dbd066 /drivers/usb/core
parent0295a34d61f14522fddb26856191520d2e1d7e77 (diff)
USB / Hub: Do not call device_set_wakeup_capable() under spinlock
A subsequent patch will modify device_set_wakeup_capable() in such a way that it will call functions which may sleep and therefore it shouldn't be called under spinlocks. In preparation to that, modify usb_set_device_state() to avoid calling device_set_wakeup_capable() under device_state_lock. Tested-by: Minchan Kim <minchan.kim@gmail.com> Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl> Acked-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/core')
-rw-r--r--drivers/usb/core/hub.c10
1 files changed, 6 insertions, 4 deletions
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 0f299b7aad60..19d3435e6140 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -1465,6 +1465,7 @@ void usb_set_device_state(struct usb_device *udev,
1465 enum usb_device_state new_state) 1465 enum usb_device_state new_state)
1466{ 1466{
1467 unsigned long flags; 1467 unsigned long flags;
1468 int wakeup = -1;
1468 1469
1469 spin_lock_irqsave(&device_state_lock, flags); 1470 spin_lock_irqsave(&device_state_lock, flags);
1470 if (udev->state == USB_STATE_NOTATTACHED) 1471 if (udev->state == USB_STATE_NOTATTACHED)
@@ -1479,11 +1480,10 @@ void usb_set_device_state(struct usb_device *udev,
1479 || new_state == USB_STATE_SUSPENDED) 1480 || new_state == USB_STATE_SUSPENDED)
1480 ; /* No change to wakeup settings */ 1481 ; /* No change to wakeup settings */
1481 else if (new_state == USB_STATE_CONFIGURED) 1482 else if (new_state == USB_STATE_CONFIGURED)
1482 device_set_wakeup_capable(&udev->dev, 1483 wakeup = udev->actconfig->desc.bmAttributes
1483 (udev->actconfig->desc.bmAttributes 1484 & USB_CONFIG_ATT_WAKEUP;
1484 & USB_CONFIG_ATT_WAKEUP));
1485 else 1485 else
1486 device_set_wakeup_capable(&udev->dev, 0); 1486 wakeup = 0;
1487 } 1487 }
1488 if (udev->state == USB_STATE_SUSPENDED && 1488 if (udev->state == USB_STATE_SUSPENDED &&
1489 new_state != USB_STATE_SUSPENDED) 1489 new_state != USB_STATE_SUSPENDED)
@@ -1495,6 +1495,8 @@ void usb_set_device_state(struct usb_device *udev,
1495 } else 1495 } else
1496 recursively_mark_NOTATTACHED(udev); 1496 recursively_mark_NOTATTACHED(udev);
1497 spin_unlock_irqrestore(&device_state_lock, flags); 1497 spin_unlock_irqrestore(&device_state_lock, flags);
1498 if (wakeup >= 0)
1499 device_set_wakeup_capable(&udev->dev, wakeup);
1498} 1500}
1499EXPORT_SYMBOL_GPL(usb_set_device_state); 1501EXPORT_SYMBOL_GPL(usb_set_device_state);
1500 1502