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