diff options
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/core/devio.c | 4 | ||||
-rw-r--r-- | drivers/usb/core/driver.c | 102 | ||||
-rw-r--r-- | drivers/usb/core/hub.c | 12 | ||||
-rw-r--r-- | drivers/usb/core/message.c | 6 | ||||
-rw-r--r-- | drivers/usb/core/usb.h | 9 |
5 files changed, 71 insertions, 62 deletions
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index fed92be63b5e..3ed4cb2d56d9 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c | |||
@@ -561,7 +561,7 @@ static int usbdev_open(struct inode *inode, struct file *file) | |||
561 | dev = inode->i_private; | 561 | dev = inode->i_private; |
562 | if (!dev) | 562 | if (!dev) |
563 | goto out; | 563 | goto out; |
564 | ret = usb_autoresume_device(dev, 1); | 564 | ret = usb_autoresume_device(dev); |
565 | if (ret) | 565 | if (ret) |
566 | goto out; | 566 | goto out; |
567 | 567 | ||
@@ -609,7 +609,7 @@ static int usbdev_release(struct inode *inode, struct file *file) | |||
609 | releaseintf(ps, ifnum); | 609 | releaseintf(ps, ifnum); |
610 | } | 610 | } |
611 | destroy_all_async(ps); | 611 | destroy_all_async(ps); |
612 | usb_autosuspend_device(dev, 1); | 612 | usb_autosuspend_device(dev); |
613 | usb_unlock_device(dev); | 613 | usb_unlock_device(dev); |
614 | usb_put_dev(dev); | 614 | usb_put_dev(dev); |
615 | put_pid(ps->disc_pid); | 615 | put_pid(ps->disc_pid); |
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index 0fa15bd62c48..d6eb5ce1dd1d 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c | |||
@@ -205,7 +205,7 @@ static int usb_probe_interface(struct device *dev) | |||
205 | if (id) { | 205 | if (id) { |
206 | dev_dbg(dev, "%s - got id\n", __FUNCTION__); | 206 | dev_dbg(dev, "%s - got id\n", __FUNCTION__); |
207 | 207 | ||
208 | error = usb_autoresume_device(udev, 1); | 208 | error = usb_autoresume_device(udev); |
209 | if (error) | 209 | if (error) |
210 | return error; | 210 | return error; |
211 | 211 | ||
@@ -229,7 +229,7 @@ static int usb_probe_interface(struct device *dev) | |||
229 | } else | 229 | } else |
230 | intf->condition = USB_INTERFACE_BOUND; | 230 | intf->condition = USB_INTERFACE_BOUND; |
231 | 231 | ||
232 | usb_autosuspend_device(udev, 1); | 232 | usb_autosuspend_device(udev); |
233 | } | 233 | } |
234 | 234 | ||
235 | return error; | 235 | return error; |
@@ -247,7 +247,7 @@ static int usb_unbind_interface(struct device *dev) | |||
247 | 247 | ||
248 | /* Autoresume for set_interface call below */ | 248 | /* Autoresume for set_interface call below */ |
249 | udev = interface_to_usbdev(intf); | 249 | udev = interface_to_usbdev(intf); |
250 | error = usb_autoresume_device(udev, 1); | 250 | error = usb_autoresume_device(udev); |
251 | 251 | ||
252 | /* release all urbs for this interface */ | 252 | /* release all urbs for this interface */ |
253 | usb_disable_interface(interface_to_usbdev(intf), intf); | 253 | usb_disable_interface(interface_to_usbdev(intf), intf); |
@@ -265,7 +265,7 @@ static int usb_unbind_interface(struct device *dev) | |||
265 | intf->needs_remote_wakeup = 0; | 265 | intf->needs_remote_wakeup = 0; |
266 | 266 | ||
267 | if (!error) | 267 | if (!error) |
268 | usb_autosuspend_device(udev, 1); | 268 | usb_autosuspend_device(udev); |
269 | 269 | ||
270 | return 0; | 270 | return 0; |
271 | } | 271 | } |
@@ -940,6 +940,8 @@ done: | |||
940 | return status; | 940 | return status; |
941 | } | 941 | } |
942 | 942 | ||
943 | #ifdef CONFIG_USB_SUSPEND | ||
944 | |||
943 | /* Internal routine to check whether we may autosuspend a device. */ | 945 | /* Internal routine to check whether we may autosuspend a device. */ |
944 | static int autosuspend_check(struct usb_device *udev) | 946 | static int autosuspend_check(struct usb_device *udev) |
945 | { | 947 | { |
@@ -970,6 +972,12 @@ static int autosuspend_check(struct usb_device *udev) | |||
970 | return 0; | 972 | return 0; |
971 | } | 973 | } |
972 | 974 | ||
975 | #else | ||
976 | |||
977 | #define autosuspend_check(udev) 0 | ||
978 | |||
979 | #endif | ||
980 | |||
973 | /** | 981 | /** |
974 | * usb_suspend_both - suspend a USB device and its interfaces | 982 | * usb_suspend_both - suspend a USB device and its interfaces |
975 | * @udev: the usb_device to suspend | 983 | * @udev: the usb_device to suspend |
@@ -1048,7 +1056,7 @@ int usb_suspend_both(struct usb_device *udev, pm_message_t msg) | |||
1048 | 1056 | ||
1049 | /* If the suspend succeeded, propagate it up the tree */ | 1057 | /* If the suspend succeeded, propagate it up the tree */ |
1050 | } else if (parent) | 1058 | } else if (parent) |
1051 | usb_autosuspend_device(parent, 1); | 1059 | usb_autosuspend_device(parent); |
1052 | 1060 | ||
1053 | // dev_dbg(&udev->dev, "%s: status %d\n", __FUNCTION__, status); | 1061 | // dev_dbg(&udev->dev, "%s: status %d\n", __FUNCTION__, status); |
1054 | return status; | 1062 | return status; |
@@ -1096,11 +1104,11 @@ int usb_resume_both(struct usb_device *udev) | |||
1096 | /* Propagate the resume up the tree, if necessary */ | 1104 | /* Propagate the resume up the tree, if necessary */ |
1097 | if (udev->state == USB_STATE_SUSPENDED) { | 1105 | if (udev->state == USB_STATE_SUSPENDED) { |
1098 | if (parent) { | 1106 | if (parent) { |
1099 | status = usb_autoresume_device(parent, 1); | 1107 | status = usb_autoresume_device(parent); |
1100 | if (status == 0) { | 1108 | if (status == 0) { |
1101 | status = usb_resume_device(udev); | 1109 | status = usb_resume_device(udev); |
1102 | if (status) { | 1110 | if (status) { |
1103 | usb_autosuspend_device(parent, 1); | 1111 | usb_autosuspend_device(parent); |
1104 | 1112 | ||
1105 | /* It's possible usb_resume_device() | 1113 | /* It's possible usb_resume_device() |
1106 | * failed after the port was | 1114 | * failed after the port was |
@@ -1146,39 +1154,53 @@ int usb_resume_both(struct usb_device *udev) | |||
1146 | 1154 | ||
1147 | #ifdef CONFIG_USB_SUSPEND | 1155 | #ifdef CONFIG_USB_SUSPEND |
1148 | 1156 | ||
1157 | /* Internal routine to adjust a device's usage counter and change | ||
1158 | * its autosuspend state. | ||
1159 | */ | ||
1160 | static int usb_autopm_do_device(struct usb_device *udev, int inc_usage_cnt) | ||
1161 | { | ||
1162 | int status = 0; | ||
1163 | |||
1164 | usb_pm_lock(udev); | ||
1165 | udev->pm_usage_cnt += inc_usage_cnt; | ||
1166 | WARN_ON(udev->pm_usage_cnt < 0); | ||
1167 | if (inc_usage_cnt >= 0 && udev->pm_usage_cnt > 0) { | ||
1168 | udev->auto_pm = 1; | ||
1169 | status = usb_resume_both(udev); | ||
1170 | if (status != 0) | ||
1171 | udev->pm_usage_cnt -= inc_usage_cnt; | ||
1172 | } else if (inc_usage_cnt <= 0 && autosuspend_check(udev) == 0) | ||
1173 | queue_delayed_work(ksuspend_usb_wq, &udev->autosuspend, | ||
1174 | USB_AUTOSUSPEND_DELAY); | ||
1175 | usb_pm_unlock(udev); | ||
1176 | return status; | ||
1177 | } | ||
1178 | |||
1149 | /** | 1179 | /** |
1150 | * usb_autosuspend_device - delayed autosuspend of a USB device and its interfaces | 1180 | * usb_autosuspend_device - delayed autosuspend of a USB device and its interfaces |
1151 | * @udev: the usb_device to autosuspend | 1181 | * @udev: the usb_device to autosuspend |
1152 | * @dec_usage_cnt: flag to decrement @udev's PM-usage counter | ||
1153 | * | 1182 | * |
1154 | * This routine should be called when a core subsystem is finished using | 1183 | * This routine should be called when a core subsystem is finished using |
1155 | * @udev and wants to allow it to autosuspend. Examples would be when | 1184 | * @udev and wants to allow it to autosuspend. Examples would be when |
1156 | * @udev's device file in usbfs is closed or after a configuration change. | 1185 | * @udev's device file in usbfs is closed or after a configuration change. |
1157 | * | 1186 | * |
1158 | * @dec_usage_cnt should be 1 if the subsystem previously incremented | 1187 | * @udev's usage counter is decremented. If it or any of the usage counters |
1159 | * @udev's usage counter (such as by passing 1 to usb_autoresume_device); | 1188 | * for an active interface is greater than 0, no autosuspend request will be |
1160 | * otherwise it should be 0. | 1189 | * queued. (If an interface driver does not support autosuspend then its |
1161 | * | 1190 | * usage counter is permanently positive.) Furthermore, if an interface |
1162 | * If the usage counter for @udev or any of its active interfaces is greater | 1191 | * driver requires remote-wakeup capability during autosuspend but remote |
1163 | * than 0, the autosuspend request will not be queued. (If an interface | 1192 | * wakeup is disabled, the autosuspend will fail. |
1164 | * driver does not support autosuspend then its usage counter is permanently | ||
1165 | * positive.) Likewise, if an interface driver requires remote-wakeup | ||
1166 | * capability during autosuspend but remote wakeup is disabled, the | ||
1167 | * autosuspend will fail. | ||
1168 | * | 1193 | * |
1169 | * Often the caller will hold @udev's device lock, but this is not | 1194 | * Often the caller will hold @udev's device lock, but this is not |
1170 | * necessary. | 1195 | * necessary. |
1171 | * | 1196 | * |
1172 | * This routine can run only in process context. | 1197 | * This routine can run only in process context. |
1173 | */ | 1198 | */ |
1174 | void usb_autosuspend_device(struct usb_device *udev, int dec_usage_cnt) | 1199 | void usb_autosuspend_device(struct usb_device *udev) |
1175 | { | 1200 | { |
1176 | usb_pm_lock(udev); | 1201 | int status; |
1177 | udev->pm_usage_cnt -= dec_usage_cnt; | 1202 | |
1178 | if (autosuspend_check(udev) == 0) | 1203 | status = usb_autopm_do_device(udev, -1); |
1179 | queue_delayed_work(ksuspend_usb_wq, &udev->autosuspend, | ||
1180 | USB_AUTOSUSPEND_DELAY); | ||
1181 | usb_pm_unlock(udev); | ||
1182 | // dev_dbg(&udev->dev, "%s: cnt %d\n", | 1204 | // dev_dbg(&udev->dev, "%s: cnt %d\n", |
1183 | // __FUNCTION__, udev->pm_usage_cnt); | 1205 | // __FUNCTION__, udev->pm_usage_cnt); |
1184 | } | 1206 | } |
@@ -1186,39 +1208,27 @@ void usb_autosuspend_device(struct usb_device *udev, int dec_usage_cnt) | |||
1186 | /** | 1208 | /** |
1187 | * usb_autoresume_device - immediately autoresume a USB device and its interfaces | 1209 | * usb_autoresume_device - immediately autoresume a USB device and its interfaces |
1188 | * @udev: the usb_device to autoresume | 1210 | * @udev: the usb_device to autoresume |
1189 | * @inc_usage_cnt: flag to increment @udev's PM-usage counter | ||
1190 | * | 1211 | * |
1191 | * This routine should be called when a core subsystem wants to use @udev | 1212 | * This routine should be called when a core subsystem wants to use @udev |
1192 | * and needs to guarantee that it is not suspended. In addition, the | 1213 | * and needs to guarantee that it is not suspended. No autosuspend will |
1193 | * caller can prevent @udev from being autosuspended subsequently. (Note | 1214 | * occur until usb_autosuspend_device is called. (Note that this will not |
1194 | * that this will not prevent suspend events originating in the PM core.) | 1215 | * prevent suspend events originating in the PM core.) Examples would be |
1195 | * Examples would be when @udev's device file in usbfs is opened (autosuspend | 1216 | * when @udev's device file in usbfs is opened or when a remote-wakeup |
1196 | * should be prevented until the file is closed) or when a remote-wakeup | 1217 | * request is received. |
1197 | * request is received (later autosuspends should not be prevented). | ||
1198 | * | 1218 | * |
1199 | * @inc_usage_cnt should be 1 to increment @udev's usage counter and prevent | 1219 | * @udev's usage counter is incremented to prevent subsequent autosuspends. |
1200 | * autosuspends. This prevention will persist until the usage counter is | 1220 | * However if the autoresume fails then the usage counter is re-decremented. |
1201 | * decremented again (such as by passing 1 to usb_autosuspend_device). | ||
1202 | * Otherwise @inc_usage_cnt should be 0 to leave the usage counter unchanged. | ||
1203 | * Regardless, if the autoresume fails then the usage counter is not | ||
1204 | * incremented. | ||
1205 | * | 1221 | * |
1206 | * Often the caller will hold @udev's device lock, but this is not | 1222 | * Often the caller will hold @udev's device lock, but this is not |
1207 | * necessary (and attempting it might cause deadlock). | 1223 | * necessary (and attempting it might cause deadlock). |
1208 | * | 1224 | * |
1209 | * This routine can run only in process context. | 1225 | * This routine can run only in process context. |
1210 | */ | 1226 | */ |
1211 | int usb_autoresume_device(struct usb_device *udev, int inc_usage_cnt) | 1227 | int usb_autoresume_device(struct usb_device *udev) |
1212 | { | 1228 | { |
1213 | int status; | 1229 | int status; |
1214 | 1230 | ||
1215 | usb_pm_lock(udev); | 1231 | status = usb_autopm_do_device(udev, 1); |
1216 | udev->pm_usage_cnt += inc_usage_cnt; | ||
1217 | udev->auto_pm = 1; | ||
1218 | status = usb_resume_both(udev); | ||
1219 | if (status != 0) | ||
1220 | udev->pm_usage_cnt -= inc_usage_cnt; | ||
1221 | usb_pm_unlock(udev); | ||
1222 | // dev_dbg(&udev->dev, "%s: status %d cnt %d\n", | 1232 | // dev_dbg(&udev->dev, "%s: status %d cnt %d\n", |
1223 | // __FUNCTION__, status, udev->pm_usage_cnt); | 1233 | // __FUNCTION__, status, udev->pm_usage_cnt); |
1224 | return status; | 1234 | return status; |
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index e46d38b18249..0ce393eb3c4b 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
@@ -1234,7 +1234,7 @@ void usb_disconnect(struct usb_device **pdev) | |||
1234 | if (udev->parent) { | 1234 | if (udev->parent) { |
1235 | usb_pm_lock(udev); | 1235 | usb_pm_lock(udev); |
1236 | if (!udev->discon_suspended) | 1236 | if (!udev->discon_suspended) |
1237 | usb_autosuspend_device(udev->parent, 1); | 1237 | usb_autosuspend_device(udev->parent); |
1238 | usb_pm_unlock(udev); | 1238 | usb_pm_unlock(udev); |
1239 | } | 1239 | } |
1240 | 1240 | ||
@@ -1368,7 +1368,7 @@ static int __usb_new_device(void *void_data) | |||
1368 | 1368 | ||
1369 | /* Increment the parent's count of unsuspended children */ | 1369 | /* Increment the parent's count of unsuspended children */ |
1370 | if (udev->parent) | 1370 | if (udev->parent) |
1371 | usb_autoresume_device(udev->parent, 1); | 1371 | usb_autoresume_device(udev->parent); |
1372 | 1372 | ||
1373 | exit: | 1373 | exit: |
1374 | module_put(THIS_MODULE); | 1374 | module_put(THIS_MODULE); |
@@ -1881,12 +1881,12 @@ static int remote_wakeup(struct usb_device *udev) | |||
1881 | usb_lock_device(udev); | 1881 | usb_lock_device(udev); |
1882 | if (udev->state == USB_STATE_SUSPENDED) { | 1882 | if (udev->state == USB_STATE_SUSPENDED) { |
1883 | dev_dbg(&udev->dev, "usb %sresume\n", "wakeup-"); | 1883 | dev_dbg(&udev->dev, "usb %sresume\n", "wakeup-"); |
1884 | status = usb_autoresume_device(udev, 1); | 1884 | status = usb_autoresume_device(udev); |
1885 | 1885 | ||
1886 | /* Give the interface drivers a chance to do something, | 1886 | /* Give the interface drivers a chance to do something, |
1887 | * then autosuspend the device again. */ | 1887 | * then autosuspend the device again. */ |
1888 | if (status == 0) | 1888 | if (status == 0) |
1889 | usb_autosuspend_device(udev, 1); | 1889 | usb_autosuspend_device(udev); |
1890 | } | 1890 | } |
1891 | usb_unlock_device(udev); | 1891 | usb_unlock_device(udev); |
1892 | return status; | 1892 | return status; |
@@ -3099,7 +3099,7 @@ int usb_reset_composite_device(struct usb_device *udev, | |||
3099 | } | 3099 | } |
3100 | 3100 | ||
3101 | /* Prevent autosuspend during the reset */ | 3101 | /* Prevent autosuspend during the reset */ |
3102 | usb_autoresume_device(udev, 1); | 3102 | usb_autoresume_device(udev); |
3103 | 3103 | ||
3104 | if (iface && iface->condition != USB_INTERFACE_BINDING) | 3104 | if (iface && iface->condition != USB_INTERFACE_BINDING) |
3105 | iface = NULL; | 3105 | iface = NULL; |
@@ -3142,7 +3142,7 @@ int usb_reset_composite_device(struct usb_device *udev, | |||
3142 | } | 3142 | } |
3143 | } | 3143 | } |
3144 | 3144 | ||
3145 | usb_autosuspend_device(udev, 1); | 3145 | usb_autosuspend_device(udev); |
3146 | return ret; | 3146 | return ret; |
3147 | } | 3147 | } |
3148 | EXPORT_SYMBOL(usb_reset_composite_device); | 3148 | EXPORT_SYMBOL(usb_reset_composite_device); |
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 5684d8722922..29b0fa9ff9d0 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c | |||
@@ -1398,7 +1398,7 @@ free_interfaces: | |||
1398 | } | 1398 | } |
1399 | 1399 | ||
1400 | /* Wake up the device so we can send it the Set-Config request */ | 1400 | /* Wake up the device so we can send it the Set-Config request */ |
1401 | ret = usb_autoresume_device(dev, 1); | 1401 | ret = usb_autoresume_device(dev); |
1402 | if (ret) | 1402 | if (ret) |
1403 | goto free_interfaces; | 1403 | goto free_interfaces; |
1404 | 1404 | ||
@@ -1421,7 +1421,7 @@ free_interfaces: | |||
1421 | dev->actconfig = cp; | 1421 | dev->actconfig = cp; |
1422 | if (!cp) { | 1422 | if (!cp) { |
1423 | usb_set_device_state(dev, USB_STATE_ADDRESS); | 1423 | usb_set_device_state(dev, USB_STATE_ADDRESS); |
1424 | usb_autosuspend_device(dev, 1); | 1424 | usb_autosuspend_device(dev); |
1425 | goto free_interfaces; | 1425 | goto free_interfaces; |
1426 | } | 1426 | } |
1427 | usb_set_device_state(dev, USB_STATE_CONFIGURED); | 1427 | usb_set_device_state(dev, USB_STATE_CONFIGURED); |
@@ -1490,7 +1490,7 @@ free_interfaces: | |||
1490 | usb_create_sysfs_intf_files (intf); | 1490 | usb_create_sysfs_intf_files (intf); |
1491 | } | 1491 | } |
1492 | 1492 | ||
1493 | usb_autosuspend_device(dev, 1); | 1493 | usb_autosuspend_device(dev); |
1494 | return 0; | 1494 | return 0; |
1495 | } | 1495 | } |
1496 | 1496 | ||
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h index 13322e33f912..17830a81be14 100644 --- a/drivers/usb/core/usb.h +++ b/drivers/usb/core/usb.h | |||
@@ -64,14 +64,13 @@ static inline void usb_pm_unlock(struct usb_device *udev) {} | |||
64 | 64 | ||
65 | #define USB_AUTOSUSPEND_DELAY (HZ*2) | 65 | #define USB_AUTOSUSPEND_DELAY (HZ*2) |
66 | 66 | ||
67 | extern void usb_autosuspend_device(struct usb_device *udev, int dec_busy_cnt); | 67 | extern void usb_autosuspend_device(struct usb_device *udev); |
68 | extern int usb_autoresume_device(struct usb_device *udev, int inc_busy_cnt); | 68 | extern int usb_autoresume_device(struct usb_device *udev); |
69 | 69 | ||
70 | #else | 70 | #else |
71 | 71 | ||
72 | #define usb_autosuspend_device(udev, dec_busy_cnt) do {} while (0) | 72 | #define usb_autosuspend_device(udev) do {} while (0) |
73 | static inline int usb_autoresume_device(struct usb_device *udev, | 73 | static inline int usb_autoresume_device(struct usb_device *udev) |
74 | int inc_busy_cnt) | ||
75 | { | 74 | { |
76 | return 0; | 75 | return 0; |
77 | } | 76 | } |