aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMing Lei <tom.leiming@gmail.com>2010-11-15 15:56:54 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2010-11-16 17:02:00 -0500
commit63defa73c8c1193c1273474440c30d34c2524597 (patch)
tree3d7cbe9351e507ca2e55a874e496398979602ec1
parentf646cf94520e22cb11eb5d2e9a35b33bfe4bea1b (diff)
USB: use the no_callbacks flag for interfaces
Call pm_runtime_no_callbacks to set no_callbacks flag for USB interfaces. Since interfaces cannot be power-managed separately from their parent devices, there's no reason for the runtime-PM core to invoke any callbacks for them. Signed-off-by: Ming Lei <tom.leiming@gmail.com> Reviewed-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/usb/core/driver.c82
-rw-r--r--drivers/usb/core/message.c2
2 files changed, 31 insertions, 53 deletions
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index c0e60fbcb048..eda2d2c25459 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -1612,18 +1612,9 @@ EXPORT_SYMBOL_GPL(usb_autopm_get_interface);
1612 */ 1612 */
1613int usb_autopm_get_interface_async(struct usb_interface *intf) 1613int usb_autopm_get_interface_async(struct usb_interface *intf)
1614{ 1614{
1615 int status = 0; 1615 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 1616
1617 status = pm_runtime_get(&intf->dev);
1627 if (status < 0 && status != -EINPROGRESS) 1618 if (status < 0 && status != -EINPROGRESS)
1628 pm_runtime_put_noidle(&intf->dev); 1619 pm_runtime_put_noidle(&intf->dev);
1629 else 1620 else
@@ -1717,71 +1708,56 @@ static int autosuspend_check(struct usb_device *udev)
1717 1708
1718static int usb_runtime_suspend(struct device *dev) 1709static int usb_runtime_suspend(struct device *dev)
1719{ 1710{
1720 int status = 0; 1711 struct usb_device *udev = to_usb_device(dev);
1712 int status;
1721 1713
1722 /* A USB device can be suspended if it passes the various autosuspend 1714 /* A USB device can be suspended if it passes the various autosuspend
1723 * checks. Runtime suspend for a USB device means suspending all the 1715 * checks. Runtime suspend for a USB device means suspending all the
1724 * interfaces and then the device itself. 1716 * interfaces and then the device itself.
1725 */ 1717 */
1726 if (is_usb_device(dev)) { 1718 if (autosuspend_check(udev) != 0)
1727 struct usb_device *udev = to_usb_device(dev); 1719 return -EAGAIN;
1728
1729 if (autosuspend_check(udev) != 0)
1730 return -EAGAIN;
1731
1732 status = usb_suspend_both(udev, PMSG_AUTO_SUSPEND);
1733 1720
1734 /* If an interface fails the suspend, adjust the last_busy 1721 status = usb_suspend_both(udev, PMSG_AUTO_SUSPEND);
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 1722
1744 /* Prevent the parent from suspending immediately after */ 1723 /* If an interface fails the suspend, adjust the last_busy
1745 else if (udev->parent) 1724 * time so that we don't get another suspend attempt right
1746 udev->parent->last_busy = jiffies; 1725 * away.
1726 */
1727 if (status) {
1728 udev->last_busy = jiffies +
1729 (udev->autosuspend_delay == 0 ? HZ/2 : 0);
1747 } 1730 }
1748 1731
1749 /* Runtime suspend for a USB interface doesn't mean anything. */ 1732 /* Prevent the parent from suspending immediately after */
1733 else if (udev->parent)
1734 udev->parent->last_busy = jiffies;
1735
1750 return status; 1736 return status;
1751} 1737}
1752 1738
1753static int usb_runtime_resume(struct device *dev) 1739static int usb_runtime_resume(struct device *dev)
1754{ 1740{
1741 struct usb_device *udev = to_usb_device(dev);
1742 int status;
1743
1755 /* Runtime resume for a USB device means resuming both the device 1744 /* Runtime resume for a USB device means resuming both the device
1756 * and all its interfaces. 1745 * and all its interfaces.
1757 */ 1746 */
1758 if (is_usb_device(dev)) { 1747 status = usb_resume_both(udev, PMSG_AUTO_RESUME);
1759 struct usb_device *udev = to_usb_device(dev); 1748 udev->last_busy = jiffies;
1760 int status; 1749 return 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} 1750}
1770 1751
1771static int usb_runtime_idle(struct device *dev) 1752static int usb_runtime_idle(struct device *dev)
1772{ 1753{
1754 struct usb_device *udev = to_usb_device(dev);
1755
1773 /* An idle USB device can be suspended if it passes the various 1756 /* An idle USB device can be suspended if it passes the various
1774 * autosuspend checks. An idle interface can be suspended at 1757 * autosuspend checks.
1775 * any time.
1776 */ 1758 */
1777 if (is_usb_device(dev)) { 1759 if (autosuspend_check(udev) == 0)
1778 struct usb_device *udev = to_usb_device(dev); 1760 pm_runtime_suspend(dev);
1779
1780 if (autosuspend_check(udev) != 0)
1781 return 0;
1782 }
1783
1784 pm_runtime_suspend(dev);
1785 return 0; 1761 return 0;
1786} 1762}
1787 1763
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index d6e3e410477e..f377e49fcb30 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -12,6 +12,7 @@
12#include <linux/ctype.h> 12#include <linux/ctype.h>
13#include <linux/nls.h> 13#include <linux/nls.h>
14#include <linux/device.h> 14#include <linux/device.h>
15#include <linux/pm_runtime.h>
15#include <linux/scatterlist.h> 16#include <linux/scatterlist.h>
16#include <linux/usb/quirks.h> 17#include <linux/usb/quirks.h>
17#include <linux/usb/hcd.h> /* for usbcore internals */ 18#include <linux/usb/hcd.h> /* for usbcore internals */
@@ -1804,6 +1805,7 @@ free_interfaces:
1804 INIT_WORK(&intf->reset_ws, __usb_queue_reset_device); 1805 INIT_WORK(&intf->reset_ws, __usb_queue_reset_device);
1805 intf->minor = -1; 1806 intf->minor = -1;
1806 device_initialize(&intf->dev); 1807 device_initialize(&intf->dev);
1808 pm_runtime_no_callbacks(&intf->dev);
1807 dev_set_name(&intf->dev, "%d-%s:%d.%d", 1809 dev_set_name(&intf->dev, "%d-%s:%d.%d",
1808 dev->bus->busnum, dev->devpath, 1810 dev->bus->busnum, dev->devpath,
1809 configuration, alt->desc.bInterfaceNumber); 1811 configuration, alt->desc.bInterfaceNumber);