Handling Device Idle

A common reason for a driver to lower the power state of its device is to reduce its power consumption when the device hasn't been accessed for a certain period of time. This involves creating a timer for the idle period of the device. If the timer expires and the device hasn't been accessed during that period, the driver places the device into a lower power state. After the device has been placed into a lower power state, the next time that the driver needs to access the device, it will need to place the hardware back in a usable state. Because these operations are common for all drivers that perform an idle power saving mode, this functionality is built into the I/O Kit and provided to driver developers through the IOService class.

There are two basic methods that a driver needs to call to let the I/O Kit track when its device has been idle and lower its power state.

  • setIdleTimerPeriod(period): Installs a timer that expires after the specified number of seconds has elapsed.
  • activityTickle(type, powerState): Is called by the driver before every access of the device, which informs the I/O Kit of the time at which the hardware was last accessed.

The method setIdleTimerPeriod() is typically called once, following the initialization of power management in the driver's start() method. Once called, the I/O Kit creates a timer that runs at the specified timeout period (in seconds). If the device hasn't been accessed during this period, the I/O Kit will lower the power state of the driver to the state below the driver's current power level. If the device remains inactive for the next idle period, the driver's power state is lowered again. In both cases, the driver receives a request to lower its power state through the same method, setPowerState(), that is used to deliver all power request changes, as described in the section “Responding to Power State Changes” earlier in this chapter. This continues until the device has been placed into the off state (power state 0).

When the device's power state is lowered as a result of inactivity, the I/O Kit sets the power state using the method changePowerStateToPriv(). Just as if the driver had called changePowerStateToPriv() itself, the new power state for the device cannot drop below the value set by the public method changePowerStateTo() or the power state required by the device's children. This means that the public power level that is set through changePowerStateTo() determines the minimum power state that the device can be placed in when idle. Typically, a driver that uses an idle timer will make a call to changePowerStateTo(0) in its start() method, thereby allowing the idle timer to take the device all the way down to the off state.

The idle timer requires the driver to inform the I/O Kit of every access to the hardware device, otherwise the idle timer will fire and lower the power state of the device while it is in use. To do this, the driver makes a call to the activityTickle() method when the device is used, typically at the start of each operation. The signature of the activityTickle() method is provided as follows:

bool    activityTickle(unsigned long type, unsigned long stateNumber);

The activityTickle() method takes two parameters, a type and a power state ordinal, that the caller uses to specify the minimum power level that the device must be in to handle the upcoming operation. The I/O Kit provides two pre-defined values for the type parameter in the header file <IOKit/pwr_mgt/IOPM.h>:

  • kIOPMSubclassPolicy
  • kIOPMSuperclassPolicy1

The type parameter defines which implementation should handle the activityTickle() request, either the driver itself (in which case kIOPMSubclassPolicy is passed) or the IOService superclass (in which case kIOPMSuperclassPolicy1 is passed). If the driver wishes to provide a custom implementation of activityTickle(), as well as passing kIOPMSubclassPolicy as the type parameter for each call to activityTickle(), it also needs to override the implementation of the activityTickle() method.

Most drivers, however, will be able to use the default implementation of activityTickle() provided by the IOService superclass. It's important that a driver that wishes to use the default implementation passes a value of kIOPMSuperclassPolicy1 for the type parameter of each call to activityTickle(), since the IOService implementation will ignore a request that has any other value passed as the type parameter.

The default implementation of activityTickle() will raise the power level of the device to the power state specified by the stateNumber parameter. Internally, the IOService class raises the device's power state by calling the changePowerStateToPriv() method, which the driver will receive through a call to its setPowerState() method. The Boolean value returned from the method indicates whether the device was already in the requested power state; a return value of true indicates that no power state transition was necessary, whereas a return value of false indicates that the power state of the device needed to be raised.

Since the activityTickle() method is asynchronous, it is important that the caller wait until the driver has completed the transition to the power state, and should not assume that the device is in a usable state when the activityTickle() method returns. The means by which a driver can observe power changes in a driver, including power changes in other driver objects, is explained in the next section.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.116.69.240