diff options
Diffstat (limited to 'drivers/usb/core/hub.c')
-rw-r--r-- | drivers/usb/core/hub.c | 65 |
1 files changed, 15 insertions, 50 deletions
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 746f26f222ab..0e0a190bbd00 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/kthread.h> | 22 | #include <linux/kthread.h> |
23 | #include <linux/mutex.h> | 23 | #include <linux/mutex.h> |
24 | #include <linux/freezer.h> | 24 | #include <linux/freezer.h> |
25 | #include <linux/pm_runtime.h> | ||
25 | 26 | ||
26 | #include <asm/uaccess.h> | 27 | #include <asm/uaccess.h> |
27 | #include <asm/byteorder.h> | 28 | #include <asm/byteorder.h> |
@@ -71,7 +72,6 @@ struct usb_hub { | |||
71 | 72 | ||
72 | unsigned mA_per_port; /* current for each child */ | 73 | unsigned mA_per_port; /* current for each child */ |
73 | 74 | ||
74 | unsigned init_done:1; | ||
75 | unsigned limited_power:1; | 75 | unsigned limited_power:1; |
76 | unsigned quiescing:1; | 76 | unsigned quiescing:1; |
77 | unsigned disconnected:1; | 77 | unsigned disconnected:1; |
@@ -820,7 +820,6 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) | |||
820 | } | 820 | } |
821 | init3: | 821 | init3: |
822 | hub->quiescing = 0; | 822 | hub->quiescing = 0; |
823 | hub->init_done = 1; | ||
824 | 823 | ||
825 | status = usb_submit_urb(hub->urb, GFP_NOIO); | 824 | status = usb_submit_urb(hub->urb, GFP_NOIO); |
826 | if (status < 0) | 825 | if (status < 0) |
@@ -861,11 +860,6 @@ static void hub_quiesce(struct usb_hub *hub, enum hub_quiescing_type type) | |||
861 | int i; | 860 | int i; |
862 | 861 | ||
863 | cancel_delayed_work_sync(&hub->init_work); | 862 | cancel_delayed_work_sync(&hub->init_work); |
864 | if (!hub->init_done) { | ||
865 | hub->init_done = 1; | ||
866 | usb_autopm_put_interface_no_suspend( | ||
867 | to_usb_interface(hub->intfdev)); | ||
868 | } | ||
869 | 863 | ||
870 | /* khubd and related activity won't re-trigger */ | 864 | /* khubd and related activity won't re-trigger */ |
871 | hub->quiescing = 1; | 865 | hub->quiescing = 1; |
@@ -1405,10 +1399,8 @@ static void recursively_mark_NOTATTACHED(struct usb_device *udev) | |||
1405 | if (udev->children[i]) | 1399 | if (udev->children[i]) |
1406 | recursively_mark_NOTATTACHED(udev->children[i]); | 1400 | recursively_mark_NOTATTACHED(udev->children[i]); |
1407 | } | 1401 | } |
1408 | if (udev->state == USB_STATE_SUSPENDED) { | 1402 | if (udev->state == USB_STATE_SUSPENDED) |
1409 | udev->discon_suspended = 1; | ||
1410 | udev->active_duration -= jiffies; | 1403 | udev->active_duration -= jiffies; |
1411 | } | ||
1412 | udev->state = USB_STATE_NOTATTACHED; | 1404 | udev->state = USB_STATE_NOTATTACHED; |
1413 | } | 1405 | } |
1414 | 1406 | ||
@@ -1532,31 +1524,6 @@ static void update_address(struct usb_device *udev, int devnum) | |||
1532 | udev->devnum = devnum; | 1524 | udev->devnum = devnum; |
1533 | } | 1525 | } |
1534 | 1526 | ||
1535 | #ifdef CONFIG_USB_SUSPEND | ||
1536 | |||
1537 | static void usb_stop_pm(struct usb_device *udev) | ||
1538 | { | ||
1539 | /* Synchronize with the ksuspend thread to prevent any more | ||
1540 | * autosuspend requests from being submitted, and decrement | ||
1541 | * the parent's count of unsuspended children. | ||
1542 | */ | ||
1543 | usb_pm_lock(udev); | ||
1544 | if (udev->parent && !udev->discon_suspended) | ||
1545 | usb_autosuspend_device(udev->parent); | ||
1546 | usb_pm_unlock(udev); | ||
1547 | |||
1548 | /* Stop any autosuspend or autoresume requests already submitted */ | ||
1549 | cancel_delayed_work_sync(&udev->autosuspend); | ||
1550 | cancel_work_sync(&udev->autoresume); | ||
1551 | } | ||
1552 | |||
1553 | #else | ||
1554 | |||
1555 | static inline void usb_stop_pm(struct usb_device *udev) | ||
1556 | { } | ||
1557 | |||
1558 | #endif | ||
1559 | |||
1560 | /** | 1527 | /** |
1561 | * usb_disconnect - disconnect a device (usbcore-internal) | 1528 | * usb_disconnect - disconnect a device (usbcore-internal) |
1562 | * @pdev: pointer to device being disconnected | 1529 | * @pdev: pointer to device being disconnected |
@@ -1625,8 +1592,6 @@ void usb_disconnect(struct usb_device **pdev) | |||
1625 | *pdev = NULL; | 1592 | *pdev = NULL; |
1626 | spin_unlock_irq(&device_state_lock); | 1593 | spin_unlock_irq(&device_state_lock); |
1627 | 1594 | ||
1628 | usb_stop_pm(udev); | ||
1629 | |||
1630 | put_device(&udev->dev); | 1595 | put_device(&udev->dev); |
1631 | } | 1596 | } |
1632 | 1597 | ||
@@ -1803,9 +1768,6 @@ int usb_new_device(struct usb_device *udev) | |||
1803 | int err; | 1768 | int err; |
1804 | 1769 | ||
1805 | if (udev->parent) { | 1770 | if (udev->parent) { |
1806 | /* Increment the parent's count of unsuspended children */ | ||
1807 | usb_autoresume_device(udev->parent); | ||
1808 | |||
1809 | /* Initialize non-root-hub device wakeup to disabled; | 1771 | /* Initialize non-root-hub device wakeup to disabled; |
1810 | * device (un)configuration controls wakeup capable | 1772 | * device (un)configuration controls wakeup capable |
1811 | * sysfs power/wakeup controls wakeup enabled/disabled | 1773 | * sysfs power/wakeup controls wakeup enabled/disabled |
@@ -1814,6 +1776,10 @@ int usb_new_device(struct usb_device *udev) | |||
1814 | device_set_wakeup_enable(&udev->dev, 1); | 1776 | device_set_wakeup_enable(&udev->dev, 1); |
1815 | } | 1777 | } |
1816 | 1778 | ||
1779 | /* Tell the runtime-PM framework the device is active */ | ||
1780 | pm_runtime_set_active(&udev->dev); | ||
1781 | pm_runtime_enable(&udev->dev); | ||
1782 | |||
1817 | usb_detect_quirks(udev); | 1783 | usb_detect_quirks(udev); |
1818 | err = usb_enumerate_device(udev); /* Read descriptors */ | 1784 | err = usb_enumerate_device(udev); /* Read descriptors */ |
1819 | if (err < 0) | 1785 | if (err < 0) |
@@ -1844,7 +1810,8 @@ int usb_new_device(struct usb_device *udev) | |||
1844 | 1810 | ||
1845 | fail: | 1811 | fail: |
1846 | usb_set_device_state(udev, USB_STATE_NOTATTACHED); | 1812 | usb_set_device_state(udev, USB_STATE_NOTATTACHED); |
1847 | usb_stop_pm(udev); | 1813 | pm_runtime_disable(&udev->dev); |
1814 | pm_runtime_set_suspended(&udev->dev); | ||
1848 | return err; | 1815 | return err; |
1849 | } | 1816 | } |
1850 | 1817 | ||
@@ -2408,8 +2375,11 @@ int usb_remote_wakeup(struct usb_device *udev) | |||
2408 | 2375 | ||
2409 | if (udev->state == USB_STATE_SUSPENDED) { | 2376 | if (udev->state == USB_STATE_SUSPENDED) { |
2410 | dev_dbg(&udev->dev, "usb %sresume\n", "wakeup-"); | 2377 | dev_dbg(&udev->dev, "usb %sresume\n", "wakeup-"); |
2411 | usb_mark_last_busy(udev); | 2378 | status = usb_autoresume_device(udev); |
2412 | status = usb_external_resume_device(udev, PMSG_REMOTE_RESUME); | 2379 | if (status == 0) { |
2380 | /* Let the drivers do their thing, then... */ | ||
2381 | usb_autosuspend_device(udev); | ||
2382 | } | ||
2413 | } | 2383 | } |
2414 | return status; | 2384 | return status; |
2415 | } | 2385 | } |
@@ -2446,11 +2416,6 @@ int usb_port_resume(struct usb_device *udev, pm_message_t msg) | |||
2446 | return status; | 2416 | return status; |
2447 | } | 2417 | } |
2448 | 2418 | ||
2449 | int usb_remote_wakeup(struct usb_device *udev) | ||
2450 | { | ||
2451 | return 0; | ||
2452 | } | ||
2453 | |||
2454 | #endif | 2419 | #endif |
2455 | 2420 | ||
2456 | static int hub_suspend(struct usb_interface *intf, pm_message_t msg) | 2421 | static int hub_suspend(struct usb_interface *intf, pm_message_t msg) |
@@ -3268,7 +3233,7 @@ static void hub_events(void) | |||
3268 | * disconnected while waiting for the lock to succeed. */ | 3233 | * disconnected while waiting for the lock to succeed. */ |
3269 | usb_lock_device(hdev); | 3234 | usb_lock_device(hdev); |
3270 | if (unlikely(hub->disconnected)) | 3235 | if (unlikely(hub->disconnected)) |
3271 | goto loop2; | 3236 | goto loop_disconnected; |
3272 | 3237 | ||
3273 | /* If the hub has died, clean up after it */ | 3238 | /* If the hub has died, clean up after it */ |
3274 | if (hdev->state == USB_STATE_NOTATTACHED) { | 3239 | if (hdev->state == USB_STATE_NOTATTACHED) { |
@@ -3428,7 +3393,7 @@ static void hub_events(void) | |||
3428 | * kick_khubd() and allow autosuspend. | 3393 | * kick_khubd() and allow autosuspend. |
3429 | */ | 3394 | */ |
3430 | usb_autopm_put_interface(intf); | 3395 | usb_autopm_put_interface(intf); |
3431 | loop2: | 3396 | loop_disconnected: |
3432 | usb_unlock_device(hdev); | 3397 | usb_unlock_device(hdev); |
3433 | kref_put(&hub->kref, hub_release); | 3398 | kref_put(&hub->kref, hub_release); |
3434 | 3399 | ||