Skip to content

Commit 83a62c5

Browse files
Ravi Chandra Sadinenigregkh
authored andcommitted
USB: Increment wakeup count on remote wakeup.
On chromebooks we depend on wakeup count to identify the wakeup source. But currently USB devices do not increment the wakeup count when they trigger the remote wake. This patch addresses the same. Resume condition is reported differently on USB 2.0 and USB 3.0 devices. On USB 2.0 devices, a wake capable device, if wake enabled, drives resume signal to indicate a remote wake (USB 2.0 spec section 7.1.7.7). The upstream facing port then sets C_PORT_SUSPEND bit and reports a port change event (USB 2.0 spec section 11.24.2.7.2.3). Thus if a port has resumed before driving the resume signal from the host and C_PORT_SUSPEND is set, then the device attached to the given port might be the reason for the last system wakeup. Increment the wakeup count for the same. On USB 3.0 devices, a function may signal that it wants to exit from device suspend by sending a Function Wake Device Notification to the host (USB3.0 spec section 8.5.6.4) Thus on receiving the Function Wake, increment the wakeup count. Signed-off-by: Ravi Chandra Sadineni <[email protected]> Acked-by: Alan Stern <[email protected]> Cc: stable <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 3ae2da7 commit 83a62c5

File tree

2 files changed

+10
-1
lines changed

2 files changed

+10
-1
lines changed

drivers/usb/core/hcd.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2377,6 +2377,7 @@ void usb_hcd_resume_root_hub (struct usb_hcd *hcd)
23772377

23782378
spin_lock_irqsave (&hcd_root_hub_lock, flags);
23792379
if (hcd->rh_registered) {
2380+
pm_wakeup_event(&hcd->self.root_hub->dev, 0);
23802381
set_bit(HCD_FLAG_WAKEUP_PENDING, &hcd->flags);
23812382
queue_work(pm_wq, &hcd->wakeup_work);
23822383
}

drivers/usb/core/hub.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -653,12 +653,17 @@ void usb_wakeup_notification(struct usb_device *hdev,
653653
unsigned int portnum)
654654
{
655655
struct usb_hub *hub;
656+
struct usb_port *port_dev;
656657

657658
if (!hdev)
658659
return;
659660

660661
hub = usb_hub_to_struct_hub(hdev);
661662
if (hub) {
663+
port_dev = hub->ports[portnum - 1];
664+
if (port_dev && port_dev->child)
665+
pm_wakeup_event(&port_dev->child->dev, 0);
666+
662667
set_bit(portnum, hub->wakeup_bits);
663668
kick_hub_wq(hub);
664669
}
@@ -3434,8 +3439,11 @@ int usb_port_resume(struct usb_device *udev, pm_message_t msg)
34343439

34353440
/* Skip the initial Clear-Suspend step for a remote wakeup */
34363441
status = hub_port_status(hub, port1, &portstatus, &portchange);
3437-
if (status == 0 && !port_is_suspended(hub, portstatus))
3442+
if (status == 0 && !port_is_suspended(hub, portstatus)) {
3443+
if (portchange & USB_PORT_STAT_C_SUSPEND)
3444+
pm_wakeup_event(&udev->dev, 0);
34383445
goto SuspendCleared;
3446+
}
34393447

34403448
/* see 7.1.7.7; affects power usage, but not budgeting */
34413449
if (hub_is_superspeed(hub->hdev))

0 commit comments

Comments
 (0)