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>
This commit is contained in:
parent
5c79a1e303
commit
7e73be227b
|
@ -3348,6 +3348,55 @@ int usb_remote_wakeup(struct usb_device *udev)
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Returns 1 if there was a remote wakeup and a connect status change. */
|
||||||
|
static int hub_handle_remote_wakeup(struct usb_hub *hub, unsigned int port,
|
||||||
|
u16 portstatus, u16 portchange)
|
||||||
|
__must_hold(&port_dev->status_lock)
|
||||||
|
{
|
||||||
|
struct usb_port *port_dev = hub->ports[port - 1];
|
||||||
|
struct usb_device *hdev;
|
||||||
|
struct usb_device *udev;
|
||||||
|
int connect_change = 0;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
hdev = hub->hdev;
|
||||||
|
udev = port_dev->child;
|
||||||
|
if (!hub_is_superspeed(hdev)) {
|
||||||
|
if (!(portchange & USB_PORT_STAT_C_SUSPEND))
|
||||||
|
return 0;
|
||||||
|
usb_clear_port_feature(hdev, port, USB_PORT_FEAT_C_SUSPEND);
|
||||||
|
} else {
|
||||||
|
if (!udev || udev->state != USB_STATE_SUSPENDED ||
|
||||||
|
(portstatus & USB_PORT_STAT_LINK_STATE) !=
|
||||||
|
USB_SS_PORT_LS_U0)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (udev) {
|
||||||
|
/* TRSMRCY = 10 msec */
|
||||||
|
msleep(10);
|
||||||
|
|
||||||
|
usb_unlock_port(port_dev);
|
||||||
|
ret = usb_remote_wakeup(udev);
|
||||||
|
usb_lock_port(port_dev);
|
||||||
|
if (ret < 0)
|
||||||
|
connect_change = 1;
|
||||||
|
} else {
|
||||||
|
ret = -ENODEV;
|
||||||
|
hub_port_disable(hub, port, 1);
|
||||||
|
}
|
||||||
|
dev_dbg(&port_dev->dev, "resume, status %d\n", ret);
|
||||||
|
return connect_change;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
static int hub_handle_remote_wakeup(struct usb_hub *hub, unsigned int port,
|
||||||
|
u16 portstatus, u16 portchange)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int check_ports_changed(struct usb_hub *hub)
|
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,
|
||||||
usb_lock_port(port_dev);
|
usb_lock_port(port_dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Returns 1 if there was a remote wakeup and a connect status change. */
|
|
||||||
static int hub_handle_remote_wakeup(struct usb_hub *hub, unsigned int port,
|
|
||||||
u16 portstatus, u16 portchange)
|
|
||||||
__must_hold(&port_dev->status_lock)
|
|
||||||
{
|
|
||||||
struct usb_port *port_dev = hub->ports[port - 1];
|
|
||||||
struct usb_device *hdev;
|
|
||||||
struct usb_device *udev;
|
|
||||||
int connect_change = 0;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
hdev = hub->hdev;
|
|
||||||
udev = port_dev->child;
|
|
||||||
if (!hub_is_superspeed(hdev)) {
|
|
||||||
if (!(portchange & USB_PORT_STAT_C_SUSPEND))
|
|
||||||
return 0;
|
|
||||||
usb_clear_port_feature(hdev, port, USB_PORT_FEAT_C_SUSPEND);
|
|
||||||
} else {
|
|
||||||
if (!udev || udev->state != USB_STATE_SUSPENDED ||
|
|
||||||
(portstatus & USB_PORT_STAT_LINK_STATE) !=
|
|
||||||
USB_SS_PORT_LS_U0)
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (udev) {
|
|
||||||
/* TRSMRCY = 10 msec */
|
|
||||||
msleep(10);
|
|
||||||
|
|
||||||
usb_unlock_port(port_dev);
|
|
||||||
ret = usb_remote_wakeup(udev);
|
|
||||||
usb_lock_port(port_dev);
|
|
||||||
if (ret < 0)
|
|
||||||
connect_change = 1;
|
|
||||||
} else {
|
|
||||||
ret = -ENODEV;
|
|
||||||
hub_port_disable(hub, port, 1);
|
|
||||||
}
|
|
||||||
dev_dbg(&port_dev->dev, "resume, status %d\n", ret);
|
|
||||||
return connect_change;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void port_event(struct usb_hub *hub, int port1)
|
static void port_event(struct usb_hub *hub, int port1)
|
||||||
__must_hold(&port_dev->status_lock)
|
__must_hold(&port_dev->status_lock)
|
||||||
{
|
{
|
||||||
|
|
|
@ -107,11 +107,6 @@ static inline int usb_autoresume_device(struct usb_device *udev)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int usb_remote_wakeup(struct usb_device *udev)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int usb_set_usb2_hardware_lpm(struct usb_device *udev, int enable)
|
static inline int usb_set_usb2_hardware_lpm(struct usb_device *udev, int enable)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Reference in New Issue