diff options
author | Dan Williams <dan.j.williams@intel.com> | 2014-05-20 21:09:31 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-05-27 19:51:51 -0400 |
commit | 7e73be227b1510a2ba1391185be7cc357e2226ef (patch) | |
tree | 6e305d41d1ee55f12522602ba17eb1a65041c5e5 /drivers/usb/core | |
parent | 5c79a1e303363d46082408fd306cdea6d33013fc (diff) |
usb: hub_handle_remote_wakeup() depends on CONFIG_PM_RUNTIME=y
Per Alan:
"You mean from within hub_handle_remote_wakeup()? That routine will
never get called if CONFIG_PM_RUNTIME isn't enabled, because khubd
never sees wakeup requests if they arise during system suspend.
In fact, that routine ought to go inside the "#ifdef CONFIG_PM_RUNTIME"
portion of hub.c, along with the other suspend/resume code."
Suggested-by: Alan Stern <stern@rowland.harvard.edu>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/core')
-rw-r--r-- | drivers/usb/core/hub.c | 90 | ||||
-rw-r--r-- | drivers/usb/core/usb.h | 5 |
2 files changed, 49 insertions, 46 deletions
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index d43054e8e257..28f5bbae35e0 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
@@ -3348,6 +3348,55 @@ int usb_remote_wakeup(struct usb_device *udev) | |||
3348 | return status; | 3348 | return status; |
3349 | } | 3349 | } |
3350 | 3350 | ||
3351 | /* Returns 1 if there was a remote wakeup and a connect status change. */ | ||
3352 | static int hub_handle_remote_wakeup(struct usb_hub *hub, unsigned int port, | ||
3353 | u16 portstatus, u16 portchange) | ||
3354 | __must_hold(&port_dev->status_lock) | ||
3355 | { | ||
3356 | struct usb_port *port_dev = hub->ports[port - 1]; | ||
3357 | struct usb_device *hdev; | ||
3358 | struct usb_device *udev; | ||
3359 | int connect_change = 0; | ||
3360 | int ret; | ||
3361 | |||
3362 | hdev = hub->hdev; | ||
3363 | udev = port_dev->child; | ||
3364 | if (!hub_is_superspeed(hdev)) { | ||
3365 | if (!(portchange & USB_PORT_STAT_C_SUSPEND)) | ||
3366 | return 0; | ||
3367 | usb_clear_port_feature(hdev, port, USB_PORT_FEAT_C_SUSPEND); | ||
3368 | } else { | ||
3369 | if (!udev || udev->state != USB_STATE_SUSPENDED || | ||
3370 | (portstatus & USB_PORT_STAT_LINK_STATE) != | ||
3371 | USB_SS_PORT_LS_U0) | ||
3372 | return 0; | ||
3373 | } | ||
3374 | |||
3375 | if (udev) { | ||
3376 | /* TRSMRCY = 10 msec */ | ||
3377 | msleep(10); | ||
3378 | |||
3379 | usb_unlock_port(port_dev); | ||
3380 | ret = usb_remote_wakeup(udev); | ||
3381 | usb_lock_port(port_dev); | ||
3382 | if (ret < 0) | ||
3383 | connect_change = 1; | ||
3384 | } else { | ||
3385 | ret = -ENODEV; | ||
3386 | hub_port_disable(hub, port, 1); | ||
3387 | } | ||
3388 | dev_dbg(&port_dev->dev, "resume, status %d\n", ret); | ||
3389 | return connect_change; | ||
3390 | } | ||
3391 | |||
3392 | #else | ||
3393 | |||
3394 | static int hub_handle_remote_wakeup(struct usb_hub *hub, unsigned int port, | ||
3395 | u16 portstatus, u16 portchange) | ||
3396 | { | ||
3397 | return 0; | ||
3398 | } | ||
3399 | |||
3351 | #endif | 3400 | #endif |
3352 | 3401 | ||
3353 | static int check_ports_changed(struct usb_hub *hub) | 3402 | static int check_ports_changed(struct usb_hub *hub) |
@@ -4697,47 +4746,6 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, | |||
4697 | usb_lock_port(port_dev); | 4746 | usb_lock_port(port_dev); |
4698 | } | 4747 | } |
4699 | 4748 | ||
4700 | /* Returns 1 if there was a remote wakeup and a connect status change. */ | ||
4701 | static int hub_handle_remote_wakeup(struct usb_hub *hub, unsigned int port, | ||
4702 | u16 portstatus, u16 portchange) | ||
4703 | __must_hold(&port_dev->status_lock) | ||
4704 | { | ||
4705 | struct usb_port *port_dev = hub->ports[port - 1]; | ||
4706 | struct usb_device *hdev; | ||
4707 | struct usb_device *udev; | ||
4708 | int connect_change = 0; | ||
4709 | int ret; | ||
4710 | |||
4711 | hdev = hub->hdev; | ||
4712 | udev = port_dev->child; | ||
4713 | if (!hub_is_superspeed(hdev)) { | ||
4714 | if (!(portchange & USB_PORT_STAT_C_SUSPEND)) | ||
4715 | return 0; | ||
4716 | usb_clear_port_feature(hdev, port, USB_PORT_FEAT_C_SUSPEND); | ||
4717 | } else { | ||
4718 | if (!udev || udev->state != USB_STATE_SUSPENDED || | ||
4719 | (portstatus & USB_PORT_STAT_LINK_STATE) != | ||
4720 | USB_SS_PORT_LS_U0) | ||
4721 | return 0; | ||
4722 | } | ||
4723 | |||
4724 | if (udev) { | ||
4725 | /* TRSMRCY = 10 msec */ | ||
4726 | msleep(10); | ||
4727 | |||
4728 | usb_unlock_port(port_dev); | ||
4729 | ret = usb_remote_wakeup(udev); | ||
4730 | usb_lock_port(port_dev); | ||
4731 | if (ret < 0) | ||
4732 | connect_change = 1; | ||
4733 | } else { | ||
4734 | ret = -ENODEV; | ||
4735 | hub_port_disable(hub, port, 1); | ||
4736 | } | ||
4737 | dev_dbg(&port_dev->dev, "resume, status %d\n", ret); | ||
4738 | return connect_change; | ||
4739 | } | ||
4740 | |||
4741 | static void port_event(struct usb_hub *hub, int port1) | 4749 | static void port_event(struct usb_hub *hub, int port1) |
4742 | __must_hold(&port_dev->status_lock) | 4750 | __must_hold(&port_dev->status_lock) |
4743 | { | 4751 | { |
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h index 98dc08e13448..d9d08720c386 100644 --- a/drivers/usb/core/usb.h +++ b/drivers/usb/core/usb.h | |||
@@ -107,11 +107,6 @@ static inline int usb_autoresume_device(struct usb_device *udev) | |||
107 | return 0; | 107 | return 0; |
108 | } | 108 | } |
109 | 109 | ||
110 | static inline int usb_remote_wakeup(struct usb_device *udev) | ||
111 | { | ||
112 | return 0; | ||
113 | } | ||
114 | |||
115 | static inline int usb_set_usb2_hardware_lpm(struct usb_device *udev, int enable) | 110 | static inline int usb_set_usb2_hardware_lpm(struct usb_device *udev, int enable) |
116 | { | 111 | { |
117 | return 0; | 112 | return 0; |