aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/core/driver.c15
-rw-r--r--drivers/usb/core/usb.c73
-rw-r--r--drivers/usb/core/usb.h3
3 files changed, 72 insertions, 19 deletions
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index 637b2bea5563..2da70b4d33fe 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -1630,12 +1630,10 @@ int usb_external_resume_device(struct usb_device *udev)
1630 return status; 1630 return status;
1631} 1631}
1632 1632
1633static int usb_suspend(struct device *dev, pm_message_t message) 1633int usb_suspend(struct device *dev, pm_message_t message)
1634{ 1634{
1635 struct usb_device *udev; 1635 struct usb_device *udev;
1636 1636
1637 if (!is_usb_device(dev)) /* Ignore PM for interfaces */
1638 return 0;
1639 udev = to_usb_device(dev); 1637 udev = to_usb_device(dev);
1640 1638
1641 /* If udev is already suspended, we can skip this suspend and 1639 /* If udev is already suspended, we can skip this suspend and
@@ -1654,12 +1652,10 @@ static int usb_suspend(struct device *dev, pm_message_t message)
1654 return usb_external_suspend_device(udev, message); 1652 return usb_external_suspend_device(udev, message);
1655} 1653}
1656 1654
1657static int usb_resume(struct device *dev) 1655int usb_resume(struct device *dev)
1658{ 1656{
1659 struct usb_device *udev; 1657 struct usb_device *udev;
1660 1658
1661 if (!is_usb_device(dev)) /* Ignore PM for interfaces */
1662 return 0;
1663 udev = to_usb_device(dev); 1659 udev = to_usb_device(dev);
1664 1660
1665 /* If udev->skip_sys_resume is set then udev was already suspended 1661 /* If udev->skip_sys_resume is set then udev was already suspended
@@ -1671,17 +1667,10 @@ static int usb_resume(struct device *dev)
1671 return usb_external_resume_device(udev); 1667 return usb_external_resume_device(udev);
1672} 1668}
1673 1669
1674#else
1675
1676#define usb_suspend NULL
1677#define usb_resume NULL
1678
1679#endif /* CONFIG_PM */ 1670#endif /* CONFIG_PM */
1680 1671
1681struct bus_type usb_bus_type = { 1672struct bus_type usb_bus_type = {
1682 .name = "usb", 1673 .name = "usb",
1683 .match = usb_device_match, 1674 .match = usb_device_match,
1684 .uevent = usb_uevent, 1675 .uevent = usb_uevent,
1685 .suspend = usb_suspend,
1686 .resume = usb_resume,
1687}; 1676};
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index 84fcaa6a21ec..be1fa0723f2c 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -219,12 +219,6 @@ static int usb_dev_uevent(struct device *dev, struct kobj_uevent_env *env)
219} 219}
220#endif /* CONFIG_HOTPLUG */ 220#endif /* CONFIG_HOTPLUG */
221 221
222struct device_type usb_device_type = {
223 .name = "usb_device",
224 .release = usb_release_dev,
225 .uevent = usb_dev_uevent,
226};
227
228#ifdef CONFIG_PM 222#ifdef CONFIG_PM
229 223
230static int ksuspend_usb_init(void) 224static int ksuspend_usb_init(void)
@@ -244,13 +238,80 @@ static void ksuspend_usb_cleanup(void)
244 destroy_workqueue(ksuspend_usb_wq); 238 destroy_workqueue(ksuspend_usb_wq);
245} 239}
246 240
241/* USB device Power-Management thunks.
242 * There's no need to distinguish here between quiescing a USB device
243 * and powering it down; the generic_suspend() routine takes care of
244 * it by skipping the usb_port_suspend() call for a quiesce. And for
245 * USB interfaces there's no difference at all.
246 */
247
248static int usb_dev_prepare(struct device *dev)
249{
250 return 0; /* Implement eventually? */
251}
252
253static void usb_dev_complete(struct device *dev)
254{
255 /* Currently used only for rebinding interfaces */
256 usb_resume(dev); /* Implement eventually? */
257}
258
259static int usb_dev_suspend(struct device *dev)
260{
261 return usb_suspend(dev, PMSG_SUSPEND);
262}
263
264static int usb_dev_resume(struct device *dev)
265{
266 return usb_resume(dev);
267}
268
269static int usb_dev_freeze(struct device *dev)
270{
271 return usb_suspend(dev, PMSG_FREEZE);
272}
273
274static int usb_dev_thaw(struct device *dev)
275{
276 return usb_resume(dev);
277}
278
279static int usb_dev_poweroff(struct device *dev)
280{
281 return usb_suspend(dev, PMSG_HIBERNATE);
282}
283
284static int usb_dev_restore(struct device *dev)
285{
286 return usb_resume(dev);
287}
288
289static struct pm_ops usb_device_pm_ops = {
290 .prepare = usb_dev_prepare,
291 .complete = usb_dev_complete,
292 .suspend = usb_dev_suspend,
293 .resume = usb_dev_resume,
294 .freeze = usb_dev_freeze,
295 .thaw = usb_dev_thaw,
296 .poweroff = usb_dev_poweroff,
297 .restore = usb_dev_restore,
298};
299
247#else 300#else
248 301
249#define ksuspend_usb_init() 0 302#define ksuspend_usb_init() 0
250#define ksuspend_usb_cleanup() do {} while (0) 303#define ksuspend_usb_cleanup() do {} while (0)
304#define usb_device_pm_ops (*(struct pm_ops *)0)
251 305
252#endif /* CONFIG_PM */ 306#endif /* CONFIG_PM */
253 307
308struct device_type usb_device_type = {
309 .name = "usb_device",
310 .release = usb_release_dev,
311 .uevent = usb_dev_uevent,
312 .pm = &usb_device_pm_ops,
313};
314
254 315
255/* Returns 1 if @usb_bus is WUSB, 0 otherwise */ 316/* Returns 1 if @usb_bus is WUSB, 0 otherwise */
256static unsigned usb_bus_is_wusb(struct usb_bus *bus) 317static unsigned usb_bus_is_wusb(struct usb_bus *bus)
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h
index d9a6e16dbf84..9a1a45ac3add 100644
--- a/drivers/usb/core/usb.h
+++ b/drivers/usb/core/usb.h
@@ -41,6 +41,9 @@ extern void usb_host_cleanup(void);
41 41
42#ifdef CONFIG_PM 42#ifdef CONFIG_PM
43 43
44extern int usb_suspend(struct device *dev, pm_message_t msg);
45extern int usb_resume(struct device *dev);
46
44extern void usb_autosuspend_work(struct work_struct *work); 47extern void usb_autosuspend_work(struct work_struct *work);
45extern int usb_port_suspend(struct usb_device *dev); 48extern int usb_port_suspend(struct usb_device *dev);
46extern int usb_port_resume(struct usb_device *dev); 49extern int usb_port_resume(struct usb_device *dev);