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 | |
| 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>
| -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; |
