aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/core/driver.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/core/driver.c')
-rw-r--r--drivers/usb/core/driver.c31
1 files changed, 25 insertions, 6 deletions
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index 34e3da5aa72a..45887a0ff873 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -24,6 +24,7 @@
24 24
25#include <linux/device.h> 25#include <linux/device.h>
26#include <linux/slab.h> 26#include <linux/slab.h>
27#include <linux/export.h>
27#include <linux/usb.h> 28#include <linux/usb.h>
28#include <linux/usb/quirks.h> 29#include <linux/usb/quirks.h>
29#include <linux/usb/hcd.h> 30#include <linux/usb/hcd.h>
@@ -1046,8 +1047,7 @@ static int usb_resume_device(struct usb_device *udev, pm_message_t msg)
1046 /* Non-root devices on a full/low-speed bus must wait for their 1047 /* Non-root devices on a full/low-speed bus must wait for their
1047 * companion high-speed root hub, in case a handoff is needed. 1048 * companion high-speed root hub, in case a handoff is needed.
1048 */ 1049 */
1049 if (!(msg.event & PM_EVENT_AUTO) && udev->parent && 1050 if (!PMSG_IS_AUTO(msg) && udev->parent && udev->bus->hs_companion)
1050 udev->bus->hs_companion)
1051 device_pm_wait_for_dev(&udev->dev, 1051 device_pm_wait_for_dev(&udev->dev,
1052 &udev->bus->hs_companion->root_hub->dev); 1052 &udev->bus->hs_companion->root_hub->dev);
1053 1053
@@ -1075,7 +1075,7 @@ static int usb_suspend_interface(struct usb_device *udev,
1075 1075
1076 if (driver->suspend) { 1076 if (driver->suspend) {
1077 status = driver->suspend(intf, msg); 1077 status = driver->suspend(intf, msg);
1078 if (status && !(msg.event & PM_EVENT_AUTO)) 1078 if (status && !PMSG_IS_AUTO(msg))
1079 dev_err(&intf->dev, "%s error %d\n", 1079 dev_err(&intf->dev, "%s error %d\n",
1080 "suspend", status); 1080 "suspend", status);
1081 } else { 1081 } else {
@@ -1189,7 +1189,7 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg)
1189 status = usb_suspend_interface(udev, intf, msg); 1189 status = usb_suspend_interface(udev, intf, msg);
1190 1190
1191 /* Ignore errors during system sleep transitions */ 1191 /* Ignore errors during system sleep transitions */
1192 if (!(msg.event & PM_EVENT_AUTO)) 1192 if (!PMSG_IS_AUTO(msg))
1193 status = 0; 1193 status = 0;
1194 if (status != 0) 1194 if (status != 0)
1195 break; 1195 break;
@@ -1199,7 +1199,7 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg)
1199 status = usb_suspend_device(udev, msg); 1199 status = usb_suspend_device(udev, msg);
1200 1200
1201 /* Again, ignore errors during system sleep transitions */ 1201 /* Again, ignore errors during system sleep transitions */
1202 if (!(msg.event & PM_EVENT_AUTO)) 1202 if (!PMSG_IS_AUTO(msg))
1203 status = 0; 1203 status = 0;
1204 } 1204 }
1205 1205
@@ -1583,7 +1583,7 @@ int usb_autopm_get_interface_async(struct usb_interface *intf)
1583 dev_vdbg(&intf->dev, "%s: cnt %d -> %d\n", 1583 dev_vdbg(&intf->dev, "%s: cnt %d -> %d\n",
1584 __func__, atomic_read(&intf->dev.power.usage_count), 1584 __func__, atomic_read(&intf->dev.power.usage_count),
1585 status); 1585 status);
1586 if (status > 0) 1586 if (status > 0 || status == -EINPROGRESS)
1587 status = 0; 1587 status = 0;
1588 return status; 1588 return status;
1589} 1589}
@@ -1668,6 +1668,11 @@ int usb_runtime_suspend(struct device *dev)
1668 return -EAGAIN; 1668 return -EAGAIN;
1669 1669
1670 status = usb_suspend_both(udev, PMSG_AUTO_SUSPEND); 1670 status = usb_suspend_both(udev, PMSG_AUTO_SUSPEND);
1671
1672 /* Allow a retry if autosuspend failed temporarily */
1673 if (status == -EAGAIN || status == -EBUSY)
1674 usb_mark_last_busy(udev);
1675
1671 /* The PM core reacts badly unless the return code is 0, 1676 /* The PM core reacts badly unless the return code is 0,
1672 * -EAGAIN, or -EBUSY, so always return -EBUSY on an error. 1677 * -EAGAIN, or -EBUSY, so always return -EBUSY on an error.
1673 */ 1678 */
@@ -1700,6 +1705,20 @@ int usb_runtime_idle(struct device *dev)
1700 return 0; 1705 return 0;
1701} 1706}
1702 1707
1708int usb_set_usb2_hardware_lpm(struct usb_device *udev, int enable)
1709{
1710 struct usb_hcd *hcd = bus_to_hcd(udev->bus);
1711 int ret = -EPERM;
1712
1713 if (hcd->driver->set_usb2_hw_lpm) {
1714 ret = hcd->driver->set_usb2_hw_lpm(hcd, udev, enable);
1715 if (!ret)
1716 udev->usb2_hw_lpm_enabled = enable;
1717 }
1718
1719 return ret;
1720}
1721
1703#endif /* CONFIG_USB_SUSPEND */ 1722#endif /* CONFIG_USB_SUSPEND */
1704 1723
1705struct bus_type usb_bus_type = { 1724struct bus_type usb_bus_type = {