mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 02:32:09 -04:00
Merge branches 'idle-fix' and 'misc' into release
This commit is contained in:
commit
eeaab2d8af
10325 changed files with 498938 additions and 290093 deletions
|
|
@ -384,6 +384,15 @@ config ACPI_CUSTOM_METHOD
|
|||
load additional kernel modules after boot, this feature may be used
|
||||
to override that restriction).
|
||||
|
||||
config ACPI_BGRT
|
||||
tristate "Boottime Graphics Resource Table support"
|
||||
default n
|
||||
help
|
||||
This driver adds support for exposing the ACPI Boottime Graphics
|
||||
Resource Table, which allows the operating system to obtain
|
||||
data from the firmware boot splash. It will appear under
|
||||
/sys/firmware/acpi/bgrt/ .
|
||||
|
||||
source "drivers/acpi/apei/Kconfig"
|
||||
|
||||
endif # ACPI
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ obj-$(CONFIG_ACPI_SBS) += sbs.o
|
|||
obj-$(CONFIG_ACPI_HED) += hed.o
|
||||
obj-$(CONFIG_ACPI_EC_DEBUGFS) += ec_sys.o
|
||||
obj-$(CONFIG_ACPI_CUSTOM_METHOD)+= custom_method.o
|
||||
obj-$(CONFIG_ACPI_BGRT) += bgrt.o
|
||||
|
||||
# processor has its own "processor." module_param namespace
|
||||
processor-y := processor_driver.o processor_throttling.o
|
||||
|
|
|
|||
|
|
@ -68,12 +68,14 @@ acpi-y += \
|
|||
|
||||
acpi-y += \
|
||||
hwacpi.o \
|
||||
hwesleep.o \
|
||||
hwgpe.o \
|
||||
hwpci.o \
|
||||
hwregs.o \
|
||||
hwsleep.o \
|
||||
hwvalid.o \
|
||||
hwxface.o
|
||||
hwxface.o \
|
||||
hwxfsleep.o
|
||||
|
||||
acpi-$(ACPI_FUTURE_USAGE) += hwtimer.o
|
||||
|
||||
|
|
|
|||
|
|
@ -51,7 +51,6 @@
|
|||
*
|
||||
* Note: The order of these include files is important.
|
||||
*/
|
||||
#include "acconfig.h" /* Global configuration constants */
|
||||
#include "acmacros.h" /* C macros */
|
||||
#include "aclocal.h" /* Internal data types */
|
||||
#include "acobject.h" /* ACPI internal object */
|
||||
|
|
|
|||
|
|
@ -1,231 +0,0 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Name: acconfig.h - Global configuration constants
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2000 - 2012, Intel Corp.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions, and the following disclaimer,
|
||||
* without modification.
|
||||
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
|
||||
* substantially similar to the "NO WARRANTY" disclaimer below
|
||||
* ("Disclaimer") and any redistribution must be conditioned upon
|
||||
* including a substantially similar Disclaimer requirement for further
|
||||
* binary redistribution.
|
||||
* 3. Neither the names of the above-listed copyright holders nor the names
|
||||
* of any contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* Alternatively, this software may be distributed under the terms of the
|
||||
* GNU General Public License ("GPL") version 2 as published by the Free
|
||||
* Software Foundation.
|
||||
*
|
||||
* NO WARRANTY
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGES.
|
||||
*/
|
||||
|
||||
#ifndef _ACCONFIG_H
|
||||
#define _ACCONFIG_H
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Configuration options
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
* ACPI_DEBUG_OUTPUT - This switch enables all the debug facilities of the
|
||||
* ACPI subsystem. This includes the DEBUG_PRINT output
|
||||
* statements. When disabled, all DEBUG_PRINT
|
||||
* statements are compiled out.
|
||||
*
|
||||
* ACPI_APPLICATION - Use this switch if the subsystem is going to be run
|
||||
* at the application level.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* OS name, used for the _OS object. The _OS object is essentially obsolete,
|
||||
* but there is a large base of ASL/AML code in existing machines that check
|
||||
* for the string below. The use of this string usually guarantees that
|
||||
* the ASL will execute down the most tested code path. Also, there is some
|
||||
* code that will not execute the _OSI method unless _OS matches the string
|
||||
* below. Therefore, change this string at your own risk.
|
||||
*/
|
||||
#define ACPI_OS_NAME "Microsoft Windows NT"
|
||||
|
||||
/* Maximum objects in the various object caches */
|
||||
|
||||
#define ACPI_MAX_STATE_CACHE_DEPTH 96 /* State objects */
|
||||
#define ACPI_MAX_PARSE_CACHE_DEPTH 96 /* Parse tree objects */
|
||||
#define ACPI_MAX_EXTPARSE_CACHE_DEPTH 96 /* Parse tree objects */
|
||||
#define ACPI_MAX_OBJECT_CACHE_DEPTH 96 /* Interpreter operand objects */
|
||||
#define ACPI_MAX_NAMESPACE_CACHE_DEPTH 96 /* Namespace objects */
|
||||
|
||||
/*
|
||||
* Should the subsystem abort the loading of an ACPI table if the
|
||||
* table checksum is incorrect?
|
||||
*/
|
||||
#define ACPI_CHECKSUM_ABORT FALSE
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Subsystem Constants
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/* Version of ACPI supported */
|
||||
|
||||
#define ACPI_CA_SUPPORT_LEVEL 3
|
||||
|
||||
/* Maximum count for a semaphore object */
|
||||
|
||||
#define ACPI_MAX_SEMAPHORE_COUNT 256
|
||||
|
||||
/* Maximum object reference count (detects object deletion issues) */
|
||||
|
||||
#define ACPI_MAX_REFERENCE_COUNT 0x1000
|
||||
|
||||
/* Default page size for use in mapping memory for operation regions */
|
||||
|
||||
#define ACPI_DEFAULT_PAGE_SIZE 4096 /* Must be power of 2 */
|
||||
|
||||
/* owner_id tracking. 8 entries allows for 255 owner_ids */
|
||||
|
||||
#define ACPI_NUM_OWNERID_MASKS 8
|
||||
|
||||
/* Size of the root table array is increased by this increment */
|
||||
|
||||
#define ACPI_ROOT_TABLE_SIZE_INCREMENT 4
|
||||
|
||||
/* Maximum number of While() loop iterations before forced abort */
|
||||
|
||||
#define ACPI_MAX_LOOP_ITERATIONS 0xFFFF
|
||||
|
||||
/* Maximum sleep allowed via Sleep() operator */
|
||||
|
||||
#define ACPI_MAX_SLEEP 2000 /* Two seconds */
|
||||
|
||||
/* Address Range lists are per-space_id (Memory and I/O only) */
|
||||
|
||||
#define ACPI_ADDRESS_RANGE_MAX 2
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* ACPI Specification constants (Do not change unless the specification changes)
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/* Number of distinct GPE register blocks and register width */
|
||||
|
||||
#define ACPI_MAX_GPE_BLOCKS 2
|
||||
#define ACPI_GPE_REGISTER_WIDTH 8
|
||||
|
||||
/* Method info (in WALK_STATE), containing local variables and argumetns */
|
||||
|
||||
#define ACPI_METHOD_NUM_LOCALS 8
|
||||
#define ACPI_METHOD_MAX_LOCAL 7
|
||||
|
||||
#define ACPI_METHOD_NUM_ARGS 7
|
||||
#define ACPI_METHOD_MAX_ARG 6
|
||||
|
||||
/* Length of _HID, _UID, _CID, and UUID values */
|
||||
|
||||
#define ACPI_DEVICE_ID_LENGTH 0x09
|
||||
#define ACPI_MAX_CID_LENGTH 48
|
||||
#define ACPI_UUID_LENGTH 16
|
||||
|
||||
/*
|
||||
* Operand Stack (in WALK_STATE), Must be large enough to contain METHOD_MAX_ARG
|
||||
*/
|
||||
#define ACPI_OBJ_NUM_OPERANDS 8
|
||||
#define ACPI_OBJ_MAX_OPERAND 7
|
||||
|
||||
/* Number of elements in the Result Stack frame, can be an arbitrary value */
|
||||
|
||||
#define ACPI_RESULTS_FRAME_OBJ_NUM 8
|
||||
|
||||
/*
|
||||
* Maximal number of elements the Result Stack can contain,
|
||||
* it may be an arbitray value not exceeding the types of
|
||||
* result_size and result_count (now u8).
|
||||
*/
|
||||
#define ACPI_RESULTS_OBJ_NUM_MAX 255
|
||||
|
||||
/* Names within the namespace are 4 bytes long */
|
||||
|
||||
#define ACPI_NAME_SIZE 4
|
||||
#define ACPI_PATH_SEGMENT_LENGTH 5 /* 4 chars for name + 1 char for separator */
|
||||
#define ACPI_PATH_SEPARATOR '.'
|
||||
|
||||
/* Sizes for ACPI table headers */
|
||||
|
||||
#define ACPI_OEM_ID_SIZE 6
|
||||
#define ACPI_OEM_TABLE_ID_SIZE 8
|
||||
|
||||
/* Constants used in searching for the RSDP in low memory */
|
||||
|
||||
#define ACPI_EBDA_PTR_LOCATION 0x0000040E /* Physical Address */
|
||||
#define ACPI_EBDA_PTR_LENGTH 2
|
||||
#define ACPI_EBDA_WINDOW_SIZE 1024
|
||||
#define ACPI_HI_RSDP_WINDOW_BASE 0x000E0000 /* Physical Address */
|
||||
#define ACPI_HI_RSDP_WINDOW_SIZE 0x00020000
|
||||
#define ACPI_RSDP_SCAN_STEP 16
|
||||
|
||||
/* Operation regions */
|
||||
|
||||
#define ACPI_USER_REGION_BEGIN 0x80
|
||||
|
||||
/* Maximum space_ids for Operation Regions */
|
||||
|
||||
#define ACPI_MAX_ADDRESS_SPACE 255
|
||||
|
||||
/* Array sizes. Used for range checking also */
|
||||
|
||||
#define ACPI_MAX_MATCH_OPCODE 5
|
||||
|
||||
/* RSDP checksums */
|
||||
|
||||
#define ACPI_RSDP_CHECKSUM_LENGTH 20
|
||||
#define ACPI_RSDP_XCHECKSUM_LENGTH 36
|
||||
|
||||
/* SMBus, GSBus and IPMI bidirectional buffer size */
|
||||
|
||||
#define ACPI_SMBUS_BUFFER_SIZE 34
|
||||
#define ACPI_GSBUS_BUFFER_SIZE 34
|
||||
#define ACPI_IPMI_BUFFER_SIZE 66
|
||||
|
||||
/* _sx_d and _sx_w control methods */
|
||||
|
||||
#define ACPI_NUM_sx_d_METHODS 4
|
||||
#define ACPI_NUM_sx_w_METHODS 5
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* ACPI AML Debugger
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#define ACPI_DEBUGGER_MAX_ARGS 8 /* Must be max method args + 1 */
|
||||
|
||||
#define ACPI_DEBUGGER_COMMAND_PROMPT '-'
|
||||
#define ACPI_DEBUGGER_EXECUTE_PROMPT '%'
|
||||
|
||||
#endif /* _ACCONFIG_H */
|
||||
|
|
@ -111,7 +111,7 @@ acpi_status acpi_db_find_name_in_namespace(char *name_arg);
|
|||
|
||||
void acpi_db_set_scope(char *name);
|
||||
|
||||
acpi_status acpi_db_sleep(char *object_arg);
|
||||
ACPI_HW_DEPENDENT_RETURN_OK(acpi_status acpi_db_sleep(char *object_arg))
|
||||
|
||||
void acpi_db_find_references(char *object_arg);
|
||||
|
||||
|
|
@ -119,11 +119,13 @@ void acpi_db_display_locks(void);
|
|||
|
||||
void acpi_db_display_resources(char *object_arg);
|
||||
|
||||
void acpi_db_display_gpes(void);
|
||||
ACPI_HW_DEPENDENT_RETURN_VOID(void acpi_db_display_gpes(void))
|
||||
|
||||
void acpi_db_check_integrity(void);
|
||||
|
||||
void acpi_db_generate_gpe(char *gpe_arg, char *block_arg);
|
||||
ACPI_HW_DEPENDENT_RETURN_VOID(void
|
||||
acpi_db_generate_gpe(char *gpe_arg,
|
||||
char *block_arg))
|
||||
|
||||
void acpi_db_check_predefined_names(void);
|
||||
|
||||
|
|
|
|||
|
|
@ -69,11 +69,10 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node *node,
|
|||
*/
|
||||
acpi_status acpi_ev_init_global_lock_handler(void);
|
||||
|
||||
acpi_status acpi_ev_acquire_global_lock(u16 timeout);
|
||||
|
||||
acpi_status acpi_ev_release_global_lock(void);
|
||||
|
||||
acpi_status acpi_ev_remove_global_lock_handler(void);
|
||||
ACPI_HW_DEPENDENT_RETURN_OK(acpi_status
|
||||
acpi_ev_acquire_global_lock(u16 timeout))
|
||||
ACPI_HW_DEPENDENT_RETURN_OK(acpi_status acpi_ev_release_global_lock(void))
|
||||
acpi_status acpi_ev_remove_global_lock_handler(void);
|
||||
|
||||
/*
|
||||
* evgpe - Low-level GPE support
|
||||
|
|
@ -114,7 +113,9 @@ acpi_ev_initialize_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
|
|||
struct acpi_gpe_block_info *gpe_block,
|
||||
void *context);
|
||||
|
||||
acpi_status acpi_ev_delete_gpe_block(struct acpi_gpe_block_info *gpe_block);
|
||||
ACPI_HW_DEPENDENT_RETURN_OK(acpi_status
|
||||
acpi_ev_delete_gpe_block(struct acpi_gpe_block_info
|
||||
*gpe_block))
|
||||
|
||||
u32
|
||||
acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device,
|
||||
|
|
@ -126,9 +127,10 @@ acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device,
|
|||
*/
|
||||
acpi_status acpi_ev_gpe_initialize(void);
|
||||
|
||||
void acpi_ev_update_gpes(acpi_owner_id table_owner_id);
|
||||
ACPI_HW_DEPENDENT_RETURN_VOID(void
|
||||
acpi_ev_update_gpes(acpi_owner_id table_owner_id))
|
||||
|
||||
acpi_status
|
||||
acpi_status
|
||||
acpi_ev_match_gpe_method(acpi_handle obj_handle,
|
||||
u32 level, void *context, void **return_value);
|
||||
|
||||
|
|
@ -237,6 +239,5 @@ acpi_status acpi_ev_remove_sci_handler(void);
|
|||
|
||||
u32 acpi_ev_initialize_sCI(u32 program_sCI);
|
||||
|
||||
void acpi_ev_terminate(void);
|
||||
|
||||
ACPI_HW_DEPENDENT_RETURN_VOID(void acpi_ev_terminate(void))
|
||||
#endif /* __ACEVENTS_H__ */
|
||||
|
|
|
|||
|
|
@ -147,7 +147,7 @@ u8 acpi_gbl_system_awake_and_running;
|
|||
*/
|
||||
u8 acpi_gbl_reduced_hardware;
|
||||
|
||||
#endif
|
||||
#endif /* DEFINE_ACPI_GLOBALS */
|
||||
|
||||
/* Do not disassemble buffers to resource descriptors */
|
||||
|
||||
|
|
@ -184,8 +184,12 @@ ACPI_EXTERN u32 acpi_gbl_trace_dbg_layer;
|
|||
* found in the RSDT/XSDT.
|
||||
*/
|
||||
ACPI_EXTERN struct acpi_table_list acpi_gbl_root_table_list;
|
||||
|
||||
#if (!ACPI_REDUCED_HARDWARE)
|
||||
ACPI_EXTERN struct acpi_table_facs *acpi_gbl_FACS;
|
||||
|
||||
#endif /* !ACPI_REDUCED_HARDWARE */
|
||||
|
||||
/* These addresses are calculated from the FADT Event Block addresses */
|
||||
|
||||
ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1a_status;
|
||||
|
|
@ -397,10 +401,15 @@ ACPI_EXTERN struct acpi_fixed_event_handler
|
|||
ACPI_EXTERN struct acpi_gpe_xrupt_info *acpi_gbl_gpe_xrupt_list_head;
|
||||
ACPI_EXTERN struct acpi_gpe_block_info
|
||||
*acpi_gbl_gpe_fadt_blocks[ACPI_MAX_GPE_BLOCKS];
|
||||
|
||||
#if (!ACPI_REDUCED_HARDWARE)
|
||||
|
||||
ACPI_EXTERN u8 acpi_gbl_all_gpes_initialized;
|
||||
ACPI_EXTERN ACPI_GBL_EVENT_HANDLER acpi_gbl_global_event_handler;
|
||||
ACPI_EXTERN void *acpi_gbl_global_event_handler_context;
|
||||
|
||||
#endif /* !ACPI_REDUCED_HARDWARE */
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Debugger globals
|
||||
|
|
|
|||
|
|
@ -80,6 +80,26 @@ acpi_status acpi_hw_register_write(u32 register_id, u32 value);
|
|||
|
||||
acpi_status acpi_hw_clear_acpi_status(void);
|
||||
|
||||
/*
|
||||
* hwsleep - sleep/wake support (Legacy sleep registers)
|
||||
*/
|
||||
acpi_status acpi_hw_legacy_sleep(u8 sleep_state, u8 flags);
|
||||
|
||||
acpi_status acpi_hw_legacy_wake_prep(u8 sleep_state, u8 flags);
|
||||
|
||||
acpi_status acpi_hw_legacy_wake(u8 sleep_state, u8 flags);
|
||||
|
||||
/*
|
||||
* hwesleep - sleep/wake support (Extended FADT-V5 sleep registers)
|
||||
*/
|
||||
void acpi_hw_execute_sleep_method(char *method_name, u32 integer_argument);
|
||||
|
||||
acpi_status acpi_hw_extended_sleep(u8 sleep_state, u8 flags);
|
||||
|
||||
acpi_status acpi_hw_extended_wake_prep(u8 sleep_state, u8 flags);
|
||||
|
||||
acpi_status acpi_hw_extended_wake(u8 sleep_state, u8 flags);
|
||||
|
||||
/*
|
||||
* hwvalid - Port I/O with validation
|
||||
*/
|
||||
|
|
@ -128,16 +148,4 @@ acpi_status
|
|||
acpi_hw_derive_pci_id(struct acpi_pci_id *pci_id,
|
||||
acpi_handle root_pci_device, acpi_handle pci_region);
|
||||
|
||||
#ifdef ACPI_FUTURE_USAGE
|
||||
/*
|
||||
* hwtimer - ACPI Timer prototypes
|
||||
*/
|
||||
acpi_status acpi_get_timer_resolution(u32 * resolution);
|
||||
|
||||
acpi_status acpi_get_timer(u32 * ticks);
|
||||
|
||||
acpi_status
|
||||
acpi_get_timer_duration(u32 start_ticks, u32 end_ticks, u32 * time_elapsed);
|
||||
#endif /* ACPI_FUTURE_USAGE */
|
||||
|
||||
#endif /* __ACHWARE_H__ */
|
||||
|
|
|
|||
|
|
@ -370,6 +370,7 @@ struct acpi_predefined_data {
|
|||
/* Defines for Flags field above */
|
||||
|
||||
#define ACPI_OBJECT_REPAIRED 1
|
||||
#define ACPI_OBJECT_WRAPPED 2
|
||||
|
||||
/*
|
||||
* Bitmapped return value types
|
||||
|
|
|
|||
|
|
@ -516,6 +516,12 @@
|
|||
|
||||
#endif /* ACPI_DEBUG_OUTPUT */
|
||||
|
||||
#if (!ACPI_REDUCED_HARDWARE)
|
||||
#define ACPI_HW_OPTIONAL_FUNCTION(addr) addr
|
||||
#else
|
||||
#define ACPI_HW_OPTIONAL_FUNCTION(addr) NULL
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Some code only gets executed when the debugger is built in.
|
||||
* Note that this is entirely independent of whether the
|
||||
|
|
|
|||
|
|
@ -283,8 +283,9 @@ acpi_ns_repair_object(struct acpi_predefined_data *data,
|
|||
union acpi_operand_object **return_object_ptr);
|
||||
|
||||
acpi_status
|
||||
acpi_ns_repair_package_list(struct acpi_predefined_data *data,
|
||||
union acpi_operand_object **obj_desc_ptr);
|
||||
acpi_ns_wrap_with_package(struct acpi_predefined_data *data,
|
||||
union acpi_operand_object *original_object,
|
||||
union acpi_operand_object **obj_desc_ptr);
|
||||
|
||||
acpi_status
|
||||
acpi_ns_repair_null_element(struct acpi_predefined_data *data,
|
||||
|
|
|
|||
|
|
@ -67,6 +67,11 @@ acpi_status acpi_tb_resize_root_table_list(void);
|
|||
|
||||
acpi_status acpi_tb_verify_table(struct acpi_table_desc *table_desc);
|
||||
|
||||
struct acpi_table_header *acpi_tb_table_override(struct acpi_table_header
|
||||
*table_header,
|
||||
struct acpi_table_desc
|
||||
*table_desc);
|
||||
|
||||
acpi_status
|
||||
acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index);
|
||||
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@
|
|||
|
||||
#define _COMPONENT ACPI_EVENTS
|
||||
ACPI_MODULE_NAME("evevent")
|
||||
|
||||
#if (!ACPI_REDUCED_HARDWARE) /* Entire module */
|
||||
/* Local prototypes */
|
||||
static acpi_status acpi_ev_fixed_event_initialize(void);
|
||||
|
||||
|
|
@ -291,3 +291,5 @@ static u32 acpi_ev_fixed_event_dispatch(u32 event)
|
|||
return ((acpi_gbl_fixed_event_handlers[event].
|
||||
handler) (acpi_gbl_fixed_event_handlers[event].context));
|
||||
}
|
||||
|
||||
#endif /* !ACPI_REDUCED_HARDWARE */
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@
|
|||
|
||||
#define _COMPONENT ACPI_EVENTS
|
||||
ACPI_MODULE_NAME("evglock")
|
||||
|
||||
#if (!ACPI_REDUCED_HARDWARE) /* Entire module */
|
||||
/* Local prototypes */
|
||||
static u32 acpi_ev_global_lock_handler(void *context);
|
||||
|
||||
|
|
@ -339,3 +339,5 @@ acpi_status acpi_ev_release_global_lock(void)
|
|||
acpi_os_release_mutex(acpi_gbl_global_lock_mutex->mutex.os_mutex);
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
#endif /* !ACPI_REDUCED_HARDWARE */
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@
|
|||
|
||||
#define _COMPONENT ACPI_EVENTS
|
||||
ACPI_MODULE_NAME("evgpe")
|
||||
|
||||
#if (!ACPI_REDUCED_HARDWARE) /* Entire module */
|
||||
/* Local prototypes */
|
||||
static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context);
|
||||
|
||||
|
|
@ -766,3 +766,5 @@ acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device,
|
|||
|
||||
return_UINT32(ACPI_INTERRUPT_HANDLED);
|
||||
}
|
||||
|
||||
#endif /* !ACPI_REDUCED_HARDWARE */
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@
|
|||
|
||||
#define _COMPONENT ACPI_EVENTS
|
||||
ACPI_MODULE_NAME("evgpeblk")
|
||||
|
||||
#if (!ACPI_REDUCED_HARDWARE) /* Entire module */
|
||||
/* Local prototypes */
|
||||
static acpi_status
|
||||
acpi_ev_install_gpe_block(struct acpi_gpe_block_info *gpe_block,
|
||||
|
|
@ -504,3 +504,5 @@ acpi_ev_initialize_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
|
|||
|
||||
return_ACPI_STATUS(AE_OK);
|
||||
}
|
||||
|
||||
#endif /* !ACPI_REDUCED_HARDWARE */
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@
|
|||
|
||||
#define _COMPONENT ACPI_EVENTS
|
||||
ACPI_MODULE_NAME("evgpeinit")
|
||||
|
||||
#if (!ACPI_REDUCED_HARDWARE) /* Entire module */
|
||||
/*
|
||||
* Note: History of _PRW support in ACPICA
|
||||
*
|
||||
|
|
@ -440,3 +440,5 @@ acpi_ev_match_gpe_method(acpi_handle obj_handle,
|
|||
name, gpe_number));
|
||||
return_ACPI_STATUS(AE_OK);
|
||||
}
|
||||
|
||||
#endif /* !ACPI_REDUCED_HARDWARE */
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@
|
|||
#define _COMPONENT ACPI_EVENTS
|
||||
ACPI_MODULE_NAME("evgpeutil")
|
||||
|
||||
#if (!ACPI_REDUCED_HARDWARE) /* Entire module */
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_ev_walk_gpe_list
|
||||
|
|
@ -374,3 +375,5 @@ acpi_ev_delete_gpe_handlers(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
|
|||
|
||||
return_ACPI_STATUS(AE_OK);
|
||||
}
|
||||
|
||||
#endif /* !ACPI_REDUCED_HARDWARE */
|
||||
|
|
|
|||
|
|
@ -108,27 +108,30 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node * node,
|
|||
ACPI_FUNCTION_NAME(ev_queue_notify_request);
|
||||
|
||||
/*
|
||||
* For value 3 (Ejection Request), some device method may need to be run.
|
||||
* For value 2 (Device Wake) if _PRW exists, the _PS0 method may need
|
||||
* to be run.
|
||||
* For value 0x03 (Ejection Request), may need to run a device method.
|
||||
* For value 0x02 (Device Wake), if _PRW exists, may need to run
|
||||
* the _PS0 method.
|
||||
* For value 0x80 (Status Change) on the power button or sleep button,
|
||||
* initiate soft-off or sleep operation?
|
||||
* initiate soft-off or sleep operation.
|
||||
*
|
||||
* For all cases, simply dispatch the notify to the handler.
|
||||
*/
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
||||
"Dispatching Notify on [%4.4s] Node %p Value 0x%2.2X (%s)\n",
|
||||
acpi_ut_get_node_name(node), node, notify_value,
|
||||
acpi_ut_get_notify_name(notify_value)));
|
||||
"Dispatching Notify on [%4.4s] (%s) Value 0x%2.2X (%s) Node %p\n",
|
||||
acpi_ut_get_node_name(node),
|
||||
acpi_ut_get_type_name(node->type), notify_value,
|
||||
acpi_ut_get_notify_name(notify_value), node));
|
||||
|
||||
/* Get the notify object attached to the NS Node */
|
||||
|
||||
obj_desc = acpi_ns_get_attached_object(node);
|
||||
if (obj_desc) {
|
||||
|
||||
/* We have the notify object, Get the right handler */
|
||||
/* We have the notify object, Get the correct handler */
|
||||
|
||||
switch (node->type) {
|
||||
|
||||
/* Notify allowed only on these types */
|
||||
/* Notify is allowed only on these types */
|
||||
|
||||
case ACPI_TYPE_DEVICE:
|
||||
case ACPI_TYPE_THERMAL:
|
||||
|
|
@ -152,7 +155,7 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node * node,
|
|||
}
|
||||
|
||||
/*
|
||||
* If there is any handler to run, schedule the dispatcher.
|
||||
* If there is a handler to run, schedule the dispatcher.
|
||||
* Check for:
|
||||
* 1) Global system notify handler
|
||||
* 2) Global device notify handler
|
||||
|
|
@ -270,6 +273,7 @@ static void ACPI_SYSTEM_XFACE acpi_ev_notify_dispatch(void *context)
|
|||
acpi_ut_delete_generic_state(notify_info);
|
||||
}
|
||||
|
||||
#if (!ACPI_REDUCED_HARDWARE)
|
||||
/******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_ev_terminate
|
||||
|
|
@ -338,3 +342,5 @@ void acpi_ev_terminate(void)
|
|||
}
|
||||
return_VOID;
|
||||
}
|
||||
|
||||
#endif /* !ACPI_REDUCED_HARDWARE */
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@
|
|||
|
||||
#define _COMPONENT ACPI_EVENTS
|
||||
ACPI_MODULE_NAME("evsci")
|
||||
|
||||
#if (!ACPI_REDUCED_HARDWARE) /* Entire module */
|
||||
/* Local prototypes */
|
||||
static u32 ACPI_SYSTEM_XFACE acpi_ev_sci_xrupt_handler(void *context);
|
||||
|
||||
|
|
@ -181,3 +181,5 @@ acpi_status acpi_ev_remove_sci_handler(void)
|
|||
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
#endif /* !ACPI_REDUCED_HARDWARE */
|
||||
|
|
|
|||
|
|
@ -51,222 +51,6 @@
|
|||
#define _COMPONENT ACPI_EVENTS
|
||||
ACPI_MODULE_NAME("evxface")
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_install_exception_handler
|
||||
*
|
||||
* PARAMETERS: Handler - Pointer to the handler function for the
|
||||
* event
|
||||
*
|
||||
* RETURN: Status
|
||||
*
|
||||
* DESCRIPTION: Saves the pointer to the handler function
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifdef ACPI_FUTURE_USAGE
|
||||
acpi_status acpi_install_exception_handler(acpi_exception_handler handler)
|
||||
{
|
||||
acpi_status status;
|
||||
|
||||
ACPI_FUNCTION_TRACE(acpi_install_exception_handler);
|
||||
|
||||
status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
/* Don't allow two handlers. */
|
||||
|
||||
if (acpi_gbl_exception_handler) {
|
||||
status = AE_ALREADY_EXISTS;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Install the handler */
|
||||
|
||||
acpi_gbl_exception_handler = handler;
|
||||
|
||||
cleanup:
|
||||
(void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
ACPI_EXPORT_SYMBOL(acpi_install_exception_handler)
|
||||
#endif /* ACPI_FUTURE_USAGE */
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_install_global_event_handler
|
||||
*
|
||||
* PARAMETERS: Handler - Pointer to the global event handler function
|
||||
* Context - Value passed to the handler on each event
|
||||
*
|
||||
* RETURN: Status
|
||||
*
|
||||
* DESCRIPTION: Saves the pointer to the handler function. The global handler
|
||||
* is invoked upon each incoming GPE and Fixed Event. It is
|
||||
* invoked at interrupt level at the time of the event dispatch.
|
||||
* Can be used to update event counters, etc.
|
||||
*
|
||||
******************************************************************************/
|
||||
acpi_status
|
||||
acpi_install_global_event_handler(ACPI_GBL_EVENT_HANDLER handler, void *context)
|
||||
{
|
||||
acpi_status status;
|
||||
|
||||
ACPI_FUNCTION_TRACE(acpi_install_global_event_handler);
|
||||
|
||||
/* Parameter validation */
|
||||
|
||||
if (!handler) {
|
||||
return_ACPI_STATUS(AE_BAD_PARAMETER);
|
||||
}
|
||||
|
||||
status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
/* Don't allow two handlers. */
|
||||
|
||||
if (acpi_gbl_global_event_handler) {
|
||||
status = AE_ALREADY_EXISTS;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
acpi_gbl_global_event_handler = handler;
|
||||
acpi_gbl_global_event_handler_context = context;
|
||||
|
||||
cleanup:
|
||||
(void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
ACPI_EXPORT_SYMBOL(acpi_install_global_event_handler)
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_install_fixed_event_handler
|
||||
*
|
||||
* PARAMETERS: Event - Event type to enable.
|
||||
* Handler - Pointer to the handler function for the
|
||||
* event
|
||||
* Context - Value passed to the handler on each GPE
|
||||
*
|
||||
* RETURN: Status
|
||||
*
|
||||
* DESCRIPTION: Saves the pointer to the handler function and then enables the
|
||||
* event.
|
||||
*
|
||||
******************************************************************************/
|
||||
acpi_status
|
||||
acpi_install_fixed_event_handler(u32 event,
|
||||
acpi_event_handler handler, void *context)
|
||||
{
|
||||
acpi_status status;
|
||||
|
||||
ACPI_FUNCTION_TRACE(acpi_install_fixed_event_handler);
|
||||
|
||||
/* Parameter validation */
|
||||
|
||||
if (event > ACPI_EVENT_MAX) {
|
||||
return_ACPI_STATUS(AE_BAD_PARAMETER);
|
||||
}
|
||||
|
||||
status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
/* Don't allow two handlers. */
|
||||
|
||||
if (NULL != acpi_gbl_fixed_event_handlers[event].handler) {
|
||||
status = AE_ALREADY_EXISTS;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Install the handler before enabling the event */
|
||||
|
||||
acpi_gbl_fixed_event_handlers[event].handler = handler;
|
||||
acpi_gbl_fixed_event_handlers[event].context = context;
|
||||
|
||||
status = acpi_clear_event(event);
|
||||
if (ACPI_SUCCESS(status))
|
||||
status = acpi_enable_event(event, 0);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
ACPI_WARNING((AE_INFO, "Could not enable fixed event 0x%X",
|
||||
event));
|
||||
|
||||
/* Remove the handler */
|
||||
|
||||
acpi_gbl_fixed_event_handlers[event].handler = NULL;
|
||||
acpi_gbl_fixed_event_handlers[event].context = NULL;
|
||||
} else {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
||||
"Enabled fixed event %X, Handler=%p\n", event,
|
||||
handler));
|
||||
}
|
||||
|
||||
cleanup:
|
||||
(void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
ACPI_EXPORT_SYMBOL(acpi_install_fixed_event_handler)
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_remove_fixed_event_handler
|
||||
*
|
||||
* PARAMETERS: Event - Event type to disable.
|
||||
* Handler - Address of the handler
|
||||
*
|
||||
* RETURN: Status
|
||||
*
|
||||
* DESCRIPTION: Disables the event and unregisters the event handler.
|
||||
*
|
||||
******************************************************************************/
|
||||
acpi_status
|
||||
acpi_remove_fixed_event_handler(u32 event, acpi_event_handler handler)
|
||||
{
|
||||
acpi_status status = AE_OK;
|
||||
|
||||
ACPI_FUNCTION_TRACE(acpi_remove_fixed_event_handler);
|
||||
|
||||
/* Parameter validation */
|
||||
|
||||
if (event > ACPI_EVENT_MAX) {
|
||||
return_ACPI_STATUS(AE_BAD_PARAMETER);
|
||||
}
|
||||
|
||||
status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
/* Disable the event before removing the handler */
|
||||
|
||||
status = acpi_disable_event(event, 0);
|
||||
|
||||
/* Always Remove the handler */
|
||||
|
||||
acpi_gbl_fixed_event_handlers[event].handler = NULL;
|
||||
acpi_gbl_fixed_event_handlers[event].context = NULL;
|
||||
|
||||
if (ACPI_FAILURE(status)) {
|
||||
ACPI_WARNING((AE_INFO,
|
||||
"Could not write to fixed event enable register 0x%X",
|
||||
event));
|
||||
} else {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Disabled fixed event %X\n",
|
||||
event));
|
||||
}
|
||||
|
||||
(void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
ACPI_EXPORT_SYMBOL(acpi_remove_fixed_event_handler)
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
|
|
@ -334,6 +118,7 @@ acpi_add_handler_object(struct acpi_object_notify_handler *parent_obj,
|
|||
return AE_OK;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_install_notify_handler
|
||||
|
|
@ -703,6 +488,224 @@ acpi_remove_notify_handler(acpi_handle device,
|
|||
|
||||
ACPI_EXPORT_SYMBOL(acpi_remove_notify_handler)
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_install_exception_handler
|
||||
*
|
||||
* PARAMETERS: Handler - Pointer to the handler function for the
|
||||
* event
|
||||
*
|
||||
* RETURN: Status
|
||||
*
|
||||
* DESCRIPTION: Saves the pointer to the handler function
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifdef ACPI_FUTURE_USAGE
|
||||
acpi_status acpi_install_exception_handler(acpi_exception_handler handler)
|
||||
{
|
||||
acpi_status status;
|
||||
|
||||
ACPI_FUNCTION_TRACE(acpi_install_exception_handler);
|
||||
|
||||
status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
/* Don't allow two handlers. */
|
||||
|
||||
if (acpi_gbl_exception_handler) {
|
||||
status = AE_ALREADY_EXISTS;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Install the handler */
|
||||
|
||||
acpi_gbl_exception_handler = handler;
|
||||
|
||||
cleanup:
|
||||
(void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
ACPI_EXPORT_SYMBOL(acpi_install_exception_handler)
|
||||
#endif /* ACPI_FUTURE_USAGE */
|
||||
|
||||
#if (!ACPI_REDUCED_HARDWARE)
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_install_global_event_handler
|
||||
*
|
||||
* PARAMETERS: Handler - Pointer to the global event handler function
|
||||
* Context - Value passed to the handler on each event
|
||||
*
|
||||
* RETURN: Status
|
||||
*
|
||||
* DESCRIPTION: Saves the pointer to the handler function. The global handler
|
||||
* is invoked upon each incoming GPE and Fixed Event. It is
|
||||
* invoked at interrupt level at the time of the event dispatch.
|
||||
* Can be used to update event counters, etc.
|
||||
*
|
||||
******************************************************************************/
|
||||
acpi_status
|
||||
acpi_install_global_event_handler(ACPI_GBL_EVENT_HANDLER handler, void *context)
|
||||
{
|
||||
acpi_status status;
|
||||
|
||||
ACPI_FUNCTION_TRACE(acpi_install_global_event_handler);
|
||||
|
||||
/* Parameter validation */
|
||||
|
||||
if (!handler) {
|
||||
return_ACPI_STATUS(AE_BAD_PARAMETER);
|
||||
}
|
||||
|
||||
status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
/* Don't allow two handlers. */
|
||||
|
||||
if (acpi_gbl_global_event_handler) {
|
||||
status = AE_ALREADY_EXISTS;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
acpi_gbl_global_event_handler = handler;
|
||||
acpi_gbl_global_event_handler_context = context;
|
||||
|
||||
cleanup:
|
||||
(void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
ACPI_EXPORT_SYMBOL(acpi_install_global_event_handler)
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_install_fixed_event_handler
|
||||
*
|
||||
* PARAMETERS: Event - Event type to enable.
|
||||
* Handler - Pointer to the handler function for the
|
||||
* event
|
||||
* Context - Value passed to the handler on each GPE
|
||||
*
|
||||
* RETURN: Status
|
||||
*
|
||||
* DESCRIPTION: Saves the pointer to the handler function and then enables the
|
||||
* event.
|
||||
*
|
||||
******************************************************************************/
|
||||
acpi_status
|
||||
acpi_install_fixed_event_handler(u32 event,
|
||||
acpi_event_handler handler, void *context)
|
||||
{
|
||||
acpi_status status;
|
||||
|
||||
ACPI_FUNCTION_TRACE(acpi_install_fixed_event_handler);
|
||||
|
||||
/* Parameter validation */
|
||||
|
||||
if (event > ACPI_EVENT_MAX) {
|
||||
return_ACPI_STATUS(AE_BAD_PARAMETER);
|
||||
}
|
||||
|
||||
status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
/* Don't allow two handlers. */
|
||||
|
||||
if (NULL != acpi_gbl_fixed_event_handlers[event].handler) {
|
||||
status = AE_ALREADY_EXISTS;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Install the handler before enabling the event */
|
||||
|
||||
acpi_gbl_fixed_event_handlers[event].handler = handler;
|
||||
acpi_gbl_fixed_event_handlers[event].context = context;
|
||||
|
||||
status = acpi_clear_event(event);
|
||||
if (ACPI_SUCCESS(status))
|
||||
status = acpi_enable_event(event, 0);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
ACPI_WARNING((AE_INFO, "Could not enable fixed event 0x%X",
|
||||
event));
|
||||
|
||||
/* Remove the handler */
|
||||
|
||||
acpi_gbl_fixed_event_handlers[event].handler = NULL;
|
||||
acpi_gbl_fixed_event_handlers[event].context = NULL;
|
||||
} else {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
||||
"Enabled fixed event %X, Handler=%p\n", event,
|
||||
handler));
|
||||
}
|
||||
|
||||
cleanup:
|
||||
(void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
ACPI_EXPORT_SYMBOL(acpi_install_fixed_event_handler)
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_remove_fixed_event_handler
|
||||
*
|
||||
* PARAMETERS: Event - Event type to disable.
|
||||
* Handler - Address of the handler
|
||||
*
|
||||
* RETURN: Status
|
||||
*
|
||||
* DESCRIPTION: Disables the event and unregisters the event handler.
|
||||
*
|
||||
******************************************************************************/
|
||||
acpi_status
|
||||
acpi_remove_fixed_event_handler(u32 event, acpi_event_handler handler)
|
||||
{
|
||||
acpi_status status = AE_OK;
|
||||
|
||||
ACPI_FUNCTION_TRACE(acpi_remove_fixed_event_handler);
|
||||
|
||||
/* Parameter validation */
|
||||
|
||||
if (event > ACPI_EVENT_MAX) {
|
||||
return_ACPI_STATUS(AE_BAD_PARAMETER);
|
||||
}
|
||||
|
||||
status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
/* Disable the event before removing the handler */
|
||||
|
||||
status = acpi_disable_event(event, 0);
|
||||
|
||||
/* Always Remove the handler */
|
||||
|
||||
acpi_gbl_fixed_event_handlers[event].handler = NULL;
|
||||
acpi_gbl_fixed_event_handlers[event].context = NULL;
|
||||
|
||||
if (ACPI_FAILURE(status)) {
|
||||
ACPI_WARNING((AE_INFO,
|
||||
"Could not write to fixed event enable register 0x%X",
|
||||
event));
|
||||
} else {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Disabled fixed event %X\n",
|
||||
event));
|
||||
}
|
||||
|
||||
(void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
ACPI_EXPORT_SYMBOL(acpi_remove_fixed_event_handler)
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_install_gpe_handler
|
||||
|
|
@ -984,3 +987,4 @@ acpi_status acpi_release_global_lock(u32 handle)
|
|||
}
|
||||
|
||||
ACPI_EXPORT_SYMBOL(acpi_release_global_lock)
|
||||
#endif /* !ACPI_REDUCED_HARDWARE */
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@
|
|||
#define _COMPONENT ACPI_EVENTS
|
||||
ACPI_MODULE_NAME("evxfevnt")
|
||||
|
||||
#if (!ACPI_REDUCED_HARDWARE) /* Entire module */
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_enable
|
||||
|
|
@ -352,3 +353,4 @@ acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status)
|
|||
}
|
||||
|
||||
ACPI_EXPORT_SYMBOL(acpi_get_event_status)
|
||||
#endif /* !ACPI_REDUCED_HARDWARE */
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@
|
|||
#define _COMPONENT ACPI_EVENTS
|
||||
ACPI_MODULE_NAME("evxfgpe")
|
||||
|
||||
#if (!ACPI_REDUCED_HARDWARE) /* Entire module */
|
||||
/******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_update_all_gpes
|
||||
|
|
@ -695,3 +696,4 @@ acpi_get_gpe_device(u32 index, acpi_handle *gpe_device)
|
|||
}
|
||||
|
||||
ACPI_EXPORT_SYMBOL(acpi_get_gpe_device)
|
||||
#endif /* !ACPI_REDUCED_HARDWARE */
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@
|
|||
#define _COMPONENT ACPI_HARDWARE
|
||||
ACPI_MODULE_NAME("hwacpi")
|
||||
|
||||
#if (!ACPI_REDUCED_HARDWARE) /* Entire module */
|
||||
/******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_hw_set_mode
|
||||
|
|
@ -166,3 +167,5 @@ u32 acpi_hw_get_mode(void)
|
|||
return_UINT32(ACPI_SYS_MODE_LEGACY);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* !ACPI_REDUCED_HARDWARE */
|
||||
|
|
|
|||
247
drivers/acpi/acpica/hwesleep.c
Normal file
247
drivers/acpi/acpica/hwesleep.c
Normal file
|
|
@ -0,0 +1,247 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Name: hwesleep.c - ACPI Hardware Sleep/Wake Support functions for the
|
||||
* extended FADT-V5 sleep registers.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2000 - 2012, Intel Corp.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions, and the following disclaimer,
|
||||
* without modification.
|
||||
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
|
||||
* substantially similar to the "NO WARRANTY" disclaimer below
|
||||
* ("Disclaimer") and any redistribution must be conditioned upon
|
||||
* including a substantially similar Disclaimer requirement for further
|
||||
* binary redistribution.
|
||||
* 3. Neither the names of the above-listed copyright holders nor the names
|
||||
* of any contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* Alternatively, this software may be distributed under the terms of the
|
||||
* GNU General Public License ("GPL") version 2 as published by the Free
|
||||
* Software Foundation.
|
||||
*
|
||||
* NO WARRANTY
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGES.
|
||||
*/
|
||||
|
||||
#include <acpi/acpi.h>
|
||||
#include "accommon.h"
|
||||
|
||||
#define _COMPONENT ACPI_HARDWARE
|
||||
ACPI_MODULE_NAME("hwesleep")
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_hw_execute_sleep_method
|
||||
*
|
||||
* PARAMETERS: method_pathname - Pathname of method to execute
|
||||
* integer_argument - Argument to pass to the method
|
||||
*
|
||||
* RETURN: None
|
||||
*
|
||||
* DESCRIPTION: Execute a sleep/wake related method with one integer argument
|
||||
* and no return value.
|
||||
*
|
||||
******************************************************************************/
|
||||
void acpi_hw_execute_sleep_method(char *method_pathname, u32 integer_argument)
|
||||
{
|
||||
struct acpi_object_list arg_list;
|
||||
union acpi_object arg;
|
||||
acpi_status status;
|
||||
|
||||
ACPI_FUNCTION_TRACE(hw_execute_sleep_method);
|
||||
|
||||
/* One argument, integer_argument; No return value expected */
|
||||
|
||||
arg_list.count = 1;
|
||||
arg_list.pointer = &arg;
|
||||
arg.type = ACPI_TYPE_INTEGER;
|
||||
arg.integer.value = (u64)integer_argument;
|
||||
|
||||
status = acpi_evaluate_object(NULL, method_pathname, &arg_list, NULL);
|
||||
if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
|
||||
ACPI_EXCEPTION((AE_INFO, status, "While executing method %s",
|
||||
method_pathname));
|
||||
}
|
||||
|
||||
return_VOID;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_hw_extended_sleep
|
||||
*
|
||||
* PARAMETERS: sleep_state - Which sleep state to enter
|
||||
* Flags - ACPI_EXECUTE_GTS to run optional method
|
||||
*
|
||||
* RETURN: Status
|
||||
*
|
||||
* DESCRIPTION: Enter a system sleep state via the extended FADT sleep
|
||||
* registers (V5 FADT).
|
||||
* THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
acpi_status acpi_hw_extended_sleep(u8 sleep_state, u8 flags)
|
||||
{
|
||||
acpi_status status;
|
||||
u8 sleep_type_value;
|
||||
u64 sleep_status;
|
||||
|
||||
ACPI_FUNCTION_TRACE(hw_extended_sleep);
|
||||
|
||||
/* Extended sleep registers must be valid */
|
||||
|
||||
if (!acpi_gbl_FADT.sleep_control.address ||
|
||||
!acpi_gbl_FADT.sleep_status.address) {
|
||||
return_ACPI_STATUS(AE_NOT_EXIST);
|
||||
}
|
||||
|
||||
/* Clear wake status (WAK_STS) */
|
||||
|
||||
status = acpi_write(ACPI_X_WAKE_STATUS, &acpi_gbl_FADT.sleep_status);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
acpi_gbl_system_awake_and_running = FALSE;
|
||||
|
||||
/* Optionally execute _GTS (Going To Sleep) */
|
||||
|
||||
if (flags & ACPI_EXECUTE_GTS) {
|
||||
acpi_hw_execute_sleep_method(METHOD_PATHNAME__GTS, sleep_state);
|
||||
}
|
||||
|
||||
/* Flush caches, as per ACPI specification */
|
||||
|
||||
ACPI_FLUSH_CPU_CACHE();
|
||||
|
||||
/*
|
||||
* Set the SLP_TYP and SLP_EN bits.
|
||||
*
|
||||
* Note: We only use the first value returned by the \_Sx method
|
||||
* (acpi_gbl_sleep_type_a) - As per ACPI specification.
|
||||
*/
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INIT,
|
||||
"Entering sleep state [S%u]\n", sleep_state));
|
||||
|
||||
sleep_type_value =
|
||||
((acpi_gbl_sleep_type_a << ACPI_X_SLEEP_TYPE_POSITION) &
|
||||
ACPI_X_SLEEP_TYPE_MASK);
|
||||
|
||||
status = acpi_write((sleep_type_value | ACPI_X_SLEEP_ENABLE),
|
||||
&acpi_gbl_FADT.sleep_control);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
/* Wait for transition back to Working State */
|
||||
|
||||
do {
|
||||
status = acpi_read(&sleep_status, &acpi_gbl_FADT.sleep_status);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
} while (!(((u8)sleep_status) & ACPI_X_WAKE_STATUS));
|
||||
|
||||
return_ACPI_STATUS(AE_OK);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_hw_extended_wake_prep
|
||||
*
|
||||
* PARAMETERS: sleep_state - Which sleep state we just exited
|
||||
* Flags - ACPI_EXECUTE_BFS to run optional method
|
||||
*
|
||||
* RETURN: Status
|
||||
*
|
||||
* DESCRIPTION: Perform first part of OS-independent ACPI cleanup after
|
||||
* a sleep. Called with interrupts ENABLED.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
acpi_status acpi_hw_extended_wake_prep(u8 sleep_state, u8 flags)
|
||||
{
|
||||
acpi_status status;
|
||||
u8 sleep_type_value;
|
||||
|
||||
ACPI_FUNCTION_TRACE(hw_extended_wake_prep);
|
||||
|
||||
status = acpi_get_sleep_type_data(ACPI_STATE_S0,
|
||||
&acpi_gbl_sleep_type_a,
|
||||
&acpi_gbl_sleep_type_b);
|
||||
if (ACPI_SUCCESS(status)) {
|
||||
sleep_type_value =
|
||||
((acpi_gbl_sleep_type_a << ACPI_X_SLEEP_TYPE_POSITION) &
|
||||
ACPI_X_SLEEP_TYPE_MASK);
|
||||
|
||||
(void)acpi_write((sleep_type_value | ACPI_X_SLEEP_ENABLE),
|
||||
&acpi_gbl_FADT.sleep_control);
|
||||
}
|
||||
|
||||
/* Optionally execute _BFS (Back From Sleep) */
|
||||
|
||||
if (flags & ACPI_EXECUTE_BFS) {
|
||||
acpi_hw_execute_sleep_method(METHOD_PATHNAME__BFS, sleep_state);
|
||||
}
|
||||
return_ACPI_STATUS(AE_OK);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_hw_extended_wake
|
||||
*
|
||||
* PARAMETERS: sleep_state - Which sleep state we just exited
|
||||
* Flags - Reserved, set to zero
|
||||
*
|
||||
* RETURN: Status
|
||||
*
|
||||
* DESCRIPTION: Perform OS-independent ACPI cleanup after a sleep
|
||||
* Called with interrupts ENABLED.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
acpi_status acpi_hw_extended_wake(u8 sleep_state, u8 flags)
|
||||
{
|
||||
ACPI_FUNCTION_TRACE(hw_extended_wake);
|
||||
|
||||
/* Ensure enter_sleep_state_prep -> enter_sleep_state ordering */
|
||||
|
||||
acpi_gbl_sleep_type_a = ACPI_SLEEP_TYPE_INVALID;
|
||||
|
||||
/* Execute the wake methods */
|
||||
|
||||
acpi_hw_execute_sleep_method(METHOD_PATHNAME__SST, ACPI_SST_WAKING);
|
||||
acpi_hw_execute_sleep_method(METHOD_PATHNAME__WAK, sleep_state);
|
||||
|
||||
/*
|
||||
* Some BIOS code assumes that WAK_STS will be cleared on resume
|
||||
* and use it to determine whether the system is rebooting or
|
||||
* resuming. Clear WAK_STS for compatibility.
|
||||
*/
|
||||
(void)acpi_write(ACPI_X_WAKE_STATUS, &acpi_gbl_FADT.sleep_status);
|
||||
acpi_gbl_system_awake_and_running = TRUE;
|
||||
|
||||
acpi_hw_execute_sleep_method(METHOD_PATHNAME__SST, ACPI_SST_WORKING);
|
||||
return_ACPI_STATUS(AE_OK);
|
||||
}
|
||||
|
|
@ -48,7 +48,7 @@
|
|||
|
||||
#define _COMPONENT ACPI_HARDWARE
|
||||
ACPI_MODULE_NAME("hwgpe")
|
||||
|
||||
#if (!ACPI_REDUCED_HARDWARE) /* Entire module */
|
||||
/* Local prototypes */
|
||||
static acpi_status
|
||||
acpi_hw_enable_wakeup_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
|
||||
|
|
@ -479,3 +479,5 @@ acpi_status acpi_hw_enable_all_wakeup_gpes(void)
|
|||
status = acpi_ev_walk_gpe_list(acpi_hw_enable_wakeup_gpe_block, NULL);
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
#endif /* !ACPI_REDUCED_HARDWARE */
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@
|
|||
#define _COMPONENT ACPI_HARDWARE
|
||||
ACPI_MODULE_NAME("hwregs")
|
||||
|
||||
#if (!ACPI_REDUCED_HARDWARE)
|
||||
/* Local Prototypes */
|
||||
static acpi_status
|
||||
acpi_hw_read_multiple(u32 *value,
|
||||
|
|
@ -62,6 +63,8 @@ acpi_hw_write_multiple(u32 value,
|
|||
struct acpi_generic_address *register_a,
|
||||
struct acpi_generic_address *register_b);
|
||||
|
||||
#endif /* !ACPI_REDUCED_HARDWARE */
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_hw_validate_register
|
||||
|
|
@ -154,6 +157,7 @@ acpi_hw_validate_register(struct acpi_generic_address *reg,
|
|||
acpi_status acpi_hw_read(u32 *value, struct acpi_generic_address *reg)
|
||||
{
|
||||
u64 address;
|
||||
u64 value64;
|
||||
acpi_status status;
|
||||
|
||||
ACPI_FUNCTION_NAME(hw_read);
|
||||
|
|
@ -175,7 +179,9 @@ acpi_status acpi_hw_read(u32 *value, struct acpi_generic_address *reg)
|
|||
*/
|
||||
if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
|
||||
status = acpi_os_read_memory((acpi_physical_address)
|
||||
address, value, reg->bit_width);
|
||||
address, &value64, reg->bit_width);
|
||||
|
||||
*value = (u32)value64;
|
||||
} else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */
|
||||
|
||||
status = acpi_hw_read_port((acpi_io_address)
|
||||
|
|
@ -225,7 +231,8 @@ acpi_status acpi_hw_write(u32 value, struct acpi_generic_address *reg)
|
|||
*/
|
||||
if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
|
||||
status = acpi_os_write_memory((acpi_physical_address)
|
||||
address, value, reg->bit_width);
|
||||
address, (u64)value,
|
||||
reg->bit_width);
|
||||
} else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */
|
||||
|
||||
status = acpi_hw_write_port((acpi_io_address)
|
||||
|
|
@ -240,6 +247,7 @@ acpi_status acpi_hw_write(u32 value, struct acpi_generic_address *reg)
|
|||
return (status);
|
||||
}
|
||||
|
||||
#if (!ACPI_REDUCED_HARDWARE)
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_hw_clear_acpi_status
|
||||
|
|
@ -285,7 +293,7 @@ exit:
|
|||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_hw_get_register_bit_mask
|
||||
* FUNCTION: acpi_hw_get_bit_register_info
|
||||
*
|
||||
* PARAMETERS: register_id - Index of ACPI Register to access
|
||||
*
|
||||
|
|
@ -658,3 +666,5 @@ acpi_hw_write_multiple(u32 value,
|
|||
|
||||
return (status);
|
||||
}
|
||||
|
||||
#endif /* !ACPI_REDUCED_HARDWARE */
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Name: hwsleep.c - ACPI Hardware Sleep/Wake Interface
|
||||
* Name: hwsleep.c - ACPI Hardware Sleep/Wake Support functions for the
|
||||
* original/legacy sleep/PM registers.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
|
|
@ -43,213 +43,37 @@
|
|||
*/
|
||||
|
||||
#include <acpi/acpi.h>
|
||||
#include <linux/acpi.h>
|
||||
#include "accommon.h"
|
||||
#include "actables.h"
|
||||
#include <linux/tboot.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#define _COMPONENT ACPI_HARDWARE
|
||||
ACPI_MODULE_NAME("hwsleep")
|
||||
|
||||
#if (!ACPI_REDUCED_HARDWARE) /* Entire module */
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_set_firmware_waking_vector
|
||||
*
|
||||
* PARAMETERS: physical_address - 32-bit physical address of ACPI real mode
|
||||
* entry point.
|
||||
*
|
||||
* RETURN: Status
|
||||
*
|
||||
* DESCRIPTION: Sets the 32-bit firmware_waking_vector field of the FACS
|
||||
*
|
||||
******************************************************************************/
|
||||
acpi_status
|
||||
acpi_set_firmware_waking_vector(u32 physical_address)
|
||||
{
|
||||
ACPI_FUNCTION_TRACE(acpi_set_firmware_waking_vector);
|
||||
|
||||
|
||||
/*
|
||||
* According to the ACPI specification 2.0c and later, the 64-bit
|
||||
* waking vector should be cleared and the 32-bit waking vector should
|
||||
* be used, unless we want the wake-up code to be called by the BIOS in
|
||||
* Protected Mode. Some systems (for example HP dv5-1004nr) are known
|
||||
* to fail to resume if the 64-bit vector is used.
|
||||
*/
|
||||
|
||||
/* Set the 32-bit vector */
|
||||
|
||||
acpi_gbl_FACS->firmware_waking_vector = physical_address;
|
||||
|
||||
/* Clear the 64-bit vector if it exists */
|
||||
|
||||
if ((acpi_gbl_FACS->length > 32) && (acpi_gbl_FACS->version >= 1)) {
|
||||
acpi_gbl_FACS->xfirmware_waking_vector = 0;
|
||||
}
|
||||
|
||||
return_ACPI_STATUS(AE_OK);
|
||||
}
|
||||
|
||||
ACPI_EXPORT_SYMBOL(acpi_set_firmware_waking_vector)
|
||||
|
||||
#if ACPI_MACHINE_WIDTH == 64
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_set_firmware_waking_vector64
|
||||
*
|
||||
* PARAMETERS: physical_address - 64-bit physical address of ACPI protected
|
||||
* mode entry point.
|
||||
*
|
||||
* RETURN: Status
|
||||
*
|
||||
* DESCRIPTION: Sets the 64-bit X_firmware_waking_vector field of the FACS, if
|
||||
* it exists in the table. This function is intended for use with
|
||||
* 64-bit host operating systems.
|
||||
*
|
||||
******************************************************************************/
|
||||
acpi_status
|
||||
acpi_set_firmware_waking_vector64(u64 physical_address)
|
||||
{
|
||||
ACPI_FUNCTION_TRACE(acpi_set_firmware_waking_vector64);
|
||||
|
||||
|
||||
/* Determine if the 64-bit vector actually exists */
|
||||
|
||||
if ((acpi_gbl_FACS->length <= 32) || (acpi_gbl_FACS->version < 1)) {
|
||||
return_ACPI_STATUS(AE_NOT_EXIST);
|
||||
}
|
||||
|
||||
/* Clear 32-bit vector, set the 64-bit X_ vector */
|
||||
|
||||
acpi_gbl_FACS->firmware_waking_vector = 0;
|
||||
acpi_gbl_FACS->xfirmware_waking_vector = physical_address;
|
||||
|
||||
return_ACPI_STATUS(AE_OK);
|
||||
}
|
||||
|
||||
ACPI_EXPORT_SYMBOL(acpi_set_firmware_waking_vector64)
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_enter_sleep_state_prep
|
||||
* FUNCTION: acpi_hw_legacy_sleep
|
||||
*
|
||||
* PARAMETERS: sleep_state - Which sleep state to enter
|
||||
* Flags - ACPI_EXECUTE_GTS to run optional method
|
||||
*
|
||||
* RETURN: Status
|
||||
*
|
||||
* DESCRIPTION: Prepare to enter a system sleep state (see ACPI 2.0 spec p 231)
|
||||
* This function must execute with interrupts enabled.
|
||||
* We break sleeping into 2 stages so that OSPM can handle
|
||||
* various OS-specific tasks between the two steps.
|
||||
*
|
||||
******************************************************************************/
|
||||
acpi_status acpi_enter_sleep_state_prep(u8 sleep_state)
|
||||
{
|
||||
acpi_status status;
|
||||
struct acpi_object_list arg_list;
|
||||
union acpi_object arg;
|
||||
|
||||
ACPI_FUNCTION_TRACE(acpi_enter_sleep_state_prep);
|
||||
|
||||
/* _PSW methods could be run here to enable wake-on keyboard, LAN, etc. */
|
||||
|
||||
status = acpi_get_sleep_type_data(sleep_state,
|
||||
&acpi_gbl_sleep_type_a,
|
||||
&acpi_gbl_sleep_type_b);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
/* Setup parameter object */
|
||||
|
||||
arg_list.count = 1;
|
||||
arg_list.pointer = &arg;
|
||||
|
||||
arg.type = ACPI_TYPE_INTEGER;
|
||||
arg.integer.value = sleep_state;
|
||||
|
||||
/* Run the _PTS method */
|
||||
|
||||
status = acpi_evaluate_object(NULL, METHOD_NAME__PTS, &arg_list, NULL);
|
||||
if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
/* Setup the argument to _SST */
|
||||
|
||||
switch (sleep_state) {
|
||||
case ACPI_STATE_S0:
|
||||
arg.integer.value = ACPI_SST_WORKING;
|
||||
break;
|
||||
|
||||
case ACPI_STATE_S1:
|
||||
case ACPI_STATE_S2:
|
||||
case ACPI_STATE_S3:
|
||||
arg.integer.value = ACPI_SST_SLEEPING;
|
||||
break;
|
||||
|
||||
case ACPI_STATE_S4:
|
||||
arg.integer.value = ACPI_SST_SLEEP_CONTEXT;
|
||||
break;
|
||||
|
||||
default:
|
||||
arg.integer.value = ACPI_SST_INDICATOR_OFF; /* Default is off */
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the system indicators to show the desired sleep state.
|
||||
* _SST is an optional method (return no error if not found)
|
||||
*/
|
||||
status = acpi_evaluate_object(NULL, METHOD_NAME__SST, &arg_list, NULL);
|
||||
if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
|
||||
ACPI_EXCEPTION((AE_INFO, status,
|
||||
"While executing method _SST"));
|
||||
}
|
||||
|
||||
return_ACPI_STATUS(AE_OK);
|
||||
}
|
||||
|
||||
ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_prep)
|
||||
|
||||
static unsigned int gts, bfs;
|
||||
module_param(gts, uint, 0644);
|
||||
module_param(bfs, uint, 0644);
|
||||
MODULE_PARM_DESC(gts, "Enable evaluation of _GTS on suspend.");
|
||||
MODULE_PARM_DESC(bfs, "Enable evaluation of _BFS on resume".);
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_enter_sleep_state
|
||||
*
|
||||
* PARAMETERS: sleep_state - Which sleep state to enter
|
||||
*
|
||||
* RETURN: Status
|
||||
*
|
||||
* DESCRIPTION: Enter a system sleep state (see ACPI 2.0 spec p 231)
|
||||
* DESCRIPTION: Enter a system sleep state via the legacy FADT PM registers
|
||||
* THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED
|
||||
*
|
||||
******************************************************************************/
|
||||
acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
|
||||
acpi_status acpi_hw_legacy_sleep(u8 sleep_state, u8 flags)
|
||||
{
|
||||
u32 pm1a_control;
|
||||
u32 pm1b_control;
|
||||
struct acpi_bit_register_info *sleep_type_reg_info;
|
||||
struct acpi_bit_register_info *sleep_enable_reg_info;
|
||||
u32 pm1a_control;
|
||||
u32 pm1b_control;
|
||||
u32 in_value;
|
||||
struct acpi_object_list arg_list;
|
||||
union acpi_object arg;
|
||||
acpi_status status;
|
||||
|
||||
ACPI_FUNCTION_TRACE(acpi_enter_sleep_state);
|
||||
|
||||
if ((acpi_gbl_sleep_type_a > ACPI_SLEEP_TYPE_MAX) ||
|
||||
(acpi_gbl_sleep_type_b > ACPI_SLEEP_TYPE_MAX)) {
|
||||
ACPI_ERROR((AE_INFO, "Sleep values out of range: A=0x%X B=0x%X",
|
||||
acpi_gbl_sleep_type_a, acpi_gbl_sleep_type_b));
|
||||
return_ACPI_STATUS(AE_AML_OPERAND_VALUE);
|
||||
}
|
||||
ACPI_FUNCTION_TRACE(hw_legacy_sleep);
|
||||
|
||||
sleep_type_reg_info =
|
||||
acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_TYPE);
|
||||
|
|
@ -271,6 +95,18 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
|
|||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
if (sleep_state != ACPI_STATE_S5) {
|
||||
/*
|
||||
* Disable BM arbitration. This feature is contained within an
|
||||
* optional register (PM2 Control), so ignore a BAD_ADDRESS
|
||||
* exception.
|
||||
*/
|
||||
status = acpi_write_bit_register(ACPI_BITREG_ARB_DISABLE, 1);
|
||||
if (ACPI_FAILURE(status) && (status != AE_BAD_ADDRESS)) {
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 1) Disable/Clear all GPEs
|
||||
* 2) Enable all wakeup GPEs
|
||||
|
|
@ -286,18 +122,10 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
|
|||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
if (gts) {
|
||||
/* Execute the _GTS method */
|
||||
/* Optionally execute _GTS (Going To Sleep) */
|
||||
|
||||
arg_list.count = 1;
|
||||
arg_list.pointer = &arg;
|
||||
arg.type = ACPI_TYPE_INTEGER;
|
||||
arg.integer.value = sleep_state;
|
||||
|
||||
status = acpi_evaluate_object(NULL, METHOD_NAME__GTS, &arg_list, NULL);
|
||||
if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
if (flags & ACPI_EXECUTE_GTS) {
|
||||
acpi_hw_execute_sleep_method(METHOD_PATHNAME__GTS, sleep_state);
|
||||
}
|
||||
|
||||
/* Get current value of PM1A control */
|
||||
|
|
@ -344,8 +172,12 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
|
|||
|
||||
ACPI_FLUSH_CPU_CACHE();
|
||||
|
||||
tboot_sleep(sleep_state, pm1a_control, pm1b_control);
|
||||
|
||||
status = acpi_os_prepare_sleep(sleep_state, pm1a_control,
|
||||
pm1b_control);
|
||||
if (ACPI_SKIP(status))
|
||||
return_ACPI_STATUS(AE_OK);
|
||||
if (ACPI_FAILURE(status))
|
||||
return_ACPI_STATUS(status);
|
||||
/* Write #2: Write both SLP_TYP + SLP_EN */
|
||||
|
||||
status = acpi_hw_write_pm1_control(pm1a_control, pm1b_control);
|
||||
|
|
@ -375,114 +207,44 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
|
|||
}
|
||||
}
|
||||
|
||||
/* Wait until we enter sleep state */
|
||||
/* Wait for transition back to Working State */
|
||||
|
||||
do {
|
||||
status = acpi_read_bit_register(ACPI_BITREG_WAKE_STATUS,
|
||||
&in_value);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
/* Spin until we wake */
|
||||
|
||||
} while (!in_value);
|
||||
|
||||
return_ACPI_STATUS(AE_OK);
|
||||
}
|
||||
|
||||
ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state)
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_enter_sleep_state_s4bios
|
||||
*
|
||||
* PARAMETERS: None
|
||||
*
|
||||
* RETURN: Status
|
||||
*
|
||||
* DESCRIPTION: Perform a S4 bios request.
|
||||
* THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED
|
||||
*
|
||||
******************************************************************************/
|
||||
acpi_status asmlinkage acpi_enter_sleep_state_s4bios(void)
|
||||
{
|
||||
u32 in_value;
|
||||
acpi_status status;
|
||||
|
||||
ACPI_FUNCTION_TRACE(acpi_enter_sleep_state_s4bios);
|
||||
|
||||
/* Clear the wake status bit (PM1) */
|
||||
|
||||
status =
|
||||
acpi_write_bit_register(ACPI_BITREG_WAKE_STATUS, ACPI_CLEAR_STATUS);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
status = acpi_hw_clear_acpi_status();
|
||||
if (ACPI_FAILURE(status)) {
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
/*
|
||||
* 1) Disable/Clear all GPEs
|
||||
* 2) Enable all wakeup GPEs
|
||||
*/
|
||||
status = acpi_hw_disable_all_gpes();
|
||||
if (ACPI_FAILURE(status)) {
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
acpi_gbl_system_awake_and_running = FALSE;
|
||||
|
||||
status = acpi_hw_enable_all_wakeup_gpes();
|
||||
if (ACPI_FAILURE(status)) {
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
ACPI_FLUSH_CPU_CACHE();
|
||||
|
||||
status = acpi_hw_write_port(acpi_gbl_FADT.smi_command,
|
||||
(u32) acpi_gbl_FADT.S4bios_request, 8);
|
||||
|
||||
do {
|
||||
acpi_os_stall(1000);
|
||||
status =
|
||||
acpi_read_bit_register(ACPI_BITREG_WAKE_STATUS, &in_value);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
} while (!in_value);
|
||||
|
||||
return_ACPI_STATUS(AE_OK);
|
||||
}
|
||||
|
||||
ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_s4bios)
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_leave_sleep_state_prep
|
||||
* FUNCTION: acpi_hw_legacy_wake_prep
|
||||
*
|
||||
* PARAMETERS: sleep_state - Which sleep state we are exiting
|
||||
* PARAMETERS: sleep_state - Which sleep state we just exited
|
||||
* Flags - ACPI_EXECUTE_BFS to run optional method
|
||||
*
|
||||
* RETURN: Status
|
||||
*
|
||||
* DESCRIPTION: Perform the first state of OS-independent ACPI cleanup after a
|
||||
* sleep.
|
||||
* Called with interrupts DISABLED.
|
||||
* Called with interrupts ENABLED.
|
||||
*
|
||||
******************************************************************************/
|
||||
acpi_status acpi_leave_sleep_state_prep(u8 sleep_state)
|
||||
|
||||
acpi_status acpi_hw_legacy_wake_prep(u8 sleep_state, u8 flags)
|
||||
{
|
||||
struct acpi_object_list arg_list;
|
||||
union acpi_object arg;
|
||||
acpi_status status;
|
||||
struct acpi_bit_register_info *sleep_type_reg_info;
|
||||
struct acpi_bit_register_info *sleep_enable_reg_info;
|
||||
u32 pm1a_control;
|
||||
u32 pm1b_control;
|
||||
|
||||
ACPI_FUNCTION_TRACE(acpi_leave_sleep_state_prep);
|
||||
ACPI_FUNCTION_TRACE(hw_legacy_wake_prep);
|
||||
|
||||
/*
|
||||
* Set SLP_TYPE and SLP_EN to state S0.
|
||||
|
|
@ -525,27 +287,20 @@ acpi_status acpi_leave_sleep_state_prep(u8 sleep_state)
|
|||
}
|
||||
}
|
||||
|
||||
if (bfs) {
|
||||
/* Execute the _BFS method */
|
||||
/* Optionally execute _BFS (Back From Sleep) */
|
||||
|
||||
arg_list.count = 1;
|
||||
arg_list.pointer = &arg;
|
||||
arg.type = ACPI_TYPE_INTEGER;
|
||||
arg.integer.value = sleep_state;
|
||||
|
||||
status = acpi_evaluate_object(NULL, METHOD_NAME__BFS, &arg_list, NULL);
|
||||
if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
|
||||
ACPI_EXCEPTION((AE_INFO, status, "During Method _BFS"));
|
||||
}
|
||||
if (flags & ACPI_EXECUTE_BFS) {
|
||||
acpi_hw_execute_sleep_method(METHOD_PATHNAME__BFS, sleep_state);
|
||||
}
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_leave_sleep_state
|
||||
* FUNCTION: acpi_hw_legacy_wake
|
||||
*
|
||||
* PARAMETERS: sleep_state - Which sleep state we just exited
|
||||
* Flags - Reserved, set to zero
|
||||
*
|
||||
* RETURN: Status
|
||||
*
|
||||
|
|
@ -553,31 +308,17 @@ acpi_status acpi_leave_sleep_state_prep(u8 sleep_state)
|
|||
* Called with interrupts ENABLED.
|
||||
*
|
||||
******************************************************************************/
|
||||
acpi_status acpi_leave_sleep_state(u8 sleep_state)
|
||||
|
||||
acpi_status acpi_hw_legacy_wake(u8 sleep_state, u8 flags)
|
||||
{
|
||||
struct acpi_object_list arg_list;
|
||||
union acpi_object arg;
|
||||
acpi_status status;
|
||||
|
||||
ACPI_FUNCTION_TRACE(acpi_leave_sleep_state);
|
||||
ACPI_FUNCTION_TRACE(hw_legacy_wake);
|
||||
|
||||
/* Ensure enter_sleep_state_prep -> enter_sleep_state ordering */
|
||||
|
||||
acpi_gbl_sleep_type_a = ACPI_SLEEP_TYPE_INVALID;
|
||||
|
||||
/* Setup parameter object */
|
||||
|
||||
arg_list.count = 1;
|
||||
arg_list.pointer = &arg;
|
||||
arg.type = ACPI_TYPE_INTEGER;
|
||||
|
||||
/* Ignore any errors from these methods */
|
||||
|
||||
arg.integer.value = ACPI_SST_WAKING;
|
||||
status = acpi_evaluate_object(NULL, METHOD_NAME__SST, &arg_list, NULL);
|
||||
if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
|
||||
ACPI_EXCEPTION((AE_INFO, status, "During Method _SST"));
|
||||
}
|
||||
acpi_hw_execute_sleep_method(METHOD_PATHNAME__SST, ACPI_SST_WAKING);
|
||||
|
||||
/*
|
||||
* GPEs must be enabled before _WAK is called as GPEs
|
||||
|
|
@ -591,46 +332,50 @@ acpi_status acpi_leave_sleep_state(u8 sleep_state)
|
|||
if (ACPI_FAILURE(status)) {
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
status = acpi_hw_enable_all_runtime_gpes();
|
||||
if (ACPI_FAILURE(status)) {
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
arg.integer.value = sleep_state;
|
||||
status = acpi_evaluate_object(NULL, METHOD_NAME__WAK, &arg_list, NULL);
|
||||
if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
|
||||
ACPI_EXCEPTION((AE_INFO, status, "During Method _WAK"));
|
||||
}
|
||||
/* TBD: _WAK "sometimes" returns stuff - do we want to look at it? */
|
||||
/*
|
||||
* Now we can execute _WAK, etc. Some machines require that the GPEs
|
||||
* are enabled before the wake methods are executed.
|
||||
*/
|
||||
acpi_hw_execute_sleep_method(METHOD_PATHNAME__WAK, sleep_state);
|
||||
|
||||
/*
|
||||
* Some BIOSes assume that WAK_STS will be cleared on resume and use
|
||||
* it to determine whether the system is rebooting or resuming. Clear
|
||||
* it for compatibility.
|
||||
* Some BIOS code assumes that WAK_STS will be cleared on resume
|
||||
* and use it to determine whether the system is rebooting or
|
||||
* resuming. Clear WAK_STS for compatibility.
|
||||
*/
|
||||
acpi_write_bit_register(ACPI_BITREG_WAKE_STATUS, 1);
|
||||
|
||||
acpi_gbl_system_awake_and_running = TRUE;
|
||||
|
||||
/* Enable power button */
|
||||
|
||||
(void)
|
||||
acpi_write_bit_register(acpi_gbl_fixed_event_info
|
||||
[ACPI_EVENT_POWER_BUTTON].
|
||||
enable_register_id, ACPI_ENABLE_EVENT);
|
||||
[ACPI_EVENT_POWER_BUTTON].
|
||||
enable_register_id, ACPI_ENABLE_EVENT);
|
||||
|
||||
(void)
|
||||
acpi_write_bit_register(acpi_gbl_fixed_event_info
|
||||
[ACPI_EVENT_POWER_BUTTON].
|
||||
status_register_id, ACPI_CLEAR_STATUS);
|
||||
[ACPI_EVENT_POWER_BUTTON].
|
||||
status_register_id, ACPI_CLEAR_STATUS);
|
||||
|
||||
arg.integer.value = ACPI_SST_WORKING;
|
||||
status = acpi_evaluate_object(NULL, METHOD_NAME__SST, &arg_list, NULL);
|
||||
if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
|
||||
ACPI_EXCEPTION((AE_INFO, status, "During Method _SST"));
|
||||
/*
|
||||
* Enable BM arbitration. This feature is contained within an
|
||||
* optional register (PM2 Control), so ignore a BAD_ADDRESS
|
||||
* exception.
|
||||
*/
|
||||
status = acpi_write_bit_register(ACPI_BITREG_ARB_DISABLE, 0);
|
||||
if (ACPI_FAILURE(status) && (status != AE_BAD_ADDRESS)) {
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
acpi_hw_execute_sleep_method(METHOD_PATHNAME__SST, ACPI_SST_WORKING);
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
ACPI_EXPORT_SYMBOL(acpi_leave_sleep_state)
|
||||
#endif /* !ACPI_REDUCED_HARDWARE */
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@
|
|||
#define _COMPONENT ACPI_HARDWARE
|
||||
ACPI_MODULE_NAME("hwtimer")
|
||||
|
||||
#if (!ACPI_REDUCED_HARDWARE) /* Entire module */
|
||||
/******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_get_timer_resolution
|
||||
|
|
@ -187,3 +188,4 @@ acpi_get_timer_duration(u32 start_ticks, u32 end_ticks, u32 * time_elapsed)
|
|||
}
|
||||
|
||||
ACPI_EXPORT_SYMBOL(acpi_get_timer_duration)
|
||||
#endif /* !ACPI_REDUCED_HARDWARE */
|
||||
|
|
|
|||
|
|
@ -74,8 +74,7 @@ acpi_status acpi_reset(void)
|
|||
|
||||
/* Check if the reset register is supported */
|
||||
|
||||
if (!(acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER) ||
|
||||
!reset_reg->address) {
|
||||
if (!reset_reg->address) {
|
||||
return_ACPI_STATUS(AE_NOT_EXIST);
|
||||
}
|
||||
|
||||
|
|
@ -138,11 +137,6 @@ acpi_status acpi_read(u64 *return_value, struct acpi_generic_address *reg)
|
|||
return (status);
|
||||
}
|
||||
|
||||
width = reg->bit_width;
|
||||
if (width == 64) {
|
||||
width = 32; /* Break into two 32-bit transfers */
|
||||
}
|
||||
|
||||
/* Initialize entire 64-bit return value to zero */
|
||||
|
||||
*return_value = 0;
|
||||
|
|
@ -154,25 +148,18 @@ acpi_status acpi_read(u64 *return_value, struct acpi_generic_address *reg)
|
|||
*/
|
||||
if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
|
||||
status = acpi_os_read_memory((acpi_physical_address)
|
||||
address, &value, width);
|
||||
address, return_value,
|
||||
reg->bit_width);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
return (status);
|
||||
}
|
||||
*return_value = value;
|
||||
|
||||
if (reg->bit_width == 64) {
|
||||
|
||||
/* Read the top 32 bits */
|
||||
|
||||
status = acpi_os_read_memory((acpi_physical_address)
|
||||
(address + 4), &value, 32);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
return (status);
|
||||
}
|
||||
*return_value |= ((u64)value << 32);
|
||||
}
|
||||
} else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */
|
||||
|
||||
width = reg->bit_width;
|
||||
if (width == 64) {
|
||||
width = 32; /* Break into two 32-bit transfers */
|
||||
}
|
||||
|
||||
status = acpi_hw_read_port((acpi_io_address)
|
||||
address, &value, width);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
|
|
@ -231,33 +218,23 @@ acpi_status acpi_write(u64 value, struct acpi_generic_address *reg)
|
|||
return (status);
|
||||
}
|
||||
|
||||
width = reg->bit_width;
|
||||
if (width == 64) {
|
||||
width = 32; /* Break into two 32-bit transfers */
|
||||
}
|
||||
|
||||
/*
|
||||
* Two address spaces supported: Memory or IO. PCI_Config is
|
||||
* not supported here because the GAS structure is insufficient
|
||||
*/
|
||||
if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
|
||||
status = acpi_os_write_memory((acpi_physical_address)
|
||||
address, ACPI_LODWORD(value),
|
||||
width);
|
||||
address, value, reg->bit_width);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
return (status);
|
||||
}
|
||||
|
||||
if (reg->bit_width == 64) {
|
||||
status = acpi_os_write_memory((acpi_physical_address)
|
||||
(address + 4),
|
||||
ACPI_HIDWORD(value), 32);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
return (status);
|
||||
}
|
||||
}
|
||||
} else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */
|
||||
|
||||
width = reg->bit_width;
|
||||
if (width == 64) {
|
||||
width = 32; /* Break into two 32-bit transfers */
|
||||
}
|
||||
|
||||
status = acpi_hw_write_port((acpi_io_address)
|
||||
address, ACPI_LODWORD(value),
|
||||
width);
|
||||
|
|
@ -286,6 +263,7 @@ acpi_status acpi_write(u64 value, struct acpi_generic_address *reg)
|
|||
|
||||
ACPI_EXPORT_SYMBOL(acpi_write)
|
||||
|
||||
#if (!ACPI_REDUCED_HARDWARE)
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_read_bit_register
|
||||
|
|
@ -453,7 +431,7 @@ unlock_and_exit:
|
|||
}
|
||||
|
||||
ACPI_EXPORT_SYMBOL(acpi_write_bit_register)
|
||||
|
||||
#endif /* !ACPI_REDUCED_HARDWARE */
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_get_sleep_type_data
|
||||
|
|
|
|||
431
drivers/acpi/acpica/hwxfsleep.c
Normal file
431
drivers/acpi/acpica/hwxfsleep.c
Normal file
|
|
@ -0,0 +1,431 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Name: hwxfsleep.c - ACPI Hardware Sleep/Wake External Interfaces
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2000 - 2012, Intel Corp.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions, and the following disclaimer,
|
||||
* without modification.
|
||||
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
|
||||
* substantially similar to the "NO WARRANTY" disclaimer below
|
||||
* ("Disclaimer") and any redistribution must be conditioned upon
|
||||
* including a substantially similar Disclaimer requirement for further
|
||||
* binary redistribution.
|
||||
* 3. Neither the names of the above-listed copyright holders nor the names
|
||||
* of any contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* Alternatively, this software may be distributed under the terms of the
|
||||
* GNU General Public License ("GPL") version 2 as published by the Free
|
||||
* Software Foundation.
|
||||
*
|
||||
* NO WARRANTY
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGES.
|
||||
*/
|
||||
|
||||
#include <acpi/acpi.h>
|
||||
#include "accommon.h"
|
||||
#include <linux/module.h>
|
||||
|
||||
#define _COMPONENT ACPI_HARDWARE
|
||||
ACPI_MODULE_NAME("hwxfsleep")
|
||||
|
||||
/* Local prototypes */
|
||||
static acpi_status
|
||||
acpi_hw_sleep_dispatch(u8 sleep_state, u8 flags, u32 function_id);
|
||||
|
||||
/*
|
||||
* Dispatch table used to efficiently branch to the various sleep
|
||||
* functions.
|
||||
*/
|
||||
#define ACPI_SLEEP_FUNCTION_ID 0
|
||||
#define ACPI_WAKE_PREP_FUNCTION_ID 1
|
||||
#define ACPI_WAKE_FUNCTION_ID 2
|
||||
|
||||
/* Legacy functions are optional, based upon ACPI_REDUCED_HARDWARE */
|
||||
|
||||
static struct acpi_sleep_functions acpi_sleep_dispatch[] = {
|
||||
{ACPI_HW_OPTIONAL_FUNCTION(acpi_hw_legacy_sleep),
|
||||
acpi_hw_extended_sleep},
|
||||
{ACPI_HW_OPTIONAL_FUNCTION(acpi_hw_legacy_wake_prep),
|
||||
acpi_hw_extended_wake_prep},
|
||||
{ACPI_HW_OPTIONAL_FUNCTION(acpi_hw_legacy_wake), acpi_hw_extended_wake}
|
||||
};
|
||||
|
||||
/*
|
||||
* These functions are removed for the ACPI_REDUCED_HARDWARE case:
|
||||
* acpi_set_firmware_waking_vector
|
||||
* acpi_set_firmware_waking_vector64
|
||||
* acpi_enter_sleep_state_s4bios
|
||||
*/
|
||||
|
||||
#if (!ACPI_REDUCED_HARDWARE)
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_set_firmware_waking_vector
|
||||
*
|
||||
* PARAMETERS: physical_address - 32-bit physical address of ACPI real mode
|
||||
* entry point.
|
||||
*
|
||||
* RETURN: Status
|
||||
*
|
||||
* DESCRIPTION: Sets the 32-bit firmware_waking_vector field of the FACS
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
acpi_status acpi_set_firmware_waking_vector(u32 physical_address)
|
||||
{
|
||||
ACPI_FUNCTION_TRACE(acpi_set_firmware_waking_vector);
|
||||
|
||||
|
||||
/*
|
||||
* According to the ACPI specification 2.0c and later, the 64-bit
|
||||
* waking vector should be cleared and the 32-bit waking vector should
|
||||
* be used, unless we want the wake-up code to be called by the BIOS in
|
||||
* Protected Mode. Some systems (for example HP dv5-1004nr) are known
|
||||
* to fail to resume if the 64-bit vector is used.
|
||||
*/
|
||||
|
||||
/* Set the 32-bit vector */
|
||||
|
||||
acpi_gbl_FACS->firmware_waking_vector = physical_address;
|
||||
|
||||
/* Clear the 64-bit vector if it exists */
|
||||
|
||||
if ((acpi_gbl_FACS->length > 32) && (acpi_gbl_FACS->version >= 1)) {
|
||||
acpi_gbl_FACS->xfirmware_waking_vector = 0;
|
||||
}
|
||||
|
||||
return_ACPI_STATUS(AE_OK);
|
||||
}
|
||||
|
||||
ACPI_EXPORT_SYMBOL(acpi_set_firmware_waking_vector)
|
||||
|
||||
#if ACPI_MACHINE_WIDTH == 64
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_set_firmware_waking_vector64
|
||||
*
|
||||
* PARAMETERS: physical_address - 64-bit physical address of ACPI protected
|
||||
* mode entry point.
|
||||
*
|
||||
* RETURN: Status
|
||||
*
|
||||
* DESCRIPTION: Sets the 64-bit X_firmware_waking_vector field of the FACS, if
|
||||
* it exists in the table. This function is intended for use with
|
||||
* 64-bit host operating systems.
|
||||
*
|
||||
******************************************************************************/
|
||||
acpi_status acpi_set_firmware_waking_vector64(u64 physical_address)
|
||||
{
|
||||
ACPI_FUNCTION_TRACE(acpi_set_firmware_waking_vector64);
|
||||
|
||||
|
||||
/* Determine if the 64-bit vector actually exists */
|
||||
|
||||
if ((acpi_gbl_FACS->length <= 32) || (acpi_gbl_FACS->version < 1)) {
|
||||
return_ACPI_STATUS(AE_NOT_EXIST);
|
||||
}
|
||||
|
||||
/* Clear 32-bit vector, set the 64-bit X_ vector */
|
||||
|
||||
acpi_gbl_FACS->firmware_waking_vector = 0;
|
||||
acpi_gbl_FACS->xfirmware_waking_vector = physical_address;
|
||||
return_ACPI_STATUS(AE_OK);
|
||||
}
|
||||
|
||||
ACPI_EXPORT_SYMBOL(acpi_set_firmware_waking_vector64)
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_enter_sleep_state_s4bios
|
||||
*
|
||||
* PARAMETERS: None
|
||||
*
|
||||
* RETURN: Status
|
||||
*
|
||||
* DESCRIPTION: Perform a S4 bios request.
|
||||
* THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED
|
||||
*
|
||||
******************************************************************************/
|
||||
acpi_status asmlinkage acpi_enter_sleep_state_s4bios(void)
|
||||
{
|
||||
u32 in_value;
|
||||
acpi_status status;
|
||||
|
||||
ACPI_FUNCTION_TRACE(acpi_enter_sleep_state_s4bios);
|
||||
|
||||
/* Clear the wake status bit (PM1) */
|
||||
|
||||
status =
|
||||
acpi_write_bit_register(ACPI_BITREG_WAKE_STATUS, ACPI_CLEAR_STATUS);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
status = acpi_hw_clear_acpi_status();
|
||||
if (ACPI_FAILURE(status)) {
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
/*
|
||||
* 1) Disable/Clear all GPEs
|
||||
* 2) Enable all wakeup GPEs
|
||||
*/
|
||||
status = acpi_hw_disable_all_gpes();
|
||||
if (ACPI_FAILURE(status)) {
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
acpi_gbl_system_awake_and_running = FALSE;
|
||||
|
||||
status = acpi_hw_enable_all_wakeup_gpes();
|
||||
if (ACPI_FAILURE(status)) {
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
ACPI_FLUSH_CPU_CACHE();
|
||||
|
||||
status = acpi_hw_write_port(acpi_gbl_FADT.smi_command,
|
||||
(u32)acpi_gbl_FADT.S4bios_request, 8);
|
||||
|
||||
do {
|
||||
acpi_os_stall(1000);
|
||||
status =
|
||||
acpi_read_bit_register(ACPI_BITREG_WAKE_STATUS, &in_value);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
} while (!in_value);
|
||||
|
||||
return_ACPI_STATUS(AE_OK);
|
||||
}
|
||||
|
||||
ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_s4bios)
|
||||
#endif /* !ACPI_REDUCED_HARDWARE */
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_hw_sleep_dispatch
|
||||
*
|
||||
* PARAMETERS: sleep_state - Which sleep state to enter/exit
|
||||
* function_id - Sleep, wake_prep, or Wake
|
||||
*
|
||||
* RETURN: Status from the invoked sleep handling function.
|
||||
*
|
||||
* DESCRIPTION: Dispatch a sleep/wake request to the appropriate handling
|
||||
* function.
|
||||
*
|
||||
******************************************************************************/
|
||||
static acpi_status
|
||||
acpi_hw_sleep_dispatch(u8 sleep_state, u8 flags, u32 function_id)
|
||||
{
|
||||
acpi_status status;
|
||||
struct acpi_sleep_functions *sleep_functions =
|
||||
&acpi_sleep_dispatch[function_id];
|
||||
|
||||
#if (!ACPI_REDUCED_HARDWARE)
|
||||
|
||||
/*
|
||||
* If the Hardware Reduced flag is set (from the FADT), we must
|
||||
* use the extended sleep registers
|
||||
*/
|
||||
if (acpi_gbl_reduced_hardware || acpi_gbl_FADT.sleep_control.address) {
|
||||
status = sleep_functions->extended_function(sleep_state, flags);
|
||||
} else {
|
||||
/* Legacy sleep */
|
||||
|
||||
status = sleep_functions->legacy_function(sleep_state, flags);
|
||||
}
|
||||
|
||||
return (status);
|
||||
|
||||
#else
|
||||
/*
|
||||
* For the case where reduced-hardware-only code is being generated,
|
||||
* we know that only the extended sleep registers are available
|
||||
*/
|
||||
status = sleep_functions->extended_function(sleep_state, flags);
|
||||
return (status);
|
||||
|
||||
#endif /* !ACPI_REDUCED_HARDWARE */
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_enter_sleep_state_prep
|
||||
*
|
||||
* PARAMETERS: sleep_state - Which sleep state to enter
|
||||
*
|
||||
* RETURN: Status
|
||||
*
|
||||
* DESCRIPTION: Prepare to enter a system sleep state.
|
||||
* This function must execute with interrupts enabled.
|
||||
* We break sleeping into 2 stages so that OSPM can handle
|
||||
* various OS-specific tasks between the two steps.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
acpi_status acpi_enter_sleep_state_prep(u8 sleep_state)
|
||||
{
|
||||
acpi_status status;
|
||||
struct acpi_object_list arg_list;
|
||||
union acpi_object arg;
|
||||
u32 sst_value;
|
||||
|
||||
ACPI_FUNCTION_TRACE(acpi_enter_sleep_state_prep);
|
||||
|
||||
status = acpi_get_sleep_type_data(sleep_state,
|
||||
&acpi_gbl_sleep_type_a,
|
||||
&acpi_gbl_sleep_type_b);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
/* Execute the _PTS method (Prepare To Sleep) */
|
||||
|
||||
arg_list.count = 1;
|
||||
arg_list.pointer = &arg;
|
||||
arg.type = ACPI_TYPE_INTEGER;
|
||||
arg.integer.value = sleep_state;
|
||||
|
||||
status =
|
||||
acpi_evaluate_object(NULL, METHOD_PATHNAME__PTS, &arg_list, NULL);
|
||||
if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
/* Setup the argument to the _SST method (System STatus) */
|
||||
|
||||
switch (sleep_state) {
|
||||
case ACPI_STATE_S0:
|
||||
sst_value = ACPI_SST_WORKING;
|
||||
break;
|
||||
|
||||
case ACPI_STATE_S1:
|
||||
case ACPI_STATE_S2:
|
||||
case ACPI_STATE_S3:
|
||||
sst_value = ACPI_SST_SLEEPING;
|
||||
break;
|
||||
|
||||
case ACPI_STATE_S4:
|
||||
sst_value = ACPI_SST_SLEEP_CONTEXT;
|
||||
break;
|
||||
|
||||
default:
|
||||
sst_value = ACPI_SST_INDICATOR_OFF; /* Default is off */
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the system indicators to show the desired sleep state.
|
||||
* _SST is an optional method (return no error if not found)
|
||||
*/
|
||||
acpi_hw_execute_sleep_method(METHOD_PATHNAME__SST, sst_value);
|
||||
return_ACPI_STATUS(AE_OK);
|
||||
}
|
||||
|
||||
ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_prep)
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_enter_sleep_state
|
||||
*
|
||||
* PARAMETERS: sleep_state - Which sleep state to enter
|
||||
* Flags - ACPI_EXECUTE_GTS to run optional method
|
||||
*
|
||||
* RETURN: Status
|
||||
*
|
||||
* DESCRIPTION: Enter a system sleep state (see ACPI 2.0 spec p 231)
|
||||
* THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED
|
||||
*
|
||||
******************************************************************************/
|
||||
acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state, u8 flags)
|
||||
{
|
||||
acpi_status status;
|
||||
|
||||
ACPI_FUNCTION_TRACE(acpi_enter_sleep_state);
|
||||
|
||||
if ((acpi_gbl_sleep_type_a > ACPI_SLEEP_TYPE_MAX) ||
|
||||
(acpi_gbl_sleep_type_b > ACPI_SLEEP_TYPE_MAX)) {
|
||||
ACPI_ERROR((AE_INFO, "Sleep values out of range: A=0x%X B=0x%X",
|
||||
acpi_gbl_sleep_type_a, acpi_gbl_sleep_type_b));
|
||||
return_ACPI_STATUS(AE_AML_OPERAND_VALUE);
|
||||
}
|
||||
|
||||
status =
|
||||
acpi_hw_sleep_dispatch(sleep_state, flags, ACPI_SLEEP_FUNCTION_ID);
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state)
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_leave_sleep_state_prep
|
||||
*
|
||||
* PARAMETERS: sleep_state - Which sleep state we are exiting
|
||||
* Flags - ACPI_EXECUTE_BFS to run optional method
|
||||
*
|
||||
* RETURN: Status
|
||||
*
|
||||
* DESCRIPTION: Perform the first state of OS-independent ACPI cleanup after a
|
||||
* sleep.
|
||||
* Called with interrupts DISABLED.
|
||||
*
|
||||
******************************************************************************/
|
||||
acpi_status acpi_leave_sleep_state_prep(u8 sleep_state, u8 flags)
|
||||
{
|
||||
acpi_status status;
|
||||
|
||||
ACPI_FUNCTION_TRACE(acpi_leave_sleep_state_prep);
|
||||
|
||||
status =
|
||||
acpi_hw_sleep_dispatch(sleep_state, flags,
|
||||
ACPI_WAKE_PREP_FUNCTION_ID);
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
ACPI_EXPORT_SYMBOL(acpi_leave_sleep_state_prep)
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_leave_sleep_state
|
||||
*
|
||||
* PARAMETERS: sleep_state - Which sleep state we are exiting
|
||||
*
|
||||
* RETURN: Status
|
||||
*
|
||||
* DESCRIPTION: Perform OS-independent ACPI cleanup after a sleep
|
||||
* Called with interrupts ENABLED.
|
||||
*
|
||||
******************************************************************************/
|
||||
acpi_status acpi_leave_sleep_state(u8 sleep_state)
|
||||
{
|
||||
acpi_status status;
|
||||
|
||||
ACPI_FUNCTION_TRACE(acpi_leave_sleep_state);
|
||||
|
||||
|
||||
status = acpi_hw_sleep_dispatch(sleep_state, 0, ACPI_WAKE_FUNCTION_ID);
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
ACPI_EXPORT_SYMBOL(acpi_leave_sleep_state)
|
||||
|
|
@ -242,7 +242,20 @@ acpi_ns_dump_one_object(acpi_handle obj_handle,
|
|||
|
||||
if (!obj_desc) {
|
||||
|
||||
/* No attached object, we are done */
|
||||
/* No attached object. Some types should always have an object */
|
||||
|
||||
switch (type) {
|
||||
case ACPI_TYPE_INTEGER:
|
||||
case ACPI_TYPE_PACKAGE:
|
||||
case ACPI_TYPE_BUFFER:
|
||||
case ACPI_TYPE_STRING:
|
||||
case ACPI_TYPE_METHOD:
|
||||
acpi_os_printf("<No attached object>");
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
acpi_os_printf("\n");
|
||||
return (AE_OK);
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@ void acpi_ns_dump_root_devices(void)
|
|||
return;
|
||||
}
|
||||
|
||||
status = acpi_get_handle(NULL, ACPI_NS_SYSTEM_BUS, &sys_bus_handle);
|
||||
status = acpi_get_handle(NULL, METHOD_NAME__SB_, &sys_bus_handle);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -638,8 +638,8 @@ acpi_ns_check_package(struct acpi_predefined_data *data,
|
|||
/* Create the new outer package and populate it */
|
||||
|
||||
status =
|
||||
acpi_ns_repair_package_list(data,
|
||||
return_object_ptr);
|
||||
acpi_ns_wrap_with_package(data, *elements,
|
||||
return_object_ptr);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
return (status);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -71,11 +71,10 @@ ACPI_MODULE_NAME("nsrepair")
|
|||
* Buffer -> String
|
||||
* Buffer -> Package of Integers
|
||||
* Package -> Package of one Package
|
||||
* An incorrect standalone object is wrapped with required outer package
|
||||
*
|
||||
* Additional possible repairs:
|
||||
*
|
||||
* Required package elements that are NULL replaced by Integer/String/Buffer
|
||||
* Incorrect standalone package wrapped with required outer package
|
||||
*
|
||||
******************************************************************************/
|
||||
/* Local prototypes */
|
||||
|
|
@ -91,10 +90,6 @@ static acpi_status
|
|||
acpi_ns_convert_to_buffer(union acpi_operand_object *original_object,
|
||||
union acpi_operand_object **return_object);
|
||||
|
||||
static acpi_status
|
||||
acpi_ns_convert_to_package(union acpi_operand_object *original_object,
|
||||
union acpi_operand_object **return_object);
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_ns_repair_object
|
||||
|
|
@ -151,9 +146,24 @@ acpi_ns_repair_object(struct acpi_predefined_data *data,
|
|||
}
|
||||
}
|
||||
if (expected_btypes & ACPI_RTYPE_PACKAGE) {
|
||||
status = acpi_ns_convert_to_package(return_object, &new_object);
|
||||
/*
|
||||
* A package is expected. We will wrap the existing object with a
|
||||
* new package object. It is often the case that if a variable-length
|
||||
* package is required, but there is only a single object needed, the
|
||||
* BIOS will return that object instead of wrapping it with a Package
|
||||
* object. Note: after the wrapping, the package will be validated
|
||||
* for correct contents (expected object type or types).
|
||||
*/
|
||||
status =
|
||||
acpi_ns_wrap_with_package(data, return_object, &new_object);
|
||||
if (ACPI_SUCCESS(status)) {
|
||||
goto object_repaired;
|
||||
/*
|
||||
* The original object just had its reference count
|
||||
* incremented for being inserted into the new package.
|
||||
*/
|
||||
*return_object_ptr = new_object; /* New Package object */
|
||||
data->flags |= ACPI_OBJECT_REPAIRED;
|
||||
return (AE_OK);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -165,22 +175,27 @@ acpi_ns_repair_object(struct acpi_predefined_data *data,
|
|||
|
||||
/* Object was successfully repaired */
|
||||
|
||||
/*
|
||||
* If the original object is a package element, we need to:
|
||||
* 1. Set the reference count of the new object to match the
|
||||
* reference count of the old object.
|
||||
* 2. Decrement the reference count of the original object.
|
||||
*/
|
||||
if (package_index != ACPI_NOT_PACKAGE_ELEMENT) {
|
||||
new_object->common.reference_count =
|
||||
return_object->common.reference_count;
|
||||
/*
|
||||
* The original object is a package element. We need to
|
||||
* decrement the reference count of the original object,
|
||||
* for removing it from the package.
|
||||
*
|
||||
* However, if the original object was just wrapped with a
|
||||
* package object as part of the repair, we don't need to
|
||||
* change the reference count.
|
||||
*/
|
||||
if (!(data->flags & ACPI_OBJECT_WRAPPED)) {
|
||||
new_object->common.reference_count =
|
||||
return_object->common.reference_count;
|
||||
|
||||
if (return_object->common.reference_count > 1) {
|
||||
return_object->common.reference_count--;
|
||||
if (return_object->common.reference_count > 1) {
|
||||
return_object->common.reference_count--;
|
||||
}
|
||||
}
|
||||
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
|
||||
"%s: Converted %s to expected %s at index %u\n",
|
||||
"%s: Converted %s to expected %s at Package index %u\n",
|
||||
data->pathname,
|
||||
acpi_ut_get_object_type_name(return_object),
|
||||
acpi_ut_get_object_type_name(new_object),
|
||||
|
|
@ -451,65 +466,6 @@ acpi_ns_convert_to_buffer(union acpi_operand_object *original_object,
|
|||
return (AE_OK);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_ns_convert_to_package
|
||||
*
|
||||
* PARAMETERS: original_object - Object to be converted
|
||||
* return_object - Where the new converted object is returned
|
||||
*
|
||||
* RETURN: Status. AE_OK if conversion was successful.
|
||||
*
|
||||
* DESCRIPTION: Attempt to convert a Buffer object to a Package. Each byte of
|
||||
* the buffer is converted to a single integer package element.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
static acpi_status
|
||||
acpi_ns_convert_to_package(union acpi_operand_object *original_object,
|
||||
union acpi_operand_object **return_object)
|
||||
{
|
||||
union acpi_operand_object *new_object;
|
||||
union acpi_operand_object **elements;
|
||||
u32 length;
|
||||
u8 *buffer;
|
||||
|
||||
switch (original_object->common.type) {
|
||||
case ACPI_TYPE_BUFFER:
|
||||
|
||||
/* Buffer-to-Package conversion */
|
||||
|
||||
length = original_object->buffer.length;
|
||||
new_object = acpi_ut_create_package_object(length);
|
||||
if (!new_object) {
|
||||
return (AE_NO_MEMORY);
|
||||
}
|
||||
|
||||
/* Convert each buffer byte to an integer package element */
|
||||
|
||||
elements = new_object->package.elements;
|
||||
buffer = original_object->buffer.pointer;
|
||||
|
||||
while (length--) {
|
||||
*elements =
|
||||
acpi_ut_create_integer_object((u64) *buffer);
|
||||
if (!*elements) {
|
||||
acpi_ut_remove_reference(new_object);
|
||||
return (AE_NO_MEMORY);
|
||||
}
|
||||
elements++;
|
||||
buffer++;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return (AE_AML_OPERAND_TYPE);
|
||||
}
|
||||
|
||||
*return_object = new_object;
|
||||
return (AE_OK);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_ns_repair_null_element
|
||||
|
|
@ -677,55 +633,56 @@ acpi_ns_remove_null_elements(struct acpi_predefined_data *data,
|
|||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_ns_repair_package_list
|
||||
* FUNCTION: acpi_ns_wrap_with_package
|
||||
*
|
||||
* PARAMETERS: Data - Pointer to validation data structure
|
||||
* obj_desc_ptr - Pointer to the object to repair. The new
|
||||
* package object is returned here,
|
||||
* overwriting the old object.
|
||||
* original_object - Pointer to the object to repair.
|
||||
* obj_desc_ptr - The new package object is returned here
|
||||
*
|
||||
* RETURN: Status, new object in *obj_desc_ptr
|
||||
*
|
||||
* DESCRIPTION: Repair a common problem with objects that are defined to return
|
||||
* a variable-length Package of Packages. If the variable-length
|
||||
* is one, some BIOS code mistakenly simply declares a single
|
||||
* Package instead of a Package with one sub-Package. This
|
||||
* function attempts to repair this error by wrapping a Package
|
||||
* object around the original Package, creating the correct
|
||||
* Package with one sub-Package.
|
||||
* DESCRIPTION: Repair a common problem with objects that are defined to
|
||||
* return a variable-length Package of sub-objects. If there is
|
||||
* only one sub-object, some BIOS code mistakenly simply declares
|
||||
* the single object instead of a Package with one sub-object.
|
||||
* This function attempts to repair this error by wrapping a
|
||||
* Package object around the original object, creating the
|
||||
* correct and expected Package with one sub-object.
|
||||
*
|
||||
* Names that can be repaired in this manner include:
|
||||
* _ALR, _CSD, _HPX, _MLS, _PRT, _PSS, _TRT, TSS
|
||||
* _ALR, _CSD, _HPX, _MLS, _PLD, _PRT, _PSS, _TRT, _TSS,
|
||||
* _BCL, _DOD, _FIX, _Sx
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
acpi_status
|
||||
acpi_ns_repair_package_list(struct acpi_predefined_data *data,
|
||||
union acpi_operand_object **obj_desc_ptr)
|
||||
acpi_ns_wrap_with_package(struct acpi_predefined_data *data,
|
||||
union acpi_operand_object *original_object,
|
||||
union acpi_operand_object **obj_desc_ptr)
|
||||
{
|
||||
union acpi_operand_object *pkg_obj_desc;
|
||||
|
||||
ACPI_FUNCTION_NAME(ns_repair_package_list);
|
||||
ACPI_FUNCTION_NAME(ns_wrap_with_package);
|
||||
|
||||
/*
|
||||
* Create the new outer package and populate it. The new package will
|
||||
* have a single element, the lone subpackage.
|
||||
* have a single element, the lone sub-object.
|
||||
*/
|
||||
pkg_obj_desc = acpi_ut_create_package_object(1);
|
||||
if (!pkg_obj_desc) {
|
||||
return (AE_NO_MEMORY);
|
||||
}
|
||||
|
||||
pkg_obj_desc->package.elements[0] = *obj_desc_ptr;
|
||||
pkg_obj_desc->package.elements[0] = original_object;
|
||||
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
|
||||
"%s: Wrapped %s with expected Package object\n",
|
||||
data->pathname,
|
||||
acpi_ut_get_object_type_name(original_object)));
|
||||
|
||||
/* Return the new object in the object pointer */
|
||||
|
||||
*obj_desc_ptr = pkg_obj_desc;
|
||||
data->flags |= ACPI_OBJECT_REPAIRED;
|
||||
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
|
||||
"%s: Repaired incorrectly formed Package\n",
|
||||
data->pathname));
|
||||
|
||||
data->flags |= ACPI_OBJECT_REPAIRED | ACPI_OBJECT_WRAPPED;
|
||||
return (AE_OK);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -341,7 +341,7 @@ acpi_status acpi_ns_build_internal_name(struct acpi_namestring_info *info)
|
|||
|
||||
if (!acpi_ns_valid_path_separator(*external_name) &&
|
||||
(*external_name != 0)) {
|
||||
return_ACPI_STATUS(AE_BAD_PARAMETER);
|
||||
return_ACPI_STATUS(AE_BAD_PATHNAME);
|
||||
}
|
||||
|
||||
/* Move on the next segment */
|
||||
|
|
|
|||
|
|
@ -363,10 +363,6 @@ static void acpi_tb_convert_fadt(void)
|
|||
u32 address32;
|
||||
u32 i;
|
||||
|
||||
/* Update the local FADT table header length */
|
||||
|
||||
acpi_gbl_FADT.header.length = sizeof(struct acpi_table_fadt);
|
||||
|
||||
/*
|
||||
* Expand the 32-bit FACS and DSDT addresses to 64-bit as necessary.
|
||||
* Later code will always use the X 64-bit field. Also, check for an
|
||||
|
|
@ -408,6 +404,10 @@ static void acpi_tb_convert_fadt(void)
|
|||
acpi_gbl_FADT.boot_flags = 0;
|
||||
}
|
||||
|
||||
/* Update the local FADT table header length */
|
||||
|
||||
acpi_gbl_FADT.header.length = sizeof(struct acpi_table_fadt);
|
||||
|
||||
/*
|
||||
* Expand the ACPI 1.0 32-bit addresses to the ACPI 2.0 64-bit "X"
|
||||
* generic address structures as necessary. Later code will always use
|
||||
|
|
|
|||
|
|
@ -114,7 +114,6 @@ acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index)
|
|||
{
|
||||
u32 i;
|
||||
acpi_status status = AE_OK;
|
||||
struct acpi_table_header *override_table = NULL;
|
||||
|
||||
ACPI_FUNCTION_TRACE(tb_add_table);
|
||||
|
||||
|
|
@ -224,25 +223,10 @@ acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index)
|
|||
/*
|
||||
* ACPI Table Override:
|
||||
* Allow the host to override dynamically loaded tables.
|
||||
* NOTE: the table is fully mapped at this point, and the mapping will
|
||||
* be deleted by tb_table_override if the table is actually overridden.
|
||||
*/
|
||||
status = acpi_os_table_override(table_desc->pointer, &override_table);
|
||||
if (ACPI_SUCCESS(status) && override_table) {
|
||||
ACPI_INFO((AE_INFO,
|
||||
"%4.4s @ 0x%p Table override, replaced with:",
|
||||
table_desc->pointer->signature,
|
||||
ACPI_CAST_PTR(void, table_desc->address)));
|
||||
|
||||
/* We can delete the table that was passed as a parameter */
|
||||
|
||||
acpi_tb_delete_table(table_desc);
|
||||
|
||||
/* Setup descriptor for the new table */
|
||||
|
||||
table_desc->address = ACPI_PTR_TO_PHYSADDR(override_table);
|
||||
table_desc->pointer = override_table;
|
||||
table_desc->length = override_table->length;
|
||||
table_desc->flags = ACPI_TABLE_ORIGIN_OVERRIDE;
|
||||
}
|
||||
(void)acpi_tb_table_override(table_desc->pointer, table_desc);
|
||||
|
||||
/* Add the table to the global root table list */
|
||||
|
||||
|
|
@ -261,6 +245,95 @@ acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index)
|
|||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_tb_table_override
|
||||
*
|
||||
* PARAMETERS: table_header - Header for the original table
|
||||
* table_desc - Table descriptor initialized for the
|
||||
* original table. May or may not be mapped.
|
||||
*
|
||||
* RETURN: Pointer to the entire new table. NULL if table not overridden.
|
||||
* If overridden, installs the new table within the input table
|
||||
* descriptor.
|
||||
*
|
||||
* DESCRIPTION: Attempt table override by calling the OSL override functions.
|
||||
* Note: If the table is overridden, then the entire new table
|
||||
* is mapped and returned by this function.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
struct acpi_table_header *acpi_tb_table_override(struct acpi_table_header
|
||||
*table_header,
|
||||
struct acpi_table_desc
|
||||
*table_desc)
|
||||
{
|
||||
acpi_status status;
|
||||
struct acpi_table_header *new_table = NULL;
|
||||
acpi_physical_address new_address = 0;
|
||||
u32 new_table_length = 0;
|
||||
u8 new_flags;
|
||||
char *override_type;
|
||||
|
||||
/* (1) Attempt logical override (returns a logical address) */
|
||||
|
||||
status = acpi_os_table_override(table_header, &new_table);
|
||||
if (ACPI_SUCCESS(status) && new_table) {
|
||||
new_address = ACPI_PTR_TO_PHYSADDR(new_table);
|
||||
new_table_length = new_table->length;
|
||||
new_flags = ACPI_TABLE_ORIGIN_OVERRIDE;
|
||||
override_type = "Logical";
|
||||
goto finish_override;
|
||||
}
|
||||
|
||||
/* (2) Attempt physical override (returns a physical address) */
|
||||
|
||||
status = acpi_os_physical_table_override(table_header,
|
||||
&new_address,
|
||||
&new_table_length);
|
||||
if (ACPI_SUCCESS(status) && new_address && new_table_length) {
|
||||
|
||||
/* Map the entire new table */
|
||||
|
||||
new_table = acpi_os_map_memory(new_address, new_table_length);
|
||||
if (!new_table) {
|
||||
ACPI_EXCEPTION((AE_INFO, AE_NO_MEMORY,
|
||||
"%4.4s %p Attempted physical table override failed",
|
||||
table_header->signature,
|
||||
ACPI_CAST_PTR(void,
|
||||
table_desc->address)));
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
override_type = "Physical";
|
||||
new_flags = ACPI_TABLE_ORIGIN_MAPPED;
|
||||
goto finish_override;
|
||||
}
|
||||
|
||||
return (NULL); /* There was no override */
|
||||
|
||||
finish_override:
|
||||
|
||||
ACPI_INFO((AE_INFO,
|
||||
"%4.4s %p %s table override, new table: %p",
|
||||
table_header->signature,
|
||||
ACPI_CAST_PTR(void, table_desc->address),
|
||||
override_type, new_table));
|
||||
|
||||
/* We can now unmap/delete the original table (if fully mapped) */
|
||||
|
||||
acpi_tb_delete_table(table_desc);
|
||||
|
||||
/* Setup descriptor for the new table */
|
||||
|
||||
table_desc->address = new_address;
|
||||
table_desc->pointer = new_table;
|
||||
table_desc->length = new_table_length;
|
||||
table_desc->flags = new_flags;
|
||||
|
||||
return (new_table);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_tb_resize_root_table_list
|
||||
|
|
@ -396,7 +469,11 @@ void acpi_tb_delete_table(struct acpi_table_desc *table_desc)
|
|||
case ACPI_TABLE_ORIGIN_ALLOCATED:
|
||||
ACPI_FREE(table_desc->pointer);
|
||||
break;
|
||||
default:;
|
||||
|
||||
/* Not mapped or allocated, there is nothing we can do */
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
table_desc->pointer = NULL;
|
||||
|
|
|
|||
|
|
@ -118,6 +118,7 @@ acpi_tb_check_xsdt(acpi_physical_address address)
|
|||
return AE_OK;
|
||||
}
|
||||
|
||||
#if (!ACPI_REDUCED_HARDWARE)
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_tb_initialize_facs
|
||||
|
|
@ -148,6 +149,7 @@ acpi_status acpi_tb_initialize_facs(void)
|
|||
&acpi_gbl_FACS));
|
||||
return status;
|
||||
}
|
||||
#endif /* !ACPI_REDUCED_HARDWARE */
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
|
|
@ -444,7 +446,7 @@ struct acpi_table_header *acpi_tb_copy_dsdt(u32 table_index)
|
|||
* RETURN: None
|
||||
*
|
||||
* DESCRIPTION: Install an ACPI table into the global data structure. The
|
||||
* table override mechanism is implemented here to allow the host
|
||||
* table override mechanism is called to allow the host
|
||||
* OS to replace any table before it is installed in the root
|
||||
* table array.
|
||||
*
|
||||
|
|
@ -454,11 +456,9 @@ void
|
|||
acpi_tb_install_table(acpi_physical_address address,
|
||||
char *signature, u32 table_index)
|
||||
{
|
||||
u8 flags;
|
||||
acpi_status status;
|
||||
struct acpi_table_header *table_to_install;
|
||||
struct acpi_table_header *mapped_table;
|
||||
struct acpi_table_header *override_table = NULL;
|
||||
struct acpi_table_header *table;
|
||||
struct acpi_table_header *final_table;
|
||||
struct acpi_table_desc *table_desc;
|
||||
|
||||
if (!address) {
|
||||
ACPI_ERROR((AE_INFO,
|
||||
|
|
@ -469,69 +469,78 @@ acpi_tb_install_table(acpi_physical_address address,
|
|||
|
||||
/* Map just the table header */
|
||||
|
||||
mapped_table =
|
||||
acpi_os_map_memory(address, sizeof(struct acpi_table_header));
|
||||
if (!mapped_table) {
|
||||
table = acpi_os_map_memory(address, sizeof(struct acpi_table_header));
|
||||
if (!table) {
|
||||
ACPI_ERROR((AE_INFO,
|
||||
"Could not map memory for table [%s] at %p",
|
||||
signature, ACPI_CAST_PTR(void, address)));
|
||||
return;
|
||||
}
|
||||
|
||||
/* If a particular signature is expected (DSDT/FACS), it must match */
|
||||
|
||||
if (signature && !ACPI_COMPARE_NAME(mapped_table->signature, signature)) {
|
||||
if (signature && !ACPI_COMPARE_NAME(table->signature, signature)) {
|
||||
ACPI_ERROR((AE_INFO,
|
||||
"Invalid signature 0x%X for ACPI table, expected [%s]",
|
||||
*ACPI_CAST_PTR(u32, mapped_table->signature),
|
||||
signature));
|
||||
*ACPI_CAST_PTR(u32, table->signature), signature));
|
||||
goto unmap_and_exit;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the table entry. Set the pointer to NULL, since the
|
||||
* table is not fully mapped at this time.
|
||||
*/
|
||||
table_desc = &acpi_gbl_root_table_list.tables[table_index];
|
||||
|
||||
table_desc->address = address;
|
||||
table_desc->pointer = NULL;
|
||||
table_desc->length = table->length;
|
||||
table_desc->flags = ACPI_TABLE_ORIGIN_MAPPED;
|
||||
ACPI_MOVE_32_TO_32(table_desc->signature.ascii, table->signature);
|
||||
|
||||
/*
|
||||
* ACPI Table Override:
|
||||
*
|
||||
* Before we install the table, let the host OS override it with a new
|
||||
* one if desired. Any table within the RSDT/XSDT can be replaced,
|
||||
* including the DSDT which is pointed to by the FADT.
|
||||
*
|
||||
* NOTE: If the table is overridden, then final_table will contain a
|
||||
* mapped pointer to the full new table. If the table is not overridden,
|
||||
* or if there has been a physical override, then the table will be
|
||||
* fully mapped later (in verify table). In any case, we must
|
||||
* unmap the header that was mapped above.
|
||||
*/
|
||||
status = acpi_os_table_override(mapped_table, &override_table);
|
||||
if (ACPI_SUCCESS(status) && override_table) {
|
||||
ACPI_INFO((AE_INFO,
|
||||
"%4.4s @ 0x%p Table override, replaced with:",
|
||||
mapped_table->signature, ACPI_CAST_PTR(void,
|
||||
address)));
|
||||
|
||||
acpi_gbl_root_table_list.tables[table_index].pointer =
|
||||
override_table;
|
||||
address = ACPI_PTR_TO_PHYSADDR(override_table);
|
||||
|
||||
table_to_install = override_table;
|
||||
flags = ACPI_TABLE_ORIGIN_OVERRIDE;
|
||||
} else {
|
||||
table_to_install = mapped_table;
|
||||
flags = ACPI_TABLE_ORIGIN_MAPPED;
|
||||
final_table = acpi_tb_table_override(table, table_desc);
|
||||
if (!final_table) {
|
||||
final_table = table; /* There was no override */
|
||||
}
|
||||
|
||||
/* Initialize the table entry */
|
||||
acpi_tb_print_table_header(table_desc->address, final_table);
|
||||
|
||||
acpi_gbl_root_table_list.tables[table_index].address = address;
|
||||
acpi_gbl_root_table_list.tables[table_index].length =
|
||||
table_to_install->length;
|
||||
acpi_gbl_root_table_list.tables[table_index].flags = flags;
|
||||
|
||||
ACPI_MOVE_32_TO_32(&
|
||||
(acpi_gbl_root_table_list.tables[table_index].
|
||||
signature), table_to_install->signature);
|
||||
|
||||
acpi_tb_print_table_header(address, table_to_install);
|
||||
/* Set the global integer width (based upon revision of the DSDT) */
|
||||
|
||||
if (table_index == ACPI_TABLE_INDEX_DSDT) {
|
||||
acpi_ut_set_integer_width(final_table->revision);
|
||||
}
|
||||
|
||||
/* Global integer width is based upon revision of the DSDT */
|
||||
|
||||
acpi_ut_set_integer_width(table_to_install->revision);
|
||||
/*
|
||||
* If we have a physical override during this early loading of the ACPI
|
||||
* tables, unmap the table for now. It will be mapped again later when
|
||||
* it is actually used. This supports very early loading of ACPI tables,
|
||||
* before virtual memory is fully initialized and running within the
|
||||
* host OS. Note: A logical override has the ACPI_TABLE_ORIGIN_OVERRIDE
|
||||
* flag set and will not be deleted below.
|
||||
*/
|
||||
if (final_table != table) {
|
||||
acpi_tb_delete_table(table_desc);
|
||||
}
|
||||
|
||||
unmap_and_exit:
|
||||
acpi_os_unmap_memory(mapped_table, sizeof(struct acpi_table_header));
|
||||
|
||||
/* Always unmap the table header that we mapped above */
|
||||
|
||||
acpi_os_unmap_memory(table, sizeof(struct acpi_table_header));
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
|
|
|
|||
|
|
@ -497,19 +497,20 @@ char *acpi_ut_get_mutex_name(u32 mutex_id)
|
|||
|
||||
/* Names for Notify() values, used for debug output */
|
||||
|
||||
static const char *acpi_gbl_notify_value_names[] = {
|
||||
"Bus Check",
|
||||
"Device Check",
|
||||
"Device Wake",
|
||||
"Eject Request",
|
||||
"Device Check Light",
|
||||
"Frequency Mismatch",
|
||||
"Bus Mode Mismatch",
|
||||
"Power Fault",
|
||||
"Capabilities Check",
|
||||
"Device PLD Check",
|
||||
"Reserved",
|
||||
"System Locality Update"
|
||||
static const char *acpi_gbl_notify_value_names[ACPI_NOTIFY_MAX + 1] = {
|
||||
/* 00 */ "Bus Check",
|
||||
/* 01 */ "Device Check",
|
||||
/* 02 */ "Device Wake",
|
||||
/* 03 */ "Eject Request",
|
||||
/* 04 */ "Device Check Light",
|
||||
/* 05 */ "Frequency Mismatch",
|
||||
/* 06 */ "Bus Mode Mismatch",
|
||||
/* 07 */ "Power Fault",
|
||||
/* 08 */ "Capabilities Check",
|
||||
/* 09 */ "Device PLD Check",
|
||||
/* 10 */ "Reserved",
|
||||
/* 11 */ "System Locality Update",
|
||||
/* 12 */ "Shutdown Request"
|
||||
};
|
||||
|
||||
const char *acpi_ut_get_notify_name(u32 notify_value)
|
||||
|
|
@ -519,9 +520,10 @@ const char *acpi_ut_get_notify_name(u32 notify_value)
|
|||
return (acpi_gbl_notify_value_names[notify_value]);
|
||||
} else if (notify_value <= ACPI_MAX_SYS_NOTIFY) {
|
||||
return ("Reserved");
|
||||
} else { /* Greater or equal to 0x80 */
|
||||
|
||||
return ("**Device Specific**");
|
||||
} else if (notify_value <= ACPI_MAX_DEVICE_SPECIFIC_NOTIFY) {
|
||||
return ("Device Specific");
|
||||
} else {
|
||||
return ("Hardware Specific");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -140,6 +140,7 @@ const struct acpi_predefined_names acpi_gbl_pre_defined_names[] = {
|
|||
{NULL, ACPI_TYPE_ANY, NULL}
|
||||
};
|
||||
|
||||
#if (!ACPI_REDUCED_HARDWARE)
|
||||
/******************************************************************************
|
||||
*
|
||||
* Event and Hardware globals
|
||||
|
|
@ -236,6 +237,7 @@ struct acpi_fixed_event_info acpi_gbl_fixed_event_info[ACPI_NUM_FIXED_EVENTS] =
|
|||
ACPI_BITMASK_RT_CLOCK_STATUS,
|
||||
ACPI_BITMASK_RT_CLOCK_ENABLE},
|
||||
};
|
||||
#endif /* !ACPI_REDUCED_HARDWARE */
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
|
|
@ -286,6 +288,8 @@ acpi_status acpi_ut_init_globals(void)
|
|||
|
||||
acpi_gbl_owner_id_mask[ACPI_NUM_OWNERID_MASKS - 1] = 0x80000000;
|
||||
|
||||
#if (!ACPI_REDUCED_HARDWARE)
|
||||
|
||||
/* GPE support */
|
||||
|
||||
acpi_gbl_gpe_xrupt_list_head = NULL;
|
||||
|
|
@ -294,6 +298,10 @@ acpi_status acpi_ut_init_globals(void)
|
|||
acpi_current_gpe_count = 0;
|
||||
acpi_gbl_all_gpes_initialized = FALSE;
|
||||
|
||||
acpi_gbl_global_event_handler = NULL;
|
||||
|
||||
#endif /* !ACPI_REDUCED_HARDWARE */
|
||||
|
||||
/* Global handlers */
|
||||
|
||||
acpi_gbl_system_notify.handler = NULL;
|
||||
|
|
@ -302,7 +310,6 @@ acpi_status acpi_ut_init_globals(void)
|
|||
acpi_gbl_init_handler = NULL;
|
||||
acpi_gbl_table_handler = NULL;
|
||||
acpi_gbl_interface_handler = NULL;
|
||||
acpi_gbl_global_event_handler = NULL;
|
||||
|
||||
/* Global Lock support */
|
||||
|
||||
|
|
|
|||
|
|
@ -53,27 +53,35 @@ ACPI_MODULE_NAME("utinit")
|
|||
/* Local prototypes */
|
||||
static void acpi_ut_terminate(void);
|
||||
|
||||
#if (!ACPI_REDUCED_HARDWARE)
|
||||
|
||||
static void acpi_ut_free_gpe_lists(void);
|
||||
|
||||
#else
|
||||
|
||||
#define acpi_ut_free_gpe_lists()
|
||||
#endif /* !ACPI_REDUCED_HARDWARE */
|
||||
|
||||
#if (!ACPI_REDUCED_HARDWARE)
|
||||
/******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_ut_terminate
|
||||
* FUNCTION: acpi_ut_free_gpe_lists
|
||||
*
|
||||
* PARAMETERS: none
|
||||
*
|
||||
* RETURN: none
|
||||
*
|
||||
* DESCRIPTION: Free global memory
|
||||
* DESCRIPTION: Free global GPE lists
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
static void acpi_ut_terminate(void)
|
||||
static void acpi_ut_free_gpe_lists(void)
|
||||
{
|
||||
struct acpi_gpe_block_info *gpe_block;
|
||||
struct acpi_gpe_block_info *next_gpe_block;
|
||||
struct acpi_gpe_xrupt_info *gpe_xrupt_info;
|
||||
struct acpi_gpe_xrupt_info *next_gpe_xrupt_info;
|
||||
|
||||
ACPI_FUNCTION_TRACE(ut_terminate);
|
||||
|
||||
/* Free global GPE blocks and related info structures */
|
||||
|
||||
gpe_xrupt_info = acpi_gbl_gpe_xrupt_list_head;
|
||||
|
|
@ -91,7 +99,26 @@ static void acpi_ut_terminate(void)
|
|||
ACPI_FREE(gpe_xrupt_info);
|
||||
gpe_xrupt_info = next_gpe_xrupt_info;
|
||||
}
|
||||
}
|
||||
#endif /* !ACPI_REDUCED_HARDWARE */
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_ut_terminate
|
||||
*
|
||||
* PARAMETERS: none
|
||||
*
|
||||
* RETURN: none
|
||||
*
|
||||
* DESCRIPTION: Free global memory
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
static void acpi_ut_terminate(void)
|
||||
{
|
||||
ACPI_FUNCTION_TRACE(ut_terminate);
|
||||
|
||||
acpi_ut_free_gpe_lists();
|
||||
acpi_ut_delete_address_lists();
|
||||
return_VOID;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -145,6 +145,8 @@ acpi_status acpi_enable_subsystem(u32 flags)
|
|||
|
||||
ACPI_FUNCTION_TRACE(acpi_enable_subsystem);
|
||||
|
||||
#if (!ACPI_REDUCED_HARDWARE)
|
||||
|
||||
/* Enable ACPI mode */
|
||||
|
||||
if (!(flags & ACPI_NO_ACPI_ENABLE)) {
|
||||
|
|
@ -169,6 +171,7 @@ acpi_status acpi_enable_subsystem(u32 flags)
|
|||
ACPI_WARNING((AE_INFO, "Could not map the FACS table"));
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
#endif /* !ACPI_REDUCED_HARDWARE */
|
||||
|
||||
/*
|
||||
* Install the default op_region handlers. These are installed unless
|
||||
|
|
@ -184,7 +187,7 @@ acpi_status acpi_enable_subsystem(u32 flags)
|
|||
return_ACPI_STATUS(status);
|
||||
}
|
||||
}
|
||||
|
||||
#if (!ACPI_REDUCED_HARDWARE)
|
||||
/*
|
||||
* Initialize ACPI Event handling (Fixed and General Purpose)
|
||||
*
|
||||
|
|
@ -220,6 +223,7 @@ acpi_status acpi_enable_subsystem(u32 flags)
|
|||
return_ACPI_STATUS(status);
|
||||
}
|
||||
}
|
||||
#endif /* !ACPI_REDUCED_HARDWARE */
|
||||
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -558,33 +558,48 @@ void apei_resources_release(struct apei_resources *resources)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(apei_resources_release);
|
||||
|
||||
static int apei_check_gar(struct acpi_generic_address *reg, u64 *paddr)
|
||||
static int apei_check_gar(struct acpi_generic_address *reg, u64 *paddr,
|
||||
u32 *access_bit_width)
|
||||
{
|
||||
u32 width, space_id;
|
||||
u32 bit_width, bit_offset, access_size_code, space_id;
|
||||
|
||||
width = reg->bit_width;
|
||||
bit_width = reg->bit_width;
|
||||
bit_offset = reg->bit_offset;
|
||||
access_size_code = reg->access_width;
|
||||
space_id = reg->space_id;
|
||||
/* Handle possible alignment issues */
|
||||
memcpy(paddr, ®->address, sizeof(*paddr));
|
||||
if (!*paddr) {
|
||||
pr_warning(FW_BUG APEI_PFX
|
||||
"Invalid physical address in GAR [0x%llx/%u/%u]\n",
|
||||
*paddr, width, space_id);
|
||||
"Invalid physical address in GAR [0x%llx/%u/%u/%u/%u]\n",
|
||||
*paddr, bit_width, bit_offset, access_size_code,
|
||||
space_id);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((width != 8) && (width != 16) && (width != 32) && (width != 64)) {
|
||||
if (access_size_code < 1 || access_size_code > 4) {
|
||||
pr_warning(FW_BUG APEI_PFX
|
||||
"Invalid bit width in GAR [0x%llx/%u/%u]\n",
|
||||
*paddr, width, space_id);
|
||||
"Invalid access size code in GAR [0x%llx/%u/%u/%u/%u]\n",
|
||||
*paddr, bit_width, bit_offset, access_size_code,
|
||||
space_id);
|
||||
return -EINVAL;
|
||||
}
|
||||
*access_bit_width = 1UL << (access_size_code + 2);
|
||||
|
||||
if ((bit_width + bit_offset) > *access_bit_width) {
|
||||
pr_warning(FW_BUG APEI_PFX
|
||||
"Invalid bit width + offset in GAR [0x%llx/%u/%u/%u/%u]\n",
|
||||
*paddr, bit_width, bit_offset, access_size_code,
|
||||
space_id);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY &&
|
||||
space_id != ACPI_ADR_SPACE_SYSTEM_IO) {
|
||||
pr_warning(FW_BUG APEI_PFX
|
||||
"Invalid address space type in GAR [0x%llx/%u/%u]\n",
|
||||
*paddr, width, space_id);
|
||||
"Invalid address space type in GAR [0x%llx/%u/%u/%u/%u]\n",
|
||||
*paddr, bit_width, bit_offset, access_size_code,
|
||||
space_id);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
|
@ -595,23 +610,25 @@ static int apei_check_gar(struct acpi_generic_address *reg, u64 *paddr)
|
|||
int apei_read(u64 *val, struct acpi_generic_address *reg)
|
||||
{
|
||||
int rc;
|
||||
u32 access_bit_width;
|
||||
u64 address;
|
||||
acpi_status status;
|
||||
|
||||
rc = apei_check_gar(reg, &address);
|
||||
rc = apei_check_gar(reg, &address, &access_bit_width);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
*val = 0;
|
||||
switch(reg->space_id) {
|
||||
case ACPI_ADR_SPACE_SYSTEM_MEMORY:
|
||||
status = acpi_os_read_memory64((acpi_physical_address)
|
||||
address, val, reg->bit_width);
|
||||
status = acpi_os_read_memory((acpi_physical_address) address,
|
||||
val, access_bit_width);
|
||||
if (ACPI_FAILURE(status))
|
||||
return -EIO;
|
||||
break;
|
||||
case ACPI_ADR_SPACE_SYSTEM_IO:
|
||||
status = acpi_os_read_port(address, (u32 *)val, reg->bit_width);
|
||||
status = acpi_os_read_port(address, (u32 *)val,
|
||||
access_bit_width);
|
||||
if (ACPI_FAILURE(status))
|
||||
return -EIO;
|
||||
break;
|
||||
|
|
@ -627,22 +644,23 @@ EXPORT_SYMBOL_GPL(apei_read);
|
|||
int apei_write(u64 val, struct acpi_generic_address *reg)
|
||||
{
|
||||
int rc;
|
||||
u32 access_bit_width;
|
||||
u64 address;
|
||||
acpi_status status;
|
||||
|
||||
rc = apei_check_gar(reg, &address);
|
||||
rc = apei_check_gar(reg, &address, &access_bit_width);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
switch (reg->space_id) {
|
||||
case ACPI_ADR_SPACE_SYSTEM_MEMORY:
|
||||
status = acpi_os_write_memory64((acpi_physical_address)
|
||||
address, val, reg->bit_width);
|
||||
status = acpi_os_write_memory((acpi_physical_address) address,
|
||||
val, access_bit_width);
|
||||
if (ACPI_FAILURE(status))
|
||||
return -EIO;
|
||||
break;
|
||||
case ACPI_ADR_SPACE_SYSTEM_IO:
|
||||
status = acpi_os_write_port(address, val, reg->bit_width);
|
||||
status = acpi_os_write_port(address, val, access_bit_width);
|
||||
if (ACPI_FAILURE(status))
|
||||
return -EIO;
|
||||
break;
|
||||
|
|
@ -661,23 +679,24 @@ static int collect_res_callback(struct apei_exec_context *ctx,
|
|||
struct apei_resources *resources = data;
|
||||
struct acpi_generic_address *reg = &entry->register_region;
|
||||
u8 ins = entry->instruction;
|
||||
u32 access_bit_width;
|
||||
u64 paddr;
|
||||
int rc;
|
||||
|
||||
if (!(ctx->ins_table[ins].flags & APEI_EXEC_INS_ACCESS_REGISTER))
|
||||
return 0;
|
||||
|
||||
rc = apei_check_gar(reg, &paddr);
|
||||
rc = apei_check_gar(reg, &paddr, &access_bit_width);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
switch (reg->space_id) {
|
||||
case ACPI_ADR_SPACE_SYSTEM_MEMORY:
|
||||
return apei_res_add(&resources->iomem, paddr,
|
||||
reg->bit_width / 8);
|
||||
access_bit_width / 8);
|
||||
case ACPI_ADR_SPACE_SYSTEM_IO:
|
||||
return apei_res_add(&resources->ioport, paddr,
|
||||
reg->bit_width / 8);
|
||||
access_bit_width / 8);
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -362,6 +362,7 @@ void apei_estatus_print(const char *pfx,
|
|||
gedata_len = gdata->error_data_length;
|
||||
apei_estatus_print_section(pfx, gdata, sec_no);
|
||||
data_len -= gedata_len + sizeof(*gdata);
|
||||
gdata = (void *)(gdata + 1) + gedata_len;
|
||||
sec_no++;
|
||||
}
|
||||
}
|
||||
|
|
@ -396,6 +397,7 @@ int apei_estatus_check(const struct acpi_hest_generic_status *estatus)
|
|||
if (gedata_len > data_len - sizeof(*gdata))
|
||||
return -EINVAL;
|
||||
data_len -= gedata_len + sizeof(*gdata);
|
||||
gdata = (void *)(gdata + 1) + gedata_len;
|
||||
}
|
||||
if (data_len)
|
||||
return -EINVAL;
|
||||
|
|
|
|||
|
|
@ -74,6 +74,8 @@ struct vendor_error_type_extension {
|
|||
u8 reserved[3];
|
||||
};
|
||||
|
||||
static u32 notrigger;
|
||||
|
||||
static u32 vendor_flags;
|
||||
static struct debugfs_blob_wrapper vendor_blob;
|
||||
static char vendor_dev[64];
|
||||
|
|
@ -238,7 +240,7 @@ static void *einj_get_parameter_address(void)
|
|||
return v5param;
|
||||
}
|
||||
}
|
||||
if (paddrv4) {
|
||||
if (param_extension && paddrv4) {
|
||||
struct einj_parameter *v4param;
|
||||
|
||||
v4param = acpi_os_map_memory(paddrv4, sizeof(*v4param));
|
||||
|
|
@ -496,9 +498,11 @@ static int __einj_error_inject(u32 type, u64 param1, u64 param2)
|
|||
if (rc)
|
||||
return rc;
|
||||
trigger_paddr = apei_exec_ctx_get_output(&ctx);
|
||||
rc = __einj_error_trigger(trigger_paddr, type, param1, param2);
|
||||
if (rc)
|
||||
return rc;
|
||||
if (notrigger == 0) {
|
||||
rc = __einj_error_trigger(trigger_paddr, type, param1, param2);
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
rc = apei_exec_run_optional(&ctx, ACPI_EINJ_END_OPERATION);
|
||||
|
||||
return rc;
|
||||
|
|
@ -700,6 +704,11 @@ static int __init einj_init(void)
|
|||
einj_debug_dir, &error_param2);
|
||||
if (!fentry)
|
||||
goto err_unmap;
|
||||
|
||||
fentry = debugfs_create_x32("notrigger", S_IRUSR | S_IWUSR,
|
||||
einj_debug_dir, ¬rigger);
|
||||
if (!fentry)
|
||||
goto err_unmap;
|
||||
}
|
||||
|
||||
if (vendor_dev[0]) {
|
||||
|
|
|
|||
|
|
@ -917,7 +917,7 @@ static int erst_check_table(struct acpi_table_erst *erst_tab)
|
|||
{
|
||||
if ((erst_tab->header_length !=
|
||||
(sizeof(struct acpi_table_erst) - sizeof(erst_tab->header)))
|
||||
&& (erst_tab->header_length != sizeof(struct acpi_table_einj)))
|
||||
&& (erst_tab->header_length != sizeof(struct acpi_table_erst)))
|
||||
return -EINVAL;
|
||||
if (erst_tab->header.length < sizeof(struct acpi_table_erst))
|
||||
return -EINVAL;
|
||||
|
|
|
|||
175
drivers/acpi/bgrt.c
Normal file
175
drivers/acpi/bgrt.c
Normal file
|
|
@ -0,0 +1,175 @@
|
|||
/*
|
||||
* Copyright 2012 Red Hat, Inc <mjg@redhat.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/sysfs.h>
|
||||
#include <acpi/acpi.h>
|
||||
#include <acpi/acpi_bus.h>
|
||||
|
||||
static struct acpi_table_bgrt *bgrt_tab;
|
||||
static struct kobject *bgrt_kobj;
|
||||
|
||||
struct bmp_header {
|
||||
u16 id;
|
||||
u32 size;
|
||||
} __attribute ((packed));
|
||||
|
||||
static struct bmp_header bmp_header;
|
||||
|
||||
static ssize_t show_version(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab->version);
|
||||
}
|
||||
static DEVICE_ATTR(version, S_IRUGO, show_version, NULL);
|
||||
|
||||
static ssize_t show_status(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab->status);
|
||||
}
|
||||
static DEVICE_ATTR(status, S_IRUGO, show_status, NULL);
|
||||
|
||||
static ssize_t show_type(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab->image_type);
|
||||
}
|
||||
static DEVICE_ATTR(type, S_IRUGO, show_type, NULL);
|
||||
|
||||
static ssize_t show_xoffset(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab->image_offset_x);
|
||||
}
|
||||
static DEVICE_ATTR(xoffset, S_IRUGO, show_xoffset, NULL);
|
||||
|
||||
static ssize_t show_yoffset(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab->image_offset_y);
|
||||
}
|
||||
static DEVICE_ATTR(yoffset, S_IRUGO, show_yoffset, NULL);
|
||||
|
||||
static ssize_t show_image(struct file *file, struct kobject *kobj,
|
||||
struct bin_attribute *attr, char *buf, loff_t off, size_t count)
|
||||
{
|
||||
int size = attr->size;
|
||||
void __iomem *image = attr->private;
|
||||
|
||||
if (off >= size) {
|
||||
count = 0;
|
||||
} else {
|
||||
if (off + count > size)
|
||||
count = size - off;
|
||||
|
||||
memcpy_fromio(buf, image+off, count);
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static struct bin_attribute image_attr = {
|
||||
.attr = {
|
||||
.name = "image",
|
||||
.mode = S_IRUGO,
|
||||
},
|
||||
.read = show_image,
|
||||
};
|
||||
|
||||
static struct attribute *bgrt_attributes[] = {
|
||||
&dev_attr_version.attr,
|
||||
&dev_attr_status.attr,
|
||||
&dev_attr_type.attr,
|
||||
&dev_attr_xoffset.attr,
|
||||
&dev_attr_yoffset.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static struct attribute_group bgrt_attribute_group = {
|
||||
.attrs = bgrt_attributes,
|
||||
};
|
||||
|
||||
static int __init bgrt_init(void)
|
||||
{
|
||||
acpi_status status;
|
||||
int ret;
|
||||
void __iomem *bgrt;
|
||||
|
||||
if (acpi_disabled)
|
||||
return -ENODEV;
|
||||
|
||||
status = acpi_get_table("BGRT", 0,
|
||||
(struct acpi_table_header **)&bgrt_tab);
|
||||
|
||||
if (ACPI_FAILURE(status))
|
||||
return -ENODEV;
|
||||
|
||||
sysfs_bin_attr_init(&image_attr);
|
||||
|
||||
bgrt = ioremap(bgrt_tab->image_address, sizeof(struct bmp_header));
|
||||
|
||||
if (!bgrt) {
|
||||
ret = -EINVAL;
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
memcpy_fromio(&bmp_header, bgrt, sizeof(bmp_header));
|
||||
image_attr.size = bmp_header.size;
|
||||
iounmap(bgrt);
|
||||
|
||||
image_attr.private = ioremap(bgrt_tab->image_address, image_attr.size);
|
||||
|
||||
if (!image_attr.private) {
|
||||
ret = -EINVAL;
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
|
||||
bgrt_kobj = kobject_create_and_add("bgrt", acpi_kobj);
|
||||
if (!bgrt_kobj) {
|
||||
ret = -EINVAL;
|
||||
goto out_iounmap;
|
||||
}
|
||||
|
||||
ret = sysfs_create_group(bgrt_kobj, &bgrt_attribute_group);
|
||||
if (ret)
|
||||
goto out_kobject;
|
||||
|
||||
ret = sysfs_create_bin_file(bgrt_kobj, &image_attr);
|
||||
if (ret)
|
||||
goto out_group;
|
||||
|
||||
return 0;
|
||||
|
||||
out_group:
|
||||
sysfs_remove_group(bgrt_kobj, &bgrt_attribute_group);
|
||||
out_kobject:
|
||||
kobject_put(bgrt_kobj);
|
||||
out_iounmap:
|
||||
iounmap(image_attr.private);
|
||||
out_err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit bgrt_exit(void)
|
||||
{
|
||||
iounmap(image_attr.private);
|
||||
sysfs_remove_group(bgrt_kobj, &bgrt_attribute_group);
|
||||
sysfs_remove_bin_file(bgrt_kobj, &image_attr);
|
||||
}
|
||||
|
||||
module_init(bgrt_init);
|
||||
module_exit(bgrt_exit);
|
||||
|
||||
MODULE_AUTHOR("Matthew Garrett");
|
||||
MODULE_DESCRIPTION("BGRT boot graphic support");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
@ -1010,6 +1010,7 @@ static int __init acpi_bus_init(void)
|
|||
}
|
||||
|
||||
struct kobject *acpi_kobj;
|
||||
EXPORT_SYMBOL_GPL(acpi_kobj);
|
||||
|
||||
static int __init acpi_init(void)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -445,6 +445,16 @@ int ec_transaction(u8 command,
|
|||
|
||||
EXPORT_SYMBOL(ec_transaction);
|
||||
|
||||
/* Get the handle to the EC device */
|
||||
acpi_handle ec_get_handle(void)
|
||||
{
|
||||
if (!first_ec)
|
||||
return NULL;
|
||||
return first_ec->handle;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(ec_get_handle);
|
||||
|
||||
void acpi_ec_block_transactions(void)
|
||||
{
|
||||
struct acpi_ec *ec = first_ec;
|
||||
|
|
@ -812,10 +822,10 @@ static int acpi_ec_add(struct acpi_device *device)
|
|||
first_ec = ec;
|
||||
device->driver_data = ec;
|
||||
|
||||
WARN(!request_region(ec->data_addr, 1, "EC data"),
|
||||
"Could not request EC data io port 0x%lx", ec->data_addr);
|
||||
WARN(!request_region(ec->command_addr, 1, "EC cmd"),
|
||||
"Could not request EC cmd io port 0x%lx", ec->command_addr);
|
||||
ret = !!request_region(ec->data_addr, 1, "EC data");
|
||||
WARN(!ret, "Could not request EC data io port 0x%lx", ec->data_addr);
|
||||
ret = !!request_region(ec->command_addr, 1, "EC cmd");
|
||||
WARN(!ret, "Could not request EC cmd io port 0x%lx", ec->command_addr);
|
||||
|
||||
pr_info(PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n",
|
||||
ec->gpe, ec->command_addr, ec->data_addr);
|
||||
|
|
|
|||
|
|
@ -95,8 +95,8 @@ static int suspend_nvs_register(unsigned long start, unsigned long size)
|
|||
{
|
||||
struct nvs_page *entry, *next;
|
||||
|
||||
pr_info("PM: Registering ACPI NVS region at %lx (%ld bytes)\n",
|
||||
start, size);
|
||||
pr_info("PM: Registering ACPI NVS region [mem %#010lx-%#010lx] (%ld bytes)\n",
|
||||
start, start + size - 1, size);
|
||||
|
||||
while (size > 0) {
|
||||
unsigned int nr_bytes;
|
||||
|
|
|
|||
|
|
@ -77,6 +77,9 @@ EXPORT_SYMBOL(acpi_in_debugger);
|
|||
extern char line_buf[80];
|
||||
#endif /*ENABLE_DEBUGGER */
|
||||
|
||||
static int (*__acpi_os_prepare_sleep)(u8 sleep_state, u32 pm1a_ctrl,
|
||||
u32 pm1b_ctrl);
|
||||
|
||||
static acpi_osd_handler acpi_irq_handler;
|
||||
static void *acpi_irq_context;
|
||||
static struct workqueue_struct *kacpid_wq;
|
||||
|
|
@ -347,7 +350,7 @@ static void acpi_unmap(acpi_physical_address pg_off, void __iomem *vaddr)
|
|||
unsigned long pfn;
|
||||
|
||||
pfn = pg_off >> PAGE_SHIFT;
|
||||
if (page_is_ram(pfn))
|
||||
if (should_use_kmap(pfn))
|
||||
kunmap(pfn_to_page(pfn));
|
||||
else
|
||||
iounmap(vaddr);
|
||||
|
|
@ -554,6 +557,15 @@ acpi_os_table_override(struct acpi_table_header * existing_table,
|
|||
return AE_OK;
|
||||
}
|
||||
|
||||
acpi_status
|
||||
acpi_os_physical_table_override(struct acpi_table_header *existing_table,
|
||||
acpi_physical_address * new_address,
|
||||
u32 *new_table_length)
|
||||
{
|
||||
return AE_SUPPORT;
|
||||
}
|
||||
|
||||
|
||||
static irqreturn_t acpi_irq(int irq, void *dev_id)
|
||||
{
|
||||
u32 handled;
|
||||
|
|
@ -595,7 +607,8 @@ acpi_os_install_interrupt_handler(u32 gsi, acpi_osd_handler handler,
|
|||
|
||||
acpi_irq_handler = handler;
|
||||
acpi_irq_context = context;
|
||||
if (request_irq(irq, acpi_irq, IRQF_SHARED, "acpi", acpi_irq)) {
|
||||
if (request_threaded_irq(irq, NULL, acpi_irq, IRQF_SHARED, "acpi",
|
||||
acpi_irq)) {
|
||||
printk(KERN_ERR PREFIX "SCI (IRQ%d) allocation failed\n", irq);
|
||||
acpi_irq_handler = NULL;
|
||||
return AE_NOT_ACQUIRED;
|
||||
|
|
@ -699,49 +712,6 @@ acpi_status acpi_os_write_port(acpi_io_address port, u32 value, u32 width)
|
|||
|
||||
EXPORT_SYMBOL(acpi_os_write_port);
|
||||
|
||||
acpi_status
|
||||
acpi_os_read_memory(acpi_physical_address phys_addr, u32 * value, u32 width)
|
||||
{
|
||||
void __iomem *virt_addr;
|
||||
unsigned int size = width / 8;
|
||||
bool unmap = false;
|
||||
u32 dummy;
|
||||
|
||||
rcu_read_lock();
|
||||
virt_addr = acpi_map_vaddr_lookup(phys_addr, size);
|
||||
if (!virt_addr) {
|
||||
rcu_read_unlock();
|
||||
virt_addr = acpi_os_ioremap(phys_addr, size);
|
||||
if (!virt_addr)
|
||||
return AE_BAD_ADDRESS;
|
||||
unmap = true;
|
||||
}
|
||||
|
||||
if (!value)
|
||||
value = &dummy;
|
||||
|
||||
switch (width) {
|
||||
case 8:
|
||||
*(u8 *) value = readb(virt_addr);
|
||||
break;
|
||||
case 16:
|
||||
*(u16 *) value = readw(virt_addr);
|
||||
break;
|
||||
case 32:
|
||||
*(u32 *) value = readl(virt_addr);
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
|
||||
if (unmap)
|
||||
iounmap(virt_addr);
|
||||
else
|
||||
rcu_read_unlock();
|
||||
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
#ifdef readq
|
||||
static inline u64 read64(const volatile void __iomem *addr)
|
||||
{
|
||||
|
|
@ -758,7 +728,7 @@ static inline u64 read64(const volatile void __iomem *addr)
|
|||
#endif
|
||||
|
||||
acpi_status
|
||||
acpi_os_read_memory64(acpi_physical_address phys_addr, u64 *value, u32 width)
|
||||
acpi_os_read_memory(acpi_physical_address phys_addr, u64 *value, u32 width)
|
||||
{
|
||||
void __iomem *virt_addr;
|
||||
unsigned int size = width / 8;
|
||||
|
|
@ -803,45 +773,6 @@ acpi_os_read_memory64(acpi_physical_address phys_addr, u64 *value, u32 width)
|
|||
return AE_OK;
|
||||
}
|
||||
|
||||
acpi_status
|
||||
acpi_os_write_memory(acpi_physical_address phys_addr, u32 value, u32 width)
|
||||
{
|
||||
void __iomem *virt_addr;
|
||||
unsigned int size = width / 8;
|
||||
bool unmap = false;
|
||||
|
||||
rcu_read_lock();
|
||||
virt_addr = acpi_map_vaddr_lookup(phys_addr, size);
|
||||
if (!virt_addr) {
|
||||
rcu_read_unlock();
|
||||
virt_addr = acpi_os_ioremap(phys_addr, size);
|
||||
if (!virt_addr)
|
||||
return AE_BAD_ADDRESS;
|
||||
unmap = true;
|
||||
}
|
||||
|
||||
switch (width) {
|
||||
case 8:
|
||||
writeb(value, virt_addr);
|
||||
break;
|
||||
case 16:
|
||||
writew(value, virt_addr);
|
||||
break;
|
||||
case 32:
|
||||
writel(value, virt_addr);
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
|
||||
if (unmap)
|
||||
iounmap(virt_addr);
|
||||
else
|
||||
rcu_read_unlock();
|
||||
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
#ifdef writeq
|
||||
static inline void write64(u64 val, volatile void __iomem *addr)
|
||||
{
|
||||
|
|
@ -856,7 +787,7 @@ static inline void write64(u64 val, volatile void __iomem *addr)
|
|||
#endif
|
||||
|
||||
acpi_status
|
||||
acpi_os_write_memory64(acpi_physical_address phys_addr, u64 value, u32 width)
|
||||
acpi_os_write_memory(acpi_physical_address phys_addr, u64 value, u32 width)
|
||||
{
|
||||
void __iomem *virt_addr;
|
||||
unsigned int size = width / 8;
|
||||
|
|
@ -1641,3 +1572,24 @@ acpi_status acpi_os_terminate(void)
|
|||
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
acpi_status acpi_os_prepare_sleep(u8 sleep_state, u32 pm1a_control,
|
||||
u32 pm1b_control)
|
||||
{
|
||||
int rc = 0;
|
||||
if (__acpi_os_prepare_sleep)
|
||||
rc = __acpi_os_prepare_sleep(sleep_state,
|
||||
pm1a_control, pm1b_control);
|
||||
if (rc < 0)
|
||||
return AE_ERROR;
|
||||
else if (rc > 0)
|
||||
return AE_CTRL_SKIP;
|
||||
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
void acpi_os_set_prepare_sleep(int (*func)(u8 sleep_state,
|
||||
u32 pm1a_ctrl, u32 pm1b_ctrl))
|
||||
{
|
||||
__acpi_os_prepare_sleep = func;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,9 +40,11 @@
|
|||
#include <linux/init.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <acpi/acpi_bus.h>
|
||||
#include <acpi/acpi_drivers.h>
|
||||
#include "sleep.h"
|
||||
#include "internal.h"
|
||||
|
||||
#define PREFIX "ACPI: "
|
||||
|
||||
|
|
@ -77,6 +79,20 @@ static struct acpi_driver acpi_power_driver = {
|
|||
},
|
||||
};
|
||||
|
||||
/*
|
||||
* A power managed device
|
||||
* A device may rely on multiple power resources.
|
||||
* */
|
||||
struct acpi_power_managed_device {
|
||||
struct device *dev; /* The physical device */
|
||||
acpi_handle *handle;
|
||||
};
|
||||
|
||||
struct acpi_power_resource_device {
|
||||
struct acpi_power_managed_device *device;
|
||||
struct acpi_power_resource_device *next;
|
||||
};
|
||||
|
||||
struct acpi_power_resource {
|
||||
struct acpi_device * device;
|
||||
acpi_bus_id name;
|
||||
|
|
@ -84,6 +100,9 @@ struct acpi_power_resource {
|
|||
u32 order;
|
||||
unsigned int ref_count;
|
||||
struct mutex resource_lock;
|
||||
|
||||
/* List of devices relying on this power resource */
|
||||
struct acpi_power_resource_device *devices;
|
||||
};
|
||||
|
||||
static struct list_head acpi_power_resource_list;
|
||||
|
|
@ -183,8 +202,26 @@ static int acpi_power_get_list_state(struct acpi_handle_list *list, int *state)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Resume the device when all power resources in _PR0 are on */
|
||||
static void acpi_power_on_device(struct acpi_power_managed_device *device)
|
||||
{
|
||||
struct acpi_device *acpi_dev;
|
||||
acpi_handle handle = device->handle;
|
||||
int state;
|
||||
|
||||
if (acpi_bus_get_device(handle, &acpi_dev))
|
||||
return;
|
||||
|
||||
if(acpi_power_get_inferred_state(acpi_dev, &state))
|
||||
return;
|
||||
|
||||
if (state == ACPI_STATE_D0 && pm_runtime_suspended(device->dev))
|
||||
pm_request_resume(device->dev);
|
||||
}
|
||||
|
||||
static int __acpi_power_on(struct acpi_power_resource *resource)
|
||||
{
|
||||
struct acpi_power_resource_device *device_list = resource->devices;
|
||||
acpi_status status = AE_OK;
|
||||
|
||||
status = acpi_evaluate_object(resource->device->handle, "_ON", NULL, NULL);
|
||||
|
|
@ -197,6 +234,12 @@ static int __acpi_power_on(struct acpi_power_resource *resource)
|
|||
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Power resource [%s] turned on\n",
|
||||
resource->name));
|
||||
|
||||
while (device_list) {
|
||||
acpi_power_on_device(device_list->device);
|
||||
|
||||
device_list = device_list->next;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -299,6 +342,125 @@ static int acpi_power_on_list(struct acpi_handle_list *list)
|
|||
return result;
|
||||
}
|
||||
|
||||
static void __acpi_power_resource_unregister_device(struct device *dev,
|
||||
acpi_handle res_handle)
|
||||
{
|
||||
struct acpi_power_resource *resource = NULL;
|
||||
struct acpi_power_resource_device *prev, *curr;
|
||||
|
||||
if (acpi_power_get_context(res_handle, &resource))
|
||||
return;
|
||||
|
||||
mutex_lock(&resource->resource_lock);
|
||||
prev = NULL;
|
||||
curr = resource->devices;
|
||||
while (curr) {
|
||||
if (curr->device->dev == dev) {
|
||||
if (!prev)
|
||||
resource->devices = curr->next;
|
||||
else
|
||||
prev->next = curr->next;
|
||||
|
||||
kfree(curr);
|
||||
break;
|
||||
}
|
||||
|
||||
prev = curr;
|
||||
curr = curr->next;
|
||||
}
|
||||
mutex_unlock(&resource->resource_lock);
|
||||
}
|
||||
|
||||
/* Unlink dev from all power resources in _PR0 */
|
||||
void acpi_power_resource_unregister_device(struct device *dev, acpi_handle handle)
|
||||
{
|
||||
struct acpi_device *acpi_dev;
|
||||
struct acpi_handle_list *list;
|
||||
int i;
|
||||
|
||||
if (!dev || !handle)
|
||||
return;
|
||||
|
||||
if (acpi_bus_get_device(handle, &acpi_dev))
|
||||
return;
|
||||
|
||||
list = &acpi_dev->power.states[ACPI_STATE_D0].resources;
|
||||
|
||||
for (i = 0; i < list->count; i++)
|
||||
__acpi_power_resource_unregister_device(dev,
|
||||
list->handles[i]);
|
||||
}
|
||||
|
||||
static int __acpi_power_resource_register_device(
|
||||
struct acpi_power_managed_device *powered_device, acpi_handle handle)
|
||||
{
|
||||
struct acpi_power_resource *resource = NULL;
|
||||
struct acpi_power_resource_device *power_resource_device;
|
||||
int result;
|
||||
|
||||
result = acpi_power_get_context(handle, &resource);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
power_resource_device = kzalloc(
|
||||
sizeof(*power_resource_device), GFP_KERNEL);
|
||||
if (!power_resource_device)
|
||||
return -ENOMEM;
|
||||
|
||||
power_resource_device->device = powered_device;
|
||||
|
||||
mutex_lock(&resource->resource_lock);
|
||||
power_resource_device->next = resource->devices;
|
||||
resource->devices = power_resource_device;
|
||||
mutex_unlock(&resource->resource_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Link dev to all power resources in _PR0 */
|
||||
int acpi_power_resource_register_device(struct device *dev, acpi_handle handle)
|
||||
{
|
||||
struct acpi_device *acpi_dev;
|
||||
struct acpi_handle_list *list;
|
||||
struct acpi_power_managed_device *powered_device;
|
||||
int i, ret;
|
||||
|
||||
if (!dev || !handle)
|
||||
return -ENODEV;
|
||||
|
||||
ret = acpi_bus_get_device(handle, &acpi_dev);
|
||||
if (ret)
|
||||
goto no_power_resource;
|
||||
|
||||
if (!acpi_dev->power.flags.power_resources)
|
||||
goto no_power_resource;
|
||||
|
||||
powered_device = kzalloc(sizeof(*powered_device), GFP_KERNEL);
|
||||
if (!powered_device)
|
||||
return -ENOMEM;
|
||||
|
||||
powered_device->dev = dev;
|
||||
powered_device->handle = handle;
|
||||
|
||||
list = &acpi_dev->power.states[ACPI_STATE_D0].resources;
|
||||
|
||||
for (i = 0; i < list->count; i++) {
|
||||
ret = __acpi_power_resource_register_device(powered_device,
|
||||
list->handles[i]);
|
||||
|
||||
if (ret) {
|
||||
acpi_power_resource_unregister_device(dev, handle);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
no_power_resource:
|
||||
printk(KERN_WARNING PREFIX "Invalid Power Resource to register!");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/**
|
||||
* acpi_device_sleep_wake - execute _DSW (Device Sleep Wake) or (deprecated in
|
||||
* ACPI 3.0) _PSW (Power State Wake)
|
||||
|
|
@ -500,14 +662,14 @@ int acpi_power_transition(struct acpi_device *device, int state)
|
|||
{
|
||||
int result;
|
||||
|
||||
if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3))
|
||||
if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3_COLD))
|
||||
return -EINVAL;
|
||||
|
||||
if (device->power.state == state)
|
||||
return 0;
|
||||
|
||||
if ((device->power.state < ACPI_STATE_D0)
|
||||
|| (device->power.state > ACPI_STATE_D3))
|
||||
|| (device->power.state > ACPI_STATE_D3_COLD))
|
||||
return -ENODEV;
|
||||
|
||||
/* TBD: Resources must be ordered. */
|
||||
|
|
|
|||
|
|
@ -46,7 +46,6 @@
|
|||
#include <linux/slab.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/cpu.h>
|
||||
#include <asm/delay.h>
|
||||
#include <asm/uaccess.h>
|
||||
|
|
@ -68,6 +67,7 @@
|
|||
#define ACPI_PROCESSOR_NOTIFY_PERFORMANCE 0x80
|
||||
#define ACPI_PROCESSOR_NOTIFY_POWER 0x81
|
||||
#define ACPI_PROCESSOR_NOTIFY_THROTTLING 0x82
|
||||
#define ACPI_PROCESSOR_DEVICE_HID "ACPI0007"
|
||||
|
||||
#define ACPI_PROCESSOR_LIMIT_USER 0
|
||||
#define ACPI_PROCESSOR_LIMIT_THERMAL 1
|
||||
|
|
@ -88,7 +88,7 @@ static int acpi_processor_start(struct acpi_processor *pr);
|
|||
|
||||
static const struct acpi_device_id processor_device_ids[] = {
|
||||
{ACPI_PROCESSOR_OBJECT_HID, 0},
|
||||
{"ACPI0007", 0},
|
||||
{ACPI_PROCESSOR_DEVICE_HID, 0},
|
||||
{"", 0},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, processor_device_ids);
|
||||
|
|
@ -474,6 +474,7 @@ static __ref int acpi_processor_start(struct acpi_processor *pr)
|
|||
|
||||
#ifdef CONFIG_CPU_FREQ
|
||||
acpi_processor_ppc_has_changed(pr, 0);
|
||||
acpi_processor_load_module(pr);
|
||||
#endif
|
||||
acpi_processor_get_throttling_info(pr);
|
||||
acpi_processor_get_limit_info(pr);
|
||||
|
|
@ -535,8 +536,8 @@ static int __cpuinit acpi_processor_add(struct acpi_device *device)
|
|||
return -ENOMEM;
|
||||
|
||||
if (!zalloc_cpumask_var(&pr->throttling.shared_cpu_map, GFP_KERNEL)) {
|
||||
kfree(pr);
|
||||
return -ENOMEM;
|
||||
result = -ENOMEM;
|
||||
goto err_free_pr;
|
||||
}
|
||||
|
||||
pr->handle = device->handle;
|
||||
|
|
@ -576,7 +577,7 @@ static int __cpuinit acpi_processor_add(struct acpi_device *device)
|
|||
dev = get_cpu_device(pr->id);
|
||||
if (sysfs_create_link(&device->dev.kobj, &dev->kobj, "sysdev")) {
|
||||
result = -EFAULT;
|
||||
goto err_free_cpumask;
|
||||
goto err_clear_processor;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -594,9 +595,15 @@ static int __cpuinit acpi_processor_add(struct acpi_device *device)
|
|||
|
||||
err_remove_sysfs:
|
||||
sysfs_remove_link(&device->dev.kobj, "sysdev");
|
||||
err_clear_processor:
|
||||
/*
|
||||
* processor_device_array is not cleared to allow checks for buggy BIOS
|
||||
*/
|
||||
per_cpu(processors, pr->id) = NULL;
|
||||
err_free_cpumask:
|
||||
free_cpumask_var(pr->throttling.shared_cpu_map);
|
||||
|
||||
err_free_pr:
|
||||
kfree(pr);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -741,20 +748,46 @@ static void acpi_processor_hotplug_notify(acpi_handle handle,
|
|||
return;
|
||||
}
|
||||
|
||||
static acpi_status is_processor_device(acpi_handle handle)
|
||||
{
|
||||
struct acpi_device_info *info;
|
||||
char *hid;
|
||||
acpi_status status;
|
||||
|
||||
status = acpi_get_object_info(handle, &info);
|
||||
if (ACPI_FAILURE(status))
|
||||
return status;
|
||||
|
||||
if (info->type == ACPI_TYPE_PROCESSOR) {
|
||||
kfree(info);
|
||||
return AE_OK; /* found a processor object */
|
||||
}
|
||||
|
||||
if (!(info->valid & ACPI_VALID_HID)) {
|
||||
kfree(info);
|
||||
return AE_ERROR;
|
||||
}
|
||||
|
||||
hid = info->hardware_id.string;
|
||||
if ((hid == NULL) || strcmp(hid, ACPI_PROCESSOR_DEVICE_HID)) {
|
||||
kfree(info);
|
||||
return AE_ERROR;
|
||||
}
|
||||
|
||||
kfree(info);
|
||||
return AE_OK; /* found a processor device object */
|
||||
}
|
||||
|
||||
static acpi_status
|
||||
processor_walk_namespace_cb(acpi_handle handle,
|
||||
u32 lvl, void *context, void **rv)
|
||||
{
|
||||
acpi_status status;
|
||||
int *action = context;
|
||||
acpi_object_type type = 0;
|
||||
|
||||
status = acpi_get_type(handle, &type);
|
||||
status = is_processor_device(handle);
|
||||
if (ACPI_FAILURE(status))
|
||||
return (AE_OK);
|
||||
|
||||
if (type != ACPI_TYPE_PROCESSOR)
|
||||
return (AE_OK);
|
||||
return AE_OK; /* not a processor; continue to walk */
|
||||
|
||||
switch (*action) {
|
||||
case INSTALL_NOTIFY_HANDLER:
|
||||
|
|
@ -772,7 +805,8 @@ processor_walk_namespace_cb(acpi_handle handle,
|
|||
break;
|
||||
}
|
||||
|
||||
return (AE_OK);
|
||||
/* found a processor; skip walking underneath */
|
||||
return AE_CTRL_DEPTH;
|
||||
}
|
||||
|
||||
static acpi_status acpi_processor_hotadd_init(struct acpi_processor *pr)
|
||||
|
|
@ -830,7 +864,7 @@ void acpi_processor_install_hotplug_notify(void)
|
|||
{
|
||||
#ifdef CONFIG_ACPI_HOTPLUG_CPU
|
||||
int action = INSTALL_NOTIFY_HANDLER;
|
||||
acpi_walk_namespace(ACPI_TYPE_PROCESSOR,
|
||||
acpi_walk_namespace(ACPI_TYPE_ANY,
|
||||
ACPI_ROOT_OBJECT,
|
||||
ACPI_UINT32_MAX,
|
||||
processor_walk_namespace_cb, NULL, &action, NULL);
|
||||
|
|
@ -843,7 +877,7 @@ void acpi_processor_uninstall_hotplug_notify(void)
|
|||
{
|
||||
#ifdef CONFIG_ACPI_HOTPLUG_CPU
|
||||
int action = UNINSTALL_NOTIFY_HANDLER;
|
||||
acpi_walk_namespace(ACPI_TYPE_PROCESSOR,
|
||||
acpi_walk_namespace(ACPI_TYPE_ANY,
|
||||
ACPI_ROOT_OBJECT,
|
||||
ACPI_UINT32_MAX,
|
||||
processor_walk_namespace_cb, NULL, &action, NULL);
|
||||
|
|
|
|||
|
|
@ -1190,8 +1190,7 @@ int acpi_processor_cst_has_changed(struct acpi_processor *pr)
|
|||
* to make the code that updates C-States be called once.
|
||||
*/
|
||||
|
||||
if (smp_processor_id() == 0 &&
|
||||
cpuidle_get_driver() == &acpi_idle_driver) {
|
||||
if (pr->id == 0 && cpuidle_get_driver() == &acpi_idle_driver) {
|
||||
|
||||
cpuidle_pause_and_lock();
|
||||
/* Protect against cpu-hotplug */
|
||||
|
|
|
|||
|
|
@ -240,6 +240,28 @@ void acpi_processor_ppc_exit(void)
|
|||
acpi_processor_ppc_status &= ~PPC_REGISTERED;
|
||||
}
|
||||
|
||||
/*
|
||||
* Do a quick check if the systems looks like it should use ACPI
|
||||
* cpufreq. We look at a _PCT method being available, but don't
|
||||
* do a whole lot of sanity checks.
|
||||
*/
|
||||
void acpi_processor_load_module(struct acpi_processor *pr)
|
||||
{
|
||||
static int requested;
|
||||
acpi_status status = 0;
|
||||
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
|
||||
|
||||
if (!arch_has_acpi_pdc() || requested)
|
||||
return;
|
||||
status = acpi_evaluate_object(pr->handle, "_PCT", NULL, &buffer);
|
||||
if (!ACPI_FAILURE(status)) {
|
||||
printk(KERN_INFO PREFIX "Requesting acpi_cpufreq\n");
|
||||
request_module_nowait("acpi_cpufreq");
|
||||
requested = 1;
|
||||
}
|
||||
kfree(buffer.pointer);
|
||||
}
|
||||
|
||||
static int acpi_processor_get_performance_control(struct acpi_processor *pr)
|
||||
{
|
||||
int result = 0;
|
||||
|
|
|
|||
|
|
@ -57,6 +57,27 @@ ACPI_MODULE_NAME("processor_thermal");
|
|||
static DEFINE_PER_CPU(unsigned int, cpufreq_thermal_reduction_pctg);
|
||||
static unsigned int acpi_thermal_cpufreq_is_init = 0;
|
||||
|
||||
#define reduction_pctg(cpu) \
|
||||
per_cpu(cpufreq_thermal_reduction_pctg, phys_package_first_cpu(cpu))
|
||||
|
||||
/*
|
||||
* Emulate "per package data" using per cpu data (which should really be
|
||||
* provided elsewhere)
|
||||
*
|
||||
* Note we can lose a CPU on cpu hotunplug, in this case we forget the state
|
||||
* temporarily. Fortunately that's not a big issue here (I hope)
|
||||
*/
|
||||
static int phys_package_first_cpu(int cpu)
|
||||
{
|
||||
int i;
|
||||
int id = topology_physical_package_id(cpu);
|
||||
|
||||
for_each_online_cpu(i)
|
||||
if (topology_physical_package_id(i) == id)
|
||||
return i;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cpu_has_cpufreq(unsigned int cpu)
|
||||
{
|
||||
struct cpufreq_policy policy;
|
||||
|
|
@ -76,7 +97,7 @@ static int acpi_thermal_cpufreq_notifier(struct notifier_block *nb,
|
|||
|
||||
max_freq = (
|
||||
policy->cpuinfo.max_freq *
|
||||
(100 - per_cpu(cpufreq_thermal_reduction_pctg, policy->cpu) * 20)
|
||||
(100 - reduction_pctg(policy->cpu) * 20)
|
||||
) / 100;
|
||||
|
||||
cpufreq_verify_within_limits(policy, 0, max_freq);
|
||||
|
|
@ -102,16 +123,28 @@ static int cpufreq_get_cur_state(unsigned int cpu)
|
|||
if (!cpu_has_cpufreq(cpu))
|
||||
return 0;
|
||||
|
||||
return per_cpu(cpufreq_thermal_reduction_pctg, cpu);
|
||||
return reduction_pctg(cpu);
|
||||
}
|
||||
|
||||
static int cpufreq_set_cur_state(unsigned int cpu, int state)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!cpu_has_cpufreq(cpu))
|
||||
return 0;
|
||||
|
||||
per_cpu(cpufreq_thermal_reduction_pctg, cpu) = state;
|
||||
cpufreq_update_policy(cpu);
|
||||
reduction_pctg(cpu) = state;
|
||||
|
||||
/*
|
||||
* Update all the CPUs in the same package because they all
|
||||
* contribute to the temperature and often share the same
|
||||
* frequency.
|
||||
*/
|
||||
for_each_online_cpu(i) {
|
||||
if (topology_physical_package_id(i) ==
|
||||
topology_physical_package_id(cpu))
|
||||
cpufreq_update_policy(i);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -119,10 +152,6 @@ void acpi_thermal_cpufreq_init(void)
|
|||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < nr_cpu_ids; i++)
|
||||
if (cpu_present(i))
|
||||
per_cpu(cpufreq_thermal_reduction_pctg, i) = 0;
|
||||
|
||||
i = cpufreq_register_notifier(&acpi_thermal_cpufreq_notifier_block,
|
||||
CPUFREQ_POLICY_NOTIFIER);
|
||||
if (!i)
|
||||
|
|
|
|||
|
|
@ -769,7 +769,7 @@ static int acpi_read_throttling_status(struct acpi_processor *pr,
|
|||
u64 *value)
|
||||
{
|
||||
u32 bit_width, bit_offset;
|
||||
u64 ptc_value;
|
||||
u32 ptc_value;
|
||||
u64 ptc_mask;
|
||||
struct acpi_processor_throttling *throttling;
|
||||
int ret = -1;
|
||||
|
|
@ -777,12 +777,11 @@ static int acpi_read_throttling_status(struct acpi_processor *pr,
|
|||
throttling = &pr->throttling;
|
||||
switch (throttling->status_register.space_id) {
|
||||
case ACPI_ADR_SPACE_SYSTEM_IO:
|
||||
ptc_value = 0;
|
||||
bit_width = throttling->status_register.bit_width;
|
||||
bit_offset = throttling->status_register.bit_offset;
|
||||
|
||||
acpi_os_read_port((acpi_io_address) throttling->status_register.
|
||||
address, (u32 *) &ptc_value,
|
||||
address, &ptc_value,
|
||||
(u32) (bit_width + bit_offset));
|
||||
ptc_mask = (1 << bit_width) - 1;
|
||||
*value = (u64) ((ptc_value >> bit_offset) & ptc_mask);
|
||||
|
|
|
|||
|
|
@ -23,8 +23,7 @@ void acpi_reboot(void)
|
|||
/* Is the reset register supported? The spec says we should be
|
||||
* checking the bit width and bit offset, but Windows ignores
|
||||
* these fields */
|
||||
if (!(acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER))
|
||||
return;
|
||||
/* Ignore also acpi_gbl_FADT.flags.ACPI_FADT_RESET_REGISTER */
|
||||
|
||||
reset_value = acpi_gbl_FADT.reset_value;
|
||||
|
||||
|
|
|
|||
|
|
@ -880,18 +880,22 @@ static int acpi_bus_get_power_flags(struct acpi_device *device)
|
|||
int j;
|
||||
|
||||
device->power.flags.power_resources = 1;
|
||||
ps->flags.valid = 1;
|
||||
for (j = 0; j < ps->resources.count; j++)
|
||||
acpi_bus_add_power_resource(ps->resources.handles[j]);
|
||||
}
|
||||
|
||||
/* The exist of _PR3 indicates D3Cold support */
|
||||
if (i == ACPI_STATE_D3) {
|
||||
status = acpi_get_handle(device->handle, object_name, &handle);
|
||||
if (ACPI_SUCCESS(status))
|
||||
device->power.states[ACPI_STATE_D3_COLD].flags.valid = 1;
|
||||
}
|
||||
|
||||
/* Evaluate "_PSx" to see if we can do explicit sets */
|
||||
object_name[2] = 'S';
|
||||
status = acpi_get_handle(device->handle, object_name, &handle);
|
||||
if (ACPI_SUCCESS(status)) {
|
||||
if (ACPI_SUCCESS(status))
|
||||
ps->flags.explicit_set = 1;
|
||||
ps->flags.valid = 1;
|
||||
}
|
||||
|
||||
/* State is valid if we have some power control */
|
||||
if (ps->resources.count || ps->flags.explicit_set)
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@
|
|||
#include <linux/suspend.h>
|
||||
#include <linux/reboot.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
|
||||
|
|
@ -26,6 +28,24 @@
|
|||
#include "internal.h"
|
||||
#include "sleep.h"
|
||||
|
||||
static unsigned int gts, bfs;
|
||||
module_param(gts, uint, 0644);
|
||||
module_param(bfs, uint, 0644);
|
||||
MODULE_PARM_DESC(gts, "Enable evaluation of _GTS on suspend.");
|
||||
MODULE_PARM_DESC(bfs, "Enable evaluation of _BFS on resume".);
|
||||
|
||||
static u8 wake_sleep_flags(void)
|
||||
{
|
||||
u8 flags = ACPI_NO_OPTIONAL_METHODS;
|
||||
|
||||
if (gts)
|
||||
flags |= ACPI_EXECUTE_GTS;
|
||||
if (bfs)
|
||||
flags |= ACPI_EXECUTE_BFS;
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
static u8 sleep_states[ACPI_S_STATE_COUNT];
|
||||
|
||||
static void acpi_sleep_tts_switch(u32 acpi_state)
|
||||
|
|
@ -243,6 +263,7 @@ static int acpi_suspend_enter(suspend_state_t pm_state)
|
|||
{
|
||||
acpi_status status = AE_OK;
|
||||
u32 acpi_state = acpi_target_sleep_state;
|
||||
u8 flags = wake_sleep_flags();
|
||||
int error;
|
||||
|
||||
ACPI_FLUSH_CPU_CACHE();
|
||||
|
|
@ -250,7 +271,7 @@ static int acpi_suspend_enter(suspend_state_t pm_state)
|
|||
switch (acpi_state) {
|
||||
case ACPI_STATE_S1:
|
||||
barrier();
|
||||
status = acpi_enter_sleep_state(acpi_state);
|
||||
status = acpi_enter_sleep_state(acpi_state, flags);
|
||||
break;
|
||||
|
||||
case ACPI_STATE_S3:
|
||||
|
|
@ -265,7 +286,7 @@ static int acpi_suspend_enter(suspend_state_t pm_state)
|
|||
acpi_write_bit_register(ACPI_BITREG_SCI_ENABLE, 1);
|
||||
|
||||
/* Reprogram control registers and execute _BFS */
|
||||
acpi_leave_sleep_state_prep(acpi_state);
|
||||
acpi_leave_sleep_state_prep(acpi_state, flags);
|
||||
|
||||
/* ACPI 3.0 specs (P62) says that it's the responsibility
|
||||
* of the OSPM to clear the status bit [ implying that the
|
||||
|
|
@ -529,27 +550,30 @@ static int acpi_hibernation_begin(void)
|
|||
|
||||
static int acpi_hibernation_enter(void)
|
||||
{
|
||||
u8 flags = wake_sleep_flags();
|
||||
acpi_status status = AE_OK;
|
||||
|
||||
ACPI_FLUSH_CPU_CACHE();
|
||||
|
||||
/* This shouldn't return. If it returns, we have a problem */
|
||||
status = acpi_enter_sleep_state(ACPI_STATE_S4);
|
||||
status = acpi_enter_sleep_state(ACPI_STATE_S4, flags);
|
||||
/* Reprogram control registers and execute _BFS */
|
||||
acpi_leave_sleep_state_prep(ACPI_STATE_S4);
|
||||
acpi_leave_sleep_state_prep(ACPI_STATE_S4, flags);
|
||||
|
||||
return ACPI_SUCCESS(status) ? 0 : -EFAULT;
|
||||
}
|
||||
|
||||
static void acpi_hibernation_leave(void)
|
||||
{
|
||||
u8 flags = wake_sleep_flags();
|
||||
|
||||
/*
|
||||
* If ACPI is not enabled by the BIOS and the boot kernel, we need to
|
||||
* enable it here.
|
||||
*/
|
||||
acpi_enable();
|
||||
/* Reprogram control registers and execute _BFS */
|
||||
acpi_leave_sleep_state_prep(ACPI_STATE_S4);
|
||||
acpi_leave_sleep_state_prep(ACPI_STATE_S4, flags);
|
||||
/* Check the hardware signature */
|
||||
if (facs && s4_hardware_signature != facs->hardware_signature) {
|
||||
printk(KERN_EMERG "ACPI: Hardware changed while hibernated, "
|
||||
|
|
@ -729,6 +753,40 @@ int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p)
|
|||
#endif /* CONFIG_PM */
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
/**
|
||||
* acpi_pm_device_run_wake - Enable/disable wake-up for given device.
|
||||
* @phys_dev: Device to enable/disable the platform to wake-up the system for.
|
||||
* @enable: Whether enable or disable the wake-up functionality.
|
||||
*
|
||||
* Find the ACPI device object corresponding to @pci_dev and try to
|
||||
* enable/disable the GPE associated with it.
|
||||
*/
|
||||
int acpi_pm_device_run_wake(struct device *phys_dev, bool enable)
|
||||
{
|
||||
struct acpi_device *dev;
|
||||
acpi_handle handle;
|
||||
|
||||
if (!device_run_wake(phys_dev))
|
||||
return -EINVAL;
|
||||
|
||||
handle = DEVICE_ACPI_HANDLE(phys_dev);
|
||||
if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &dev))) {
|
||||
dev_dbg(phys_dev, "ACPI handle has no context in %s!\n",
|
||||
__func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (enable) {
|
||||
acpi_enable_wakeup_device_power(dev, ACPI_STATE_S0);
|
||||
acpi_enable_gpe(dev->wakeup.gpe_device, dev->wakeup.gpe_number);
|
||||
} else {
|
||||
acpi_disable_gpe(dev->wakeup.gpe_device, dev->wakeup.gpe_number);
|
||||
acpi_disable_wakeup_device_power(dev);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* acpi_pm_device_sleep_wake - enable or disable the system wake-up
|
||||
* capability of given device
|
||||
|
|
@ -770,10 +828,12 @@ static void acpi_power_off_prepare(void)
|
|||
|
||||
static void acpi_power_off(void)
|
||||
{
|
||||
u8 flags = wake_sleep_flags();
|
||||
|
||||
/* acpi_sleep_prepare(ACPI_STATE_S5) should have already been called */
|
||||
printk(KERN_DEBUG "%s called\n", __func__);
|
||||
local_irq_disable();
|
||||
acpi_enter_sleep_state(ACPI_STATE_S5);
|
||||
acpi_enter_sleep_state(ACPI_STATE_S5, flags);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -788,13 +848,13 @@ static void __init acpi_gts_bfs_check(void)
|
|||
{
|
||||
acpi_handle dummy;
|
||||
|
||||
if (ACPI_SUCCESS(acpi_get_handle(ACPI_ROOT_OBJECT, METHOD_NAME__GTS, &dummy)))
|
||||
if (ACPI_SUCCESS(acpi_get_handle(ACPI_ROOT_OBJECT, METHOD_PATHNAME__GTS, &dummy)))
|
||||
{
|
||||
printk(KERN_NOTICE PREFIX "BIOS offers _GTS\n");
|
||||
printk(KERN_NOTICE PREFIX "If \"acpi.gts=1\" improves suspend, "
|
||||
"please notify [email protected]\n");
|
||||
}
|
||||
if (ACPI_SUCCESS(acpi_get_handle(ACPI_ROOT_OBJECT, METHOD_NAME__BFS, &dummy)))
|
||||
if (ACPI_SUCCESS(acpi_get_handle(ACPI_ROOT_OBJECT, METHOD_PATHNAME__BFS, &dummy)))
|
||||
{
|
||||
printk(KERN_NOTICE PREFIX "BIOS offers _BFS\n");
|
||||
printk(KERN_NOTICE PREFIX "If \"acpi.bfs=1\" improves resume, "
|
||||
|
|
|
|||
|
|
@ -941,13 +941,13 @@ static int acpi_thermal_get_info(struct acpi_thermal *tz)
|
|||
if (!tz)
|
||||
return -EINVAL;
|
||||
|
||||
/* Get temperature [_TMP] (required) */
|
||||
result = acpi_thermal_get_temperature(tz);
|
||||
/* Get trip points [_CRT, _PSV, etc.] (required) */
|
||||
result = acpi_thermal_get_trip_points(tz);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
/* Get trip points [_CRT, _PSV, etc.] (required) */
|
||||
result = acpi_thermal_get_trip_points(tz);
|
||||
/* Get temperature [_TMP] (required) */
|
||||
result = acpi_thermal_get_temperature(tz);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
|
|
|
|||
|
|
@ -548,27 +548,27 @@ acpi_video_device_EDID(struct acpi_video_device *device,
|
|||
* 1. The system BIOS should NOT automatically control the brightness
|
||||
* level of the LCD when the power changes from AC to DC.
|
||||
* Return Value:
|
||||
* -1 wrong arg.
|
||||
* -EINVAL wrong arg.
|
||||
*/
|
||||
|
||||
static int
|
||||
acpi_video_bus_DOS(struct acpi_video_bus *video, int bios_flag, int lcd_flag)
|
||||
{
|
||||
u64 status = 0;
|
||||
acpi_status status;
|
||||
union acpi_object arg0 = { ACPI_TYPE_INTEGER };
|
||||
struct acpi_object_list args = { 1, &arg0 };
|
||||
|
||||
|
||||
if (bios_flag < 0 || bios_flag > 3 || lcd_flag < 0 || lcd_flag > 1) {
|
||||
status = -1;
|
||||
goto Failed;
|
||||
}
|
||||
if (bios_flag < 0 || bios_flag > 3 || lcd_flag < 0 || lcd_flag > 1)
|
||||
return -EINVAL;
|
||||
arg0.integer.value = (lcd_flag << 2) | bios_flag;
|
||||
video->dos_setting = arg0.integer.value;
|
||||
acpi_evaluate_object(video->device->handle, "_DOS", &args, NULL);
|
||||
status = acpi_evaluate_object(video->device->handle, "_DOS",
|
||||
&args, NULL);
|
||||
if (ACPI_FAILURE(status))
|
||||
return -EIO;
|
||||
|
||||
Failed:
|
||||
return status;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -1343,15 +1343,17 @@ static int
|
|||
acpi_video_bus_get_devices(struct acpi_video_bus *video,
|
||||
struct acpi_device *device)
|
||||
{
|
||||
int status = 0;
|
||||
int status;
|
||||
struct acpi_device *dev;
|
||||
|
||||
acpi_video_device_enumerate(video);
|
||||
status = acpi_video_device_enumerate(video);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
list_for_each_entry(dev, &device->children, node) {
|
||||
|
||||
status = acpi_video_bus_get_one_device(dev, video);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
if (status) {
|
||||
printk(KERN_WARNING PREFIX
|
||||
"Can't attach device\n");
|
||||
continue;
|
||||
|
|
@ -1653,15 +1655,20 @@ static int acpi_video_bus_add(struct acpi_device *device)
|
|||
mutex_init(&video->device_list_lock);
|
||||
INIT_LIST_HEAD(&video->video_device_list);
|
||||
|
||||
acpi_video_bus_get_devices(video, device);
|
||||
acpi_video_bus_start_devices(video);
|
||||
error = acpi_video_bus_get_devices(video, device);
|
||||
if (error)
|
||||
goto err_free_video;
|
||||
|
||||
video->input = input = input_allocate_device();
|
||||
if (!input) {
|
||||
error = -ENOMEM;
|
||||
goto err_stop_video;
|
||||
goto err_put_video;
|
||||
}
|
||||
|
||||
error = acpi_video_bus_start_devices(video);
|
||||
if (error)
|
||||
goto err_free_input_dev;
|
||||
|
||||
snprintf(video->phys, sizeof(video->phys),
|
||||
"%s/video/input0", acpi_device_hid(video->device));
|
||||
|
||||
|
|
@ -1682,7 +1689,7 @@ static int acpi_video_bus_add(struct acpi_device *device)
|
|||
|
||||
error = input_register_device(input);
|
||||
if (error)
|
||||
goto err_free_input_dev;
|
||||
goto err_stop_video;
|
||||
|
||||
printk(KERN_INFO PREFIX "%s [%s] (multi-head: %s rom: %s post: %s)\n",
|
||||
ACPI_VIDEO_DEVICE_NAME, acpi_device_bid(device),
|
||||
|
|
@ -1692,14 +1699,19 @@ static int acpi_video_bus_add(struct acpi_device *device)
|
|||
|
||||
video->pm_nb.notifier_call = acpi_video_resume;
|
||||
video->pm_nb.priority = 0;
|
||||
register_pm_notifier(&video->pm_nb);
|
||||
error = register_pm_notifier(&video->pm_nb);
|
||||
if (error)
|
||||
goto err_unregister_input_dev;
|
||||
|
||||
return 0;
|
||||
|
||||
err_free_input_dev:
|
||||
input_free_device(input);
|
||||
err_unregister_input_dev:
|
||||
input_unregister_device(input);
|
||||
err_stop_video:
|
||||
acpi_video_bus_stop_devices(video);
|
||||
err_free_input_dev:
|
||||
input_free_device(input);
|
||||
err_put_video:
|
||||
acpi_video_bus_put_devices(video);
|
||||
kfree(video->attached_array);
|
||||
err_free_video:
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
* Depending on whether ACPI graphics extensions (cmp. ACPI spec Appendix B)
|
||||
* are available, video.ko should be used to handle the device.
|
||||
*
|
||||
* Otherwise vendor specific drivers like thinkpad_acpi, asus_acpi,
|
||||
* Otherwise vendor specific drivers like thinkpad_acpi, asus-laptop,
|
||||
* sony_acpi,... can take care about backlight brightness.
|
||||
*
|
||||
* If CONFIG_ACPI_VIDEO is neither set as "compiled in" (y) nor as a module (m)
|
||||
|
|
|
|||
Loading…
Reference in a new issue