⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bmpm.c

📁 内核linux2.4.20,可跟rtlinux3.2打补丁 组成实时linux系统,编译内核
💻 C
字号:
/***************************************************************************** * * Module Name: bmpm.c *   $Revision: 14 $ * *****************************************************************************//* *  Copyright (C) 2000, 2001 Andrew Grover * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 2 of the License, or *  (at your option) any later version. * *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. * *  You should have received a copy of the GNU General Public License *  along with this program; if not, write to the Free Software *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */#include <acpi.h>#include "bm.h"#include "bmpower.h"#define _COMPONENT		ACPI_BUS	MODULE_NAME		("bmpm")/**************************************************************************** *                             Internal Functions ****************************************************************************//**************************************************************************** * * FUNCTION:    bm_get_inferred_power_state * * PARAMETERS: * * RETURN: * * DESCRIPTION: * ****************************************************************************/acpi_statusbm_get_inferred_power_state (	BM_DEVICE               *device){	acpi_status             status = AE_OK;	BM_HANDLE_LIST          pr_list;	BM_POWER_STATE          list_state = ACPI_STATE_UNKNOWN;	char                    object_name[5] = {'_','P','R','0','\0'};	u32                     i = 0;	FUNCTION_TRACE("bm_get_inferred_power_state");	if (!device) {		return_ACPI_STATUS(AE_BAD_PARAMETER);	}	MEMSET(&pr_list, 0, sizeof(BM_HANDLE_LIST));	device->power.state = ACPI_STATE_D3;	/*	 * Calculate Power State:	 * ----------------------	 * Try to infer the devices's power state by checking the state of	 * the devices's power resources.  We start by evaluating _PR0	 * (resource requirements at D0) and work through _PR1 and _PR2.	 * We know the current devices power state when all resources (for	 * a give Dx state) are ON.  If no power resources are on then the	 * device is assumed to be off (D3).	 */	for (i=ACPI_STATE_D0; i<ACPI_STATE_D3; i++) {		object_name[3] = '0' + i;		status = bm_evaluate_reference_list(device->acpi_handle,			object_name, &pr_list);		if (ACPI_SUCCESS(status)) {			status = bm_pr_list_get_state(&pr_list, &list_state);			if (ACPI_SUCCESS(status)) {				if (list_state == ACPI_STATE_D0) {					device->power.state = i;					break;				}			}		}	}	return_ACPI_STATUS(AE_OK);}/**************************************************************************** *                             External Functions ****************************************************************************//**************************************************************************** * * FUNCTION:    bm_get_power_state * * PARAMETERS: * * RETURN: * * DESCRIPTION: * ****************************************************************************/acpi_statusbm_get_power_state (	BM_NODE			*node){	acpi_status             status = AE_OK;	BM_DEVICE               *device = NULL;	FUNCTION_TRACE("bm_get_power_state");	if (!node || !node->parent) {		return_ACPI_STATUS(AE_BAD_PARAMETER);	}	device = &(node->device);	device->power.state = ACPI_STATE_UNKNOWN;	/*	 * Power Control?	 * --------------	 * If this device isn't directly power manageable (e.g. doesn't	 * include _PR0/_PS0) then there's nothing to do (state is static).	 */	if (!BM_IS_POWER_CONTROL(device)) {		return_ACPI_STATUS(AE_OK);	}	/*	 * Parent Present?	 * ---------------	 * Make sure the parent is present before mucking with the child.	 */	if (!BM_NODE_PRESENT(node->parent)) {		return_ACPI_STATUS(AE_NOT_EXIST);	}		/*	 * Get Power State:	 * ----------------	 * Either directly (via _PSC) or inferred (via power resource	 * dependencies).	 */	if (BM_IS_POWER_STATE(device)) {		status = bm_evaluate_simple_integer(device->acpi_handle,			"_PSC", &(device->power.state));	}	else {		status = bm_get_inferred_power_state(device);	}	if (ACPI_SUCCESS(status)) {		ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Device [%02x] is at power state [D%d].\n", device->handle, device->power.state));	}	else {		ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Error getting power state for device [%02x]\n", device->handle));	}	return_ACPI_STATUS(status);}/**************************************************************************** * * FUNCTION:    bm_set_power_state * * PARAMETERS: * * RETURN: * * DESCRIPTION: * ****************************************************************************/acpi_statusbm_set_power_state (	BM_NODE			*node,	BM_POWER_STATE          state){	acpi_status             status = AE_OK;	BM_DEVICE		*device = NULL;	BM_DEVICE		*parent_device = NULL;	BM_HANDLE_LIST          current_list;	BM_HANDLE_LIST          target_list;	char                    object_name[5] = {'_','P','R','0','\0'};	FUNCTION_TRACE("bm_set_power_state");	if (!node || !node->parent || (state > ACPI_STATE_D3)) {		return_ACPI_STATUS(AE_BAD_PARAMETER);	}	MEMSET(&current_list, 0, sizeof(BM_HANDLE_LIST));	MEMSET(&target_list, 0, sizeof(BM_HANDLE_LIST));	device = &(node->device);	parent_device = &(node->parent->device);	/*	 * Power Control?	 * --------------	 * If this device isn't directly power manageable (e.g. doesn't	 * include _PR0/_PS0) then return an error (can't set state).	 */	if (!BM_IS_POWER_CONTROL(device)) {		return_ACPI_STATUS(AE_ERROR);	}	/*	 * Parent Present?	 * ---------------	 * Make sure the parent is present before mucking with the child.	 */	if (!BM_NODE_PRESENT(node->parent)) {		return_ACPI_STATUS(AE_NOT_EXIST);	}		/*	 * Check Parent's Power State:	 * ---------------------------	 * Can't be in a higher power state (lower Dx value) than parent.	 */	if (state < parent_device->power.state) {		ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Cannot set device [%02x] to a higher-powered state than parent_device.\n", device->handle));		return_ACPI_STATUS(AE_ERROR);	}	/*	 * Get Resources:	 * --------------	 * Get the power resources associated with the device's current	 * and target power states.	 */	if (device->power.state != ACPI_STATE_UNKNOWN) {		object_name[3] = '0' + device->power.state;		bm_evaluate_reference_list(device->acpi_handle,			object_name, &current_list);	}	object_name[3] = '0' + state;	bm_evaluate_reference_list(device->acpi_handle, object_name,		&target_list);	/*	 * Transition Resources:	 * ---------------------	 * Transition all power resources referenced by this device to	 * the correct power state (taking into consideration sequencing	 * and dependencies to other devices).	 */	if (current_list.count || target_list.count) {		status = bm_pr_list_transition(&current_list, &target_list);	}	if (ACPI_FAILURE(status)) {		return_ACPI_STATUS(status);	}	/*	 * Execute _PSx:	 * -------------	 * Execute the _PSx method corresponding to the target Dx state,	 * if it exists.	 */	object_name[2] = 'S';	object_name[3] = '0' + state;	bm_evaluate_object(device->acpi_handle, object_name, NULL, NULL);	if (ACPI_SUCCESS(status)) {		ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Device [%02x] is now at [D%d].\n", device->handle, state));		device->power.state = state;	}	return_ACPI_STATUS(status);}/**************************************************************************** * * FUNCTION:    bm_get_pm_capabilities * * PARAMETERS: * * RETURN: * * DESCRIPTION: * ****************************************************************************/acpi_statusbm_get_pm_capabilities (	BM_NODE			*node){	acpi_status             status = AE_OK;	BM_DEVICE		*device = NULL;	BM_DEVICE		*parent_device = NULL;	acpi_handle             acpi_handle = NULL;	BM_POWER_STATE          dx_supported = ACPI_STATE_UNKNOWN;	char                    object_name[5] = {'_','S','0','D','\0'};	u32                     i = 0;	FUNCTION_TRACE("bm_get_pm_capabilities");	if (!node || !node->parent) {		return_ACPI_STATUS(AE_BAD_PARAMETER);	}	device = &(node->device);	parent_device = &(node->parent->device);	/*	 * Power Management Flags:	 * -----------------------	 */	if (ACPI_SUCCESS(acpi_get_handle(device->acpi_handle, "_PSC",		&acpi_handle))) {		device->power.flags |= BM_FLAGS_POWER_STATE;	}	if (ACPI_SUCCESS(acpi_get_handle(device->acpi_handle, "_IRC",		&acpi_handle))) {		device->power.flags |= BM_FLAGS_INRUSH_CURRENT;	}	if (ACPI_SUCCESS(acpi_get_handle(device->acpi_handle, "_PRW",		&acpi_handle))) {		device->power.flags |= BM_FLAGS_WAKE_CAPABLE;	}	/*	 * Device Power State:	 * -------------------	 * Note that we can't get the device's power state until we've	 * initialized all power resources, so for now we just set to	 * unknown.	 */	device->power.state = ACPI_STATE_UNKNOWN;	/*	 * Dx Supported in S0:	 * -------------------	 * Figure out which Dx states are supported by this device for the	 * S0 (working) state.  Note that D0 and D3 are required (assumed).	 */	device->power.dx_supported[ACPI_STATE_S0] = BM_FLAGS_D0_SUPPORT |		BM_FLAGS_D3_SUPPORT;	if ((ACPI_SUCCESS(acpi_get_handle(device->acpi_handle, "_PR1",		&acpi_handle))) ||		(ACPI_SUCCESS(acpi_get_handle(device->acpi_handle, "_PS1",		&acpi_handle)))) {		device->power.dx_supported[ACPI_STATE_S0] |=			BM_FLAGS_D1_SUPPORT;	}	if ((ACPI_SUCCESS(acpi_get_handle(device->acpi_handle, "_PR2",		&acpi_handle))) ||		(ACPI_SUCCESS(acpi_get_handle(device->acpi_handle, "_PS2",		&acpi_handle)))) {		device->power.dx_supported[ACPI_STATE_S0] |=			BM_FLAGS_D2_SUPPORT;	}	/*	 * Dx Supported in S1-S5:	 * ----------------------	 * Figure out which Dx states are supported by this device for	 * all other Sx states.	 */	for (i = ACPI_STATE_S1; i <= ACPI_STATE_S5; i++) {		/*		 * D3 support is assumed (off is always possible!).		 */		device->power.dx_supported[i] = BM_FLAGS_D3_SUPPORT;		/*		 * Evalute _Sx_d:		 * -------------		 * Which returns the highest (power) Dx state supported in		 * this system (Sx) state.  We convert this value to a bit		 * mask of supported states (conceptually simpler).		 */		status = bm_evaluate_simple_integer(device->acpi_handle,			object_name, &dx_supported);		if (ACPI_SUCCESS(status)) {			switch (dx_supported) {			case 0:				device->power.dx_supported[i] |=					BM_FLAGS_D0_SUPPORT;				/* fall through */			case 1:				device->power.dx_supported[i] |=					BM_FLAGS_D1_SUPPORT;				/* fall through */			case 2:				device->power.dx_supported[i] |=					BM_FLAGS_D2_SUPPORT;				/* fall through */			case 3:				device->power.dx_supported[i] |=					BM_FLAGS_D3_SUPPORT;				break;			}			/*			 * Validate:			 * ---------			 * Mask of any states that _Sx_d falsely advertises			 * (e.g.claims D1 support but neither _PR2 or _PS2			 * exist).  In other words, S1-S5 can't offer a Dx			 * state that isn't supported by S0.			 */			device->power.dx_supported[i] &=				device->power.dx_supported[ACPI_STATE_S0];		}		object_name[2]++;	}	return_ACPI_STATUS(AE_OK);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -