diff options
| -rw-r--r-- | drivers/usb/core/driver.c | 42 | ||||
| -rw-r--r-- | drivers/usb/core/hub.c | 4 | ||||
| -rw-r--r-- | drivers/usb/core/usb.c | 4 | ||||
| -rw-r--r-- | drivers/usb/core/usb.h | 18 | ||||
| -rw-r--r-- | include/linux/usb.h | 2 |
5 files changed, 43 insertions, 27 deletions
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index ee18d187ca17..113e484c763e 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c | |||
| @@ -303,11 +303,11 @@ int usb_driver_claim_interface(struct usb_driver *driver, | |||
| 303 | dev->driver = &driver->drvwrap.driver; | 303 | dev->driver = &driver->drvwrap.driver; |
| 304 | usb_set_intfdata(iface, priv); | 304 | usb_set_intfdata(iface, priv); |
| 305 | 305 | ||
| 306 | mutex_lock_nested(&udev->pm_mutex, udev->level); | 306 | usb_pm_lock(udev); |
| 307 | iface->condition = USB_INTERFACE_BOUND; | 307 | iface->condition = USB_INTERFACE_BOUND; |
| 308 | mark_active(iface); | 308 | mark_active(iface); |
| 309 | iface->pm_usage_cnt = !(driver->supports_autosuspend); | 309 | iface->pm_usage_cnt = !(driver->supports_autosuspend); |
| 310 | mutex_unlock(&udev->pm_mutex); | 310 | usb_pm_unlock(udev); |
| 311 | 311 | ||
| 312 | /* if interface was already added, bind now; else let | 312 | /* if interface was already added, bind now; else let |
| 313 | * the future device_add() bind it, bypassing probe() | 313 | * the future device_add() bind it, bypassing probe() |
| @@ -356,11 +356,11 @@ void usb_driver_release_interface(struct usb_driver *driver, | |||
| 356 | dev->driver = NULL; | 356 | dev->driver = NULL; |
| 357 | usb_set_intfdata(iface, NULL); | 357 | usb_set_intfdata(iface, NULL); |
| 358 | 358 | ||
| 359 | mutex_lock_nested(&udev->pm_mutex, udev->level); | 359 | usb_pm_lock(udev); |
| 360 | iface->condition = USB_INTERFACE_UNBOUND; | 360 | iface->condition = USB_INTERFACE_UNBOUND; |
| 361 | mark_quiesced(iface); | 361 | mark_quiesced(iface); |
| 362 | iface->needs_remote_wakeup = 0; | 362 | iface->needs_remote_wakeup = 0; |
| 363 | mutex_unlock(&udev->pm_mutex); | 363 | usb_pm_unlock(udev); |
| 364 | } | 364 | } |
| 365 | EXPORT_SYMBOL(usb_driver_release_interface); | 365 | EXPORT_SYMBOL(usb_driver_release_interface); |
| 366 | 366 | ||
| @@ -789,7 +789,7 @@ EXPORT_SYMBOL_GPL_FUTURE(usb_deregister); | |||
| 789 | 789 | ||
| 790 | #ifdef CONFIG_PM | 790 | #ifdef CONFIG_PM |
| 791 | 791 | ||
| 792 | /* Caller has locked udev->pm_mutex */ | 792 | /* Caller has locked udev's pm_mutex */ |
| 793 | static int suspend_device(struct usb_device *udev, pm_message_t msg) | 793 | static int suspend_device(struct usb_device *udev, pm_message_t msg) |
| 794 | { | 794 | { |
| 795 | struct usb_device_driver *udriver; | 795 | struct usb_device_driver *udriver; |
| @@ -816,7 +816,7 @@ done: | |||
| 816 | return status; | 816 | return status; |
| 817 | } | 817 | } |
| 818 | 818 | ||
| 819 | /* Caller has locked udev->pm_mutex */ | 819 | /* Caller has locked udev's pm_mutex */ |
| 820 | static int resume_device(struct usb_device *udev) | 820 | static int resume_device(struct usb_device *udev) |
| 821 | { | 821 | { |
| 822 | struct usb_device_driver *udriver; | 822 | struct usb_device_driver *udriver; |
| @@ -842,7 +842,7 @@ done: | |||
| 842 | return status; | 842 | return status; |
| 843 | } | 843 | } |
| 844 | 844 | ||
| 845 | /* Caller has locked intf's usb_device's pm_mutex */ | 845 | /* Caller has locked intf's usb_device's pm mutex */ |
| 846 | static int suspend_interface(struct usb_interface *intf, pm_message_t msg) | 846 | static int suspend_interface(struct usb_interface *intf, pm_message_t msg) |
| 847 | { | 847 | { |
| 848 | struct usb_driver *driver; | 848 | struct usb_driver *driver; |
| @@ -1064,7 +1064,7 @@ int usb_resume_both(struct usb_device *udev) | |||
| 1064 | /* Propagate the resume up the tree, if necessary */ | 1064 | /* Propagate the resume up the tree, if necessary */ |
| 1065 | if (udev->state == USB_STATE_SUSPENDED) { | 1065 | if (udev->state == USB_STATE_SUSPENDED) { |
| 1066 | if (parent) { | 1066 | if (parent) { |
| 1067 | mutex_lock_nested(&parent->pm_mutex, parent->level); | 1067 | usb_pm_lock(parent); |
| 1068 | parent->auto_pm = 1; | 1068 | parent->auto_pm = 1; |
| 1069 | status = usb_resume_both(parent); | 1069 | status = usb_resume_both(parent); |
| 1070 | } else { | 1070 | } else { |
| @@ -1079,7 +1079,7 @@ int usb_resume_both(struct usb_device *udev) | |||
| 1079 | if (status == 0) | 1079 | if (status == 0) |
| 1080 | status = resume_device(udev); | 1080 | status = resume_device(udev); |
| 1081 | if (parent) | 1081 | if (parent) |
| 1082 | mutex_unlock(&parent->pm_mutex); | 1082 | usb_pm_unlock(parent); |
| 1083 | } else { | 1083 | } else { |
| 1084 | 1084 | ||
| 1085 | /* Needed only for setting udev->dev.power.power_state.event | 1085 | /* Needed only for setting udev->dev.power.power_state.event |
| @@ -1129,12 +1129,12 @@ int usb_resume_both(struct usb_device *udev) | |||
| 1129 | */ | 1129 | */ |
| 1130 | void usb_autosuspend_device(struct usb_device *udev, int dec_usage_cnt) | 1130 | void usb_autosuspend_device(struct usb_device *udev, int dec_usage_cnt) |
| 1131 | { | 1131 | { |
| 1132 | mutex_lock_nested(&udev->pm_mutex, udev->level); | 1132 | usb_pm_lock(udev); |
| 1133 | udev->pm_usage_cnt -= dec_usage_cnt; | 1133 | udev->pm_usage_cnt -= dec_usage_cnt; |
| 1134 | if (udev->pm_usage_cnt <= 0) | 1134 | if (udev->pm_usage_cnt <= 0) |
| 1135 | queue_delayed_work(ksuspend_usb_wq, &udev->autosuspend, | 1135 | queue_delayed_work(ksuspend_usb_wq, &udev->autosuspend, |
| 1136 | USB_AUTOSUSPEND_DELAY); | 1136 | USB_AUTOSUSPEND_DELAY); |
| 1137 | mutex_unlock(&udev->pm_mutex); | 1137 | usb_pm_unlock(udev); |
| 1138 | // dev_dbg(&udev->dev, "%s: cnt %d\n", | 1138 | // dev_dbg(&udev->dev, "%s: cnt %d\n", |
| 1139 | // __FUNCTION__, udev->pm_usage_cnt); | 1139 | // __FUNCTION__, udev->pm_usage_cnt); |
| 1140 | } | 1140 | } |
| @@ -1168,13 +1168,13 @@ int usb_autoresume_device(struct usb_device *udev, int inc_usage_cnt) | |||
| 1168 | { | 1168 | { |
| 1169 | int status; | 1169 | int status; |
| 1170 | 1170 | ||
| 1171 | mutex_lock_nested(&udev->pm_mutex, udev->level); | 1171 | usb_pm_lock(udev); |
| 1172 | udev->pm_usage_cnt += inc_usage_cnt; | 1172 | udev->pm_usage_cnt += inc_usage_cnt; |
| 1173 | udev->auto_pm = 1; | 1173 | udev->auto_pm = 1; |
| 1174 | status = usb_resume_both(udev); | 1174 | status = usb_resume_both(udev); |
| 1175 | if (status != 0) | 1175 | if (status != 0) |
| 1176 | udev->pm_usage_cnt -= inc_usage_cnt; | 1176 | udev->pm_usage_cnt -= inc_usage_cnt; |
| 1177 | mutex_unlock(&udev->pm_mutex); | 1177 | usb_pm_unlock(udev); |
| 1178 | // dev_dbg(&udev->dev, "%s: status %d cnt %d\n", | 1178 | // dev_dbg(&udev->dev, "%s: status %d cnt %d\n", |
| 1179 | // __FUNCTION__, status, udev->pm_usage_cnt); | 1179 | // __FUNCTION__, status, udev->pm_usage_cnt); |
| 1180 | return status; | 1180 | return status; |
| @@ -1215,13 +1215,13 @@ void usb_autopm_put_interface(struct usb_interface *intf) | |||
| 1215 | { | 1215 | { |
| 1216 | struct usb_device *udev = interface_to_usbdev(intf); | 1216 | struct usb_device *udev = interface_to_usbdev(intf); |
| 1217 | 1217 | ||
| 1218 | mutex_lock_nested(&udev->pm_mutex, udev->level); | 1218 | usb_pm_lock(udev); |
| 1219 | if (intf->condition != USB_INTERFACE_UNBOUND && | 1219 | if (intf->condition != USB_INTERFACE_UNBOUND && |
| 1220 | --intf->pm_usage_cnt <= 0) { | 1220 | --intf->pm_usage_cnt <= 0) { |
| 1221 | queue_delayed_work(ksuspend_usb_wq, &udev->autosuspend, | 1221 | queue_delayed_work(ksuspend_usb_wq, &udev->autosuspend, |
| 1222 | USB_AUTOSUSPEND_DELAY); | 1222 | USB_AUTOSUSPEND_DELAY); |
| 1223 | } | 1223 | } |
| 1224 | mutex_unlock(&udev->pm_mutex); | 1224 | usb_pm_unlock(udev); |
| 1225 | // dev_dbg(&intf->dev, "%s: cnt %d\n", | 1225 | // dev_dbg(&intf->dev, "%s: cnt %d\n", |
| 1226 | // __FUNCTION__, intf->pm_usage_cnt); | 1226 | // __FUNCTION__, intf->pm_usage_cnt); |
| 1227 | } | 1227 | } |
| @@ -1263,7 +1263,7 @@ int usb_autopm_get_interface(struct usb_interface *intf) | |||
| 1263 | struct usb_device *udev = interface_to_usbdev(intf); | 1263 | struct usb_device *udev = interface_to_usbdev(intf); |
| 1264 | int status; | 1264 | int status; |
| 1265 | 1265 | ||
| 1266 | mutex_lock_nested(&udev->pm_mutex, udev->level); | 1266 | usb_pm_lock(udev); |
| 1267 | if (intf->condition == USB_INTERFACE_UNBOUND) | 1267 | if (intf->condition == USB_INTERFACE_UNBOUND) |
| 1268 | status = -ENODEV; | 1268 | status = -ENODEV; |
| 1269 | else { | 1269 | else { |
| @@ -1273,7 +1273,7 @@ int usb_autopm_get_interface(struct usb_interface *intf) | |||
| 1273 | if (status != 0) | 1273 | if (status != 0) |
| 1274 | --intf->pm_usage_cnt; | 1274 | --intf->pm_usage_cnt; |
| 1275 | } | 1275 | } |
| 1276 | mutex_unlock(&udev->pm_mutex); | 1276 | usb_pm_unlock(udev); |
| 1277 | // dev_dbg(&intf->dev, "%s: status %d cnt %d\n", | 1277 | // dev_dbg(&intf->dev, "%s: status %d cnt %d\n", |
| 1278 | // __FUNCTION__, status, intf->pm_usage_cnt); | 1278 | // __FUNCTION__, status, intf->pm_usage_cnt); |
| 1279 | return status; | 1279 | return status; |
| @@ -1289,10 +1289,10 @@ static int usb_suspend(struct device *dev, pm_message_t message) | |||
| 1289 | if (is_usb_device(dev)) { | 1289 | if (is_usb_device(dev)) { |
| 1290 | struct usb_device *udev = to_usb_device(dev); | 1290 | struct usb_device *udev = to_usb_device(dev); |
| 1291 | 1291 | ||
| 1292 | mutex_lock_nested(&udev->pm_mutex, udev->level); | 1292 | usb_pm_lock(udev); |
| 1293 | udev->auto_pm = 0; | 1293 | udev->auto_pm = 0; |
| 1294 | status = usb_suspend_both(udev, message); | 1294 | status = usb_suspend_both(udev, message); |
| 1295 | mutex_unlock(&udev->pm_mutex); | 1295 | usb_pm_unlock(udev); |
| 1296 | } else | 1296 | } else |
| 1297 | status = 0; | 1297 | status = 0; |
| 1298 | return status; | 1298 | return status; |
| @@ -1305,10 +1305,10 @@ static int usb_resume(struct device *dev) | |||
| 1305 | if (is_usb_device(dev)) { | 1305 | if (is_usb_device(dev)) { |
| 1306 | struct usb_device *udev = to_usb_device(dev); | 1306 | struct usb_device *udev = to_usb_device(dev); |
| 1307 | 1307 | ||
| 1308 | mutex_lock_nested(&udev->pm_mutex, udev->level); | 1308 | usb_pm_lock(udev); |
| 1309 | udev->auto_pm = 0; | 1309 | udev->auto_pm = 0; |
| 1310 | status = usb_resume_both(udev); | 1310 | status = usb_resume_both(udev); |
| 1311 | mutex_unlock(&udev->pm_mutex); | 1311 | usb_pm_unlock(udev); |
| 1312 | 1312 | ||
| 1313 | /* Rebind drivers that had no suspend method? */ | 1313 | /* Rebind drivers that had no suspend method? */ |
| 1314 | } else | 1314 | } else |
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 2a8cb3c2b19c..7676690a0386 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
| @@ -1779,7 +1779,7 @@ static int remote_wakeup(struct usb_device *udev) | |||
| 1779 | * to the parent hub! */ | 1779 | * to the parent hub! */ |
| 1780 | 1780 | ||
| 1781 | usb_lock_device(udev); | 1781 | usb_lock_device(udev); |
| 1782 | mutex_lock_nested(&udev->pm_mutex, udev->level); | 1782 | usb_pm_lock(udev); |
| 1783 | if (udev->state == USB_STATE_SUSPENDED) { | 1783 | if (udev->state == USB_STATE_SUSPENDED) { |
| 1784 | dev_dbg(&udev->dev, "usb %sresume\n", "wakeup-"); | 1784 | dev_dbg(&udev->dev, "usb %sresume\n", "wakeup-"); |
| 1785 | /* TRSMRCY = 10 msec */ | 1785 | /* TRSMRCY = 10 msec */ |
| @@ -1788,7 +1788,7 @@ static int remote_wakeup(struct usb_device *udev) | |||
| 1788 | if (status == 0) | 1788 | if (status == 0) |
| 1789 | udev->dev.power.power_state.event = PM_EVENT_ON; | 1789 | udev->dev.power.power_state.event = PM_EVENT_ON; |
| 1790 | } | 1790 | } |
| 1791 | mutex_unlock(&udev->pm_mutex); | 1791 | usb_pm_unlock(udev); |
| 1792 | 1792 | ||
| 1793 | if (status == 0) | 1793 | if (status == 0) |
| 1794 | usb_autoresume_device(udev, 0); | 1794 | usb_autoresume_device(udev, 0); |
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 239f8e5d247f..e4df9edf1bc0 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c | |||
| @@ -214,10 +214,10 @@ static void usb_autosuspend_work(void *_udev) | |||
| 214 | { | 214 | { |
| 215 | struct usb_device *udev = _udev; | 215 | struct usb_device *udev = _udev; |
| 216 | 216 | ||
| 217 | mutex_lock_nested(&udev->pm_mutex, udev->level); | 217 | usb_pm_lock(udev); |
| 218 | udev->auto_pm = 1; | 218 | udev->auto_pm = 1; |
| 219 | usb_suspend_both(udev, PMSG_SUSPEND); | 219 | usb_suspend_both(udev, PMSG_SUSPEND); |
| 220 | mutex_unlock(&udev->pm_mutex); | 220 | usb_pm_unlock(udev); |
| 221 | } | 221 | } |
| 222 | 222 | ||
| 223 | #else | 223 | #else |
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h index fb6eb41c374f..f69df137ec0e 100644 --- a/drivers/usb/core/usb.h +++ b/drivers/usb/core/usb.h | |||
| @@ -36,6 +36,16 @@ extern int usb_resume_both(struct usb_device *udev); | |||
| 36 | extern int usb_port_suspend(struct usb_device *dev); | 36 | extern int usb_port_suspend(struct usb_device *dev); |
| 37 | extern int usb_port_resume(struct usb_device *dev); | 37 | extern int usb_port_resume(struct usb_device *dev); |
| 38 | 38 | ||
| 39 | static inline void usb_pm_lock(struct usb_device *udev) | ||
| 40 | { | ||
| 41 | mutex_lock_nested(&udev->pm_mutex, udev->level); | ||
| 42 | } | ||
| 43 | |||
| 44 | static inline void usb_pm_unlock(struct usb_device *udev) | ||
| 45 | { | ||
| 46 | mutex_unlock(&udev->pm_mutex); | ||
| 47 | } | ||
| 48 | |||
| 39 | #else | 49 | #else |
| 40 | 50 | ||
| 41 | #define usb_suspend_both(udev, msg) 0 | 51 | #define usb_suspend_both(udev, msg) 0 |
| @@ -45,6 +55,8 @@ static inline int usb_resume_both(struct usb_device *udev) | |||
| 45 | } | 55 | } |
| 46 | #define usb_port_suspend(dev) 0 | 56 | #define usb_port_suspend(dev) 0 |
| 47 | #define usb_port_resume(dev) 0 | 57 | #define usb_port_resume(dev) 0 |
| 58 | static inline void usb_pm_lock(struct usb_device *udev) {} | ||
| 59 | static inline void usb_pm_unlock(struct usb_device *udev) {} | ||
| 48 | 60 | ||
| 49 | #endif | 61 | #endif |
| 50 | 62 | ||
| @@ -58,7 +70,11 @@ extern int usb_autoresume_device(struct usb_device *udev, int inc_busy_cnt); | |||
| 58 | #else | 70 | #else |
| 59 | 71 | ||
| 60 | #define usb_autosuspend_device(udev, dec_busy_cnt) do {} while (0) | 72 | #define usb_autosuspend_device(udev, dec_busy_cnt) do {} while (0) |
| 61 | #define usb_autoresume_device(udev, inc_busy_cnt) 0 | 73 | static inline int usb_autoresume_device(struct usb_device *udev, |
| 74 | int inc_busy_cnt) | ||
| 75 | { | ||
| 76 | return 0; | ||
| 77 | } | ||
| 62 | 78 | ||
| 63 | #endif | 79 | #endif |
| 64 | 80 | ||
diff --git a/include/linux/usb.h b/include/linux/usb.h index 0da15b0b02be..190cc1b78fe2 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h | |||
| @@ -380,10 +380,10 @@ struct usb_device { | |||
| 380 | int maxchild; /* Number of ports if hub */ | 380 | int maxchild; /* Number of ports if hub */ |
| 381 | struct usb_device *children[USB_MAXCHILDREN]; | 381 | struct usb_device *children[USB_MAXCHILDREN]; |
| 382 | 382 | ||
| 383 | int pm_usage_cnt; /* usage counter for autosuspend */ | ||
| 383 | #ifdef CONFIG_PM | 384 | #ifdef CONFIG_PM |
| 384 | struct work_struct autosuspend; /* for delayed autosuspends */ | 385 | struct work_struct autosuspend; /* for delayed autosuspends */ |
| 385 | struct mutex pm_mutex; /* protects PM operations */ | 386 | struct mutex pm_mutex; /* protects PM operations */ |
| 386 | int pm_usage_cnt; /* usage counter for autosuspend */ | ||
| 387 | 387 | ||
| 388 | unsigned auto_pm:1; /* autosuspend/resume in progress */ | 388 | unsigned auto_pm:1; /* autosuspend/resume in progress */ |
| 389 | unsigned do_remote_wakeup:1; /* remote wakeup should be enabled */ | 389 | unsigned do_remote_wakeup:1; /* remote wakeup should be enabled */ |
