Re: [PATCH 2/2] usb: host: xhci-plat: add wakeup entry at /sys

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 20-07-07 12:11:53, Alan Stern wrote:
> On Tue, Jul 07, 2020 at 02:01:28AM +0000, Peter Chen wrote:
> > On 20-07-06 12:22:37, Alan Stern wrote:
> > > On Mon, Jul 06, 2020 at 04:03:08AM +0000, Peter Chen wrote:
> > > > So, you suggest:
> > > > At hcd-pci.c, ohci-platform.c, ehci-platform.c, and xhci-plat.c:
> > > > change device_wakeup_enable to device_init_wakeup(dev, true).
> > > 
> > > I don't think it's necessary to do that.
> > > 
> > > device_init_wakeup(dev, true) just calls device_set_wakeup_capable() and 
> > > device_wakeup_enable().  The kernel already does the 
> > > device_set_wakeup_capable() part for these devices in the code that 
> > > registers them.  For instance, the PCI core calls 
> > > device_set_wakeup_capable() when a new device is discovered and 
> > > registered, so there's no need for hcd-pci.c to repeat this action.
> > 
> > But, that's not all the use cases. There are still two other use cases:
> > (Taking xhci-plat.c as an example):
> > - It is a platform bus device created by platform bus driver
> > - It is a platform bus device created by glue layer parents
> > (eg, dwc3/cdns3), usually, it is dual-role controller.
> 
> In these cases there would be a choice: xhci-plat.c could call 
> device_init_wakeup, or the platform-bus/glue-layer driver could call 
> device_set_wakeup_capable and xhci-plat.c could continue to call 
> device_enable_wakeup.

You said "the PCI core calls device_set_wakeup_capable() when a new device is
discovered and register", why PCI core does this, is every device on
PCI bus wakeup capable?

The reason I ask this is not every device on platform-bus is wakeup
capable, to let the controller device have defaulted "enabled" value,
we need to use device_init_wakeup at xhci-plat.c

> 
> 
> > > > I think if controller's wakeup setting is only used for ehci or xhci common code, that's ok. If
> > > > it is also used for glue layer's power control and wakeup setting; it may need to set "disabled"
> > > > for default value.
> > > 
> > > What sort of wakeup events can the glue layer generate?  It seems to me 
> > > that if there is no controller driver bound to the controller device 
> > > then the controller shouldn't be able to wake the system up in any case.
> > 
> > It should be the similar with PCI device you mentioned below. The
> > glue layer device is a platform device which is the parent of controller
> > device,
> 
> I don't understand.  Let's consider EHCI as an example.  The controller 
> device is something like 0000:00:1d.7, which is on the PCI bus and is a 
> PCI device.  Its child is usb1, which is a root-hub device on the USB 
> bus.
> 
> But you're saying that the glue layer device would be the parent of the 
> controller device, right?  This means it would be analogous to the 
> parent of 0000:00:1d.7.  In the PCI world, that parent would be a PCI 
> bridge or something similar.  It would have no understanding of 
> ID/VBUS/DP/DM/RX changes, since those are all USB concepts and have 
> nothing to do with PCI.

Sorry, my words were not precise.

>From hardware level:
Controller includes core part and non-core part, core part is usually
designed by IP vendor, non-core part is usually designed by each SoC
vendors. Wakeup handling is part of non-core. The USB PHY gets
ID/VBUS/DP/DM/RX change events, the related signal ties to non-core part,
and non-core part knows the wakeup occurs.

>From software level:
Taking single role controller as example:
Glue layer is a platform device, and handles non-core part events,
including wakeup events, it is the parent of common layer which handles
core part events (eg, xhci-plat.c)

So, one controller includes two platform devices, one for glue layer,
one for common layer.

> 
> > it could detect ID/VBUS/DP/DM/RX changes and generate wakeup
> > events, these wakeup events will trigger interrupt, this interrupt
> > number could be the same with controller interrupt number or not.
> 
> This really sounds like you are talking about the controller, not the 
> controller's parent.  Or maybe a PHY, which is sort of next to the 
> controller without being its parent or child.
> 
> I like to think of it this way: A controller or device is something that 
> sits at an endpoint of a bus or communication channel, or at the meeting 
> place of two buses or communication channels.  Thus, an EHCI controller 
> sits at the meeting place of a PCI bus and a USB bus.  As a result, it 
> has interfaces to two buses: an upward-facing PCI bus interface and a 
> downward-facing USB bus interface.  The controller and root-hub devices 
> are abstractions used by the kernel to represent these two interfaces.
> That's why the ehci-pci controller driver registers itself with a 
> struct pci_driver and why root hubs are bound to the usb_generic_driver, 
> even though the actual hardware is all part of a single EHCI controller 
> chip.
> 
> So now, in the situations you're talking about, what exactly are the 
> buses, the interfaces, and the controllers/devices?

roothub is the child of the core part, core part is the child of non-core part.

> 
> > When the system is in suspend (D3), when the wakeup events occurs,
> > the system interrupt controller could trigger wakeup request, and
> > wake system up. When the system is in full-power state (D0), this
> > interrupt just wakes up glue layer, and glue layer wakes up common
> > USB stack (EHCI/XHCI).
> 
> When a device or controller relays information from one bus or another, 
> the wakeup setting indicates whether or not it should relay wakeup 
> requests.  ID/VBUS/DP/DM/RX events are all things that take place on the 
> USB bus.  As a result, the corresponding wakeup requests are 
> theoretically generated by the root-hub device -- not by the controller 
> device, since the controller device is attached to the upward-facing bus 
> and not to the USB bus.  The controller's wakeup setting thus indicates 
> whether the controller should forward these wakeup requests from the 
> root hub to the upward-facing bus.  Once a request reaches the 
> upward-facing bus, it could take the form of an ordinary IRQ signal or a 
> system-level wakeup signal.

You are right, ID/VBUS/DP/DM/RX signal changing occurs at the USB bus,
and detected by USB PHY physically.
   
The controller device (core part) or glue layer device
(non-core part)'s wakeup setting is only used to enable/disable platform
related powers (regulators) for USB (PHY) which are used to detect
ID/VBUS/DP/DM/RX signal. If the platform doesn't need USB wakeup capabilities
for system suspend, it could turn off related powers. Besides, it could tell
the system if USB interrupt can be the wakeup interrupt.

> 
> > > > I am curious how PCI USB at PC determine whether it responds USB wakeup events or not?
> > > > At Linux kernel or BIOS? It has two places for enabling USB wakeup, one for USB devices
> > > > (including roothub), another is for PCI device?
> > > 
> > > PCI devices send wakeup requests via a special PCI power management 
> > > signal called PME -- you can see its state in the output from "lspci 
> > > -vv" in the Power Management Capability section.  In legacy systems this 
> > > signal was handled by the BIOS, but nowadays the PCI and ACPI subsystems 
> > > in the Linux kernel handle it.
> > > 
> > > If a PCI host controller is in the D3 low-power state when a wakeup 
> > > event occurs, it uses the PME# signal to request a wakeup.  If it is in 
> > > the D0 full-power state when a wakeup event occurs, it uses its normal 
> > > IRQ signal to tell the system about the event.
> > > 
> > 
> > If the USBCMD.RS is cleared, does the interrupt could still occur when
> > the system is at D0, or this interrupt is not USB interrupt, it is a
> > PCI interrupt?
> 
> I don't remember the details offhand.  I think pretty much the same 
> events are generated regardless of whether USBCMD.RS is set or clear.  
> 
> Anyway, when one of these events occurs, it causes an interrupt flag to 
> be set in the hardware.  If the controller is in D0 then it will raise a 
> PCI IRQ whenever the interrupt flag is set (and not masked).  If the 
> controller is in D3 then it is not allowed to raise a PCI IRQ, so it 
> asserts the PCI PME signal instead.
> 
> I'm not sure what you mean by "USB interrupt".  The USB protocol doesn't 
> have interrupts.  (It has interrupt URBs, but those are completely 
> different things as you know.)  The closest thing USB has to an 
> interrupt is a wakeup request.
> 

The "USB interrupt" I mean here is the interrupt event triggered by core
part of the USB controller, for example the interrupt at usbsts for EHCI.

-- 

Thanks,
Peter Chen



[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux