On Wed, 10 Nov 2004, David Brownell wrote: > It's somewhat like the difference between the behavior > of a USB HCD with and without CONFIG_USB_SUSPEND. For > simplicity's sake, this assumes a root hub without any > USB devices attached: > > - With USB_SUSPEND, the root hub's USB suspend logic will > always (!) have been called before the PCI suspend call > gets issued. > > * Suspending the hub interface's device might just > shut off the virtual root hub timer (if that > board even needs that!). This is a FROZEN state > for that function, regardless of anything else. Yes. For USB device (i.e., interface) drivers, there's no distinction between FREEZE and SUSPEND. By contrast, the generic driver bound to a usb_device doesn't need to do anything for FREEZE (although it might not hurt to set a flag to prevent URBs being submitted to the frozen device), whereas for SUSPEND it needs to actually suspend the port. That's true for root hubs as well as non-virtual devices. > * After that interface suspends, so must the root hub > device itself. Though for hubs that autosuspended, > this might have nothing left to do! This hub can > probably issue wakeup events by IRQ, even though > in terms of at least DMA it's also FROZEN. > (Also HCD_STATE_SUSPENDED.) In some cases autosuspend won't kick in until after a time delay, so you might not want to rely on it here. The actual action required for suspending the root hub device itself will of course vary according to the type of controller. UHCI won't have to do anything. OHCI drivers might want to turn off some timers and disable SOF generation... > * So when the PCI device suspend gets called, all it > needs to do is shutdown PCI access ... which, if > the controller supports PCI PM, includes setting > it to a low power PCI state like D1 or D3hot, and > maybe enabling PCI PME# wakeup (For non-PCI devices, > bus glue duties are much the same.) Right. > - Otherwise (without USB_SUSPEND or autosuspend), we > currently only have PCI and root hub suspend logic. Now you're getting into trouble. Without USB_SUSPEND I wouldn't expect the USB subsystem to play very well with the PM subsystem. (Note that even without USB_SUSPEND we will still have autosuspend for UHCI root hubs, in the form of "half-suspend". Not that it will help much in this case.) Without USB_SUSPEND we don't have any root-hub suspend logic, there's only the PCI suspend logic. That is, the root-hub suspend routine may still exist in the HCD, but it won't be called by usb_suspend_device. This will definitely make things difficult. The HCD will have to call the routine itself from within its PCI suspend code when USB_SUSPEND isn't set. That means coping with in-flight URBs, new submissions, unlinks, and so on all while the controller is suspended. > * Whoops, that means root hub timers never stop > without USB_SUSPEND! That prevents some systems > from reaching lower power states ... it came up > recently with some OMAP timer patches. If timers > are constantly firing, automatic entry into deeper > sleep states (think S1) can't kick it. Kicking > those states in gave about an 8% power saving in > one simple test ... a one-day battery life going > up by almost another two hours (significant). Are you talking about the root hub status URB timers? I know you just changed that code -- doesn't the timer routine avoid calling the HCD if the HCD state isn't RUNNING or QUIESCING? Other timers are internal to the HCDs. They are examples of the things I mentioned above that would be handled by calling the root-hub suspend routine from within the PCI suspend code. > * Hmm, both OHCI and EHCI have hcd->hub_suspend() > calls, but UHCI doesn't -- just the PCI stuff. > That's not necessarily an issue, since there > probably aren't many non-PCI versions of UHCI, > but it's an issue we should remember. UHCI's suspend support has been lagging, partly because I've been working on other things instead and partly because I want to wait and see the PM interfaces stabilize before making a lot of changes. > At least for OHCI it's quite clear how to divvy up tasks > between root->suspend() and controller->suspend() ... > the root hub gets everything that's portable, the bus glue > gets the rest. EHCI can work mostly the same. > > We'll be much better off when both PM and USB cores work well > enough that we just equate USB_SUSPEND with normal CONFIG_PM > logic. Otherwise we have _way_ too many code paths to test! Maybe we shouldn't wait. Trying to do PM suspends without USB_SUSPEND support just complicates things. > > > Except it doesn't seem to me like it can be so neat, > > > especially given those examples where "frozen" is by > > > definition a power reduced state. (No audio out, > > > so the device disables all that circuitry...) > > > > That's just a harmless side effect. Unbinding an audio driver and setting > > the interface to altsetting 0 might do the same thing -- it's not relevant > > here. There's nothing wrong with a device using less power at certain > > times. What matters is that if the interface is frozen but the device > > isn't then the device really isn't suspended; you can send URBs to it, > > change its state, and so on. > > I don't quite follow. If Apples are Red, then Oranges aren't? > > Interfaces aren't devices, they don't couple that way; and I > wasn't talking about unbinding, or suggesting any kind of > new relationship between suspending devices and suspending > interfaces. (They're in the driver model tree, so interfaces > suspend before their device.) We're talking past each other. You seemed to be concerned that sometimes freezing an interface will cause a device to reduce its power usage. My reply merely stated that this shouldn't be a problem. > > > The last notion that made sense to me was having > > > "frozen" just be another suspend state ... one that > > > places even fewer constraints than system-S1 does. > > > > Don't confuse driver states with device states. FREEZE is primarily a > > driver notion whereas SUSPEND is definitely a device state (although > > it implies FREEZE, of course). > > But see the example I gave above, with root hubs. There > are three driver model devices: hub interface, hub device, > and controller. All have drivers. FREEZE and SUSPEND would > of necessity apply to each device, and thus to each driver! > > And there don't seem to be any generally useful behavioral > distinctions between those states. That's maybe most visible > for the devices that don't directly map to hardware ... like > the interface devices in USB, or network class devices. For things that don't directly map to hardware I agree, there's practically no distinction between FREEZE and SUSPEND. (Maybe no distinction at all.) For things that do, of course there is a distinction -- SUSPEND implies reduced power level and FREEZE doesn't. Also it's expected that in general devices may take longer to resume from SUSPEND than from FREEZE. If you want to say that this makes FREEZE just another, less restricted form of suspend state... That's probably just a matter of naming, not anything substantive. I won't argue against it. Alan Stern