diff options
Diffstat (limited to 'drivers/acpi/hardware')
-rw-r--r-- | drivers/acpi/hardware/hwcpu32.c | 711 | ||||
-rw-r--r-- | drivers/acpi/hardware/hwxface.c | 595 |
2 files changed, 0 insertions, 1306 deletions
diff --git a/drivers/acpi/hardware/hwcpu32.c b/drivers/acpi/hardware/hwcpu32.c deleted file mode 100644 index fde6d1c07..000000000 --- a/drivers/acpi/hardware/hwcpu32.c +++ /dev/null @@ -1,711 +0,0 @@ -/****************************************************************************** - * - * Name: hwcpu32.c - CPU support for IA32 (Throttling, Cx_states) - * $Revision: 39 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000 R. Byron Moore - * - * 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 "acnamesp.h" -#include "achware.h" - -#define _COMPONENT HARDWARE - MODULE_NAME ("Hwcpu32") - - -#define BIT_4 0x10 /* TBD: [investigate] is this correct? */ - - -/**************************************************************************** - * - * FUNCTION: Acpi_hw_enter_c1 - * - * PARAMETERS: Pblk_address - Address of the processor control block - * Pm_timer_ticks - Number of PM timer ticks elapsed while asleep - * - * RETURN: Function status. - * - * DESCRIPTION: Set C1 state on IA32 processor (halt) - * - ****************************************************************************/ - -ACPI_STATUS -acpi_hw_enter_c1( - ACPI_IO_ADDRESS pblk_address, - u32 *pm_timer_ticks) -{ - u32 timer = 0; - - - if (!pm_timer_ticks) { - /* - * Enter C1: - * --------- - */ - enable(); - halt(); - *pm_timer_ticks = ACPI_UINT32_MAX; - } - else { - timer = acpi_hw_pmt_ticks (); - - /* - * Enter C1: - * --------- - */ - enable (); - halt (); - - /* - * Compute Time in C1: - * ------------------- - */ - timer = acpi_hw_pmt_ticks () - timer; - - *pm_timer_ticks = timer; - } - - return (AE_OK); -} - - -/**************************************************************************** - * - * FUNCTION: Acpi_hw_enter_c2 - * - * PARAMETERS: Pblk_address - Address of the processor control block - * Pm_timer_ticks - Number of PM timer ticks elapsed while asleep - * - * RETURN: <none> - * - * DESCRIPTION: Set C2 state on IA32 processor - * - ****************************************************************************/ - -ACPI_STATUS -acpi_hw_enter_c2( - ACPI_IO_ADDRESS pblk_address, - u32 *pm_timer_ticks) -{ - u32 timer = 0; - - - if (!pblk_address || !pm_timer_ticks) { - return (AE_BAD_PARAMETER); - } - - /* - * Disable interrupts before all C2/C3 transitions. - */ - disable (); - - timer = acpi_hw_pmt_ticks (); - - /* - * Enter C2: - * --------- - * Read from the P_LVL2 (P_BLK+4) register to invoke a C2 transition. - */ - acpi_os_in8 ((ACPI_IO_ADDRESS) (pblk_address + 4)); - - /* - * Perform Dummy Op: - * ----------------- - * We have to do something useless after reading LVL2 because chipsets - * cannot guarantee that STPCLK# gets asserted in time to freeze execution. - */ - acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, PM2_CONTROL); - - /* - * Compute Time in C2: - * ------------------- - */ - timer = acpi_hw_pmt_ticks () - timer; - - *pm_timer_ticks = timer; - - /* - * Re-enable interrupts after coming out of C2/C3. - */ - enable (); - - return (AE_OK); -} - - -/**************************************************************************** - * - * FUNCTION: Acpi_hw_enter_c3 - * - * PARAMETERS: Pblk_address - Address of the processor control block - * Pm_timer_ticks - Number of PM timer ticks elapsed while asleep - * - * RETURN: Status of function - * - * DESCRIPTION: Set C3 state on IA32 processor (UP only, cache coherency via - * disabling bus mastering) - * - ****************************************************************************/ - -ACPI_STATUS -acpi_hw_enter_c3( - ACPI_IO_ADDRESS pblk_address, - u32 *pm_timer_ticks) -{ - u32 timer = 0; - u32 bus_master_status = 0; - - - if (!pblk_address || !pm_timer_ticks) { - return (AE_BAD_PARAMETER); - } - - /* - * Check the BM_STS bit, if it is set, do not enter C3 - * but clear the bit (with a write) and exit, telling - * the calling module that we spent zero time in C3. - * If bus mastering continues, this action should - * eventually cause a demotion to C2 - */ - if (1 == (bus_master_status = - acpi_hw_register_bit_access (ACPI_READ, ACPI_MTX_LOCK, BM_STS))) - { - /* - * Clear the BM_STS bit by setting it. - */ - acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, BM_STS, 1); - *pm_timer_ticks = 0; - return (AE_OK); - } - - /* - * Disable interrupts before all C2/C3 transitions. - */ - disable(); - - /* - * Disable Bus Mastering: - * ---------------------- - * Set the PM2_CNT.ARB_DIS bit (bit #0), preserving all other bits. - */ - acpi_hw_register_bit_access(ACPI_WRITE, ACPI_MTX_LOCK, ARB_DIS, 1); - - /* - * Get the timer base before entering C state - */ - timer = acpi_hw_pmt_ticks (); - - /* - * Enter C3: - * --------- - * Read from the P_LVL3 (P_BLK+5) register to invoke a C3 transition. - */ - acpi_os_in8 ((ACPI_IO_ADDRESS)(pblk_address + 5)); - - /* - * Perform Dummy Op: - * ----------------- - * We have to do something useless after reading LVL3 because chipsets - * cannot guarantee that STPCLK# gets asserted in time to freeze execution. - */ - acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, PM2_CONTROL); - /* - * Immediately compute the time in the C state - */ - timer = acpi_hw_pmt_ticks() - timer; - - /* - * Re-Enable Bus Mastering: - * ------------------------ - * Clear the PM2_CNT.ARB_DIS bit (bit #0), preserving all other bits. - */ - acpi_hw_register_bit_access(ACPI_WRITE, ACPI_MTX_LOCK, ARB_DIS, 0); - - /* TBD: [Unhandled]: Support 24-bit timers (this algorithm assumes 32-bit) */ - - *pm_timer_ticks = timer; - - /* - * Re-enable interrupts after coming out of C2/C3. - */ - enable(); - - return (AE_OK); -} - - -/**************************************************************************** - * - * FUNCTION: Acpi_hw_enter_cx - * - * PARAMETERS: Processor_handle - handle of the processor - * - * RETURN: Status of function - * - * DESCRIPTION: Invoke the currently active processor Cx handler to put this - * processor to sleep. - * - ****************************************************************************/ - -ACPI_STATUS -acpi_hw_enter_cx ( - ACPI_IO_ADDRESS pblk_address, - u32 *pm_timer_ticks) -{ - - if (!acpi_hw_cx_handlers[acpi_hw_active_cx_state]) { - return (AE_SUPPORT); - } - - return (acpi_hw_cx_handlers[acpi_hw_active_cx_state] (pblk_address, pm_timer_ticks)); -} - - -/**************************************************************************** - * - * FUNCTION: Acpi_hw_set_cx - * - * PARAMETERS: State - value (1-3) of the Cx state to 'make active' - * - * RETURN: Function status. - * - * DESCRIPTION: Sets the state to use during calls to Acpi_hw_enter_cx(). - * - ****************************************************************************/ - -ACPI_STATUS -acpi_hw_set_cx ( - u32 cx_state) -{ - /* - * Supported State? - * ---------------- - */ - if ((cx_state < 1) || (cx_state > 3)) { - return (AE_BAD_PARAMETER); - } - - if (!acpi_hw_cx_handlers[cx_state]) { - return (AE_SUPPORT); - } - - /* - * New Cx State? - * ------------- - * We only care when moving from one state to another... - */ - if (acpi_hw_active_cx_state == cx_state) { - return (AE_OK); - } - - /* - * Prepare to Use New State: - * ------------------------- - * If the new Cx_state is C3, the BM_RLD bit must be set to allow - * the generation of a bus master requets to cause the processor - * in the C3 state to transition to the C0 state. - */ - switch (cx_state) - { - case 3: - acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, BM_RLD, 1); - break; - } - - /* - * Clean up from Old State: - * ------------------------ - * If the old Cx_state was C3, the BM_RLD bit is reset. When the - * bit is reset, the generation of a bus master request does not - * effect any processor in the C3 state. - */ - switch (acpi_hw_active_cx_state) - { - case 3: - acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, BM_RLD, 0); - break; - } - - /* - * Enable: - * ------- - */ - acpi_hw_active_cx_state = cx_state; - - return (AE_OK); -} - - -/**************************************************************************** - * - * FUNCTION: Acpi_hw_get_cx_info - * - * PARAMETERS: Cx_states - Information (latencies) on all Cx states - * - * RETURN: Status of function - * - * DESCRIPTION: This function is called both to initialize Cx handling - * and retrieve the current Cx information (latency values). - * - ****************************************************************************/ - -ACPI_STATUS -acpi_hw_get_cx_info ( - u32 cx_states[]) -{ - u8 SMP_system = FALSE; - - - if (!cx_states) { - return(AE_BAD_PARAMETER); - } - - /* - * TBD: [Unhandled] need to init SMP_system using info from the MAPIC - * table. - */ - - /* - * Set Defaults: - * ------------- - * C0 and C1 support is implied (but what about that PROC_C1 register - * in the FADT?!?!). Set C2/C3 to max. latency (not supported until - * proven otherwise). - */ - cx_states[0] = 0; - cx_states[1] = 0; - cx_states[2] = MAX_CX_STATE_LATENCY; - cx_states[3] = MAX_CX_STATE_LATENCY; - - /* - * C2 Supported? - * ------------- - * We're only supporting C2 when the latency is <= 100 microseconds, - * and on SMP systems when P_LVL2_UP (which indicates C2 only on UP) - * is not set. - */ - if (acpi_gbl_FADT->plvl2_lat <= 100) { - if (!SMP_system) { - acpi_hw_cx_handlers[2] = acpi_hw_enter_c2; - cx_states[2] = acpi_gbl_FADT->plvl2_lat; - } - - else if (!acpi_gbl_FADT->plvl2_up) { - acpi_hw_cx_handlers[2] = acpi_hw_enter_c2; - cx_states[2] = acpi_gbl_FADT->plvl2_lat; - } - } - - /* - * C3 Supported? - * ------------- - * We're only supporting C3 on UP systems when the latency is - * <= 1000 microseconds and that include the ability to disable - * Bus Mastering while in C3 (ARB_DIS) but allows Bus Mastering - * requests to wake the system from C3 (BM_RLD). Note his method - * of maintaining cache coherency (disabling of bus mastering) - * cannot be used on SMP systems, and flushing caches (e.g. WBINVD) - * is simply too costly (at this time). - */ - if (acpi_gbl_FADT->plvl3_lat <= 1000) { - if (!SMP_system && (acpi_gbl_FADT->Xpm2_cnt_blk.address && - acpi_gbl_FADT->pm2_cnt_len)) - { - acpi_hw_cx_handlers[3] = acpi_hw_enter_c3; - cx_states[3] = acpi_gbl_FADT->plvl3_lat; - } - } - - return(AE_OK); -} - - -/**************************************************************************** - * - * FUNCTION: Acpi_hw_get_cx_handler - * - * PARAMETERS: State - the Cx state - * Handler - pointer to location for the returned handler - * - * RETURN: Status of function - * - * DESCRIPTION: This function is called to get an installed Cx state handler. - * - ****************************************************************************/ - -ACPI_STATUS -acpi_hw_get_cx_handler ( - u32 cx_state, - ACPI_C_STATE_HANDLER *handler) -{ - - if ((cx_state == 0) || (cx_state >= MAX_CX_STATES) || !handler) { - return(AE_BAD_PARAMETER); - } - - *handler = acpi_hw_cx_handlers[cx_state]; - - return(AE_OK); -} - - -/**************************************************************************** - * - * FUNCTION: Acpi_hw_set_cx_handler - * - * PARAMETERS: Cx_state - the Cx state - * Handler - new Cx state handler - * - * RETURN: Status of function - * - * DESCRIPTION: This function is called to install a new Cx state handler. - * - ****************************************************************************/ - -ACPI_STATUS -acpi_hw_set_cx_handler ( - u32 cx_state, - ACPI_C_STATE_HANDLER handler) -{ - - if ((cx_state == 0) || (cx_state >= MAX_CX_STATES) || !handler) { - return(AE_BAD_PARAMETER); - } - - acpi_hw_cx_handlers[cx_state] = handler; - - return(AE_OK); -} - - -/************************************************************************** - * - * FUNCTION: Acpi_hw_local_pow - * - * PARAMETERS: x,y operands - * - * RETURN: result - * - * DESCRIPTION: Compute x ^ y - * - *************************************************************************/ - -NATIVE_UINT -acpi_hw_local_pow ( - NATIVE_UINT x, - NATIVE_UINT y) -{ - NATIVE_UINT i; - NATIVE_UINT result = 1; - - - for (i = 0; i < y; i++) { - result = result * x; - } - - return (result); -} - - -/************************************************************************** - * - * FUNCTION: Acpi_hw_enable_throttling - * - * PARAMETERS: Pblk_address - Address of Pcnt (Processor Control) - * register - * - * RETURN: none - * - * DESCRIPTION: Enable throttling by setting the THT_EN bit. - * - *************************************************************************/ - -void -acpi_hw_enable_throttling ( - ACPI_IO_ADDRESS pblk_address) -{ - u32 pblk_value; - - - pblk_value = acpi_os_in32 (pblk_address); - pblk_value = pblk_value | BIT_4; - acpi_os_out32 (pblk_address, pblk_value); - - return; -} - - -/************************************************************************** - * - * FUNCTION: Acpi_hw_disable_throttling - * - * PARAMETERS: Pblk_address - Address of Pcnt (Processor Control) - * register - * - * RETURN: none - * - * DESCRIPTION:Disable throttling by clearing the THT_EN bit - * - *************************************************************************/ - -void -acpi_hw_disable_throttling ( - ACPI_IO_ADDRESS pblk_address) -{ - u32 pblk_value; - - - pblk_value = acpi_os_in32 (pblk_address); - pblk_value = pblk_value & (~(u32)BIT_4); - acpi_os_out32 (pblk_address, pblk_value); - - return; -} - - -/************************************************************************** - * - * FUNCTION: Acpi_hw_get_duty_cycle - * - * PARAMETERS: Duty_offset Pcnt register duty cycle field offset - * Pblk_address Pcnt register address in chipset - * Num_throttle_states # of CPU throttle states this system - * supports - * - * RETURN: none - * - * DESCRIPTION: Get the duty cycle from the chipset - * - *************************************************************************/ - -u32 -acpi_hw_get_duty_cycle ( - u8 duty_offset, - ACPI_IO_ADDRESS pblk_address, - u32 num_throttle_states) -{ - NATIVE_UINT index; - u32 duty32_value; - u32 pcnt_mask_off_duty_field; - - - /* - * Use Num_throttle_states - 1 as mask [ex. 8 - 1 = 7 (Fh)] - * and then shift it into the right position - */ - pcnt_mask_off_duty_field = num_throttle_states - 1; - - /* - * Read in the current value from the port - */ - duty32_value = acpi_os_in32 ((ACPI_IO_ADDRESS) pblk_address); - - /* - * Shift the the value to LSB - */ - for (index = 0; index < (NATIVE_UINT) duty_offset; index++) { - duty32_value = duty32_value >> 1; - } - - /* - * Get the duty field only - */ - duty32_value = duty32_value & pcnt_mask_off_duty_field; - - return ((u32) duty32_value); -} - - -/************************************************************************** - * - * FUNCTION: Acpi_hw_program_duty_cycle - * - * PARAMETERS: Duty_offset Pcnt register duty cycle field offset - * Duty_cycle duty cycle to program into chipset - * Pblk_address Pcnt register address in chipset - * Num_throttle_states # of CPU throttle states this system - * supports - * - * RETURN: none - * - * DESCRIPTION: Program chipset with specified duty cycle by bit-shifting the - * duty cycle bits to the appropriate offset, reading the duty - * cycle register, OR-ing in the duty cycle, and writing it to - * the Pcnt register. - * - *************************************************************************/ - -void -acpi_hw_program_duty_cycle ( - u8 duty_offset, - u32 duty_cycle, - ACPI_IO_ADDRESS pblk_address, - u32 num_throttle_states) -{ - NATIVE_UINT index; - u32 duty32_value; - u32 pcnt_mask_off_duty_field; - u32 port_value; - - - /* - * valid Duty_cycle passed - */ - duty32_value = duty_cycle; - - /* - * use Num_throttle_states - 1 as mask [ex. 8 - 1 = 7 (Fh)] - * and then shift it into the right position - */ - pcnt_mask_off_duty_field = num_throttle_states - 1; - - /* - * Shift the mask - */ - for (index = 0; index < (NATIVE_UINT) duty_offset; index++) { - pcnt_mask_off_duty_field = pcnt_mask_off_duty_field << 1; - duty32_value = duty32_value << 1; - } - - /* - * Read in the current value from the port - */ - port_value = acpi_os_in32 ((ACPI_IO_ADDRESS) pblk_address); - - /* - * Mask off the duty field so we don't OR in junk! - */ - port_value = port_value & (~pcnt_mask_off_duty_field); - - /* - * OR in the bits we want to write out to the port - */ - port_value = (port_value | duty32_value) & (~(u32)BIT_4); - - /* - * write it to the port - */ - acpi_os_out32 ((ACPI_IO_ADDRESS) pblk_address, port_value); - - return; -} - - diff --git a/drivers/acpi/hardware/hwxface.c b/drivers/acpi/hardware/hwxface.c deleted file mode 100644 index 156c946e7..000000000 --- a/drivers/acpi/hardware/hwxface.c +++ /dev/null @@ -1,595 +0,0 @@ - -/****************************************************************************** - * - * Name: hwxface.c - Hardware access external interfaces - * $Revision: 36 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000 R. Byron Moore - * - * 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 "acnamesp.h" -#include "achware.h" - -#define _COMPONENT HARDWARE - MODULE_NAME ("hwxface") - - -/****************************************************************************** - * - * Hardware globals - * - ******************************************************************************/ - - -ACPI_C_STATE_HANDLER acpi_hw_cx_handlers[MAX_CX_STATES] = - {NULL, acpi_hw_enter_c1, NULL, NULL}; - -u32 acpi_hw_active_cx_state = 1; - - -/**************************************************************************** - * - * FUNCTION: Acpi_get_processor_throttling_info - * - * PARAMETERS: Processor_handle - handle for the cpu to get info about - * User_buffer - caller supplied buffer - * - * RETURN: Status of function - * - * DESCRIPTION: Get throttling capabilities for the processor, this routine - * builds the data directly into the callers buffer - * - ****************************************************************************/ - -ACPI_STATUS -acpi_get_processor_throttling_info ( - ACPI_HANDLE processor_handle, - ACPI_BUFFER *user_buffer) -{ - NATIVE_UINT percent_step; - NATIVE_UINT next_percent; - NATIVE_UINT num_throttle_states; - NATIVE_UINT buffer_space_needed; - NATIVE_UINT i; - u8 duty_width; - ACPI_NAMESPACE_NODE *cpu_node; - ACPI_OPERAND_OBJECT *cpu_obj; - ACPI_CPU_THROTTLING_STATE *state_ptr; - - - /* - * Have to at least have a buffer to return info in - */ - if (!user_buffer) { - return(AE_BAD_PARAMETER); - } - - /* - * Convert and validate the device handle - */ - - cpu_node = acpi_ns_convert_handle_to_entry (processor_handle); - if (!cpu_node) { - return (AE_BAD_PARAMETER); - } - - /* - * Check for an existing internal object - */ - - cpu_obj = acpi_ns_get_attached_object ((ACPI_HANDLE) cpu_node); - if (!cpu_obj) { - return (AE_NOT_FOUND); - } - - /* - * (Duty Width on IA-64 is zero) - */ - duty_width = acpi_gbl_FADT->duty_width; - - /* - * P0 must always have a P_BLK all others may be null - * in either case, we can't throttle a processor that has no P_BLK - * - * Also if no Duty width, one state and it is 100% - * - */ - if (!cpu_obj->processor.length || !duty_width || - (ACPI_UINT16_MAX < cpu_obj->processor.address)) - { - /* - * Acpi_even though we can't throttle, we still have one state (100%) - */ - num_throttle_states = 1; - } - - else { - num_throttle_states = (int) acpi_hw_local_pow (2,duty_width); - } - - buffer_space_needed = num_throttle_states * sizeof (ACPI_CPU_THROTTLING_STATE); - - if ((user_buffer->length < buffer_space_needed) || !user_buffer->pointer) { - user_buffer->length = buffer_space_needed; - return (AE_BUFFER_OVERFLOW); - } - - user_buffer->length = buffer_space_needed; - state_ptr = (ACPI_CPU_THROTTLING_STATE *) user_buffer->pointer; - percent_step = 1000 / num_throttle_states; - - /* - * Build each entry in the buffer. Note that we're using the value - * 1000 and dividing each state by 10 to better avoid round-off - * accumulation. Also note that the throttling STATES are ordered - * sequentially from 100% (state 0) on down (e.g. 87.5% = state 1), - * which is exactly opposite from duty cycle values (12.5% = state 1). - */ - for (i = 0, next_percent = 1000; i < num_throttle_states; i++) { - state_ptr[i].state_number = i; - state_ptr[i].percent_of_clock = next_percent / 10; - next_percent -= percent_step; - } - - return(AE_OK); -} - - -/**************************************************************************** - * - * FUNCTION: Acpi_get_processor_throttling_state - * - * PARAMETERS: Processor_handle - handle for the cpu to throttle - * Throttle_state - throttling state to enter - * - * RETURN: Status of function - * - * DESCRIPTION: Get current hardware throttling state - * - ****************************************************************************/ - -ACPI_STATUS -acpi_get_processor_throttling_state ( - ACPI_HANDLE processor_handle, - u32 *throttle_state) -{ - ACPI_NAMESPACE_NODE *cpu_node; - ACPI_OPERAND_OBJECT *cpu_obj; - u32 num_throttle_states; - u32 duty_cycle; - u8 duty_offset; - u8 duty_width; - - - /* Convert and validate the device handle */ - - cpu_node = acpi_ns_convert_handle_to_entry (processor_handle); - if (!cpu_node || !throttle_state) { - return (AE_BAD_PARAMETER); - } - - /* Check for an existing internal object */ - - cpu_obj = acpi_ns_get_attached_object ((ACPI_HANDLE) cpu_node); - if (!cpu_obj) { - return (AE_NOT_FOUND); - } - - /* - * No Duty fields in IA64 tables - */ - duty_offset = acpi_gbl_FADT->duty_offset; - duty_width = acpi_gbl_FADT->duty_width; - - /* - * Must have a valid P_BLK P0 must have a P_BLK all others may be null - * in either case, we can't thottle a processor that has no P_BLK - * that means we are in the only supported state (0 - 100%) - * - * also, if Duty_width is zero there are no additional states - */ - if (!cpu_obj->processor.length || !duty_width || - (ACPI_UINT16_MAX < cpu_obj->processor.address)) - { - *throttle_state = 0; - return(AE_OK); - } - - num_throttle_states = (u32) acpi_hw_local_pow (2,duty_width); - - /* - * Get the current duty cycle value. - */ - duty_cycle = acpi_hw_get_duty_cycle (duty_offset, - cpu_obj->processor.address, - num_throttle_states); - - /* - * Convert duty cycle to throttling state (invert). - */ - if (duty_cycle == 0) { - *throttle_state = 0; - } - - else { - *throttle_state = num_throttle_states - duty_cycle; - } - - return(AE_OK); -} - - -/**************************************************************************** - * - * FUNCTION: Acpi_set_processor_throttling_state - * - * PARAMETERS: Processor_handle - handle for the cpu to throttle - * Throttle_state - throttling state to enter - * - * RETURN: Status of function - * - * DESCRIPTION: Set hardware into requested throttling state, the handle - * passed in must have a valid P_BLK - * - ****************************************************************************/ - -ACPI_STATUS -acpi_set_processor_throttling_state ( - ACPI_HANDLE processor_handle, - u32 throttle_state) -{ - ACPI_NAMESPACE_NODE *cpu_node; - ACPI_OPERAND_OBJECT *cpu_obj; - u32 num_throttle_states = 0; - u8 duty_offset; - u8 duty_width; - u32 duty_cycle = 0; - - - /* Convert and validate the device handle */ - - cpu_node = acpi_ns_convert_handle_to_entry (processor_handle); - if (!cpu_node) { - return (AE_BAD_PARAMETER); - } - - /* Check for an existing internal object */ - - cpu_obj = acpi_ns_get_attached_object ((ACPI_HANDLE) cpu_node); - if (!cpu_obj) { - return (AE_NOT_FOUND); - } - - /* - * No Duty fields in IA64 tables - */ - duty_offset = acpi_gbl_FADT->duty_offset; - duty_width = acpi_gbl_FADT->duty_width; - - /* - * Must have a valid P_BLK P0 must have a P_BLK all others may be null - * in either case, we can't thottle a processor that has no P_BLK - * that means we are in the only supported state (0 - 100%) - * - * also, if Duty_width is zero there are no additional states - */ - if (!cpu_obj->processor.length || !duty_width || - (ACPI_UINT16_MAX < cpu_obj->processor.address)) - { - /* - * If caller wants to set the state to the only state we handle - * we're done. - */ - if (throttle_state == 0) { - return (AE_OK); - } - - /* - * Can't set this state - */ - return (AE_SUPPORT); - } - - num_throttle_states = (u32) acpi_hw_local_pow (2,duty_width); - - /* - * Convert throttling state to duty cycle (invert). - */ - if (throttle_state > 0) { - duty_cycle = num_throttle_states - throttle_state; - } - - /* - * Turn off throttling (don't muck with the h/w while throttling). - */ - acpi_hw_disable_throttling (cpu_obj->processor.address); - - /* - * Program the throttling state. - */ - acpi_hw_program_duty_cycle (duty_offset, duty_cycle, - cpu_obj->processor.address, num_throttle_states); - - /* - * Only enable throttling for non-zero states (0 - 100%) - */ - if (throttle_state) { - acpi_hw_enable_throttling (cpu_obj->processor.address); - } - - return(AE_OK); -} - - -/**************************************************************************** - * - * FUNCTION: Acpi_get_processor_cx_info - * - * PARAMETERS: Processor_handle - handle for the cpu return info about - * User_buffer - caller supplied buffer - * - * RETURN: Status of function - * - * DESCRIPTION: Get Cx state latencies, this routine - * builds the data directly into the callers buffer - * - * - ****************************************************************************/ - -ACPI_STATUS -acpi_get_processor_cx_info ( - ACPI_HANDLE processor_handle, - ACPI_BUFFER *user_buffer) -{ - ACPI_STATUS status = AE_OK; - u32 cx_state_latencies[4] = {0, 0, 0, 0}; - NATIVE_UINT buffer_space_needed = 0; - ACPI_CX_STATE *state_ptr = NULL; - NATIVE_UINT i = 0; - - - /* - * Have to at least have a buffer to return info in - */ - if (!user_buffer) { - return (AE_BAD_PARAMETER); - } - - status = acpi_hw_get_cx_info (cx_state_latencies); - if (ACPI_FAILURE (status)) { - return (status); - } - - buffer_space_needed = 4 * sizeof (ACPI_CX_STATE); - - if ((user_buffer->length < buffer_space_needed) || !user_buffer->pointer) { - user_buffer->length = buffer_space_needed; - return (AE_BUFFER_OVERFLOW); - } - - user_buffer->length = buffer_space_needed; - - state_ptr = (ACPI_CX_STATE *) user_buffer->pointer; - - for (i = 0; i < 4; i++) { - state_ptr[i].state_number = i; - state_ptr[i].latency = cx_state_latencies[i]; - } - - return (AE_OK); -} - - -/**************************************************************************** - * - * FUNCTION: Acpi_set_processor_sleep_state - * - * PARAMETERS: Processor_handle - handle for the cpu return info about - * Cx_state - the Cx sleeping state (C1-C3) to make - * 'active' - * - * RETURN: Status of function - * - * DESCRIPTION: Sets which Cx state will be used during calls to - * Acpi_processor_sleep () - * - ****************************************************************************/ - -ACPI_STATUS -acpi_set_processor_sleep_state ( - ACPI_HANDLE processor_handle, - u32 cx_state) -{ - ACPI_STATUS status; - - - status = acpi_hw_set_cx (cx_state); - - return (status); -} - - -/**************************************************************************** - * - * FUNCTION: Acpi_processor_sleep - * - * PARAMETERS: Processor_handle - handle for the cpu to put to sleep (Cx) - * Time_sleeping - time (in microseconds) elapsed while - * sleeping - * - * RETURN: Status of function - * - * DESCRIPTION: Puts the processor into the currently active sleep state (Cx) - * - ****************************************************************************/ - -ACPI_STATUS -acpi_processor_sleep ( - ACPI_HANDLE processor_handle, - u32 *pm_timer_ticks) -{ - ACPI_NAMESPACE_NODE *cpu_node = NULL; - ACPI_OPERAND_OBJECT *cpu_obj = NULL; - ACPI_IO_ADDRESS address = 0; - - - /* - * Convert Processor_handle to Pblk_addres... - */ - - /* Convert and validate the device handle */ - - cpu_node = acpi_ns_convert_handle_to_entry (processor_handle); - if (!cpu_node) { - return (AE_BAD_PARAMETER); - } - - /* Check for an existing internal object */ - - cpu_obj = acpi_ns_get_attached_object ((ACPI_HANDLE) cpu_node); - if (!cpu_obj) { - return (AE_NOT_FOUND); - } - - /* Get the processor register block (P_BLK) address */ - - address = cpu_obj->processor.address; - if (!cpu_obj->processor.length) { - /* Ensure a NULL addresss (note that P_BLK isn't required for C1) */ - - address = 0; - } - - /* - * Enter the currently active Cx sleep state. - */ - return (acpi_hw_enter_cx (address, pm_timer_ticks)); -} - - -/****************************************************************************** - * - * FUNCTION: Acpi_get_timer - * - * PARAMETERS: none - * - * RETURN: Current value of the ACPI PMT (timer) - * - * DESCRIPTION: Obtains current value of ACPI PMT - * - ******************************************************************************/ - -ACPI_STATUS -acpi_get_timer ( - u32 *out_ticks) -{ - - if (!out_ticks) { - return (AE_BAD_PARAMETER); - } - - *out_ticks = acpi_hw_pmt_ticks (); - - return (AE_OK); -} - - -/****************************************************************************** - * - * FUNCTION: Acpi_set_firmware_waking_vector - * - * PARAMETERS: Physical_address - Physical address of ACPI real mode - * entry point. - * - * RETURN: AE_OK or AE_ERROR - * - * DESCRIPTION: Access function for d_firmware_waking_vector field in FACS - * - ******************************************************************************/ - -ACPI_STATUS -acpi_set_firmware_waking_vector ( - ACPI_PHYSICAL_ADDRESS physical_address) -{ - - - /* Make sure that we have an FACS */ - - if (!acpi_gbl_FACS) { - return (AE_NO_ACPI_TABLES); - } - - /* Set the vector */ - - if (acpi_gbl_FACS->vector_width == 32) { - * (u32 *) acpi_gbl_FACS->firmware_waking_vector = (u32) physical_address; - } - else { - *acpi_gbl_FACS->firmware_waking_vector = physical_address; - } - - return (AE_OK); -} - - -/****************************************************************************** - * - * FUNCTION: Acpi_get_firmware_waking_vector - * - * PARAMETERS: *Physical_address - Output buffer where contents of - * the Firmware_waking_vector field of - * the FACS will be stored. - * - * RETURN: Status - * - * DESCRIPTION: Access function for d_firmware_waking_vector field in FACS - * - ******************************************************************************/ - -ACPI_STATUS -acpi_get_firmware_waking_vector ( - ACPI_PHYSICAL_ADDRESS *physical_address) -{ - - - if (!physical_address) { - return (AE_BAD_PARAMETER); - } - - /* Make sure that we have an FACS */ - - if (!acpi_gbl_FACS) { - return (AE_NO_ACPI_TABLES); - } - - /* Get the vector */ - - if (acpi_gbl_FACS->vector_width == 32) { - *physical_address = * (u32 *) acpi_gbl_FACS->firmware_waking_vector; - } - else { - *physical_address = *acpi_gbl_FACS->firmware_waking_vector; - } - - return (AE_OK); -} - - |