aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/core/driver.c102
-rw-r--r--drivers/usb/core/hcd.c1
-rw-r--r--drivers/usb/core/hub.c1
3 files changed, 67 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);