PM(4D) PM(4D)
NAME
pm - Power Management driver
SYNOPSIS
/dev/pmDESCRIPTION
The Power Management (
pm) driver provides an interface for applications
to configure devices within the system for Power Management. The
interface is provided through
ioctl(2) commands. The
pm driver may be
accessed using
/dev/pm.
Power Management Framework
The Power Management framework model allows the system to be viewed as a
collection of devices. Each device is a collection of components that
comprise the smallest power manageable units. The device driver controls
the definition of a device's power manageable components.
A component can either be
busy or
idle at the current power level.
Normally, the Power Management framework takes an
idle component to the
next lower power level. The Power Management framework uses two factors
to determine this transition: the component must have been idle for at
least the threshold time, and the device to which the component belongs
must satisfy any dependency requirements. A dependency occurs when a
device requires another device to be power managed before it can be power
managed. Dependencies occur on a per device basis: when a dependency
exists, no components of a device may be managed unless all the devices
it depends upon are first power managed.
Using the commands below, an application may take control of the Power
Management of a device from the Power Management framework driver and
manage the transition of device power levels directly.
For this set of ioctl commands,
arg (see
ioctl(2)) points to a structure
of type
pm_req defined in <
sys/pm.h>:
typedef struct pm_req {
char *physpath; /* physical path of device */
/* to configure. See
libdevinfo(3LIB) */
int component; /* device component */
int value; /* power level, threshold value, or count */
void *data; /* command-dependent variable-sized data */
size_t datasize; /* size of data buffer */
} pm_req_t;
The fields should contain the following data:
physpath Pointer to the physical path of a device. See
libdevinfo(3LIB). For example, for the device
/devices/pseudo/pm@0:pm the
physpath value would be
/pseudo/pm@0.
component Non-negative integer specifying which component is being
configured. The numbering starts at zero.
value Non-negative integer specifying the threshold value in
seconds or the desired power level, or the number of levels
being specified.
data Pointer to a buffer which contains or receives variable-
sized data, such as the name of a device upon which this
device has a dependency.
size Size of the data buffer.
Not all fields are used in each command.
PM_DIRECT_PM The device named by
physpath is disabled from being power managed by
the framework. The caller will power manage the device directly using
the
PM_DIRECT_NOTIFY,
PM_GET_TIME_IDLE and
PM_GET_CURRENT_POWER,
PM_GET_FULL_POWER and
PM_SET_CURRENT_POWER commands. If the device
needs to have its power level changed either because its driver calls
pm_raise_power(9F),
pm_lower_power(9F), or
pm_power_has_changed(9F) or because the device is the parent of another device that is
changing power level or a device that this device depends on is
changing power level, then the power level change of the device will
be blocked and the caller will be notified as described below for the
PM_DIRECT_NOTIFY command.
Error codes:
EBUSY Device already disabled for Power Management by framework.
EPERM Caller is neither superuser nor effective group ID of 0.
PM_RELEASE_DIRECT_PM The device named by
physpath (which must have been the target of a
PM_DIRECT_PM command) is re-enabled for Power Management by the
framework.
Error codes:
EINVAL Device component out of range.
PM_DIRECT_NOTIFY PM_DIRECT_NOTIFY_WAIT These commands allow the process that is directly power managing a
device to be notified of events that could change the power level of
the device. When such an event occurs, this command returns
information about the event.
arg (see
ioctl(2)) points to a structure of type
pm_state_change defined in
<sys/pm.h>:
typedef struct pm_state_change {
char *physpath; /* device which has changed state */
int component; /* which component changed state */
#if defined(_BIG_ENDIAN)
ushort_t flags; /* PSC_EVENT_LOST, PSC_ALL_LOWEST */
ushort_t event; /* type of event */
#else
ushort_t event; /* type of event *
ushort_t flags; /* PSC_EVENT_LOST, PSC_ALL_LOWEST */
#endif
time_t timestamp; /* time of state change */+
int old_level; /* power level changing from */
int new_level; /* power level changing to */
size_t size; /* size of buffer physpath points to */
} pm_state_change_t;
When an event occurs, the struct pointed to by
arg is filled in. If
the event type is
PSC_PENDING_CHANGE, then the information in the
rest of the struct describes an action that the framework would have
taken if the device were not directly power managed by the caller.
The caller is responsible for completing the indicated level changes
using
PM_SET_CURRENT_POWER below.
An event type of
PSC_HAS_CHANGED indicates that the driver for the
directly power managed device has called
pm_power_has_changed(9F) due
to the device changing power on its own. It is provided to allow the
caller to track the power state of the device.
The system keeps events in a circular buffer. If the buffer overflow,
the oldest events are lost and when the event that next follows a
lost event is retrieved it will have PSC_EVENT_LOST set in flags.
PM_DIRECT_NOTIFY returns
EWOULDBLOCK if no event is pending, and
PM_DIRECT_NOTIFY_WAIT blocks until an event is available.
pm also supports the
poll(2) interface. When an event is pending a
poll(2) call that includes a file descriptor for
/dev/pm and that has
POLLIN or
POLLRDNORM set in its event mask will return.
PM_SET_CURRENT_POWER Component
component of the device named by
physpath (which must
contain the physical path of a device against which the process has
issued a
PM_DIRECT_PM command) is set to power level
value. If all
components of the device named by
physpath were at level 0,
value is
non-zero and some device has a dependency on this device, then all
components of that device will be brought to full power before this
command returns. Similarly, if the parent of the target device is
powered off, then it will be brought up as needed before this command
returns. When PM_SET_CURRENT_POWER is issued against a device, the
resulting power change is included in the event list for
PM_DIRECT_NOTIFY.
Error codes:
EINVAL Device component out of range, or power level < 0.
EIO Failed to power device or its ancestors or the devices on
which this device has dependency or their ancestors. Note
that this may not indicate a failure, the device driver may
have rejected the command as inappropriate because the
component has become busy.
EPERM Caller has not previously issued a successful
PM_DIRECT_PM command against this device.
PM_GET_FULL_POWER The highest supported power level of component
component of the
device named by
physpath is returned.
PM_GET_CURRENT_POWER The current power level of component
component of the device named by
physpath is returned.
Error codes:
EAGAIN Device component power level is not currently known.
PM_GET_TIME_IDLE PM_GET_TIME_IDLE returns the number of seconds that component
component of the device named by
physpath has been idle. If the
device is not idle, then
0 is returned.
Note that because the state of the device may change between the time
the process issues the
PM_GET_TIME_IDLE command and the time the
process issues a
PM_SET_CURRENT_POWER command to reduce the power
level of an idle component, the process must be prepared to deal with
a
PM_SET_CURRENT_POWER command returning failure because the driver
has rejected the command as inappropriate because the device
component has become busy. This can be differentiated from other
types of failures by issuing the
PM_GET_TIME_IDLE command again to
see if the component has become busy.
ERRORS
Upon error, the commands will return
-1, and set
errno. In addition to
the error codes listed above by command, the following error codes are
common to all commands:
EFAULT Bad address passed in as argument.
ENODEV Device is not power manageable, or device is not configured.
ENXIO Too many opens attempted.
ATTRIBUTES
See
attributes(7) for descriptions of the following attributes:
+--------------------+-----------------+
| ATTRIBUTE TYPE | ATTRIBUTE VALUE |
+--------------------+-----------------+
|Interface stability | Unstable |
+--------------------+-----------------+
SEE ALSO
Intro(2),
ioctl(2),
libdevinfo(3LIB),
power.conf(5),
attributes(7),
pmconfig(8),
attach(9E),
detach(9E),
power(9E),
pm_busy_component(9F),
pm_idle_component(9F),
pm_lower_power(9F),
pm_power_has_changed(9F),
pm_raise_power(9F) Writing Device Drivers September 20, 1999
PM(4D)