aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2008-11-25 16:39:18 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2009-01-07 13:00:03 -0500
commit65bfd2967c906ca322a4bb69a285fe0de8916ac6 (patch)
treeddd3293f945613d0d27ec1dbd36030c079fb9492 /drivers/usb
parent4ec06d629628b6e5c7ff50d349a26ef5c35696e3 (diff)
USB: Enhance usage of pm_message_t
This patch (as1177) modifies the USB core suspend and resume routines. The resume functions now will take a pm_message_t argument, so they will know what sort of resume is occurring. The new argument is also passed to the port suspend/resume and bus suspend/resume routines (although they don't use it for anything but debugging). In addition, special pm_message_t values are used for user-initiated, device-initiated (i.e., remote wakeup), and automatic suspend/resume. By testing these values, drivers can tell whether or not a particular suspend was an autosuspend. Unfortunately, they can't do the same for resumes -- not until the pm_message_t argument is also passed to the drivers' resume methods. That will require a bigger change. IMO, the whole Power Management framework should have been set up this way in the first place. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/class/cdc-acm.c2
-rw-r--r--drivers/usb/class/cdc-wdm.c3
-rw-r--r--drivers/usb/core/driver.c61
-rw-r--r--drivers/usb/core/generic.c10
-rw-r--r--drivers/usb/core/hcd.c10
-rw-r--r--drivers/usb/core/hcd.h4
-rw-r--r--drivers/usb/core/hub.c16
-rw-r--r--drivers/usb/core/sysfs.c6
-rw-r--r--drivers/usb/core/usb.c8
-rw-r--r--drivers/usb/core/usb.h15
10 files changed, 73 insertions, 62 deletions
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index d50a99f70aee..00b47ea24f86 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -1275,7 +1275,7 @@ static int acm_suspend(struct usb_interface *intf, pm_message_t message)
1275 struct acm *acm = usb_get_intfdata(intf); 1275 struct acm *acm = usb_get_intfdata(intf);
1276 int cnt; 1276 int cnt;
1277 1277
1278 if (acm->dev->auto_pm) { 1278 if (message.event & PM_EVENT_AUTO) {
1279 int b; 1279 int b;
1280 1280
1281 spin_lock_irq(&acm->read_lock); 1281 spin_lock_irq(&acm->read_lock);
diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c
index 5a8ecc045e3f..3771d6e6d0cc 100644
--- a/drivers/usb/class/cdc-wdm.c
+++ b/drivers/usb/class/cdc-wdm.c
@@ -764,7 +764,8 @@ static int wdm_suspend(struct usb_interface *intf, pm_message_t message)
764 764
765 mutex_lock(&desc->plock); 765 mutex_lock(&desc->plock);
766#ifdef CONFIG_PM 766#ifdef CONFIG_PM
767 if (interface_to_usbdev(desc->intf)->auto_pm && test_bit(WDM_IN_USE, &desc->flags)) { 767 if ((message.event & PM_EVENT_AUTO) &&
768 test_bit(WDM_IN_USE, &desc->flags)) {
768 rv = -EBUSY; 769 rv = -EBUSY;
769 } else { 770 } else {
770#endif 771#endif
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index 0226e019326a..41c06025506e 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -922,7 +922,7 @@ static int usb_suspend_device(struct usb_device *udev, pm_message_t msg)
922} 922}
923 923
924/* Caller has locked udev's pm_mutex */ 924/* Caller has locked udev's pm_mutex */
925static int usb_resume_device(struct usb_device *udev) 925static int usb_resume_device(struct usb_device *udev, pm_message_t msg)
926{ 926{
927 struct usb_device_driver *udriver; 927 struct usb_device_driver *udriver;
928 int status = 0; 928 int status = 0;
@@ -940,7 +940,7 @@ static int usb_resume_device(struct usb_device *udev)
940 udev->reset_resume = 1; 940 udev->reset_resume = 1;
941 941
942 udriver = to_usb_device_driver(udev->dev.driver); 942 udriver = to_usb_device_driver(udev->dev.driver);
943 status = udriver->resume(udev); 943 status = udriver->resume(udev, msg);
944 944
945 done: 945 done:
946 dev_vdbg(&udev->dev, "%s: status %d\n", __func__, status); 946 dev_vdbg(&udev->dev, "%s: status %d\n", __func__, status);
@@ -969,7 +969,7 @@ static int usb_suspend_interface(struct usb_device *udev,
969 status = driver->suspend(intf, msg); 969 status = driver->suspend(intf, msg);
970 if (status == 0) 970 if (status == 0)
971 mark_quiesced(intf); 971 mark_quiesced(intf);
972 else if (!udev->auto_pm) 972 else if (!(msg.event & PM_EVENT_AUTO))
973 dev_err(&intf->dev, "%s error %d\n", 973 dev_err(&intf->dev, "%s error %d\n",
974 "suspend", status); 974 "suspend", status);
975 } else { 975 } else {
@@ -987,7 +987,7 @@ static int usb_suspend_interface(struct usb_device *udev,
987 987
988/* Caller has locked intf's usb_device's pm_mutex */ 988/* Caller has locked intf's usb_device's pm_mutex */
989static int usb_resume_interface(struct usb_device *udev, 989static int usb_resume_interface(struct usb_device *udev,
990 struct usb_interface *intf, int reset_resume) 990 struct usb_interface *intf, pm_message_t msg, int reset_resume)
991{ 991{
992 struct usb_driver *driver; 992 struct usb_driver *driver;
993 int status = 0; 993 int status = 0;
@@ -1138,10 +1138,9 @@ static inline int autosuspend_check(struct usb_device *udev, int reschedule)
1138 * all the interfaces which were suspended are resumed so that they remain 1138 * all the interfaces which were suspended are resumed so that they remain
1139 * in the same state as the device. 1139 * in the same state as the device.
1140 * 1140 *
1141 * If an autosuspend is in progress (@udev->auto_pm is set), the routine 1141 * If an autosuspend is in progress the routine checks first to make sure
1142 * checks first to make sure that neither the device itself or any of its 1142 * that neither the device itself or any of its active interfaces is in use
1143 * active interfaces is in use (pm_usage_cnt is greater than 0). If they 1143 * (pm_usage_cnt is greater than 0). If they are, the autosuspend fails.
1144 * are, the autosuspend fails.
1145 * 1144 *
1146 * If the suspend succeeds, the routine recursively queues an autosuspend 1145 * If the suspend succeeds, the routine recursively queues an autosuspend
1147 * request for @udev's parent device, thereby propagating the change up 1146 * request for @udev's parent device, thereby propagating the change up
@@ -1176,7 +1175,7 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg)
1176 1175
1177 udev->do_remote_wakeup = device_may_wakeup(&udev->dev); 1176 udev->do_remote_wakeup = device_may_wakeup(&udev->dev);
1178 1177
1179 if (udev->auto_pm) { 1178 if (msg.event & PM_EVENT_AUTO) {
1180 status = autosuspend_check(udev, 0); 1179 status = autosuspend_check(udev, 0);
1181 if (status < 0) 1180 if (status < 0)
1182 goto done; 1181 goto done;
@@ -1196,13 +1195,16 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg)
1196 1195
1197 /* If the suspend failed, resume interfaces that did get suspended */ 1196 /* If the suspend failed, resume interfaces that did get suspended */
1198 if (status != 0) { 1197 if (status != 0) {
1198 pm_message_t msg2;
1199
1200 msg2.event = msg.event ^ (PM_EVENT_SUSPEND | PM_EVENT_RESUME);
1199 while (--i >= 0) { 1201 while (--i >= 0) {
1200 intf = udev->actconfig->interface[i]; 1202 intf = udev->actconfig->interface[i];
1201 usb_resume_interface(udev, intf, 0); 1203 usb_resume_interface(udev, intf, msg2, 0);
1202 } 1204 }
1203 1205
1204 /* Try another autosuspend when the interfaces aren't busy */ 1206 /* Try another autosuspend when the interfaces aren't busy */
1205 if (udev->auto_pm) 1207 if (msg.event & PM_EVENT_AUTO)
1206 autosuspend_check(udev, status == -EBUSY); 1208 autosuspend_check(udev, status == -EBUSY);
1207 1209
1208 /* If the suspend succeeded then prevent any more URB submissions, 1210 /* If the suspend succeeded then prevent any more URB submissions,
@@ -1232,6 +1234,7 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg)
1232/** 1234/**
1233 * usb_resume_both - resume a USB device and its interfaces 1235 * usb_resume_both - resume a USB device and its interfaces
1234 * @udev: the usb_device to resume 1236 * @udev: the usb_device to resume
1237 * @msg: Power Management message describing this state transition
1235 * 1238 *
1236 * This is the central routine for resuming USB devices. It calls the 1239 * This is the central routine for resuming USB devices. It calls the
1237 * the resume method for @udev and then calls the resume methods for all 1240 * the resume method for @udev and then calls the resume methods for all
@@ -1257,7 +1260,7 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg)
1257 * 1260 *
1258 * This routine can run only in process context. 1261 * This routine can run only in process context.
1259 */ 1262 */
1260static int usb_resume_both(struct usb_device *udev) 1263static int usb_resume_both(struct usb_device *udev, pm_message_t msg)
1261{ 1264{
1262 int status = 0; 1265 int status = 0;
1263 int i; 1266 int i;
@@ -1273,14 +1276,15 @@ static int usb_resume_both(struct usb_device *udev)
1273 1276
1274 /* Propagate the resume up the tree, if necessary */ 1277 /* Propagate the resume up the tree, if necessary */
1275 if (udev->state == USB_STATE_SUSPENDED) { 1278 if (udev->state == USB_STATE_SUSPENDED) {
1276 if (udev->auto_pm && udev->autoresume_disabled) { 1279 if ((msg.event & PM_EVENT_AUTO) &&
1280 udev->autoresume_disabled) {
1277 status = -EPERM; 1281 status = -EPERM;
1278 goto done; 1282 goto done;
1279 } 1283 }
1280 if (parent) { 1284 if (parent) {
1281 status = usb_autoresume_device(parent); 1285 status = usb_autoresume_device(parent);
1282 if (status == 0) { 1286 if (status == 0) {
1283 status = usb_resume_device(udev); 1287 status = usb_resume_device(udev, msg);
1284 if (status || udev->state == 1288 if (status || udev->state ==
1285 USB_STATE_NOTATTACHED) { 1289 USB_STATE_NOTATTACHED) {
1286 usb_autosuspend_device(parent); 1290 usb_autosuspend_device(parent);
@@ -1303,15 +1307,16 @@ static int usb_resume_both(struct usb_device *udev)
1303 /* We can't progagate beyond the USB subsystem, 1307 /* We can't progagate beyond the USB subsystem,
1304 * so if a root hub's controller is suspended 1308 * so if a root hub's controller is suspended
1305 * then we're stuck. */ 1309 * then we're stuck. */
1306 status = usb_resume_device(udev); 1310 status = usb_resume_device(udev, msg);
1307 } 1311 }
1308 } else if (udev->reset_resume) 1312 } else if (udev->reset_resume)
1309 status = usb_resume_device(udev); 1313 status = usb_resume_device(udev, msg);
1310 1314
1311 if (status == 0 && udev->actconfig) { 1315 if (status == 0 && udev->actconfig) {
1312 for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) { 1316 for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) {
1313 intf = udev->actconfig->interface[i]; 1317 intf = udev->actconfig->interface[i];
1314 usb_resume_interface(udev, intf, udev->reset_resume); 1318 usb_resume_interface(udev, intf, msg,
1319 udev->reset_resume);
1315 } 1320 }
1316 } 1321 }
1317 1322
@@ -1339,13 +1344,13 @@ static int usb_autopm_do_device(struct usb_device *udev, int inc_usage_cnt)
1339 udev->last_busy = jiffies; 1344 udev->last_busy = jiffies;
1340 if (inc_usage_cnt >= 0 && udev->pm_usage_cnt > 0) { 1345 if (inc_usage_cnt >= 0 && udev->pm_usage_cnt > 0) {
1341 if (udev->state == USB_STATE_SUSPENDED) 1346 if (udev->state == USB_STATE_SUSPENDED)
1342 status = usb_resume_both(udev); 1347 status = usb_resume_both(udev, PMSG_AUTO_RESUME);
1343 if (status != 0) 1348 if (status != 0)
1344 udev->pm_usage_cnt -= inc_usage_cnt; 1349 udev->pm_usage_cnt -= inc_usage_cnt;
1345 else if (inc_usage_cnt) 1350 else if (inc_usage_cnt)
1346 udev->last_busy = jiffies; 1351 udev->last_busy = jiffies;
1347 } else if (inc_usage_cnt <= 0 && udev->pm_usage_cnt <= 0) { 1352 } else if (inc_usage_cnt <= 0 && udev->pm_usage_cnt <= 0) {
1348 status = usb_suspend_both(udev, PMSG_SUSPEND); 1353 status = usb_suspend_both(udev, PMSG_AUTO_SUSPEND);
1349 } 1354 }
1350 usb_pm_unlock(udev); 1355 usb_pm_unlock(udev);
1351 return status; 1356 return status;
@@ -1469,13 +1474,14 @@ static int usb_autopm_do_interface(struct usb_interface *intf,
1469 udev->last_busy = jiffies; 1474 udev->last_busy = jiffies;
1470 if (inc_usage_cnt >= 0 && intf->pm_usage_cnt > 0) { 1475 if (inc_usage_cnt >= 0 && intf->pm_usage_cnt > 0) {
1471 if (udev->state == USB_STATE_SUSPENDED) 1476 if (udev->state == USB_STATE_SUSPENDED)
1472 status = usb_resume_both(udev); 1477 status = usb_resume_both(udev,
1478 PMSG_AUTO_RESUME);
1473 if (status != 0) 1479 if (status != 0)
1474 intf->pm_usage_cnt -= inc_usage_cnt; 1480 intf->pm_usage_cnt -= inc_usage_cnt;
1475 else 1481 else
1476 udev->last_busy = jiffies; 1482 udev->last_busy = jiffies;
1477 } else if (inc_usage_cnt <= 0 && intf->pm_usage_cnt <= 0) { 1483 } else if (inc_usage_cnt <= 0 && intf->pm_usage_cnt <= 0) {
1478 status = usb_suspend_both(udev, PMSG_SUSPEND); 1484 status = usb_suspend_both(udev, PMSG_AUTO_SUSPEND);
1479 } 1485 }
1480 } 1486 }
1481 usb_pm_unlock(udev); 1487 usb_pm_unlock(udev);
@@ -1700,6 +1706,7 @@ int usb_external_suspend_device(struct usb_device *udev, pm_message_t msg)
1700/** 1706/**
1701 * usb_external_resume_device - external resume of a USB device and its interfaces 1707 * usb_external_resume_device - external resume of a USB device and its interfaces
1702 * @udev: the usb_device to resume 1708 * @udev: the usb_device to resume
1709 * @msg: Power Management message describing this state transition
1703 * 1710 *
1704 * This routine handles external resume requests: ones not generated 1711 * This routine handles external resume requests: ones not generated
1705 * internally by a USB driver (autoresume) but rather coming from the user 1712 * internally by a USB driver (autoresume) but rather coming from the user
@@ -1708,13 +1715,13 @@ int usb_external_suspend_device(struct usb_device *udev, pm_message_t msg)
1708 * 1715 *
1709 * The caller must hold @udev's device lock. 1716 * The caller must hold @udev's device lock.
1710 */ 1717 */
1711int usb_external_resume_device(struct usb_device *udev) 1718int usb_external_resume_device(struct usb_device *udev, pm_message_t msg)
1712{ 1719{
1713 int status; 1720 int status;
1714 1721
1715 usb_pm_lock(udev); 1722 usb_pm_lock(udev);
1716 udev->auto_pm = 0; 1723 udev->auto_pm = 0;
1717 status = usb_resume_both(udev); 1724 status = usb_resume_both(udev, msg);
1718 udev->last_busy = jiffies; 1725 udev->last_busy = jiffies;
1719 usb_pm_unlock(udev); 1726 usb_pm_unlock(udev);
1720 if (status == 0) 1727 if (status == 0)
@@ -1727,7 +1734,7 @@ int usb_external_resume_device(struct usb_device *udev)
1727 return status; 1734 return status;
1728} 1735}
1729 1736
1730int usb_suspend(struct device *dev, pm_message_t message) 1737int usb_suspend(struct device *dev, pm_message_t msg)
1731{ 1738{
1732 struct usb_device *udev; 1739 struct usb_device *udev;
1733 1740
@@ -1746,10 +1753,10 @@ int usb_suspend(struct device *dev, pm_message_t message)
1746 } 1753 }
1747 1754
1748 udev->skip_sys_resume = 0; 1755 udev->skip_sys_resume = 0;
1749 return usb_external_suspend_device(udev, message); 1756 return usb_external_suspend_device(udev, msg);
1750} 1757}
1751 1758
1752int usb_resume(struct device *dev) 1759int usb_resume(struct device *dev, pm_message_t msg)
1753{ 1760{
1754 struct usb_device *udev; 1761 struct usb_device *udev;
1755 1762
@@ -1761,7 +1768,7 @@ int usb_resume(struct device *dev)
1761 */ 1768 */
1762 if (udev->skip_sys_resume) 1769 if (udev->skip_sys_resume)
1763 return 0; 1770 return 0;
1764 return usb_external_resume_device(udev); 1771 return usb_external_resume_device(udev, msg);
1765} 1772}
1766 1773
1767#endif /* CONFIG_PM */ 1774#endif /* CONFIG_PM */
diff --git a/drivers/usb/core/generic.c b/drivers/usb/core/generic.c
index 7e912f21fd36..30ecac3af15a 100644
--- a/drivers/usb/core/generic.c
+++ b/drivers/usb/core/generic.c
@@ -200,18 +200,18 @@ static int generic_suspend(struct usb_device *udev, pm_message_t msg)
200 * interfaces manually by doing a bus (or "global") suspend. 200 * interfaces manually by doing a bus (or "global") suspend.
201 */ 201 */
202 if (!udev->parent) 202 if (!udev->parent)
203 rc = hcd_bus_suspend(udev); 203 rc = hcd_bus_suspend(udev, msg);
204 204
205 /* Non-root devices don't need to do anything for FREEZE or PRETHAW */ 205 /* Non-root devices don't need to do anything for FREEZE or PRETHAW */
206 else if (msg.event == PM_EVENT_FREEZE || msg.event == PM_EVENT_PRETHAW) 206 else if (msg.event == PM_EVENT_FREEZE || msg.event == PM_EVENT_PRETHAW)
207 rc = 0; 207 rc = 0;
208 else 208 else
209 rc = usb_port_suspend(udev); 209 rc = usb_port_suspend(udev, msg);
210 210
211 return rc; 211 return rc;
212} 212}
213 213
214static int generic_resume(struct usb_device *udev) 214static int generic_resume(struct usb_device *udev, pm_message_t msg)
215{ 215{
216 int rc; 216 int rc;
217 217
@@ -221,9 +221,9 @@ static int generic_resume(struct usb_device *udev)
221 * interfaces manually by doing a bus (or "global") resume. 221 * interfaces manually by doing a bus (or "global") resume.
222 */ 222 */
223 if (!udev->parent) 223 if (!udev->parent)
224 rc = hcd_bus_resume(udev); 224 rc = hcd_bus_resume(udev, msg);
225 else 225 else
226 rc = usb_port_resume(udev); 226 rc = usb_port_resume(udev, msg);
227 return rc; 227 return rc;
228} 228}
229 229
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 7403ed871abd..a0079876d74e 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -1573,14 +1573,14 @@ int usb_hcd_get_frame_number (struct usb_device *udev)
1573 1573
1574#ifdef CONFIG_PM 1574#ifdef CONFIG_PM
1575 1575
1576int hcd_bus_suspend(struct usb_device *rhdev) 1576int hcd_bus_suspend(struct usb_device *rhdev, pm_message_t msg)
1577{ 1577{
1578 struct usb_hcd *hcd = container_of(rhdev->bus, struct usb_hcd, self); 1578 struct usb_hcd *hcd = container_of(rhdev->bus, struct usb_hcd, self);
1579 int status; 1579 int status;
1580 int old_state = hcd->state; 1580 int old_state = hcd->state;
1581 1581
1582 dev_dbg(&rhdev->dev, "bus %s%s\n", 1582 dev_dbg(&rhdev->dev, "bus %s%s\n",
1583 rhdev->auto_pm ? "auto-" : "", "suspend"); 1583 (msg.event & PM_EVENT_AUTO ? "auto-" : ""), "suspend");
1584 if (!hcd->driver->bus_suspend) { 1584 if (!hcd->driver->bus_suspend) {
1585 status = -ENOENT; 1585 status = -ENOENT;
1586 } else { 1586 } else {
@@ -1598,14 +1598,14 @@ int hcd_bus_suspend(struct usb_device *rhdev)
1598 return status; 1598 return status;
1599} 1599}
1600 1600
1601int hcd_bus_resume(struct usb_device *rhdev) 1601int hcd_bus_resume(struct usb_device *rhdev, pm_message_t msg)
1602{ 1602{
1603 struct usb_hcd *hcd = container_of(rhdev->bus, struct usb_hcd, self); 1603 struct usb_hcd *hcd = container_of(rhdev->bus, struct usb_hcd, self);
1604 int status; 1604 int status;
1605 int old_state = hcd->state; 1605 int old_state = hcd->state;
1606 1606
1607 dev_dbg(&rhdev->dev, "usb %s%s\n", 1607 dev_dbg(&rhdev->dev, "usb %s%s\n",
1608 rhdev->auto_pm ? "auto-" : "", "resume"); 1608 (msg.event & PM_EVENT_AUTO ? "auto-" : ""), "resume");
1609 if (!hcd->driver->bus_resume) 1609 if (!hcd->driver->bus_resume)
1610 return -ENOENT; 1610 return -ENOENT;
1611 if (hcd->state == HC_STATE_RUNNING) 1611 if (hcd->state == HC_STATE_RUNNING)
@@ -1638,7 +1638,7 @@ static void hcd_resume_work(struct work_struct *work)
1638 1638
1639 usb_lock_device(udev); 1639 usb_lock_device(udev);
1640 usb_mark_last_busy(udev); 1640 usb_mark_last_busy(udev);
1641 usb_external_resume_device(udev); 1641 usb_external_resume_device(udev, PMSG_REMOTE_RESUME);
1642 usb_unlock_device(udev); 1642 usb_unlock_device(udev);
1643} 1643}
1644 1644
diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h
index 0aaa9cea6b38..aa5da82d9071 100644
--- a/drivers/usb/core/hcd.h
+++ b/drivers/usb/core/hcd.h
@@ -388,8 +388,8 @@ extern int usb_find_interface_driver(struct usb_device *dev,
388#ifdef CONFIG_PM 388#ifdef CONFIG_PM
389extern void usb_hcd_resume_root_hub(struct usb_hcd *hcd); 389extern void usb_hcd_resume_root_hub(struct usb_hcd *hcd);
390extern void usb_root_hub_lost_power(struct usb_device *rhdev); 390extern void usb_root_hub_lost_power(struct usb_device *rhdev);
391extern int hcd_bus_suspend(struct usb_device *rhdev); 391extern int hcd_bus_suspend(struct usb_device *rhdev, pm_message_t msg);
392extern int hcd_bus_resume(struct usb_device *rhdev); 392extern int hcd_bus_resume(struct usb_device *rhdev, pm_message_t msg);
393#else 393#else
394static inline void usb_hcd_resume_root_hub(struct usb_hcd *hcd) 394static inline void usb_hcd_resume_root_hub(struct usb_hcd *hcd)
395{ 395{
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index ff066edf4dca..fc99ef67761d 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -1984,7 +1984,7 @@ static int check_port_resume_type(struct usb_device *udev,
1984 * 1984 *
1985 * Returns 0 on success, else negative errno. 1985 * Returns 0 on success, else negative errno.
1986 */ 1986 */
1987int usb_port_suspend(struct usb_device *udev) 1987int usb_port_suspend(struct usb_device *udev, pm_message_t msg)
1988{ 1988{
1989 struct usb_hub *hub = hdev_to_hub(udev->parent); 1989 struct usb_hub *hub = hdev_to_hub(udev->parent);
1990 int port1 = udev->portnum; 1990 int port1 = udev->portnum;
@@ -2023,7 +2023,7 @@ int usb_port_suspend(struct usb_device *udev)
2023 } else { 2023 } else {
2024 /* device has up to 10 msec to fully suspend */ 2024 /* device has up to 10 msec to fully suspend */
2025 dev_dbg(&udev->dev, "usb %ssuspend\n", 2025 dev_dbg(&udev->dev, "usb %ssuspend\n",
2026 udev->auto_pm ? "auto-" : ""); 2026 (msg.event & PM_EVENT_AUTO ? "auto-" : ""));
2027 usb_set_device_state(udev, USB_STATE_SUSPENDED); 2027 usb_set_device_state(udev, USB_STATE_SUSPENDED);
2028 msleep(10); 2028 msleep(10);
2029 } 2029 }
@@ -2142,7 +2142,7 @@ static int finish_port_resume(struct usb_device *udev)
2142 * 2142 *
2143 * Returns 0 on success, else negative errno. 2143 * Returns 0 on success, else negative errno.
2144 */ 2144 */
2145int usb_port_resume(struct usb_device *udev) 2145int usb_port_resume(struct usb_device *udev, pm_message_t msg)
2146{ 2146{
2147 struct usb_hub *hub = hdev_to_hub(udev->parent); 2147 struct usb_hub *hub = hdev_to_hub(udev->parent);
2148 int port1 = udev->portnum; 2148 int port1 = udev->portnum;
@@ -2167,7 +2167,7 @@ int usb_port_resume(struct usb_device *udev)
2167 } else { 2167 } else {
2168 /* drive resume for at least 20 msec */ 2168 /* drive resume for at least 20 msec */
2169 dev_dbg(&udev->dev, "usb %sresume\n", 2169 dev_dbg(&udev->dev, "usb %sresume\n",
2170 udev->auto_pm ? "auto-" : ""); 2170 (msg.event & PM_EVENT_AUTO ? "auto-" : ""));
2171 msleep(25); 2171 msleep(25);
2172 2172
2173 /* Virtual root hubs can trigger on GET_PORT_STATUS to 2173 /* Virtual root hubs can trigger on GET_PORT_STATUS to
@@ -2208,7 +2208,7 @@ static int remote_wakeup(struct usb_device *udev)
2208 if (udev->state == USB_STATE_SUSPENDED) { 2208 if (udev->state == USB_STATE_SUSPENDED) {
2209 dev_dbg(&udev->dev, "usb %sresume\n", "wakeup-"); 2209 dev_dbg(&udev->dev, "usb %sresume\n", "wakeup-");
2210 usb_mark_last_busy(udev); 2210 usb_mark_last_busy(udev);
2211 status = usb_external_resume_device(udev); 2211 status = usb_external_resume_device(udev, PMSG_REMOTE_RESUME);
2212 } 2212 }
2213 return status; 2213 return status;
2214} 2214}
@@ -2217,14 +2217,14 @@ static int remote_wakeup(struct usb_device *udev)
2217 2217
2218/* When CONFIG_USB_SUSPEND isn't set, we never suspend or resume any ports. */ 2218/* When CONFIG_USB_SUSPEND isn't set, we never suspend or resume any ports. */
2219 2219
2220int usb_port_suspend(struct usb_device *udev) 2220int usb_port_suspend(struct usb_device *udev, pm_message_t msg)
2221{ 2221{
2222 return 0; 2222 return 0;
2223} 2223}
2224 2224
2225/* However we may need to do a reset-resume */ 2225/* However we may need to do a reset-resume */
2226 2226
2227int usb_port_resume(struct usb_device *udev) 2227int usb_port_resume(struct usb_device *udev, pm_message_t msg)
2228{ 2228{
2229 struct usb_hub *hub = hdev_to_hub(udev->parent); 2229 struct usb_hub *hub = hdev_to_hub(udev->parent);
2230 int port1 = udev->portnum; 2230 int port1 = udev->portnum;
@@ -2264,7 +2264,7 @@ static int hub_suspend(struct usb_interface *intf, pm_message_t msg)
2264 2264
2265 udev = hdev->children [port1-1]; 2265 udev = hdev->children [port1-1];
2266 if (udev && udev->can_submit) { 2266 if (udev && udev->can_submit) {
2267 if (!hdev->auto_pm) 2267 if (!(msg.event & PM_EVENT_AUTO))
2268 dev_dbg(&intf->dev, "port %d nyet suspended\n", 2268 dev_dbg(&intf->dev, "port %d nyet suspended\n",
2269 port1); 2269 port1);
2270 return -EBUSY; 2270 return -EBUSY;
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c
index 8c65fa75b5c2..0f0ccf640114 100644
--- a/drivers/usb/core/sysfs.c
+++ b/drivers/usb/core/sysfs.c
@@ -359,19 +359,19 @@ set_level(struct device *dev, struct device_attribute *attr,
359 strncmp(buf, on_string, len) == 0) { 359 strncmp(buf, on_string, len) == 0) {
360 udev->autosuspend_disabled = 1; 360 udev->autosuspend_disabled = 1;
361 udev->autoresume_disabled = 0; 361 udev->autoresume_disabled = 0;
362 rc = usb_external_resume_device(udev); 362 rc = usb_external_resume_device(udev, PMSG_USER_RESUME);
363 363
364 } else if (len == sizeof auto_string - 1 && 364 } else if (len == sizeof auto_string - 1 &&
365 strncmp(buf, auto_string, len) == 0) { 365 strncmp(buf, auto_string, len) == 0) {
366 udev->autosuspend_disabled = 0; 366 udev->autosuspend_disabled = 0;
367 udev->autoresume_disabled = 0; 367 udev->autoresume_disabled = 0;
368 rc = usb_external_resume_device(udev); 368 rc = usb_external_resume_device(udev, PMSG_USER_RESUME);
369 369
370 } else if (len == sizeof suspend_string - 1 && 370 } else if (len == sizeof suspend_string - 1 &&
371 strncmp(buf, suspend_string, len) == 0) { 371 strncmp(buf, suspend_string, len) == 0) {
372 udev->autosuspend_disabled = 0; 372 udev->autosuspend_disabled = 0;
373 udev->autoresume_disabled = 1; 373 udev->autoresume_disabled = 1;
374 rc = usb_external_suspend_device(udev, PMSG_SUSPEND); 374 rc = usb_external_suspend_device(udev, PMSG_USER_SUSPEND);
375 375
376 } else 376 } else
377 rc = -EINVAL; 377 rc = -EINVAL;
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index 51854c2bc912..4c98f3975afe 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -253,7 +253,7 @@ static int usb_dev_prepare(struct device *dev)
253static void usb_dev_complete(struct device *dev) 253static void usb_dev_complete(struct device *dev)
254{ 254{
255 /* Currently used only for rebinding interfaces */ 255 /* Currently used only for rebinding interfaces */
256 usb_resume(dev); /* Implement eventually? */ 256 usb_resume(dev, PMSG_RESUME); /* Message event is meaningless */
257} 257}
258 258
259static int usb_dev_suspend(struct device *dev) 259static int usb_dev_suspend(struct device *dev)
@@ -263,7 +263,7 @@ static int usb_dev_suspend(struct device *dev)
263 263
264static int usb_dev_resume(struct device *dev) 264static int usb_dev_resume(struct device *dev)
265{ 265{
266 return usb_resume(dev); 266 return usb_resume(dev, PMSG_RESUME);
267} 267}
268 268
269static int usb_dev_freeze(struct device *dev) 269static int usb_dev_freeze(struct device *dev)
@@ -273,7 +273,7 @@ static int usb_dev_freeze(struct device *dev)
273 273
274static int usb_dev_thaw(struct device *dev) 274static int usb_dev_thaw(struct device *dev)
275{ 275{
276 return usb_resume(dev); 276 return usb_resume(dev, PMSG_THAW);
277} 277}
278 278
279static int usb_dev_poweroff(struct device *dev) 279static int usb_dev_poweroff(struct device *dev)
@@ -283,7 +283,7 @@ static int usb_dev_poweroff(struct device *dev)
283 283
284static int usb_dev_restore(struct device *dev) 284static int usb_dev_restore(struct device *dev)
285{ 285{
286 return usb_resume(dev); 286 return usb_resume(dev, PMSG_RESTORE);
287} 287}
288 288
289static struct dev_pm_ops usb_device_pm_ops = { 289static struct dev_pm_ops usb_device_pm_ops = {
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h
index b60ebb4de1a8..9fb195665fa8 100644
--- a/drivers/usb/core/usb.h
+++ b/drivers/usb/core/usb.h
@@ -1,3 +1,5 @@
1#include <linux/pm.h>
2
1/* Functions local to drivers/usb/core/ */ 3/* Functions local to drivers/usb/core/ */
2 4
3extern int usb_create_sysfs_dev_files(struct usb_device *dev); 5extern int usb_create_sysfs_dev_files(struct usb_device *dev);
@@ -42,15 +44,16 @@ extern void usb_host_cleanup(void);
42#ifdef CONFIG_PM 44#ifdef CONFIG_PM
43 45
44extern int usb_suspend(struct device *dev, pm_message_t msg); 46extern int usb_suspend(struct device *dev, pm_message_t msg);
45extern int usb_resume(struct device *dev); 47extern int usb_resume(struct device *dev, pm_message_t msg);
46 48
47extern void usb_autosuspend_work(struct work_struct *work); 49extern void usb_autosuspend_work(struct work_struct *work);
48extern void usb_autoresume_work(struct work_struct *work); 50extern void usb_autoresume_work(struct work_struct *work);
49extern int usb_port_suspend(struct usb_device *dev); 51extern int usb_port_suspend(struct usb_device *dev, pm_message_t msg);
50extern int usb_port_resume(struct usb_device *dev); 52extern int usb_port_resume(struct usb_device *dev, pm_message_t msg);
51extern int usb_external_suspend_device(struct usb_device *udev, 53extern int usb_external_suspend_device(struct usb_device *udev,
52 pm_message_t msg); 54 pm_message_t msg);
53extern int usb_external_resume_device(struct usb_device *udev); 55extern int usb_external_resume_device(struct usb_device *udev,
56 pm_message_t msg);
54 57
55static inline void usb_pm_lock(struct usb_device *udev) 58static inline void usb_pm_lock(struct usb_device *udev)
56{ 59{
@@ -64,12 +67,12 @@ static inline void usb_pm_unlock(struct usb_device *udev)
64 67
65#else 68#else
66 69
67static inline int usb_port_suspend(struct usb_device *udev) 70static inline int usb_port_suspend(struct usb_device *udev, pm_message_t msg)
68{ 71{
69 return 0; 72 return 0;
70} 73}
71 74
72static inline int usb_port_resume(struct usb_device *udev) 75static inline int usb_port_resume(struct usb_device *udev, pm_message_t msg)
73{ 76{
74 return 0; 77 return 0;
75} 78}