aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/core/driver.c102
-rw-r--r--drivers/usb/core/hcd.c1
-rw-r--r--drivers/usb/core/hub.c1
-rw-r--r--include/linux/usb.h8
4 files changed, 75 insertions, 37 deletions
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index 593386eb974d..631f30582481 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -932,6 +932,7 @@ static int autosuspend_check(struct usb_device *udev)
932{ 932{
933 int i; 933 int i;
934 struct usb_interface *intf; 934 struct usb_interface *intf;
935 long suspend_time;
935 936
936 /* For autosuspend, fail fast if anything is in use or autosuspend 937 /* For autosuspend, fail fast if anything is in use or autosuspend
937 * is disabled. Also fail if any interfaces require remote wakeup 938 * is disabled. Also fail if any interfaces require remote wakeup
@@ -943,6 +944,7 @@ static int autosuspend_check(struct usb_device *udev)
943 if (udev->autosuspend_delay < 0 || udev->autosuspend_disabled) 944 if (udev->autosuspend_delay < 0 || udev->autosuspend_disabled)
944 return -EPERM; 945 return -EPERM;
945 946
947 suspend_time = udev->last_busy + udev->autosuspend_delay;
946 if (udev->actconfig) { 948 if (udev->actconfig) {
947 for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) { 949 for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) {
948 intf = udev->actconfig->interface[i]; 950 intf = udev->actconfig->interface[i];
@@ -958,6 +960,17 @@ static int autosuspend_check(struct usb_device *udev)
958 } 960 }
959 } 961 }
960 } 962 }
963
964 /* If everything is okay but the device hasn't been idle for long
965 * enough, queue a delayed autosuspend request.
966 */
967 suspend_time -= jiffies;
968 if (suspend_time > 0) {
969 if (!timer_pending(&udev->autosuspend.timer))
970 queue_delayed_work(ksuspend_usb_wq, &udev->autosuspend,
971 suspend_time);
972 return -EAGAIN;
973 }
961 return 0; 974 return 0;
962} 975}
963 976
@@ -1010,19 +1023,18 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg)
1010 struct usb_interface *intf; 1023 struct usb_interface *intf;
1011 struct usb_device *parent = udev->parent; 1024 struct usb_device *parent = udev->parent;
1012 1025
1013 cancel_delayed_work(&udev->autosuspend); 1026 if (udev->state == USB_STATE_NOTATTACHED ||
1014 if (udev->state == USB_STATE_NOTATTACHED) 1027 udev->state == USB_STATE_SUSPENDED)
1015 return 0; 1028 goto done;
1016 if (udev->state == USB_STATE_SUSPENDED)
1017 return 0;
1018 1029
1019 udev->do_remote_wakeup = device_may_wakeup(&udev->dev); 1030 udev->do_remote_wakeup = device_may_wakeup(&udev->dev);
1020 1031
1021 if (udev->auto_pm) { 1032 if (udev->auto_pm) {
1022 status = autosuspend_check(udev); 1033 status = autosuspend_check(udev);
1023 if (status < 0) 1034 if (status < 0)
1024 return status; 1035 goto done;
1025 } 1036 }
1037 cancel_delayed_work(&udev->autosuspend);
1026 1038
1027 /* Suspend all the interfaces and then udev itself */ 1039 /* Suspend all the interfaces and then udev itself */
1028 if (udev->actconfig) { 1040 if (udev->actconfig) {
@@ -1047,6 +1059,7 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg)
1047 } else if (parent) 1059 } else if (parent)
1048 usb_autosuspend_device(parent); 1060 usb_autosuspend_device(parent);
1049 1061
1062 done:
1050 // dev_dbg(&udev->dev, "%s: status %d\n", __FUNCTION__, status); 1063 // dev_dbg(&udev->dev, "%s: status %d\n", __FUNCTION__, status);
1051 return status; 1064 return status;
1052} 1065}
@@ -1086,14 +1099,18 @@ static int usb_resume_both(struct usb_device *udev)
1086 struct usb_interface *intf; 1099 struct usb_interface *intf;
1087 struct usb_device *parent = udev->parent; 1100 struct usb_device *parent = udev->parent;
1088 1101
1089 if (udev->auto_pm && udev->autoresume_disabled)
1090 return -EPERM;
1091 cancel_delayed_work(&udev->autosuspend); 1102 cancel_delayed_work(&udev->autosuspend);
1092 if (udev->state == USB_STATE_NOTATTACHED) 1103 if (udev->state == USB_STATE_NOTATTACHED) {
1093 return -ENODEV; 1104 status = -ENODEV;
1105 goto done;
1106 }
1094 1107
1095 /* Propagate the resume up the tree, if necessary */ 1108 /* Propagate the resume up the tree, if necessary */
1096 if (udev->state == USB_STATE_SUSPENDED) { 1109 if (udev->state == USB_STATE_SUSPENDED) {
1110 if (udev->auto_pm && udev->autoresume_disabled) {
1111 status = -EPERM;
1112 goto done;
1113 }
1097 if (parent) { 1114 if (parent) {
1098 status = usb_autoresume_device(parent); 1115 status = usb_autoresume_device(parent);
1099 if (status == 0) { 1116 if (status == 0) {
@@ -1139,24 +1156,13 @@ static int usb_resume_both(struct usb_device *udev)
1139 } 1156 }
1140 } 1157 }
1141 1158
1159 done:
1142 // dev_dbg(&udev->dev, "%s: status %d\n", __FUNCTION__, status); 1160 // dev_dbg(&udev->dev, "%s: status %d\n", __FUNCTION__, status);
1143 return status; 1161 return status;
1144} 1162}
1145 1163
1146#ifdef CONFIG_USB_SUSPEND 1164#ifdef CONFIG_USB_SUSPEND
1147 1165
1148/* usb_autosuspend_work - callback routine to autosuspend a USB device */
1149void usb_autosuspend_work(struct work_struct *work)
1150{
1151 struct usb_device *udev =
1152 container_of(work, struct usb_device, autosuspend.work);
1153
1154 usb_pm_lock(udev);
1155 udev->auto_pm = 1;
1156 usb_suspend_both(udev, PMSG_SUSPEND);
1157 usb_pm_unlock(udev);
1158}
1159
1160/* Internal routine to adjust a device's usage counter and change 1166/* Internal routine to adjust a device's usage counter and change
1161 * its autosuspend state. 1167 * its autosuspend state.
1162 */ 1168 */
@@ -1165,20 +1171,34 @@ static int usb_autopm_do_device(struct usb_device *udev, int inc_usage_cnt)
1165 int status = 0; 1171 int status = 0;
1166 1172
1167 usb_pm_lock(udev); 1173 usb_pm_lock(udev);
1174 udev->auto_pm = 1;
1168 udev->pm_usage_cnt += inc_usage_cnt; 1175 udev->pm_usage_cnt += inc_usage_cnt;
1169 WARN_ON(udev->pm_usage_cnt < 0); 1176 WARN_ON(udev->pm_usage_cnt < 0);
1170 if (inc_usage_cnt >= 0 && udev->pm_usage_cnt > 0) { 1177 if (inc_usage_cnt >= 0 && udev->pm_usage_cnt > 0) {
1171 udev->auto_pm = 1; 1178 if (udev->state == USB_STATE_SUSPENDED)
1172 status = usb_resume_both(udev); 1179 status = usb_resume_both(udev);
1173 if (status != 0) 1180 if (status != 0)
1174 udev->pm_usage_cnt -= inc_usage_cnt; 1181 udev->pm_usage_cnt -= inc_usage_cnt;
1175 } else if (inc_usage_cnt <= 0 && autosuspend_check(udev) == 0) 1182 else if (inc_usage_cnt)
1176 queue_delayed_work(ksuspend_usb_wq, &udev->autosuspend, 1183 udev->last_busy = jiffies;
1177 udev->autosuspend_delay); 1184 } else if (inc_usage_cnt <= 0 && udev->pm_usage_cnt <= 0) {
1185 if (inc_usage_cnt)
1186 udev->last_busy = jiffies;
1187 status = usb_suspend_both(udev, PMSG_SUSPEND);
1188 }
1178 usb_pm_unlock(udev); 1189 usb_pm_unlock(udev);
1179 return status; 1190 return status;
1180} 1191}
1181 1192
1193/* usb_autosuspend_work - callback routine to autosuspend a USB device */
1194void usb_autosuspend_work(struct work_struct *work)
1195{
1196 struct usb_device *udev =
1197 container_of(work, struct usb_device, autosuspend.work);
1198
1199 usb_autopm_do_device(udev, 0);
1200}
1201
1182/** 1202/**
1183 * usb_autosuspend_device - delayed autosuspend of a USB device and its interfaces 1203 * usb_autosuspend_device - delayed autosuspend of a USB device and its interfaces
1184 * @udev: the usb_device to autosuspend 1204 * @udev: the usb_device to autosuspend
@@ -1270,15 +1290,20 @@ static int usb_autopm_do_interface(struct usb_interface *intf,
1270 if (intf->condition == USB_INTERFACE_UNBOUND) 1290 if (intf->condition == USB_INTERFACE_UNBOUND)
1271 status = -ENODEV; 1291 status = -ENODEV;
1272 else { 1292 else {
1293 udev->auto_pm = 1;
1273 intf->pm_usage_cnt += inc_usage_cnt; 1294 intf->pm_usage_cnt += inc_usage_cnt;
1274 if (inc_usage_cnt >= 0 && intf->pm_usage_cnt > 0) { 1295 if (inc_usage_cnt >= 0 && intf->pm_usage_cnt > 0) {
1275 udev->auto_pm = 1; 1296 if (udev->state == USB_STATE_SUSPENDED)
1276 status = usb_resume_both(udev); 1297 status = usb_resume_both(udev);
1277 if (status != 0) 1298 if (status != 0)
1278 intf->pm_usage_cnt -= inc_usage_cnt; 1299 intf->pm_usage_cnt -= inc_usage_cnt;
1279 } else if (inc_usage_cnt <= 0 && autosuspend_check(udev) == 0) 1300 else if (inc_usage_cnt)
1280 queue_delayed_work(ksuspend_usb_wq, &udev->autosuspend, 1301 udev->last_busy = jiffies;
1281 udev->autosuspend_delay); 1302 } else if (inc_usage_cnt <= 0 && intf->pm_usage_cnt <= 0) {
1303 if (inc_usage_cnt)
1304 udev->last_busy = jiffies;
1305 status = usb_suspend_both(udev, PMSG_SUSPEND);
1306 }
1282 } 1307 }
1283 usb_pm_unlock(udev); 1308 usb_pm_unlock(udev);
1284 return status; 1309 return status;
@@ -1337,11 +1362,14 @@ EXPORT_SYMBOL_GPL(usb_autopm_put_interface);
1337 * or @intf is unbound. A typical example would be a character-device 1362 * or @intf is unbound. A typical example would be a character-device
1338 * driver when its device file is opened. 1363 * driver when its device file is opened.
1339 * 1364 *
1340 * The routine increments @intf's usage counter. So long as the counter 1365 *
1341 * is greater than 0, autosuspend will not be allowed for @intf or its 1366 * The routine increments @intf's usage counter. (However if the
1342 * usb_device. When the driver is finished using @intf it should call 1367 * autoresume fails then the counter is re-decremented.) So long as the
1343 * usb_autopm_put_interface() to decrement the usage counter and queue 1368 * counter is greater than 0, autosuspend will not be allowed for @intf
1344 * a delayed autosuspend request (if the counter is <= 0). 1369 * or its usb_device. When the driver is finished using @intf it should
1370 * call usb_autopm_put_interface() to decrement the usage counter and
1371 * queue a delayed autosuspend request (if the counter is <= 0).
1372 *
1345 * 1373 *
1346 * Note that @intf->pm_usage_cnt is owned by the interface driver. The 1374 * Note that @intf->pm_usage_cnt is owned by the interface driver. The
1347 * core will not change its value other than the increment and decrement 1375 * core will not change its value other than the increment and decrement
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 8bc3ce6d9666..40cf882293e6 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -1306,6 +1306,7 @@ static void hcd_resume_work(struct work_struct *work)
1306 struct usb_device *udev = hcd->self.root_hub; 1306 struct usb_device *udev = hcd->self.root_hub;
1307 1307
1308 usb_lock_device(udev); 1308 usb_lock_device(udev);
1309 usb_mark_last_busy(udev);
1309 usb_external_resume_device(udev); 1310 usb_external_resume_device(udev);
1310 usb_unlock_device(udev); 1311 usb_unlock_device(udev);
1311} 1312}
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 2a0b15e42bc7..bde29ab2b504 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -1859,6 +1859,7 @@ static int remote_wakeup(struct usb_device *udev)
1859 usb_lock_device(udev); 1859 usb_lock_device(udev);
1860 if (udev->state == USB_STATE_SUSPENDED) { 1860 if (udev->state == USB_STATE_SUSPENDED) {
1861 dev_dbg(&udev->dev, "usb %sresume\n", "wakeup-"); 1861 dev_dbg(&udev->dev, "usb %sresume\n", "wakeup-");
1862 usb_mark_last_busy(udev);
1862 status = usb_external_resume_device(udev); 1863 status = usb_external_resume_device(udev);
1863 } 1864 }
1864 usb_unlock_device(udev); 1865 usb_unlock_device(udev);
diff --git a/include/linux/usb.h b/include/linux/usb.h
index f9e4445d5b53..cfbd2bb8fa2c 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -398,6 +398,7 @@ struct usb_device {
398 struct delayed_work autosuspend; /* for delayed autosuspends */ 398 struct delayed_work autosuspend; /* for delayed autosuspends */
399 struct mutex pm_mutex; /* protects PM operations */ 399 struct mutex pm_mutex; /* protects PM operations */
400 400
401 unsigned long last_busy; /* time of last use */
401 int autosuspend_delay; /* in jiffies */ 402 int autosuspend_delay; /* in jiffies */
402 403
403 unsigned auto_pm:1; /* autosuspend/resume in progress */ 404 unsigned auto_pm:1; /* autosuspend/resume in progress */
@@ -443,6 +444,11 @@ static inline void usb_autopm_disable(struct usb_interface *intf)
443 usb_autopm_set_interface(intf); 444 usb_autopm_set_interface(intf);
444} 445}
445 446
447static inline void usb_mark_last_busy(struct usb_device *udev)
448{
449 udev->last_busy = jiffies;
450}
451
446#else 452#else
447 453
448static inline int usb_autopm_set_interface(struct usb_interface *intf) 454static inline int usb_autopm_set_interface(struct usb_interface *intf)
@@ -457,6 +463,8 @@ static inline void usb_autopm_enable(struct usb_interface *intf)
457{ } 463{ }
458static inline void usb_autopm_disable(struct usb_interface *intf) 464static inline void usb_autopm_disable(struct usb_interface *intf)
459{ } 465{ }
466static inline void usb_mark_last_busy(struct usb_device *udev)
467{ }
460#endif 468#endif
461 469
462/*-------------------------------------------------------------------------*/ 470/*-------------------------------------------------------------------------*/