|
@@ -2,7 +2,7 @@
|
|
|
|
|
|
Alan Stern <stern@rowland.harvard.edu>
|
|
|
|
|
|
- November 10, 2009
|
|
|
+ December 11, 2009
|
|
|
|
|
|
|
|
|
|
|
@@ -29,9 +29,9 @@ covered to some extent (see Documentation/power/*.txt for more
|
|
|
information about system PM).
|
|
|
|
|
|
Note: Dynamic PM support for USB is present only if the kernel was
|
|
|
-built with CONFIG_USB_SUSPEND enabled. System PM support is present
|
|
|
-only if the kernel was built with CONFIG_SUSPEND or CONFIG_HIBERNATION
|
|
|
-enabled.
|
|
|
+built with CONFIG_USB_SUSPEND enabled (which depends on
|
|
|
+CONFIG_PM_RUNTIME). System PM support is present only if the kernel
|
|
|
+was built with CONFIG_SUSPEND or CONFIG_HIBERNATION enabled.
|
|
|
|
|
|
|
|
|
What is Remote Wakeup?
|
|
@@ -326,64 +326,63 @@ driver does so by calling these six functions:
|
|
|
void usb_autopm_get_interface_no_resume(struct usb_interface *intf);
|
|
|
void usb_autopm_put_interface_no_suspend(struct usb_interface *intf);
|
|
|
|
|
|
-The functions work by maintaining a counter in the usb_interface
|
|
|
-structure. When intf->pm_usage_count is > 0 then the interface is
|
|
|
-deemed to be busy, and the kernel will not autosuspend the interface's
|
|
|
-device. When intf->pm_usage_count is <= 0 then the interface is
|
|
|
-considered to be idle, and the kernel may autosuspend the device.
|
|
|
+The functions work by maintaining a usage counter in the
|
|
|
+usb_interface's embedded device structure. When the counter is > 0
|
|
|
+then the interface is deemed to be busy, and the kernel will not
|
|
|
+autosuspend the interface's device. When the usage counter is = 0
|
|
|
+then the interface is considered to be idle, and the kernel may
|
|
|
+autosuspend the device.
|
|
|
|
|
|
-(There is a similar pm_usage_count field in struct usb_device,
|
|
|
+(There is a similar usage counter field in struct usb_device,
|
|
|
associated with the device itself rather than any of its interfaces.
|
|
|
-This field is used only by the USB core.)
|
|
|
-
|
|
|
-Drivers must not modify intf->pm_usage_count directly; its value
|
|
|
-should be changed only be using the functions listed above. Drivers
|
|
|
-are responsible for insuring that the overall change to pm_usage_count
|
|
|
-during their lifetime balances out to 0 (it may be necessary for the
|
|
|
-disconnect method to call usb_autopm_put_interface() one or more times
|
|
|
-to fulfill this requirement). The first two routines use the PM mutex
|
|
|
-in struct usb_device for mutual exclusion; drivers using the async
|
|
|
-routines are responsible for their own synchronization and mutual
|
|
|
-exclusion.
|
|
|
-
|
|
|
- usb_autopm_get_interface() increments pm_usage_count and
|
|
|
- attempts an autoresume if the new value is > 0 and the
|
|
|
- device is suspended.
|
|
|
-
|
|
|
- usb_autopm_put_interface() decrements pm_usage_count and
|
|
|
- attempts an autosuspend if the new value is <= 0 and the
|
|
|
- device isn't suspended.
|
|
|
+This counter is used only by the USB core.)
|
|
|
+
|
|
|
+Drivers need not be concerned about balancing changes to the usage
|
|
|
+counter; the USB core will undo any remaining "get"s when a driver
|
|
|
+is unbound from its interface. As a corollary, drivers must not call
|
|
|
+any of the usb_autopm_* functions after their diconnect() routine has
|
|
|
+returned.
|
|
|
+
|
|
|
+Drivers using the async routines are responsible for their own
|
|
|
+synchronization and mutual exclusion.
|
|
|
+
|
|
|
+ usb_autopm_get_interface() increments the usage counter and
|
|
|
+ does an autoresume if the device is suspended. If the
|
|
|
+ autoresume fails, the counter is decremented back.
|
|
|
+
|
|
|
+ usb_autopm_put_interface() decrements the usage counter and
|
|
|
+ attempts an autosuspend if the new value is = 0.
|
|
|
|
|
|
usb_autopm_get_interface_async() and
|
|
|
usb_autopm_put_interface_async() do almost the same things as
|
|
|
- their non-async counterparts. The differences are: they do
|
|
|
- not acquire the PM mutex, and they use a workqueue to do their
|
|
|
+ their non-async counterparts. The big difference is that they
|
|
|
+ use a workqueue to do the resume or suspend part of their
|
|
|
jobs. As a result they can be called in an atomic context,
|
|
|
such as an URB's completion handler, but when they return the
|
|
|
- device will not generally not yet be in the desired state.
|
|
|
+ device will generally not yet be in the desired state.
|
|
|
|
|
|
usb_autopm_get_interface_no_resume() and
|
|
|
usb_autopm_put_interface_no_suspend() merely increment or
|
|
|
- decrement the pm_usage_count value; they do not attempt to
|
|
|
- carry out an autoresume or an autosuspend. Hence they can be
|
|
|
- called in an atomic context.
|
|
|
+ decrement the usage counter; they do not attempt to carry out
|
|
|
+ an autoresume or an autosuspend. Hence they can be called in
|
|
|
+ an atomic context.
|
|
|
|
|
|
-The conventional usage pattern is that a driver calls
|
|
|
+The simplest usage pattern is that a driver calls
|
|
|
usb_autopm_get_interface() in its open routine and
|
|
|
-usb_autopm_put_interface() in its close or release routine. But
|
|
|
-other patterns are possible.
|
|
|
+usb_autopm_put_interface() in its close or release routine. But other
|
|
|
+patterns are possible.
|
|
|
|
|
|
The autosuspend attempts mentioned above will often fail for one
|
|
|
reason or another. For example, the power/level attribute might be
|
|
|
set to "on", or another interface in the same device might not be
|
|
|
idle. This is perfectly normal. If the reason for failure was that
|
|
|
-the device hasn't been idle for long enough, a delayed workqueue
|
|
|
-routine is automatically set up to carry out the operation when the
|
|
|
-autosuspend idle-delay has expired.
|
|
|
+the device hasn't been idle for long enough, a timer is scheduled to
|
|
|
+carry out the operation automatically when the autosuspend idle-delay
|
|
|
+has expired.
|
|
|
|
|
|
Autoresume attempts also can fail, although failure would mean that
|
|
|
the device is no longer present or operating properly. Unlike
|
|
|
-autosuspend, there's no delay for an autoresume.
|
|
|
+autosuspend, there's no idle-delay for an autoresume.
|
|
|
|
|
|
|
|
|
Other parts of the driver interface
|
|
@@ -413,26 +412,27 @@ though, setting this flag won't cause the kernel to autoresume it.
|
|
|
Normally a driver would set this flag in its probe method, at which
|
|
|
time the device is guaranteed not to be autosuspended.)
|
|
|
|
|
|
-The synchronous usb_autopm_* routines have to run in a sleepable
|
|
|
-process context; they must not be called from an interrupt handler or
|
|
|
-while holding a spinlock. In fact, the entire autosuspend mechanism
|
|
|
-is not well geared toward interrupt-driven operation. However there
|
|
|
-is one thing a driver can do in an interrupt handler:
|
|
|
+If a driver does its I/O asynchronously in interrupt context, it
|
|
|
+should call usb_autopm_get_interface_async() before starting output and
|
|
|
+usb_autopm_put_interface_async() when the output queue drains. When
|
|
|
+it receives an input event, it should call
|
|
|
|
|
|
usb_mark_last_busy(struct usb_device *udev);
|
|
|
|
|
|
-This sets udev->last_busy to the current time. udev->last_busy is the
|
|
|
-field used for idle-delay calculations; updating it will cause any
|
|
|
-pending autosuspend to be moved back. The usb_autopm_* routines will
|
|
|
-also set the last_busy field to the current time.
|
|
|
-
|
|
|
-Calling urb_mark_last_busy() from within an URB completion handler is
|
|
|
-subject to races: The kernel may have just finished deciding the
|
|
|
-device has been idle for long enough but not yet gotten around to
|
|
|
-calling the driver's suspend method. The driver would have to be
|
|
|
-responsible for synchronizing its suspend method with its URB
|
|
|
-completion handler and causing the autosuspend to fail with -EBUSY if
|
|
|
-an URB had completed too recently.
|
|
|
+in the event handler. This sets udev->last_busy to the current time.
|
|
|
+udev->last_busy is the field used for idle-delay calculations;
|
|
|
+updating it will cause any pending autosuspend to be moved back. Most
|
|
|
+of the usb_autopm_* routines will also set the last_busy field to the
|
|
|
+current time.
|
|
|
+
|
|
|
+Asynchronous operation is always subject to races. For example, a
|
|
|
+driver may call one of the usb_autopm_*_interface_async() routines at
|
|
|
+a time when the core has just finished deciding the device has been
|
|
|
+idle for long enough but not yet gotten around to calling the driver's
|
|
|
+suspend method. The suspend method must be responsible for
|
|
|
+synchronizing with the output request routine and the URB completion
|
|
|
+handler; it should cause autosuspends to fail with -EBUSY if the
|
|
|
+driver needs to use the device.
|
|
|
|
|
|
External suspend calls should never be allowed to fail in this way,
|
|
|
only autosuspend calls. The driver can tell them apart by checking
|
|
@@ -440,75 +440,23 @@ the PM_EVENT_AUTO bit in the message.event argument to the suspend
|
|
|
method; this bit will be set for internal PM events (autosuspend) and
|
|
|
clear for external PM events.
|
|
|
|
|
|
-Many of the ingredients in the autosuspend framework are oriented
|
|
|
-towards interfaces: The usb_interface structure contains the
|
|
|
-pm_usage_cnt field, and the usb_autopm_* routines take an interface
|
|
|
-pointer as their argument. But somewhat confusingly, a few of the
|
|
|
-pieces (i.e., usb_mark_last_busy()) use the usb_device structure
|
|
|
-instead. Drivers need to keep this straight; they can call
|
|
|
-interface_to_usbdev() to find the device structure for a given
|
|
|
-interface.
|
|
|
|
|
|
+ Mutual exclusion
|
|
|
+ ----------------
|
|
|
|
|
|
- Locking requirements
|
|
|
- --------------------
|
|
|
-
|
|
|
-All three suspend/resume methods are always called while holding the
|
|
|
-usb_device's PM mutex. For external events -- but not necessarily for
|
|
|
-autosuspend or autoresume -- the device semaphore (udev->dev.sem) will
|
|
|
-also be held. This implies that external suspend/resume events are
|
|
|
-mutually exclusive with calls to probe, disconnect, pre_reset, and
|
|
|
-post_reset; the USB core guarantees that this is true of internal
|
|
|
-suspend/resume events as well.
|
|
|
+For external events -- but not necessarily for autosuspend or
|
|
|
+autoresume -- the device semaphore (udev->dev.sem) will be held when a
|
|
|
+suspend or resume method is called. This implies that external
|
|
|
+suspend/resume events are mutually exclusive with calls to probe,
|
|
|
+disconnect, pre_reset, and post_reset; the USB core guarantees that
|
|
|
+this is true of autosuspend/autoresume events as well.
|
|
|
|
|
|
If a driver wants to block all suspend/resume calls during some
|
|
|
-critical section, it can simply acquire udev->pm_mutex. Note that
|
|
|
-calls to resume may be triggered indirectly. Block IO due to memory
|
|
|
-allocations can make the vm subsystem resume a device. Thus while
|
|
|
-holding this lock you must not allocate memory with GFP_KERNEL or
|
|
|
-GFP_NOFS.
|
|
|
-
|
|
|
-Alternatively, if the critical section might call some of the
|
|
|
-usb_autopm_* routines, the driver can avoid deadlock by doing:
|
|
|
-
|
|
|
- down(&udev->dev.sem);
|
|
|
- rc = usb_autopm_get_interface(intf);
|
|
|
-
|
|
|
-and at the end of the critical section:
|
|
|
-
|
|
|
- if (!rc)
|
|
|
- usb_autopm_put_interface(intf);
|
|
|
- up(&udev->dev.sem);
|
|
|
-
|
|
|
-Holding the device semaphore will block all external PM calls, and the
|
|
|
-usb_autopm_get_interface() will prevent any internal PM calls, even if
|
|
|
-it fails. (Exercise: Why?)
|
|
|
-
|
|
|
-The rules for locking order are:
|
|
|
-
|
|
|
- Never acquire any device semaphore while holding any PM mutex.
|
|
|
-
|
|
|
- Never acquire udev->pm_mutex while holding the PM mutex for
|
|
|
- a device that isn't a descendant of udev.
|
|
|
-
|
|
|
-In other words, PM mutexes should only be acquired going up the device
|
|
|
-tree, and they should be acquired only after locking all the device
|
|
|
-semaphores you need to hold. These rules don't matter to drivers very
|
|
|
-much; they usually affect just the USB core.
|
|
|
-
|
|
|
-Still, drivers do need to be careful. For example, many drivers use a
|
|
|
-private mutex to synchronize their normal I/O activities with their
|
|
|
-disconnect method. Now if the driver supports autosuspend then it
|
|
|
-must call usb_autopm_put_interface() from somewhere -- maybe from its
|
|
|
-close method. It should make the call while holding the private mutex,
|
|
|
-since a driver shouldn't call any of the usb_autopm_* functions for an
|
|
|
-interface from which it has been unbound.
|
|
|
-
|
|
|
-But the usb_autpm_* routines always acquire the device's PM mutex, and
|
|
|
-consequently the locking order has to be: private mutex first, PM
|
|
|
-mutex second. Since the suspend method is always called with the PM
|
|
|
-mutex held, it mustn't try to acquire the private mutex. It has to
|
|
|
-synchronize with the driver's I/O activities in some other way.
|
|
|
+critical section, the best way is to lock the device and call
|
|
|
+usb_autopm_get_interface() (and do the reverse at the end of the
|
|
|
+critical section). Holding the device semaphore will block all
|
|
|
+external PM calls, and the usb_autopm_get_interface() will prevent any
|
|
|
+internal PM calls, even if it fails. (Exercise: Why?)
|
|
|
|
|
|
|
|
|
Interaction between dynamic PM and system PM
|
|
@@ -517,22 +465,11 @@ synchronize with the driver's I/O activities in some other way.
|
|
|
Dynamic power management and system power management can interact in
|
|
|
a couple of ways.
|
|
|
|
|
|
-Firstly, a device may already be manually suspended or autosuspended
|
|
|
-when a system suspend occurs. Since system suspends are supposed to
|
|
|
-be as transparent as possible, the device should remain suspended
|
|
|
-following the system resume. The 2.6.23 kernel obeys this principle
|
|
|
-for manually suspended devices but not for autosuspended devices; they
|
|
|
-do get resumed when the system wakes up. (Presumably they will be
|
|
|
-autosuspended again after their idle-delay time expires.) In later
|
|
|
-kernels this behavior will be fixed.
|
|
|
-
|
|
|
-(There is an exception. If a device would undergo a reset-resume
|
|
|
-instead of a normal resume, and the device is enabled for remote
|
|
|
-wakeup, then the reset-resume takes place even if the device was
|
|
|
-already suspended when the system suspend began. The justification is
|
|
|
-that a reset-resume is a kind of remote-wakeup event. Or to put it
|
|
|
-another way, a device which needs a reset won't be able to generate
|
|
|
-normal remote-wakeup signals, so it ought to be resumed immediately.)
|
|
|
+Firstly, a device may already be autosuspended when a system suspend
|
|
|
+occurs. Since system suspends are supposed to be as transparent as
|
|
|
+possible, the device should remain suspended following the system
|
|
|
+resume. But this theory may not work out well in practice; over time
|
|
|
+the kernel's behavior in this regard has changed.
|
|
|
|
|
|
Secondly, a dynamic power-management event may occur as a system
|
|
|
suspend is underway. The window for this is short, since system
|