diff options
author | Greg Kroah-Hartman <gregkh@suse.de> | 2010-12-16 13:05:06 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-12-16 13:05:06 -0500 |
commit | 36facadd9ea98f8415d0dbb63e0763b7ee9d3911 (patch) | |
tree | 99dea00b332ed852f2b0a4923b581dd723f03634 /drivers/usb/core | |
parent | 2faa83e2a519abea1055d156ce1b42b8fa57e87b (diff) | |
parent | 0b83ae960cd7d4a5ee02786ecf41ab45688999bf (diff) |
Merge branch 'usb-next' into musb-merge
* usb-next: (132 commits)
USB: uas: Use GFP_NOIO instead of GFP_KERNEL in I/O submission path
USB: uas: Ensure we only bind to a UAS interface
USB: uas: Rename sense pipe and sense urb to status pipe and status urb
USB: uas: Use kzalloc instead of kmalloc
USB: uas: Fix up the Sense IU
usb: musb: core: kill unneeded #include's
DA8xx: assign name to MUSB IRQ resource
usb: gadget: g_ncm added
usb: gadget: f_ncm.c added
usb: gadget: u_ether: prepare for NCM
usb: pch_udc: Fix setup transfers with data out
usb: pch_udc: Fix compile error, warnings and checkpatch warnings
usb: add ab8500 usb transceiver driver
USB: gadget: Implement runtime PM for MSM bus glue driver
USB: gadget: Implement runtime PM for ci13xxx gadget
USB: gadget: Add USB controller driver for MSM SoC
USB: gadget: Introduce ci13xxx_udc_driver struct
USB: gadget: Initialize ci13xxx gadget device's coherent DMA mask
USB: gadget: Fix "scheduling while atomic" bugs in ci13xxx_udc
USB: gadget: Separate out PCI bus code from ci13xxx_udc
...
Diffstat (limited to 'drivers/usb/core')
-rw-r--r-- | drivers/usb/core/driver.c | 150 | ||||
-rw-r--r-- | drivers/usb/core/hcd-pci.c | 1 | ||||
-rw-r--r-- | drivers/usb/core/hcd.c | 1 | ||||
-rw-r--r-- | drivers/usb/core/hub.c | 11 | ||||
-rw-r--r-- | drivers/usb/core/message.c | 1 | ||||
-rw-r--r-- | drivers/usb/core/quirks.c | 15 | ||||
-rw-r--r-- | drivers/usb/core/sysfs.c | 84 | ||||
-rw-r--r-- | drivers/usb/core/usb.c | 3 | ||||
-rw-r--r-- | drivers/usb/core/usb.h | 2 |
9 files changed, 61 insertions, 207 deletions
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index c0e60fbcb048..b9278a1fb9e5 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c | |||
@@ -27,7 +27,6 @@ | |||
27 | #include <linux/usb.h> | 27 | #include <linux/usb.h> |
28 | #include <linux/usb/quirks.h> | 28 | #include <linux/usb/quirks.h> |
29 | #include <linux/usb/hcd.h> | 29 | #include <linux/usb/hcd.h> |
30 | #include <linux/pm_runtime.h> | ||
31 | 30 | ||
32 | #include "usb.h" | 31 | #include "usb.h" |
33 | 32 | ||
@@ -1262,6 +1261,7 @@ static int usb_resume_both(struct usb_device *udev, pm_message_t msg) | |||
1262 | udev->reset_resume); | 1261 | udev->reset_resume); |
1263 | } | 1262 | } |
1264 | } | 1263 | } |
1264 | usb_mark_last_busy(udev); | ||
1265 | 1265 | ||
1266 | done: | 1266 | done: |
1267 | dev_vdbg(&udev->dev, "%s: status %d\n", __func__, status); | 1267 | dev_vdbg(&udev->dev, "%s: status %d\n", __func__, status); |
@@ -1329,7 +1329,6 @@ int usb_resume(struct device *dev, pm_message_t msg) | |||
1329 | pm_runtime_disable(dev); | 1329 | pm_runtime_disable(dev); |
1330 | pm_runtime_set_active(dev); | 1330 | pm_runtime_set_active(dev); |
1331 | pm_runtime_enable(dev); | 1331 | pm_runtime_enable(dev); |
1332 | udev->last_busy = jiffies; | ||
1333 | do_unbind_rebind(udev, DO_REBIND); | 1332 | do_unbind_rebind(udev, DO_REBIND); |
1334 | } | 1333 | } |
1335 | } | 1334 | } |
@@ -1397,33 +1396,8 @@ void usb_autosuspend_device(struct usb_device *udev) | |||
1397 | { | 1396 | { |
1398 | int status; | 1397 | int status; |
1399 | 1398 | ||
1400 | udev->last_busy = jiffies; | 1399 | usb_mark_last_busy(udev); |
1401 | status = pm_runtime_put_sync(&udev->dev); | 1400 | status = pm_runtime_put_sync_autosuspend(&udev->dev); |
1402 | dev_vdbg(&udev->dev, "%s: cnt %d -> %d\n", | ||
1403 | __func__, atomic_read(&udev->dev.power.usage_count), | ||
1404 | status); | ||
1405 | } | ||
1406 | |||
1407 | /** | ||
1408 | * usb_try_autosuspend_device - attempt an autosuspend of a USB device and its interfaces | ||
1409 | * @udev: the usb_device to autosuspend | ||
1410 | * | ||
1411 | * This routine should be called when a core subsystem thinks @udev may | ||
1412 | * be ready to autosuspend. | ||
1413 | * | ||
1414 | * @udev's usage counter left unchanged. If it is 0 and all the interfaces | ||
1415 | * are inactive then an autosuspend will be attempted. The attempt may | ||
1416 | * fail or be delayed. | ||
1417 | * | ||
1418 | * The caller must hold @udev's device lock. | ||
1419 | * | ||
1420 | * This routine can run only in process context. | ||
1421 | */ | ||
1422 | void usb_try_autosuspend_device(struct usb_device *udev) | ||
1423 | { | ||
1424 | int status; | ||
1425 | |||
1426 | status = pm_runtime_idle(&udev->dev); | ||
1427 | dev_vdbg(&udev->dev, "%s: cnt %d -> %d\n", | 1401 | dev_vdbg(&udev->dev, "%s: cnt %d -> %d\n", |
1428 | __func__, atomic_read(&udev->dev.power.usage_count), | 1402 | __func__, atomic_read(&udev->dev.power.usage_count), |
1429 | status); | 1403 | status); |
@@ -1482,7 +1456,7 @@ void usb_autopm_put_interface(struct usb_interface *intf) | |||
1482 | struct usb_device *udev = interface_to_usbdev(intf); | 1456 | struct usb_device *udev = interface_to_usbdev(intf); |
1483 | int status; | 1457 | int status; |
1484 | 1458 | ||
1485 | udev->last_busy = jiffies; | 1459 | usb_mark_last_busy(udev); |
1486 | atomic_dec(&intf->pm_usage_cnt); | 1460 | atomic_dec(&intf->pm_usage_cnt); |
1487 | status = pm_runtime_put_sync(&intf->dev); | 1461 | status = pm_runtime_put_sync(&intf->dev); |
1488 | dev_vdbg(&intf->dev, "%s: cnt %d -> %d\n", | 1462 | dev_vdbg(&intf->dev, "%s: cnt %d -> %d\n", |
@@ -1509,32 +1483,11 @@ EXPORT_SYMBOL_GPL(usb_autopm_put_interface); | |||
1509 | void usb_autopm_put_interface_async(struct usb_interface *intf) | 1483 | void usb_autopm_put_interface_async(struct usb_interface *intf) |
1510 | { | 1484 | { |
1511 | struct usb_device *udev = interface_to_usbdev(intf); | 1485 | struct usb_device *udev = interface_to_usbdev(intf); |
1512 | unsigned long last_busy; | 1486 | int status; |
1513 | int status = 0; | ||
1514 | 1487 | ||
1515 | last_busy = udev->last_busy; | 1488 | usb_mark_last_busy(udev); |
1516 | udev->last_busy = jiffies; | ||
1517 | atomic_dec(&intf->pm_usage_cnt); | 1489 | atomic_dec(&intf->pm_usage_cnt); |
1518 | pm_runtime_put_noidle(&intf->dev); | 1490 | status = pm_runtime_put(&intf->dev); |
1519 | |||
1520 | if (udev->dev.power.runtime_auto) { | ||
1521 | /* Optimization: Don't schedule a delayed autosuspend if | ||
1522 | * the timer is already running and the expiration time | ||
1523 | * wouldn't change. | ||
1524 | * | ||
1525 | * We have to use the interface's timer. Attempts to | ||
1526 | * schedule a suspend for the device would fail because | ||
1527 | * the interface is still active. | ||
1528 | */ | ||
1529 | if (intf->dev.power.timer_expires == 0 || | ||
1530 | round_jiffies_up(last_busy) != | ||
1531 | round_jiffies_up(jiffies)) { | ||
1532 | status = pm_schedule_suspend(&intf->dev, | ||
1533 | jiffies_to_msecs( | ||
1534 | round_jiffies_up_relative( | ||
1535 | udev->autosuspend_delay))); | ||
1536 | } | ||
1537 | } | ||
1538 | dev_vdbg(&intf->dev, "%s: cnt %d -> %d\n", | 1491 | dev_vdbg(&intf->dev, "%s: cnt %d -> %d\n", |
1539 | __func__, atomic_read(&intf->dev.power.usage_count), | 1492 | __func__, atomic_read(&intf->dev.power.usage_count), |
1540 | status); | 1493 | status); |
@@ -1554,7 +1507,7 @@ void usb_autopm_put_interface_no_suspend(struct usb_interface *intf) | |||
1554 | { | 1507 | { |
1555 | struct usb_device *udev = interface_to_usbdev(intf); | 1508 | struct usb_device *udev = interface_to_usbdev(intf); |
1556 | 1509 | ||
1557 | udev->last_busy = jiffies; | 1510 | usb_mark_last_busy(udev); |
1558 | atomic_dec(&intf->pm_usage_cnt); | 1511 | atomic_dec(&intf->pm_usage_cnt); |
1559 | pm_runtime_put_noidle(&intf->dev); | 1512 | pm_runtime_put_noidle(&intf->dev); |
1560 | } | 1513 | } |
@@ -1612,18 +1565,9 @@ EXPORT_SYMBOL_GPL(usb_autopm_get_interface); | |||
1612 | */ | 1565 | */ |
1613 | int usb_autopm_get_interface_async(struct usb_interface *intf) | 1566 | int usb_autopm_get_interface_async(struct usb_interface *intf) |
1614 | { | 1567 | { |
1615 | int status = 0; | 1568 | int status; |
1616 | enum rpm_status s; | ||
1617 | |||
1618 | /* Don't request a resume unless the interface is already suspending | ||
1619 | * or suspended. Doing so would force a running suspend timer to be | ||
1620 | * cancelled. | ||
1621 | */ | ||
1622 | pm_runtime_get_noresume(&intf->dev); | ||
1623 | s = ACCESS_ONCE(intf->dev.power.runtime_status); | ||
1624 | if (s == RPM_SUSPENDING || s == RPM_SUSPENDED) | ||
1625 | status = pm_request_resume(&intf->dev); | ||
1626 | 1569 | ||
1570 | status = pm_runtime_get(&intf->dev); | ||
1627 | if (status < 0 && status != -EINPROGRESS) | 1571 | if (status < 0 && status != -EINPROGRESS) |
1628 | pm_runtime_put_noidle(&intf->dev); | 1572 | pm_runtime_put_noidle(&intf->dev); |
1629 | else | 1573 | else |
@@ -1650,7 +1594,7 @@ void usb_autopm_get_interface_no_resume(struct usb_interface *intf) | |||
1650 | { | 1594 | { |
1651 | struct usb_device *udev = interface_to_usbdev(intf); | 1595 | struct usb_device *udev = interface_to_usbdev(intf); |
1652 | 1596 | ||
1653 | udev->last_busy = jiffies; | 1597 | usb_mark_last_busy(udev); |
1654 | atomic_inc(&intf->pm_usage_cnt); | 1598 | atomic_inc(&intf->pm_usage_cnt); |
1655 | pm_runtime_get_noresume(&intf->dev); | 1599 | pm_runtime_get_noresume(&intf->dev); |
1656 | } | 1600 | } |
@@ -1661,7 +1605,6 @@ static int autosuspend_check(struct usb_device *udev) | |||
1661 | { | 1605 | { |
1662 | int w, i; | 1606 | int w, i; |
1663 | struct usb_interface *intf; | 1607 | struct usb_interface *intf; |
1664 | unsigned long suspend_time, j; | ||
1665 | 1608 | ||
1666 | /* Fail if autosuspend is disabled, or any interfaces are in use, or | 1609 | /* Fail if autosuspend is disabled, or any interfaces are in use, or |
1667 | * any interface drivers require remote wakeup but it isn't available. | 1610 | * any interface drivers require remote wakeup but it isn't available. |
@@ -1701,87 +1644,46 @@ static int autosuspend_check(struct usb_device *udev) | |||
1701 | return -EOPNOTSUPP; | 1644 | return -EOPNOTSUPP; |
1702 | } | 1645 | } |
1703 | udev->do_remote_wakeup = w; | 1646 | udev->do_remote_wakeup = w; |
1704 | |||
1705 | /* If everything is okay but the device hasn't been idle for long | ||
1706 | * enough, queue a delayed autosuspend request. | ||
1707 | */ | ||
1708 | j = ACCESS_ONCE(jiffies); | ||
1709 | suspend_time = udev->last_busy + udev->autosuspend_delay; | ||
1710 | if (time_before(j, suspend_time)) { | ||
1711 | pm_schedule_suspend(&udev->dev, jiffies_to_msecs( | ||
1712 | round_jiffies_up_relative(suspend_time - j))); | ||
1713 | return -EAGAIN; | ||
1714 | } | ||
1715 | return 0; | 1647 | return 0; |
1716 | } | 1648 | } |
1717 | 1649 | ||
1718 | static int usb_runtime_suspend(struct device *dev) | 1650 | static int usb_runtime_suspend(struct device *dev) |
1719 | { | 1651 | { |
1720 | int status = 0; | 1652 | struct usb_device *udev = to_usb_device(dev); |
1653 | int status; | ||
1721 | 1654 | ||
1722 | /* A USB device can be suspended if it passes the various autosuspend | 1655 | /* A USB device can be suspended if it passes the various autosuspend |
1723 | * checks. Runtime suspend for a USB device means suspending all the | 1656 | * checks. Runtime suspend for a USB device means suspending all the |
1724 | * interfaces and then the device itself. | 1657 | * interfaces and then the device itself. |
1725 | */ | 1658 | */ |
1726 | if (is_usb_device(dev)) { | 1659 | if (autosuspend_check(udev) != 0) |
1727 | struct usb_device *udev = to_usb_device(dev); | 1660 | return -EAGAIN; |
1728 | |||
1729 | if (autosuspend_check(udev) != 0) | ||
1730 | return -EAGAIN; | ||
1731 | |||
1732 | status = usb_suspend_both(udev, PMSG_AUTO_SUSPEND); | ||
1733 | |||
1734 | /* If an interface fails the suspend, adjust the last_busy | ||
1735 | * time so that we don't get another suspend attempt right | ||
1736 | * away. | ||
1737 | */ | ||
1738 | if (status) { | ||
1739 | udev->last_busy = jiffies + | ||
1740 | (udev->autosuspend_delay == 0 ? | ||
1741 | HZ/2 : 0); | ||
1742 | } | ||
1743 | |||
1744 | /* Prevent the parent from suspending immediately after */ | ||
1745 | else if (udev->parent) | ||
1746 | udev->parent->last_busy = jiffies; | ||
1747 | } | ||
1748 | 1661 | ||
1749 | /* Runtime suspend for a USB interface doesn't mean anything. */ | 1662 | status = usb_suspend_both(udev, PMSG_AUTO_SUSPEND); |
1750 | return status; | 1663 | return status; |
1751 | } | 1664 | } |
1752 | 1665 | ||
1753 | static int usb_runtime_resume(struct device *dev) | 1666 | static int usb_runtime_resume(struct device *dev) |
1754 | { | 1667 | { |
1668 | struct usb_device *udev = to_usb_device(dev); | ||
1669 | int status; | ||
1670 | |||
1755 | /* Runtime resume for a USB device means resuming both the device | 1671 | /* Runtime resume for a USB device means resuming both the device |
1756 | * and all its interfaces. | 1672 | * and all its interfaces. |
1757 | */ | 1673 | */ |
1758 | if (is_usb_device(dev)) { | 1674 | status = usb_resume_both(udev, PMSG_AUTO_RESUME); |
1759 | struct usb_device *udev = to_usb_device(dev); | 1675 | return status; |
1760 | int status; | ||
1761 | |||
1762 | status = usb_resume_both(udev, PMSG_AUTO_RESUME); | ||
1763 | udev->last_busy = jiffies; | ||
1764 | return status; | ||
1765 | } | ||
1766 | |||
1767 | /* Runtime resume for a USB interface doesn't mean anything. */ | ||
1768 | return 0; | ||
1769 | } | 1676 | } |
1770 | 1677 | ||
1771 | static int usb_runtime_idle(struct device *dev) | 1678 | static int usb_runtime_idle(struct device *dev) |
1772 | { | 1679 | { |
1680 | struct usb_device *udev = to_usb_device(dev); | ||
1681 | |||
1773 | /* An idle USB device can be suspended if it passes the various | 1682 | /* An idle USB device can be suspended if it passes the various |
1774 | * autosuspend checks. An idle interface can be suspended at | 1683 | * autosuspend checks. |
1775 | * any time. | ||
1776 | */ | 1684 | */ |
1777 | if (is_usb_device(dev)) { | 1685 | if (autosuspend_check(udev) == 0) |
1778 | struct usb_device *udev = to_usb_device(dev); | 1686 | pm_runtime_autosuspend(dev); |
1779 | |||
1780 | if (autosuspend_check(udev) != 0) | ||
1781 | return 0; | ||
1782 | } | ||
1783 | |||
1784 | pm_runtime_suspend(dev); | ||
1785 | return 0; | 1687 | return 0; |
1786 | } | 1688 | } |
1787 | 1689 | ||
diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c index 3799573bd385..b55d46070a25 100644 --- a/drivers/usb/core/hcd-pci.c +++ b/drivers/usb/core/hcd-pci.c | |||
@@ -19,7 +19,6 @@ | |||
19 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
21 | #include <linux/pci.h> | 21 | #include <linux/pci.h> |
22 | #include <linux/pm_runtime.h> | ||
23 | #include <linux/usb.h> | 22 | #include <linux/usb.h> |
24 | #include <linux/usb/hcd.h> | 23 | #include <linux/usb/hcd.h> |
25 | 24 | ||
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index ced846ac4141..6a95017fa62b 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c | |||
@@ -38,7 +38,6 @@ | |||
38 | #include <asm/unaligned.h> | 38 | #include <asm/unaligned.h> |
39 | #include <linux/platform_device.h> | 39 | #include <linux/platform_device.h> |
40 | #include <linux/workqueue.h> | 40 | #include <linux/workqueue.h> |
41 | #include <linux/pm_runtime.h> | ||
42 | 41 | ||
43 | #include <linux/usb.h> | 42 | #include <linux/usb.h> |
44 | #include <linux/usb/hcd.h> | 43 | #include <linux/usb/hcd.h> |
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 27115b45edc5..b98efae6a1cf 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
@@ -24,7 +24,6 @@ | |||
24 | #include <linux/kthread.h> | 24 | #include <linux/kthread.h> |
25 | #include <linux/mutex.h> | 25 | #include <linux/mutex.h> |
26 | #include <linux/freezer.h> | 26 | #include <linux/freezer.h> |
27 | #include <linux/pm_runtime.h> | ||
28 | 27 | ||
29 | #include <asm/uaccess.h> | 28 | #include <asm/uaccess.h> |
30 | #include <asm/byteorder.h> | 29 | #include <asm/byteorder.h> |
@@ -1804,8 +1803,15 @@ int usb_new_device(struct usb_device *udev) | |||
1804 | 1803 | ||
1805 | /* Tell the runtime-PM framework the device is active */ | 1804 | /* Tell the runtime-PM framework the device is active */ |
1806 | pm_runtime_set_active(&udev->dev); | 1805 | pm_runtime_set_active(&udev->dev); |
1806 | pm_runtime_get_noresume(&udev->dev); | ||
1807 | pm_runtime_use_autosuspend(&udev->dev); | ||
1807 | pm_runtime_enable(&udev->dev); | 1808 | pm_runtime_enable(&udev->dev); |
1808 | 1809 | ||
1810 | /* By default, forbid autosuspend for all devices. It will be | ||
1811 | * allowed for hubs during binding. | ||
1812 | */ | ||
1813 | usb_disable_autosuspend(udev); | ||
1814 | |||
1809 | err = usb_enumerate_device(udev); /* Read descriptors */ | 1815 | err = usb_enumerate_device(udev); /* Read descriptors */ |
1810 | if (err < 0) | 1816 | if (err < 0) |
1811 | goto fail; | 1817 | goto fail; |
@@ -1831,6 +1837,8 @@ int usb_new_device(struct usb_device *udev) | |||
1831 | } | 1837 | } |
1832 | 1838 | ||
1833 | (void) usb_create_ep_devs(&udev->dev, &udev->ep0, udev); | 1839 | (void) usb_create_ep_devs(&udev->dev, &udev->ep0, udev); |
1840 | usb_mark_last_busy(udev); | ||
1841 | pm_runtime_put_sync_autosuspend(&udev->dev); | ||
1834 | return err; | 1842 | return err; |
1835 | 1843 | ||
1836 | fail: | 1844 | fail: |
@@ -2221,6 +2229,7 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg) | |||
2221 | usb_set_device_state(udev, USB_STATE_SUSPENDED); | 2229 | usb_set_device_state(udev, USB_STATE_SUSPENDED); |
2222 | msleep(10); | 2230 | msleep(10); |
2223 | } | 2231 | } |
2232 | usb_mark_last_busy(hub->hdev); | ||
2224 | return status; | 2233 | return status; |
2225 | } | 2234 | } |
2226 | 2235 | ||
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index d6e3e410477e..832487423826 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c | |||
@@ -1804,6 +1804,7 @@ free_interfaces: | |||
1804 | INIT_WORK(&intf->reset_ws, __usb_queue_reset_device); | 1804 | INIT_WORK(&intf->reset_ws, __usb_queue_reset_device); |
1805 | intf->minor = -1; | 1805 | intf->minor = -1; |
1806 | device_initialize(&intf->dev); | 1806 | device_initialize(&intf->dev); |
1807 | pm_runtime_no_callbacks(&intf->dev); | ||
1807 | dev_set_name(&intf->dev, "%d-%s:%d.%d", | 1808 | dev_set_name(&intf->dev, "%d-%s:%d.%d", |
1808 | dev->bus->busnum, dev->devpath, | 1809 | dev->bus->busnum, dev->devpath, |
1809 | configuration, alt->desc.bInterfaceNumber); | 1810 | configuration, alt->desc.bInterfaceNumber); |
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index 25719da45e33..44c595432d6f 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c | |||
@@ -117,21 +117,6 @@ void usb_detect_quirks(struct usb_device *udev) | |||
117 | dev_dbg(&udev->dev, "USB quirks for this device: %x\n", | 117 | dev_dbg(&udev->dev, "USB quirks for this device: %x\n", |
118 | udev->quirks); | 118 | udev->quirks); |
119 | 119 | ||
120 | #ifdef CONFIG_USB_SUSPEND | ||
121 | |||
122 | /* By default, disable autosuspend for all devices. The hub driver | ||
123 | * will enable it for hubs. | ||
124 | */ | ||
125 | usb_disable_autosuspend(udev); | ||
126 | |||
127 | /* Autosuspend can also be disabled if the initial autosuspend_delay | ||
128 | * is negative. | ||
129 | */ | ||
130 | if (udev->autosuspend_delay < 0) | ||
131 | usb_autoresume_device(udev); | ||
132 | |||
133 | #endif | ||
134 | |||
135 | /* For the present, all devices default to USB-PERSIST enabled */ | 120 | /* For the present, all devices default to USB-PERSIST enabled */ |
136 | #if 0 /* was: #ifdef CONFIG_PM */ | 121 | #if 0 /* was: #ifdef CONFIG_PM */ |
137 | /* Hubs are automatically enabled for USB-PERSIST */ | 122 | /* Hubs are automatically enabled for USB-PERSIST */ |
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index 448f5b47fc48..6781c369ce2d 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c | |||
@@ -233,8 +233,6 @@ static DEVICE_ATTR(urbnum, S_IRUGO, show_urbnum, NULL); | |||
233 | 233 | ||
234 | #ifdef CONFIG_PM | 234 | #ifdef CONFIG_PM |
235 | 235 | ||
236 | static const char power_group[] = "power"; | ||
237 | |||
238 | static ssize_t | 236 | static ssize_t |
239 | show_persist(struct device *dev, struct device_attribute *attr, char *buf) | 237 | show_persist(struct device *dev, struct device_attribute *attr, char *buf) |
240 | { | 238 | { |
@@ -278,7 +276,7 @@ static int add_persist_attributes(struct device *dev) | |||
278 | if (udev->descriptor.bDeviceClass != USB_CLASS_HUB) | 276 | if (udev->descriptor.bDeviceClass != USB_CLASS_HUB) |
279 | rc = sysfs_add_file_to_group(&dev->kobj, | 277 | rc = sysfs_add_file_to_group(&dev->kobj, |
280 | &dev_attr_persist.attr, | 278 | &dev_attr_persist.attr, |
281 | power_group); | 279 | power_group_name); |
282 | } | 280 | } |
283 | return rc; | 281 | return rc; |
284 | } | 282 | } |
@@ -287,7 +285,7 @@ static void remove_persist_attributes(struct device *dev) | |||
287 | { | 285 | { |
288 | sysfs_remove_file_from_group(&dev->kobj, | 286 | sysfs_remove_file_from_group(&dev->kobj, |
289 | &dev_attr_persist.attr, | 287 | &dev_attr_persist.attr, |
290 | power_group); | 288 | power_group_name); |
291 | } | 289 | } |
292 | #else | 290 | #else |
293 | 291 | ||
@@ -336,44 +334,20 @@ static DEVICE_ATTR(active_duration, S_IRUGO, show_active_duration, NULL); | |||
336 | static ssize_t | 334 | static ssize_t |
337 | show_autosuspend(struct device *dev, struct device_attribute *attr, char *buf) | 335 | show_autosuspend(struct device *dev, struct device_attribute *attr, char *buf) |
338 | { | 336 | { |
339 | struct usb_device *udev = to_usb_device(dev); | 337 | return sprintf(buf, "%d\n", dev->power.autosuspend_delay / 1000); |
340 | |||
341 | return sprintf(buf, "%d\n", udev->autosuspend_delay / HZ); | ||
342 | } | 338 | } |
343 | 339 | ||
344 | static ssize_t | 340 | static ssize_t |
345 | set_autosuspend(struct device *dev, struct device_attribute *attr, | 341 | set_autosuspend(struct device *dev, struct device_attribute *attr, |
346 | const char *buf, size_t count) | 342 | const char *buf, size_t count) |
347 | { | 343 | { |
348 | struct usb_device *udev = to_usb_device(dev); | 344 | int value; |
349 | int value, old_delay; | ||
350 | int rc; | ||
351 | 345 | ||
352 | if (sscanf(buf, "%d", &value) != 1 || value >= INT_MAX/HZ || | 346 | if (sscanf(buf, "%d", &value) != 1 || value >= INT_MAX/1000 || |
353 | value <= - INT_MAX/HZ) | 347 | value <= -INT_MAX/1000) |
354 | return -EINVAL; | 348 | return -EINVAL; |
355 | value *= HZ; | ||
356 | |||
357 | usb_lock_device(udev); | ||
358 | old_delay = udev->autosuspend_delay; | ||
359 | udev->autosuspend_delay = value; | ||
360 | |||
361 | if (old_delay < 0) { /* Autosuspend wasn't allowed */ | ||
362 | if (value >= 0) | ||
363 | usb_autosuspend_device(udev); | ||
364 | } else { /* Autosuspend was allowed */ | ||
365 | if (value < 0) { | ||
366 | rc = usb_autoresume_device(udev); | ||
367 | if (rc < 0) { | ||
368 | count = rc; | ||
369 | udev->autosuspend_delay = old_delay; | ||
370 | } | ||
371 | } else { | ||
372 | usb_try_autosuspend_device(udev); | ||
373 | } | ||
374 | } | ||
375 | 349 | ||
376 | usb_unlock_device(udev); | 350 | pm_runtime_set_autosuspend_delay(dev, value * 1000); |
377 | return count; | 351 | return count; |
378 | } | 352 | } |
379 | 353 | ||
@@ -438,44 +412,30 @@ set_level(struct device *dev, struct device_attribute *attr, | |||
438 | 412 | ||
439 | static DEVICE_ATTR(level, S_IRUGO | S_IWUSR, show_level, set_level); | 413 | static DEVICE_ATTR(level, S_IRUGO | S_IWUSR, show_level, set_level); |
440 | 414 | ||
415 | static struct attribute *power_attrs[] = { | ||
416 | &dev_attr_autosuspend.attr, | ||
417 | &dev_attr_level.attr, | ||
418 | &dev_attr_connected_duration.attr, | ||
419 | &dev_attr_active_duration.attr, | ||
420 | NULL, | ||
421 | }; | ||
422 | static struct attribute_group power_attr_group = { | ||
423 | .name = power_group_name, | ||
424 | .attrs = power_attrs, | ||
425 | }; | ||
426 | |||
441 | static int add_power_attributes(struct device *dev) | 427 | static int add_power_attributes(struct device *dev) |
442 | { | 428 | { |
443 | int rc = 0; | 429 | int rc = 0; |
444 | 430 | ||
445 | if (is_usb_device(dev)) { | 431 | if (is_usb_device(dev)) |
446 | rc = sysfs_add_file_to_group(&dev->kobj, | 432 | rc = sysfs_merge_group(&dev->kobj, &power_attr_group); |
447 | &dev_attr_autosuspend.attr, | ||
448 | power_group); | ||
449 | if (rc == 0) | ||
450 | rc = sysfs_add_file_to_group(&dev->kobj, | ||
451 | &dev_attr_level.attr, | ||
452 | power_group); | ||
453 | if (rc == 0) | ||
454 | rc = sysfs_add_file_to_group(&dev->kobj, | ||
455 | &dev_attr_connected_duration.attr, | ||
456 | power_group); | ||
457 | if (rc == 0) | ||
458 | rc = sysfs_add_file_to_group(&dev->kobj, | ||
459 | &dev_attr_active_duration.attr, | ||
460 | power_group); | ||
461 | } | ||
462 | return rc; | 433 | return rc; |
463 | } | 434 | } |
464 | 435 | ||
465 | static void remove_power_attributes(struct device *dev) | 436 | static void remove_power_attributes(struct device *dev) |
466 | { | 437 | { |
467 | sysfs_remove_file_from_group(&dev->kobj, | 438 | sysfs_unmerge_group(&dev->kobj, &power_attr_group); |
468 | &dev_attr_active_duration.attr, | ||
469 | power_group); | ||
470 | sysfs_remove_file_from_group(&dev->kobj, | ||
471 | &dev_attr_connected_duration.attr, | ||
472 | power_group); | ||
473 | sysfs_remove_file_from_group(&dev->kobj, | ||
474 | &dev_attr_level.attr, | ||
475 | power_group); | ||
476 | sysfs_remove_file_from_group(&dev->kobj, | ||
477 | &dev_attr_autosuspend.attr, | ||
478 | power_group); | ||
479 | } | 439 | } |
480 | 440 | ||
481 | #else | 441 | #else |
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index fdd4130fbb7d..079cb57bab4f 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c | |||
@@ -445,7 +445,8 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent, | |||
445 | INIT_LIST_HEAD(&dev->filelist); | 445 | INIT_LIST_HEAD(&dev->filelist); |
446 | 446 | ||
447 | #ifdef CONFIG_PM | 447 | #ifdef CONFIG_PM |
448 | dev->autosuspend_delay = usb_autosuspend_delay * HZ; | 448 | pm_runtime_set_autosuspend_delay(&dev->dev, |
449 | usb_autosuspend_delay * 1000); | ||
449 | dev->connect_time = jiffies; | 450 | dev->connect_time = jiffies; |
450 | dev->active_duration = -jiffies; | 451 | dev->active_duration = -jiffies; |
451 | #endif | 452 | #endif |
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h index cd882203ad34..b975450f403e 100644 --- a/drivers/usb/core/usb.h +++ b/drivers/usb/core/usb.h | |||
@@ -75,14 +75,12 @@ static inline int usb_port_resume(struct usb_device *udev, pm_message_t msg) | |||
75 | #ifdef CONFIG_USB_SUSPEND | 75 | #ifdef CONFIG_USB_SUSPEND |
76 | 76 | ||
77 | extern void usb_autosuspend_device(struct usb_device *udev); | 77 | extern void usb_autosuspend_device(struct usb_device *udev); |
78 | extern void usb_try_autosuspend_device(struct usb_device *udev); | ||
79 | extern int usb_autoresume_device(struct usb_device *udev); | 78 | extern int usb_autoresume_device(struct usb_device *udev); |
80 | extern int usb_remote_wakeup(struct usb_device *dev); | 79 | extern int usb_remote_wakeup(struct usb_device *dev); |
81 | 80 | ||
82 | #else | 81 | #else |
83 | 82 | ||
84 | #define usb_autosuspend_device(udev) do {} while (0) | 83 | #define usb_autosuspend_device(udev) do {} while (0) |
85 | #define usb_try_autosuspend_device(udev) do {} while (0) | ||
86 | static inline int usb_autoresume_device(struct usb_device *udev) | 84 | static inline int usb_autoresume_device(struct usb_device *udev) |
87 | { | 85 | { |
88 | return 0; | 86 | return 0; |