On Fri, Apr 20, 2018 at 7:12 AM, Alan Stern <stern@xxxxxxxxxxxxxxxxxxx> wrote: > On Thu, 19 Apr 2018, Ravi Chandra Sadineni wrote: > >> 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 <ravisadineni@xxxxxxxxxxxx> >> --- >> drivers/usb/core/hcd.c | 2 ++ >> drivers/usb/core/hub.c | 10 +++++++++- >> 2 files changed, 11 insertions(+), 1 deletion(-) >> >> diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c >> index 777036ae63674..ee0f3ec57ce49 100644 >> --- a/drivers/usb/core/hcd.c >> +++ b/drivers/usb/core/hcd.c >> @@ -2374,7 +2374,9 @@ static void hcd_resume_work(struct work_struct *work) >> void usb_hcd_resume_root_hub (struct usb_hcd *hcd) >> { >> unsigned long flags; >> + struct device *dev = &hcd->self.root_hub->dev; >> >> + pm_wakeup_event(dev, 0); >> spin_lock_irqsave (&hcd_root_hub_lock, flags); >> if (hcd->rh_registered) { >> set_bit(HCD_FLAG_WAKEUP_PENDING, &hcd->flags); > > In general, hcd->self.root_hub is guaranteed to be non-NULL only when > hcd->rh_registered is set. Therefore the assignment to dev and the > call to pm_wakeup_event() should be moved within this "if" statement. > > The rest of the patch looks okay. Added the check in V3. Thanks. > > Alan Stern > >> diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c >> index f6ea16e9f6bb9..aa9968d90a48c 100644 >> --- a/drivers/usb/core/hub.c >> +++ b/drivers/usb/core/hub.c >> @@ -653,12 +653,17 @@ void usb_wakeup_notification(struct usb_device *hdev, >> unsigned int portnum) >> { >> struct usb_hub *hub; >> + struct usb_port *port_dev; >> >> if (!hdev) >> return; >> >> hub = usb_hub_to_struct_hub(hdev); >> if (hub) { >> + port_dev = hub->ports[portnum - 1]; >> + if (port_dev && port_dev->child) >> + pm_wakeup_event(&port_dev->child->dev, 0); >> + >> set_bit(portnum, hub->wakeup_bits); >> kick_hub_wq(hub); >> } >> @@ -3434,8 +3439,11 @@ int usb_port_resume(struct usb_device *udev, pm_message_t msg) >> >> /* Skip the initial Clear-Suspend step for a remote wakeup */ >> status = hub_port_status(hub, port1, &portstatus, &portchange); >> - if (status == 0 && !port_is_suspended(hub, portstatus)) >> + if (status == 0 && !port_is_suspended(hub, portstatus)) { >> + if (portchange & USB_PORT_STAT_C_SUSPEND) >> + pm_wakeup_event(&udev->dev, 0); >> goto SuspendCleared; >> + } >> >> /* see 7.1.7.7; affects power usage, but not budgeting */ >> if (hub_is_superspeed(hub->hdev)) >> > Thanks, Ravi -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html