'\" te .\" Copyright (c) 2004, Sun Microsystems, Inc. All Rights Reserved .\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License. .\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License. .\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner] .TH PM_POWER_HAS_CHANGED 9F "Jul 22, 2004" .SH NAME pm_power_has_changed \- Notify Power Management framework of autonomous power level change .SH SYNOPSIS .LP .nf #include #include \fBint\fR \fBpm_power_has_changed\fR(\fBdev_info_t *\fR\fIdip,\fR int \fIcomponent\fR, int \fIlevel\fR); .fi .SH INTERFACE LEVEL .sp .LP Solaris DDI specific (Solaris DDI) .SH PARAMETERS .sp .ne 2 .na \fB\fIdip\fR\fR .ad .RS 7n Pointer to the device \fBdev_info\fR structure .RE .sp .ne 2 .na \fB\fIcomponent\fR\fR .ad .RS 13n Number of the component that has changed power level .RE .sp .ne 2 .na \fB\fIlevel\fR\fR .ad .RS 9n Power level to which the indicated component has changed .RE .SH DESCRIPTION .sp .LP The \fBpm_power_has_changed\fR(9F) function notifies the Power Management framework that the power level of component of \fIdip \fR has changed to \fIlevel\fR. .sp .LP Normally power level changes are initiated by the Power Management framework due to device idleness, or through a request to the framework from the driver via \fBpm_raise_power\fR(9F) or \fBpm_lower_power\fR(9F), but some devices may change power levels on their own. For the framework to track the power level of the device under these circumstances, the framework must be notified of autonomous power level changes by a call to \fBpm_power_has_changed()\fR. .sp .LP Because of the asynchronous nature of these events, the Power Management framework might have called \fBpower\fR(9E) between the device's autonomous power level change and the driver calling \fBpm_power_has_changed()\fR, or the framework may be in the process of changing the power level when \fBpm_power_has_changed()\fR is called. To handle these situations correctly, the driver should verify that the device is indeed at the level or set the device to the level if it doesn't support inquirying of power levels, before calling \fBpm_power_has_changed()\fR. In addition, the driver should prevent a \fBpower\fR(9E) entry point from running in parallel with \fBpm_power_has_changed()\fR. .LP Note - .sp .RS 2 If this function is called as a result of entry into the driver's \fBattach\fR(9E), \fBdetach\fR(9E) or \fBpower\fR(9E) entry point, this function must be called from the same thread which entered \fBattach\fR(9E), \fBdetach\fR(9E) or \fBpower\fR(9E). .RE .SH RETURN VALUES .sp .LP The \fBpm_power_has_changed()\fR function returns: .sp .ne 2 .na \fB\fBDDI_SUCCESS\fR\fR .ad .RS 15n The power level of component was successfully updated to \fIlevel\fR. .RE .sp .ne 2 .na \fB\fBDDI_FAILURE\fR\fR .ad .RS 15n Invalid component \fIcomponent\fR or power level \fIlevel\fR. .RE .SH CONTEXT .sp .LP This function can be called from user or kernel context. This function can also be called from interrupt context, providing that it is not the first Power Management function called by the driver. .SH EXAMPLES .sp .LP A hypothetical driver might include this code to handle \fBpm_power_has_changed\fR(9F): .sp .in +2 .nf static int xxusb_intr(struct buf *bp) { ... /* * At this point the device has informed us that it has * changed power level on its own. Inform this to framework. * We need to take care of the case when framework has * already called power() entry point and changed power level * before we were able to inform framework of this change. * Handle this by comparing the informed power level with * the actual power level and only doing the call if they * are same. In addition, make sure that power() doesn't get * run in parallel with this code by holding the mutex. */ ASSERT(mutex_owned(&xsp->lock)); if (level_informed == *(xsp->level_reg_addr)) { if (pm_power_has_changed(xsp->dip, XXUSB_COMPONENT, level_informed) != DDI_SUCCESS) { mutex_exit( &xsp->lock); return(DDI_INTR_UNCLAIMED); } } .... } xxdisk_power(dev_info *dip, int comp, int level) { mutex_enter( xsp->lock); ... ... } .fi .in -2 .SH ATTRIBUTES .sp .LP See \fBattributes\fR(5) for a description of the following attributes: .sp .sp .TS box; c | c l | l . ATTRIBUTE TYPE ATTRIBUTE VALUE _ Interface Stability Committed .TE .SH SEE ALSO .sp .LP \fBpower.conf\fR(4), \fBpm\fR(7D), \fBattach\fR(9E), \fBdetach\fR(9E), \fBpower\fR(9E), \fBpm_busy_component\fR(9F), \fBpm_idle_component\fR(9F), \fBpm_raise_power\fR(9F), \fBpm_lower_power\fR(9F), \fBpm\fR(9P), \fBpm-components\fR(9P) .sp .LP \fIWriting Device Drivers\fR