forked from Minki/linux
Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6
* 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6: (53 commits) ACPI: install ACPI table handler before any dynamic tables being loaded ACPI / PM: Blacklist another machine that needs acpi_sleep=nonvs ACPI: Page based coalescing of I/O remappings optimization ACPI: Convert simple locking to RCU based locking ACPI: Pre-map 'system event' related register blocks ACPI: Add interfaces for ioremapping/iounmapping ACPI registers ACPI: Maintain a list of ACPI memory mapped I/O remappings ACPI: Fix ioremap size for MMIO reads and writes ACPI / Battery: Return -ENODEV for unknown values in get_property() ACPI / PM: Fix reference counting of power resources Subject: [PATCH] ACPICA: Fix Scope() op in module level code ACPI battery: support percentage battery remaining capacity ACPI: Make Embedded Controller command timeout delay configurable ACPI dock: move some functions to .init.text ACPI: thermal: remove unused limit code ACPI: static sleep_states[] and acpi_gts_bfs_check ACPI: remove dead code ACPI: delete dedicated MAINTAINERS entries for ACPI EC and BATTERY drivers ACPI: Only processor needs CPU_IDLE ACPICA: Update version to 20101013 ...
This commit is contained in:
commit
474829e875
15
MAINTAINERS
15
MAINTAINERS
@ -243,21 +243,6 @@ F: drivers/pnp/pnpacpi/
|
||||
F: include/linux/acpi.h
|
||||
F: include/acpi/
|
||||
|
||||
ACPI BATTERY DRIVERS
|
||||
M: Alexey Starikovskiy <astarikovskiy@suse.de>
|
||||
L: linux-acpi@vger.kernel.org
|
||||
W: http://www.lesswatts.org/projects/acpi/
|
||||
S: Supported
|
||||
F: drivers/acpi/battery.c
|
||||
F: drivers/acpi/*sbs*
|
||||
|
||||
ACPI EC DRIVER
|
||||
M: Alexey Starikovskiy <astarikovskiy@suse.de>
|
||||
L: linux-acpi@vger.kernel.org
|
||||
W: http://www.lesswatts.org/projects/acpi/
|
||||
S: Supported
|
||||
F: drivers/acpi/ec.c
|
||||
|
||||
ACPI FAN DRIVER
|
||||
M: Zhang Rui <rui.zhang@intel.com>
|
||||
L: linux-acpi@vger.kernel.org
|
||||
|
@ -701,6 +701,7 @@ static int acpi_cpufreq_cpu_exit(struct cpufreq_policy *policy)
|
||||
per_cpu(acfreq_data, policy->cpu) = NULL;
|
||||
acpi_processor_unregister_performance(data->acpi_data,
|
||||
policy->cpu);
|
||||
kfree(data->freq_table);
|
||||
kfree(data);
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,6 @@ menuconfig ACPI
|
||||
depends on PCI
|
||||
depends on PM
|
||||
select PNP
|
||||
select CPU_IDLE
|
||||
default y
|
||||
help
|
||||
Advanced Configuration and Power Interface (ACPI) support for
|
||||
@ -66,7 +65,6 @@ config ACPI_PROCFS
|
||||
config ACPI_PROCFS_POWER
|
||||
bool "Deprecated power /proc/acpi directories"
|
||||
depends on PROC_FS
|
||||
default y
|
||||
help
|
||||
For backwards compatibility, this option allows
|
||||
deprecated power /proc/acpi/ directories to exist, even when
|
||||
@ -90,13 +88,6 @@ config ACPI_POWER_METER
|
||||
To compile this driver as a module, choose M here:
|
||||
the module will be called power-meter.
|
||||
|
||||
config ACPI_SYSFS_POWER
|
||||
bool "Future power /sys interface"
|
||||
select POWER_SUPPLY
|
||||
default y
|
||||
help
|
||||
Say N to disable power /sys interface
|
||||
|
||||
config ACPI_EC_DEBUGFS
|
||||
tristate "EC read/write access through /sys/kernel/debug/ec"
|
||||
default n
|
||||
@ -136,6 +127,7 @@ config ACPI_PROC_EVENT
|
||||
config ACPI_AC
|
||||
tristate "AC Adapter"
|
||||
depends on X86
|
||||
select POWER_SUPPLY
|
||||
default y
|
||||
help
|
||||
This driver supports the AC Adapter object, which indicates
|
||||
@ -148,6 +140,7 @@ config ACPI_AC
|
||||
config ACPI_BATTERY
|
||||
tristate "Battery"
|
||||
depends on X86
|
||||
select POWER_SUPPLY
|
||||
default y
|
||||
help
|
||||
This driver adds support for battery information through
|
||||
@ -206,6 +199,7 @@ config ACPI_DOCK
|
||||
config ACPI_PROCESSOR
|
||||
tristate "Processor"
|
||||
select THERMAL
|
||||
select CPU_IDLE
|
||||
default y
|
||||
help
|
||||
This driver installs ACPI as the idle handler for Linux and uses
|
||||
@ -364,6 +358,7 @@ config ACPI_HOTPLUG_MEMORY
|
||||
config ACPI_SBS
|
||||
tristate "Smart Battery System"
|
||||
depends on X86
|
||||
select POWER_SUPPLY
|
||||
help
|
||||
This driver supports the Smart Battery System, another
|
||||
type of access to battery information, found on some laptops.
|
||||
|
@ -32,9 +32,7 @@
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/seq_file.h>
|
||||
#endif
|
||||
#ifdef CONFIG_ACPI_SYSFS_POWER
|
||||
#include <linux/power_supply.h>
|
||||
#endif
|
||||
#include <acpi/acpi_bus.h>
|
||||
#include <acpi/acpi_drivers.h>
|
||||
|
||||
@ -86,9 +84,7 @@ static struct acpi_driver acpi_ac_driver = {
|
||||
};
|
||||
|
||||
struct acpi_ac {
|
||||
#ifdef CONFIG_ACPI_SYSFS_POWER
|
||||
struct power_supply charger;
|
||||
#endif
|
||||
struct acpi_device * device;
|
||||
unsigned long long state;
|
||||
};
|
||||
@ -104,7 +100,6 @@ static const struct file_operations acpi_ac_fops = {
|
||||
.release = single_release,
|
||||
};
|
||||
#endif
|
||||
#ifdef CONFIG_ACPI_SYSFS_POWER
|
||||
static int get_ac_property(struct power_supply *psy,
|
||||
enum power_supply_property psp,
|
||||
union power_supply_propval *val)
|
||||
@ -123,7 +118,6 @@ static int get_ac_property(struct power_supply *psy,
|
||||
static enum power_supply_property ac_props[] = {
|
||||
POWER_SUPPLY_PROP_ONLINE,
|
||||
};
|
||||
#endif
|
||||
/* --------------------------------------------------------------------------
|
||||
AC Adapter Management
|
||||
-------------------------------------------------------------------------- */
|
||||
@ -247,9 +241,7 @@ static void acpi_ac_notify(struct acpi_device *device, u32 event)
|
||||
dev_name(&device->dev), event,
|
||||
(u32) ac->state);
|
||||
acpi_notifier_call_chain(device, event, (u32) ac->state);
|
||||
#ifdef CONFIG_ACPI_SYSFS_POWER
|
||||
kobject_uevent(&ac->charger.dev->kobj, KOBJ_CHANGE);
|
||||
#endif
|
||||
}
|
||||
|
||||
return;
|
||||
@ -282,14 +274,12 @@ static int acpi_ac_add(struct acpi_device *device)
|
||||
#endif
|
||||
if (result)
|
||||
goto end;
|
||||
#ifdef CONFIG_ACPI_SYSFS_POWER
|
||||
ac->charger.name = acpi_device_bid(device);
|
||||
ac->charger.type = POWER_SUPPLY_TYPE_MAINS;
|
||||
ac->charger.properties = ac_props;
|
||||
ac->charger.num_properties = ARRAY_SIZE(ac_props);
|
||||
ac->charger.get_property = get_ac_property;
|
||||
power_supply_register(&ac->device->dev, &ac->charger);
|
||||
#endif
|
||||
|
||||
printk(KERN_INFO PREFIX "%s [%s] (%s)\n",
|
||||
acpi_device_name(device), acpi_device_bid(device),
|
||||
@ -316,10 +306,8 @@ static int acpi_ac_resume(struct acpi_device *device)
|
||||
old_state = ac->state;
|
||||
if (acpi_ac_get_state(ac))
|
||||
return 0;
|
||||
#ifdef CONFIG_ACPI_SYSFS_POWER
|
||||
if (old_state != ac->state)
|
||||
kobject_uevent(&ac->charger.dev->kobj, KOBJ_CHANGE);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -333,10 +321,8 @@ static int acpi_ac_remove(struct acpi_device *device, int type)
|
||||
|
||||
ac = acpi_driver_data(device);
|
||||
|
||||
#ifdef CONFIG_ACPI_SYSFS_POWER
|
||||
if (ac->charger.dev)
|
||||
power_supply_unregister(&ac->charger);
|
||||
#endif
|
||||
#ifdef CONFIG_ACPI_PROCFS_POWER
|
||||
acpi_ac_remove_fs(device);
|
||||
#endif
|
||||
|
@ -21,7 +21,7 @@ acpi-y += exconfig.o exfield.o exnames.o exoparg6.o exresolv.o exstorob.o\
|
||||
excreate.o exmisc.o exoparg2.o exregion.o exstore.o exutils.o \
|
||||
exdump.o exmutex.o exoparg3.o exresnte.o exstoren.o exdebug.o
|
||||
|
||||
acpi-y += hwacpi.o hwgpe.o hwregs.o hwsleep.o hwxface.o hwvalid.o
|
||||
acpi-y += hwacpi.o hwgpe.o hwregs.o hwsleep.o hwxface.o hwvalid.o hwpci.o
|
||||
|
||||
acpi-$(ACPI_FUTURE_USAGE) += hwtimer.o
|
||||
|
||||
@ -44,4 +44,5 @@ acpi-y += tbxface.o tbinstal.o tbutils.o tbfind.o tbfadt.o tbxfroot.o
|
||||
|
||||
acpi-y += utalloc.o utdebug.o uteval.o utinit.o utmisc.o utxface.o \
|
||||
utcopy.o utdelete.o utglobal.o utmath.o utobject.o \
|
||||
utstate.o utmutex.o utobject.o utresrc.o utlock.o utids.o
|
||||
utstate.o utmutex.o utobject.o utresrc.o utlock.o utids.o \
|
||||
utosi.o utxferror.o
|
||||
|
@ -105,6 +105,8 @@ void acpi_db_set_method_data(char *type_arg, char *index_arg, char *value_arg);
|
||||
acpi_status
|
||||
acpi_db_display_objects(char *obj_type_arg, char *display_count_arg);
|
||||
|
||||
void acpi_db_display_interfaces(char *action_arg, char *interface_name_arg);
|
||||
|
||||
acpi_status acpi_db_find_name_in_namespace(char *name_arg);
|
||||
|
||||
void acpi_db_set_scope(char *name);
|
||||
|
@ -105,8 +105,9 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device,
|
||||
struct acpi_gpe_block_info **return_gpe_block);
|
||||
|
||||
acpi_status
|
||||
acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device,
|
||||
struct acpi_gpe_block_info *gpe_block);
|
||||
acpi_ev_initialize_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
|
||||
struct acpi_gpe_block_info *gpe_block,
|
||||
void *ignored);
|
||||
|
||||
acpi_status acpi_ev_delete_gpe_block(struct acpi_gpe_block_info *gpe_block);
|
||||
|
||||
|
@ -132,6 +132,7 @@ struct acpi_table_fadt acpi_gbl_FADT;
|
||||
u32 acpi_current_gpe_count;
|
||||
u32 acpi_gbl_trace_flags;
|
||||
acpi_name acpi_gbl_trace_method_name;
|
||||
u8 acpi_gbl_system_awake_and_running;
|
||||
|
||||
#endif
|
||||
|
||||
@ -187,6 +188,10 @@ ACPI_EXTERN u8 acpi_gbl_integer_bit_width;
|
||||
ACPI_EXTERN u8 acpi_gbl_integer_byte_width;
|
||||
ACPI_EXTERN u8 acpi_gbl_integer_nybble_width;
|
||||
|
||||
/* Mutex for _OSI support */
|
||||
|
||||
ACPI_EXTERN acpi_mutex acpi_gbl_osi_mutex;
|
||||
|
||||
/* Reader/Writer lock is used for namespace walk and dynamic table unload */
|
||||
|
||||
ACPI_EXTERN struct acpi_rw_lock acpi_gbl_namespace_rw_lock;
|
||||
@ -255,6 +260,7 @@ ACPI_EXTERN acpi_init_handler acpi_gbl_init_handler;
|
||||
ACPI_EXTERN acpi_tbl_handler acpi_gbl_table_handler;
|
||||
ACPI_EXTERN void *acpi_gbl_table_handler_context;
|
||||
ACPI_EXTERN struct acpi_walk_state *acpi_gbl_breakpoint_walk;
|
||||
ACPI_EXTERN acpi_interface_handler acpi_gbl_interface_handler;
|
||||
|
||||
/* Owner ID support */
|
||||
|
||||
@ -273,8 +279,8 @@ ACPI_EXTERN u8 acpi_gbl_debugger_configuration;
|
||||
ACPI_EXTERN u8 acpi_gbl_step_to_next_call;
|
||||
ACPI_EXTERN u8 acpi_gbl_acpi_hardware_present;
|
||||
ACPI_EXTERN u8 acpi_gbl_events_initialized;
|
||||
ACPI_EXTERN u8 acpi_gbl_system_awake_and_running;
|
||||
ACPI_EXTERN u8 acpi_gbl_osi_data;
|
||||
ACPI_EXTERN struct acpi_interface_info *acpi_gbl_supported_interfaces;
|
||||
|
||||
#ifndef DEFINE_ACPI_GLOBALS
|
||||
|
||||
@ -364,6 +370,7 @@ 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];
|
||||
ACPI_EXTERN u8 acpi_all_gpes_initialized;
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
|
@ -121,6 +121,13 @@ acpi_hw_enable_runtime_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
|
||||
struct acpi_gpe_block_info *gpe_block,
|
||||
void *context);
|
||||
|
||||
/*
|
||||
* hwpci - PCI configuration support
|
||||
*/
|
||||
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
|
||||
|
@ -413,6 +413,7 @@ struct acpi_handler_info {
|
||||
void *context; /* Context to be passed to handler */
|
||||
struct acpi_namespace_node *method_node; /* Method node for this GPE level (saved) */
|
||||
u8 orig_flags; /* Original misc info about this GPE */
|
||||
u8 orig_enabled; /* Set if the GPE was originally enabled */
|
||||
};
|
||||
|
||||
union acpi_gpe_dispatch_info {
|
||||
@ -457,6 +458,7 @@ struct acpi_gpe_block_info {
|
||||
u32 register_count; /* Number of register pairs in block */
|
||||
u16 gpe_count; /* Number of individual GPEs in block */
|
||||
u8 block_base_number; /* Base GPE number for this block */
|
||||
u8 initialized; /* If set, the GPE block has been initialized */
|
||||
};
|
||||
|
||||
/* Information about GPE interrupt handlers, one per each interrupt level used for GPEs */
|
||||
@ -473,7 +475,6 @@ struct acpi_gpe_walk_info {
|
||||
struct acpi_gpe_block_info *gpe_block;
|
||||
u16 count;
|
||||
acpi_owner_id owner_id;
|
||||
u8 enable_this_gpe;
|
||||
u8 execute_by_owner_id;
|
||||
};
|
||||
|
||||
@ -854,7 +855,7 @@ struct acpi_bit_register_info {
|
||||
ACPI_BITMASK_POWER_BUTTON_STATUS | \
|
||||
ACPI_BITMASK_SLEEP_BUTTON_STATUS | \
|
||||
ACPI_BITMASK_RT_CLOCK_STATUS | \
|
||||
ACPI_BITMASK_PCIEXP_WAKE_DISABLE | \
|
||||
ACPI_BITMASK_PCIEXP_WAKE_STATUS | \
|
||||
ACPI_BITMASK_WAKE_STATUS)
|
||||
|
||||
#define ACPI_BITMASK_TIMER_ENABLE 0x0001
|
||||
@ -909,15 +910,21 @@ struct acpi_bit_register_info {
|
||||
#define ACPI_OSI_WIN_VISTA 0x07
|
||||
#define ACPI_OSI_WINSRV_2008 0x08
|
||||
#define ACPI_OSI_WIN_VISTA_SP1 0x09
|
||||
#define ACPI_OSI_WIN_7 0x0A
|
||||
#define ACPI_OSI_WIN_VISTA_SP2 0x0A
|
||||
#define ACPI_OSI_WIN_7 0x0B
|
||||
|
||||
#define ACPI_ALWAYS_ILLEGAL 0x00
|
||||
|
||||
struct acpi_interface_info {
|
||||
char *name;
|
||||
struct acpi_interface_info *next;
|
||||
u8 flags;
|
||||
u8 value;
|
||||
};
|
||||
|
||||
#define ACPI_OSI_INVALID 0x01
|
||||
#define ACPI_OSI_DYNAMIC 0x02
|
||||
|
||||
struct acpi_port_info {
|
||||
char *name;
|
||||
u16 start;
|
||||
@ -997,7 +1004,7 @@ struct acpi_port_info {
|
||||
struct acpi_db_method_info {
|
||||
acpi_handle main_thread_gate;
|
||||
acpi_handle thread_complete_gate;
|
||||
u32 *threads;
|
||||
acpi_thread_id *threads;
|
||||
u32 num_threads;
|
||||
u32 num_created;
|
||||
u32 num_completed;
|
||||
|
@ -338,8 +338,8 @@
|
||||
* the plist contains a set of parens to allow variable-length lists.
|
||||
* These macros are used for both the debug and non-debug versions of the code.
|
||||
*/
|
||||
#define ACPI_ERROR_NAMESPACE(s, e) acpi_ns_report_error (AE_INFO, s, e);
|
||||
#define ACPI_ERROR_METHOD(s, n, p, e) acpi_ns_report_method_error (AE_INFO, s, n, p, e);
|
||||
#define ACPI_ERROR_NAMESPACE(s, e) acpi_ut_namespace_error (AE_INFO, s, e);
|
||||
#define ACPI_ERROR_METHOD(s, n, p, e) acpi_ut_method_error (AE_INFO, s, n, p, e);
|
||||
#define ACPI_WARN_PREDEFINED(plist) acpi_ut_predefined_warning plist
|
||||
#define ACPI_INFO_PREDEFINED(plist) acpi_ut_predefined_info plist
|
||||
|
||||
|
@ -338,18 +338,6 @@ acpi_object_type acpi_ns_get_type(struct acpi_namespace_node *node);
|
||||
|
||||
u32 acpi_ns_local(acpi_object_type type);
|
||||
|
||||
void
|
||||
acpi_ns_report_error(const char *module_name,
|
||||
u32 line_number,
|
||||
const char *internal_name, acpi_status lookup_status);
|
||||
|
||||
void
|
||||
acpi_ns_report_method_error(const char *module_name,
|
||||
u32 line_number,
|
||||
const char *message,
|
||||
struct acpi_namespace_node *node,
|
||||
const char *path, acpi_status lookup_status);
|
||||
|
||||
void
|
||||
acpi_ns_print_node_pathname(struct acpi_namespace_node *node, const char *msg);
|
||||
|
||||
|
@ -248,7 +248,7 @@ ACPI_OBJECT_COMMON_HEADER ACPI_COMMON_NOTIFY_INFO};
|
||||
u32 base_byte_offset; /* Byte offset within containing object */\
|
||||
u32 value; /* Value to store into the Bank or Index register */\
|
||||
u8 start_field_bit_offset;/* Bit offset within first field datum (0-63) */\
|
||||
u8 access_bit_width; /* Read/Write size in bits (8-64) */
|
||||
|
||||
|
||||
struct acpi_object_field_common { /* COMMON FIELD (for BUFFER, REGION, BANK, and INDEX fields) */
|
||||
ACPI_OBJECT_COMMON_HEADER ACPI_COMMON_FIELD_INFO union acpi_operand_object *region_obj; /* Parent Operation Region object (REGION/BANK fields only) */
|
||||
|
@ -312,8 +312,6 @@ void acpi_ut_delete_internal_object_list(union acpi_operand_object **obj_list);
|
||||
/*
|
||||
* uteval - object evaluation
|
||||
*/
|
||||
acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state);
|
||||
|
||||
acpi_status
|
||||
acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node,
|
||||
char *path,
|
||||
@ -394,6 +392,21 @@ union acpi_operand_object *acpi_ut_create_string_object(acpi_size string_size);
|
||||
acpi_status
|
||||
acpi_ut_get_object_size(union acpi_operand_object *obj, acpi_size * obj_length);
|
||||
|
||||
/*
|
||||
* utosi - Support for the _OSI predefined control method
|
||||
*/
|
||||
acpi_status acpi_ut_initialize_interfaces(void);
|
||||
|
||||
void acpi_ut_interface_terminate(void);
|
||||
|
||||
acpi_status acpi_ut_install_interface(acpi_string interface_name);
|
||||
|
||||
acpi_status acpi_ut_remove_interface(acpi_string interface_name);
|
||||
|
||||
struct acpi_interface_info *acpi_ut_get_interface(acpi_string interface_name);
|
||||
|
||||
acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state);
|
||||
|
||||
/*
|
||||
* utstate - Generic state creation/cache routines
|
||||
*/
|
||||
@ -473,17 +486,6 @@ u8 acpi_ut_valid_acpi_char(char character, u32 position);
|
||||
|
||||
acpi_status acpi_ut_strtoul64(char *string, u32 base, u64 * ret_integer);
|
||||
|
||||
void ACPI_INTERNAL_VAR_XFACE
|
||||
acpi_ut_predefined_warning(const char *module_name,
|
||||
u32 line_number,
|
||||
char *pathname,
|
||||
u8 node_flags, const char *format, ...);
|
||||
|
||||
void ACPI_INTERNAL_VAR_XFACE
|
||||
acpi_ut_predefined_info(const char *module_name,
|
||||
u32 line_number,
|
||||
char *pathname, u8 node_flags, const char *format, ...);
|
||||
|
||||
/* Values for Base above (16=Hex, 10=Decimal) */
|
||||
|
||||
#define ACPI_ANY_BASE 0
|
||||
@ -574,6 +576,32 @@ acpi_status
|
||||
acpi_ut_create_list(char *list_name,
|
||||
u16 object_size, struct acpi_memory_list **return_cache);
|
||||
|
||||
#endif
|
||||
#endif /* ACPI_DBG_TRACK_ALLOCATIONS */
|
||||
|
||||
/*
|
||||
* utxferror - various error/warning output functions
|
||||
*/
|
||||
void ACPI_INTERNAL_VAR_XFACE
|
||||
acpi_ut_predefined_warning(const char *module_name,
|
||||
u32 line_number,
|
||||
char *pathname,
|
||||
u8 node_flags, const char *format, ...);
|
||||
|
||||
void ACPI_INTERNAL_VAR_XFACE
|
||||
acpi_ut_predefined_info(const char *module_name,
|
||||
u32 line_number,
|
||||
char *pathname, u8 node_flags, const char *format, ...);
|
||||
|
||||
void
|
||||
acpi_ut_namespace_error(const char *module_name,
|
||||
u32 line_number,
|
||||
const char *internal_name, acpi_status lookup_status);
|
||||
|
||||
void
|
||||
acpi_ut_method_error(const char *module_name,
|
||||
u32 line_number,
|
||||
const char *message,
|
||||
struct acpi_namespace_node *node,
|
||||
const char *path, acpi_status lookup_status);
|
||||
|
||||
#endif /* _ACUTILS_H */
|
||||
|
@ -573,7 +573,7 @@ acpi_ds_terminate_control_method(union acpi_operand_object *method_desc,
|
||||
|
||||
acpi_os_release_mutex(method_desc->method.
|
||||
mutex->mutex.os_mutex);
|
||||
method_desc->method.mutex->mutex.thread_id = NULL;
|
||||
method_desc->method.mutex->mutex.thread_id = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -300,10 +300,25 @@ acpi_ds_exec_begin_op(struct acpi_walk_state *walk_state,
|
||||
* we must enter this object into the namespace. The created
|
||||
* object is temporary and will be deleted upon completion of
|
||||
* the execution of this method.
|
||||
*
|
||||
* Note 10/2010: Except for the Scope() op. This opcode does
|
||||
* not actually create a new object, it refers to an existing
|
||||
* object. However, for Scope(), we want to indeed open a
|
||||
* new scope.
|
||||
*/
|
||||
status = acpi_ds_load2_begin_op(walk_state, NULL);
|
||||
if (op->common.aml_opcode != AML_SCOPE_OP) {
|
||||
status =
|
||||
acpi_ds_load2_begin_op(walk_state, NULL);
|
||||
} else {
|
||||
status =
|
||||
acpi_ds_scope_stack_push(op->named.node,
|
||||
op->named.node->
|
||||
type, walk_state);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case AML_CLASS_EXECUTE:
|
||||
|
@ -93,47 +93,6 @@ acpi_status acpi_ev_initialize_events(void)
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_ev_install_fadt_gpes
|
||||
*
|
||||
* PARAMETERS: None
|
||||
*
|
||||
* RETURN: Status
|
||||
*
|
||||
* DESCRIPTION: Completes initialization of the FADT-defined GPE blocks
|
||||
* (0 and 1). The HW must be fully initialized at this point,
|
||||
* including global lock support.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
acpi_status acpi_ev_install_fadt_gpes(void)
|
||||
{
|
||||
acpi_status status;
|
||||
|
||||
ACPI_FUNCTION_TRACE(ev_install_fadt_gpes);
|
||||
|
||||
/* Namespace must be locked */
|
||||
|
||||
status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
return (status);
|
||||
}
|
||||
|
||||
/* FADT GPE Block 0 */
|
||||
|
||||
(void)acpi_ev_initialize_gpe_block(acpi_gbl_fadt_gpe_device,
|
||||
acpi_gbl_gpe_fadt_blocks[0]);
|
||||
|
||||
/* FADT GPE Block 1 */
|
||||
|
||||
(void)acpi_ev_initialize_gpe_block(acpi_gbl_fadt_gpe_device,
|
||||
acpi_gbl_gpe_fadt_blocks[1]);
|
||||
|
||||
(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
|
||||
return_ACPI_STATUS(AE_OK);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_ev_install_xrupt_handlers
|
||||
|
@ -363,6 +363,7 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device,
|
||||
gpe_block->gpe_count = (u16)(register_count * ACPI_GPE_REGISTER_WIDTH);
|
||||
gpe_block->register_count = register_count;
|
||||
gpe_block->block_base_number = gpe_block_base_number;
|
||||
gpe_block->initialized = FALSE;
|
||||
|
||||
ACPI_MEMCPY(&gpe_block->block_address, gpe_block_address,
|
||||
sizeof(struct acpi_generic_address));
|
||||
@ -385,11 +386,12 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device,
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
acpi_all_gpes_initialized = FALSE;
|
||||
|
||||
/* Find all GPE methods (_Lxx or_Exx) for this block */
|
||||
|
||||
walk_info.gpe_block = gpe_block;
|
||||
walk_info.gpe_device = gpe_device;
|
||||
walk_info.enable_this_gpe = FALSE;
|
||||
walk_info.execute_by_owner_id = FALSE;
|
||||
|
||||
status = acpi_ns_walk_namespace(ACPI_TYPE_METHOD, gpe_device,
|
||||
@ -434,35 +436,34 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device,
|
||||
******************************************************************************/
|
||||
|
||||
acpi_status
|
||||
acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device,
|
||||
struct acpi_gpe_block_info *gpe_block)
|
||||
acpi_ev_initialize_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
|
||||
struct acpi_gpe_block_info *gpe_block,
|
||||
void *ignored)
|
||||
{
|
||||
acpi_status status;
|
||||
struct acpi_gpe_event_info *gpe_event_info;
|
||||
u32 gpe_enabled_count;
|
||||
u32 gpe_index;
|
||||
u32 gpe_number;
|
||||
u32 i;
|
||||
u32 j;
|
||||
|
||||
ACPI_FUNCTION_TRACE(ev_initialize_gpe_block);
|
||||
|
||||
/* Ignore a null GPE block (e.g., if no GPE block 1 exists) */
|
||||
|
||||
if (!gpe_block) {
|
||||
/*
|
||||
* Ignore a null GPE block (e.g., if no GPE block 1 exists) and
|
||||
* GPE blocks that have been initialized already.
|
||||
*/
|
||||
if (!gpe_block || gpe_block->initialized) {
|
||||
return_ACPI_STATUS(AE_OK);
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable all GPEs that have a corresponding method. Any other GPEs
|
||||
* within this block must be enabled via the acpi_enable_gpe interface.
|
||||
* Enable all GPEs that have a corresponding method and have the
|
||||
* ACPI_GPE_CAN_WAKE flag unset. Any other GPEs within this block must
|
||||
* be enabled via the acpi_enable_gpe() interface.
|
||||
*/
|
||||
gpe_enabled_count = 0;
|
||||
|
||||
if (gpe_device == acpi_gbl_fadt_gpe_device) {
|
||||
gpe_device = NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < gpe_block->register_count; i++) {
|
||||
for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) {
|
||||
|
||||
@ -470,27 +471,19 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device,
|
||||
|
||||
gpe_index = (i * ACPI_GPE_REGISTER_WIDTH) + j;
|
||||
gpe_event_info = &gpe_block->event_info[gpe_index];
|
||||
gpe_number = gpe_index + gpe_block->block_base_number;
|
||||
|
||||
/* Ignore GPEs that have no corresponding _Lxx/_Exx method */
|
||||
|
||||
if (!(gpe_event_info->flags & ACPI_GPE_DISPATCH_METHOD)) {
|
||||
if (!(gpe_event_info->flags & ACPI_GPE_DISPATCH_METHOD)
|
||||
|| (gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the GPE has already been enabled for runtime
|
||||
* signaling, make sure it remains enabled, but do not
|
||||
* increment its reference counter.
|
||||
*/
|
||||
status = gpe_event_info->runtime_count ?
|
||||
acpi_ev_enable_gpe(gpe_event_info) :
|
||||
acpi_enable_gpe(gpe_device, gpe_number);
|
||||
|
||||
status = acpi_raw_enable_gpe(gpe_event_info);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
ACPI_EXCEPTION((AE_INFO, status,
|
||||
"Could not enable GPE 0x%02X",
|
||||
gpe_number));
|
||||
"Could not enable GPE 0x%02X",
|
||||
gpe_index + gpe_block->block_base_number));
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -504,5 +497,7 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device,
|
||||
gpe_enabled_count));
|
||||
}
|
||||
|
||||
gpe_block->initialized = TRUE;
|
||||
|
||||
return_ACPI_STATUS(AE_OK);
|
||||
}
|
||||
|
@ -210,8 +210,7 @@ acpi_status acpi_ev_gpe_initialize(void)
|
||||
*
|
||||
* DESCRIPTION: Check for new GPE methods (_Lxx/_Exx) made available as a
|
||||
* result of a Load() or load_table() operation. If new GPE
|
||||
* methods have been installed, register the new methods and
|
||||
* enable and runtime GPEs that are associated with them.
|
||||
* methods have been installed, register the new methods.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
@ -239,7 +238,6 @@ void acpi_ev_update_gpes(acpi_owner_id table_owner_id)
|
||||
walk_info.owner_id = table_owner_id;
|
||||
walk_info.execute_by_owner_id = TRUE;
|
||||
walk_info.count = 0;
|
||||
walk_info.enable_this_gpe = TRUE;
|
||||
|
||||
/* Walk the interrupt level descriptor list */
|
||||
|
||||
@ -301,8 +299,6 @@ void acpi_ev_update_gpes(acpi_owner_id table_owner_id)
|
||||
*
|
||||
* If walk_info->execute_by_owner_id is TRUE, we only execute examine GPE methods
|
||||
* with that owner.
|
||||
* If walk_info->enable_this_gpe is TRUE, the GPE that is referred to by a GPE
|
||||
* method is immediately enabled (Used for Load/load_table operators)
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
@ -315,8 +311,6 @@ acpi_ev_match_gpe_method(acpi_handle obj_handle,
|
||||
struct acpi_gpe_walk_info *walk_info =
|
||||
ACPI_CAST_PTR(struct acpi_gpe_walk_info, context);
|
||||
struct acpi_gpe_event_info *gpe_event_info;
|
||||
struct acpi_namespace_node *gpe_device;
|
||||
acpi_status status;
|
||||
u32 gpe_number;
|
||||
char name[ACPI_NAME_SIZE + 1];
|
||||
u8 type;
|
||||
@ -421,29 +415,6 @@ acpi_ev_match_gpe_method(acpi_handle obj_handle,
|
||||
gpe_event_info->flags |= (u8)(type | ACPI_GPE_DISPATCH_METHOD);
|
||||
gpe_event_info->dispatch.method_node = method_node;
|
||||
|
||||
/*
|
||||
* Enable this GPE if requested. This only happens when during the
|
||||
* execution of a Load or load_table operator. We have found a new
|
||||
* GPE method and want to immediately enable the GPE if it is a
|
||||
* runtime GPE.
|
||||
*/
|
||||
if (walk_info->enable_this_gpe) {
|
||||
|
||||
walk_info->count++;
|
||||
gpe_device = walk_info->gpe_device;
|
||||
|
||||
if (gpe_device == acpi_gbl_fadt_gpe_device) {
|
||||
gpe_device = NULL;
|
||||
}
|
||||
|
||||
status = acpi_enable_gpe(gpe_device, gpe_number);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
ACPI_EXCEPTION((AE_INFO, status,
|
||||
"Could not enable GPE 0x%02X",
|
||||
gpe_number));
|
||||
}
|
||||
}
|
||||
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_LOAD,
|
||||
"Registered GPE method %s as GPE number 0x%.2X\n",
|
||||
name, gpe_number));
|
||||
|
@ -553,7 +553,7 @@ acpi_status acpi_ev_release_global_lock(void)
|
||||
acpi_gbl_global_lock_acquired = FALSE;
|
||||
|
||||
/* Release the local GL mutex */
|
||||
acpi_ev_global_lock_thread_id = NULL;
|
||||
acpi_ev_global_lock_thread_id = 0;
|
||||
acpi_ev_global_lock_acquired = 0;
|
||||
acpi_os_release_mutex(acpi_gbl_global_lock_mutex->mutex.os_mutex);
|
||||
return_ACPI_STATUS(status);
|
||||
|
@ -289,8 +289,8 @@ acpi_ev_pci_config_region_setup(acpi_handle handle,
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the PCI device and function numbers from the _ADR object contained
|
||||
* in the parent's scope.
|
||||
* Get the PCI device and function numbers from the _ADR object
|
||||
* contained in the parent's scope.
|
||||
*/
|
||||
status = acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR,
|
||||
pci_device_node, &pci_value);
|
||||
@ -320,9 +320,15 @@ acpi_ev_pci_config_region_setup(acpi_handle handle,
|
||||
pci_id->bus = ACPI_LOWORD(pci_value);
|
||||
}
|
||||
|
||||
/* Complete this device's pci_id */
|
||||
/* Complete/update the PCI ID for this device */
|
||||
|
||||
acpi_os_derive_pci_id(pci_root_node, region_obj->region.node, &pci_id);
|
||||
status =
|
||||
acpi_hw_derive_pci_id(pci_id, pci_root_node,
|
||||
region_obj->region.node);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
ACPI_FREE(pci_id);
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
*region_context = pci_id;
|
||||
return_ACPI_STATUS(AE_OK);
|
||||
|
@ -726,15 +726,16 @@ acpi_install_gpe_handler(acpi_handle gpe_device,
|
||||
(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK);
|
||||
|
||||
/*
|
||||
* If the GPE is associated with a method and it cannot wake up the
|
||||
* system from sleep states, it was enabled automatically during
|
||||
* initialization, so it has to be disabled now to avoid spurious
|
||||
* execution of the handler.
|
||||
* If the GPE is associated with a method, it might have been enabled
|
||||
* automatically during initialization, in which case it has to be
|
||||
* disabled now to avoid spurious execution of the handler.
|
||||
*/
|
||||
|
||||
if ((handler->orig_flags & ACPI_GPE_DISPATCH_METHOD)
|
||||
&& !(gpe_event_info->flags & ACPI_GPE_CAN_WAKE))
|
||||
&& gpe_event_info->runtime_count) {
|
||||
handler->orig_enabled = 1;
|
||||
(void)acpi_raw_disable_gpe(gpe_event_info);
|
||||
}
|
||||
|
||||
/* Install the handler */
|
||||
|
||||
@ -837,13 +838,13 @@ acpi_remove_gpe_handler(acpi_handle gpe_device,
|
||||
gpe_event_info->flags |= handler->orig_flags;
|
||||
|
||||
/*
|
||||
* If the GPE was previously associated with a method and it cannot wake
|
||||
* up the system from sleep states, it should be enabled at this point
|
||||
* to restore the post-initialization configuration.
|
||||
* If the GPE was previously associated with a method and it was
|
||||
* enabled, it should be enabled at this point to restore the
|
||||
* post-initialization configuration.
|
||||
*/
|
||||
|
||||
if ((handler->orig_flags & ACPI_GPE_DISPATCH_METHOD)
|
||||
&& !(gpe_event_info->flags & ACPI_GPE_CAN_WAKE))
|
||||
&& handler->orig_enabled)
|
||||
(void)acpi_raw_enable_gpe(gpe_event_info);
|
||||
|
||||
/* Now we can free the handler object */
|
||||
|
@ -379,21 +379,12 @@ acpi_status acpi_gpe_can_wake(acpi_handle gpe_device, u32 gpe_number)
|
||||
/* Ensure that we have a valid GPE number */
|
||||
|
||||
gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
|
||||
if (!gpe_event_info) {
|
||||
if (gpe_event_info) {
|
||||
gpe_event_info->flags |= ACPI_GPE_CAN_WAKE;
|
||||
} else {
|
||||
status = AE_BAD_PARAMETER;
|
||||
goto unlock_and_exit;
|
||||
}
|
||||
|
||||
if (gpe_event_info->flags & ACPI_GPE_CAN_WAKE) {
|
||||
goto unlock_and_exit;
|
||||
}
|
||||
|
||||
gpe_event_info->flags |= ACPI_GPE_CAN_WAKE;
|
||||
if (gpe_event_info->flags & ACPI_GPE_DISPATCH_METHOD) {
|
||||
(void)acpi_raw_disable_gpe(gpe_event_info);
|
||||
}
|
||||
|
||||
unlock_and_exit:
|
||||
acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
@ -651,7 +642,7 @@ acpi_install_gpe_block(acpi_handle gpe_device,
|
||||
struct acpi_generic_address *gpe_block_address,
|
||||
u32 register_count, u32 interrupt_number)
|
||||
{
|
||||
acpi_status status;
|
||||
acpi_status status = AE_OK;
|
||||
union acpi_operand_object *obj_desc;
|
||||
struct acpi_namespace_node *node;
|
||||
struct acpi_gpe_block_info *gpe_block;
|
||||
@ -715,10 +706,6 @@ acpi_install_gpe_block(acpi_handle gpe_device,
|
||||
|
||||
obj_desc->device.gpe_block = gpe_block;
|
||||
|
||||
/* Enable the runtime GPEs in the new block */
|
||||
|
||||
status = acpi_ev_initialize_gpe_block(node, gpe_block);
|
||||
|
||||
unlock_and_exit:
|
||||
(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
|
||||
return_ACPI_STATUS(status);
|
||||
@ -924,3 +911,43 @@ acpi_status acpi_enable_all_runtime_gpes(void)
|
||||
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_update_gpes
|
||||
*
|
||||
* PARAMETERS: None
|
||||
*
|
||||
* RETURN: None
|
||||
*
|
||||
* DESCRIPTION: Enable all GPEs that have associated _Lxx or _Exx methods and
|
||||
* are not pointed to by any device _PRW methods indicating that
|
||||
* these GPEs are generally intended for system or device wakeup
|
||||
* (such GPEs have to be enabled directly when the devices whose
|
||||
* _PRW methods point to them are set up for wakeup signaling).
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
acpi_status acpi_update_gpes(void)
|
||||
{
|
||||
acpi_status status;
|
||||
|
||||
ACPI_FUNCTION_TRACE(acpi_update_gpes);
|
||||
|
||||
status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
return_ACPI_STATUS(status);
|
||||
} else if (acpi_all_gpes_initialized) {
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
status = acpi_ev_walk_gpe_list(acpi_ev_initialize_gpe_block, NULL);
|
||||
if (ACPI_SUCCESS(status)) {
|
||||
acpi_all_gpes_initialized = TRUE;
|
||||
}
|
||||
|
||||
unlock:
|
||||
(void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
|
||||
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
@ -64,6 +64,12 @@ ACPI_MODULE_NAME("evxfregn")
|
||||
*
|
||||
* DESCRIPTION: Install a handler for all op_regions of a given space_id.
|
||||
*
|
||||
* NOTE: This function should only be called after acpi_enable_subsystem has
|
||||
* been called. This is because any _REG methods associated with the Space ID
|
||||
* are executed here, and these methods can only be safely executed after
|
||||
* the default handlers have been installed and the hardware has been
|
||||
* initialized (via acpi_enable_subsystem.)
|
||||
*
|
||||
******************************************************************************/
|
||||
acpi_status
|
||||
acpi_install_address_space_handler(acpi_handle device,
|
||||
|
@ -119,8 +119,8 @@ acpi_ex_setup_region(union acpi_operand_object *obj_desc,
|
||||
}
|
||||
|
||||
/*
|
||||
* Exit now for SMBus or IPMI address space, it has a non-linear address space
|
||||
* and the request cannot be directly validated
|
||||
* Exit now for SMBus or IPMI address space, it has a non-linear
|
||||
* address space and the request cannot be directly validated
|
||||
*/
|
||||
if (rgn_desc->region.space_id == ACPI_ADR_SPACE_SMBUS ||
|
||||
rgn_desc->region.space_id == ACPI_ADR_SPACE_IPMI) {
|
||||
@ -147,8 +147,7 @@ acpi_ex_setup_region(union acpi_operand_object *obj_desc,
|
||||
* (Region length is specified in bytes)
|
||||
*/
|
||||
if (rgn_desc->region.length <
|
||||
(obj_desc->common_field.base_byte_offset +
|
||||
field_datum_byte_offset +
|
||||
(obj_desc->common_field.base_byte_offset + field_datum_byte_offset +
|
||||
obj_desc->common_field.access_byte_width)) {
|
||||
if (acpi_gbl_enable_interpreter_slack) {
|
||||
/*
|
||||
@ -680,6 +679,7 @@ acpi_ex_extract_from_field(union acpi_operand_object *obj_desc,
|
||||
u32 buffer_tail_bits;
|
||||
u32 datum_count;
|
||||
u32 field_datum_count;
|
||||
u32 access_bit_width;
|
||||
u32 i;
|
||||
|
||||
ACPI_FUNCTION_TRACE(ex_extract_from_field);
|
||||
@ -694,16 +694,36 @@ acpi_ex_extract_from_field(union acpi_operand_object *obj_desc,
|
||||
|
||||
return_ACPI_STATUS(AE_BUFFER_OVERFLOW);
|
||||
}
|
||||
|
||||
ACPI_MEMSET(buffer, 0, buffer_length);
|
||||
access_bit_width = ACPI_MUL_8(obj_desc->common_field.access_byte_width);
|
||||
|
||||
/* Handle the simple case here */
|
||||
|
||||
if ((obj_desc->common_field.start_field_bit_offset == 0) &&
|
||||
(obj_desc->common_field.bit_length == access_bit_width)) {
|
||||
status = acpi_ex_field_datum_io(obj_desc, 0, buffer, ACPI_READ);
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
/* TBD: Move to common setup code */
|
||||
|
||||
/* Field algorithm is limited to sizeof(u64), truncate if needed */
|
||||
|
||||
if (obj_desc->common_field.access_byte_width > sizeof(u64)) {
|
||||
obj_desc->common_field.access_byte_width = sizeof(u64);
|
||||
access_bit_width = sizeof(u64) * 8;
|
||||
}
|
||||
|
||||
/* Compute the number of datums (access width data items) */
|
||||
|
||||
datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length,
|
||||
obj_desc->common_field.access_bit_width);
|
||||
datum_count =
|
||||
ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length,
|
||||
access_bit_width);
|
||||
|
||||
field_datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length +
|
||||
obj_desc->common_field.
|
||||
start_field_bit_offset,
|
||||
obj_desc->common_field.
|
||||
access_bit_width);
|
||||
|
||||
/* Priming read from the field */
|
||||
@ -738,12 +758,11 @@ acpi_ex_extract_from_field(union acpi_operand_object *obj_desc,
|
||||
* This avoids the differences in behavior between different compilers
|
||||
* concerning shift values larger than the target data width.
|
||||
*/
|
||||
if ((obj_desc->common_field.access_bit_width -
|
||||
obj_desc->common_field.start_field_bit_offset) <
|
||||
if (access_bit_width -
|
||||
obj_desc->common_field.start_field_bit_offset <
|
||||
ACPI_INTEGER_BIT_SIZE) {
|
||||
merged_datum |=
|
||||
raw_datum << (obj_desc->common_field.
|
||||
access_bit_width -
|
||||
raw_datum << (access_bit_width -
|
||||
obj_desc->common_field.
|
||||
start_field_bit_offset);
|
||||
}
|
||||
@ -765,8 +784,7 @@ acpi_ex_extract_from_field(union acpi_operand_object *obj_desc,
|
||||
|
||||
/* Mask off any extra bits in the last datum */
|
||||
|
||||
buffer_tail_bits = obj_desc->common_field.bit_length %
|
||||
obj_desc->common_field.access_bit_width;
|
||||
buffer_tail_bits = obj_desc->common_field.bit_length % access_bit_width;
|
||||
if (buffer_tail_bits) {
|
||||
merged_datum &= ACPI_MASK_BITS_ABOVE(buffer_tail_bits);
|
||||
}
|
||||
@ -798,6 +816,7 @@ acpi_status
|
||||
acpi_ex_insert_into_field(union acpi_operand_object *obj_desc,
|
||||
void *buffer, u32 buffer_length)
|
||||
{
|
||||
void *new_buffer;
|
||||
acpi_status status;
|
||||
u64 mask;
|
||||
u64 width_mask;
|
||||
@ -808,9 +827,9 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc,
|
||||
u32 buffer_tail_bits;
|
||||
u32 datum_count;
|
||||
u32 field_datum_count;
|
||||
u32 i;
|
||||
u32 access_bit_width;
|
||||
u32 required_length;
|
||||
void *new_buffer;
|
||||
u32 i;
|
||||
|
||||
ACPI_FUNCTION_TRACE(ex_insert_into_field);
|
||||
|
||||
@ -844,17 +863,24 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc,
|
||||
buffer_length = required_length;
|
||||
}
|
||||
|
||||
/* TBD: Move to common setup code */
|
||||
|
||||
/* Algo is limited to sizeof(u64), so cut the access_byte_width */
|
||||
if (obj_desc->common_field.access_byte_width > sizeof(u64)) {
|
||||
obj_desc->common_field.access_byte_width = sizeof(u64);
|
||||
}
|
||||
|
||||
access_bit_width = ACPI_MUL_8(obj_desc->common_field.access_byte_width);
|
||||
|
||||
/*
|
||||
* Create the bitmasks used for bit insertion.
|
||||
* Note: This if/else is used to bypass compiler differences with the
|
||||
* shift operator
|
||||
*/
|
||||
if (obj_desc->common_field.access_bit_width == ACPI_INTEGER_BIT_SIZE) {
|
||||
if (access_bit_width == ACPI_INTEGER_BIT_SIZE) {
|
||||
width_mask = ACPI_UINT64_MAX;
|
||||
} else {
|
||||
width_mask =
|
||||
ACPI_MASK_BITS_ABOVE(obj_desc->common_field.
|
||||
access_bit_width);
|
||||
width_mask = ACPI_MASK_BITS_ABOVE(access_bit_width);
|
||||
}
|
||||
|
||||
mask = width_mask &
|
||||
@ -863,12 +889,11 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc,
|
||||
/* Compute the number of datums (access width data items) */
|
||||
|
||||
datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length,
|
||||
obj_desc->common_field.access_bit_width);
|
||||
access_bit_width);
|
||||
|
||||
field_datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length +
|
||||
obj_desc->common_field.
|
||||
start_field_bit_offset,
|
||||
obj_desc->common_field.
|
||||
access_bit_width);
|
||||
|
||||
/* Get initial Datum from the input buffer */
|
||||
@ -905,12 +930,11 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc,
|
||||
* This avoids the differences in behavior between different compilers
|
||||
* concerning shift values larger than the target data width.
|
||||
*/
|
||||
if ((obj_desc->common_field.access_bit_width -
|
||||
if ((access_bit_width -
|
||||
obj_desc->common_field.start_field_bit_offset) <
|
||||
ACPI_INTEGER_BIT_SIZE) {
|
||||
merged_datum =
|
||||
raw_datum >> (obj_desc->common_field.
|
||||
access_bit_width -
|
||||
raw_datum >> (access_bit_width -
|
||||
obj_desc->common_field.
|
||||
start_field_bit_offset);
|
||||
} else {
|
||||
@ -929,6 +953,7 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc,
|
||||
ACPI_MEMCPY(&raw_datum, ((char *)buffer) + buffer_offset,
|
||||
ACPI_MIN(obj_desc->common_field.access_byte_width,
|
||||
buffer_length - buffer_offset));
|
||||
|
||||
merged_datum |=
|
||||
raw_datum << obj_desc->common_field.start_field_bit_offset;
|
||||
}
|
||||
@ -937,7 +962,7 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc,
|
||||
|
||||
buffer_tail_bits = (obj_desc->common_field.bit_length +
|
||||
obj_desc->common_field.start_field_bit_offset) %
|
||||
obj_desc->common_field.access_bit_width;
|
||||
access_bit_width;
|
||||
if (buffer_tail_bits) {
|
||||
mask &= ACPI_MASK_BITS_ABOVE(buffer_tail_bits);
|
||||
}
|
||||
|
@ -336,7 +336,7 @@ acpi_status acpi_ex_release_mutex_object(union acpi_operand_object *obj_desc)
|
||||
|
||||
/* Clear mutex info */
|
||||
|
||||
obj_desc->mutex.thread_id = NULL;
|
||||
obj_desc->mutex.thread_id = 0;
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
@ -393,10 +393,10 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc,
|
||||
if ((owner_thread->thread_id != walk_state->thread->thread_id) &&
|
||||
(obj_desc != acpi_gbl_global_lock_mutex)) {
|
||||
ACPI_ERROR((AE_INFO,
|
||||
"Thread %p cannot release Mutex [%4.4s] acquired by thread %p",
|
||||
ACPI_CAST_PTR(void, walk_state->thread->thread_id),
|
||||
"Thread %u cannot release Mutex [%4.4s] acquired by thread %u",
|
||||
(u32)walk_state->thread->thread_id,
|
||||
acpi_ut_get_node_name(obj_desc->mutex.node),
|
||||
ACPI_CAST_PTR(void, owner_thread->thread_id)));
|
||||
(u32)owner_thread->thread_id));
|
||||
return_ACPI_STATUS(AE_AML_NOT_OWNER);
|
||||
}
|
||||
|
||||
@ -488,7 +488,7 @@ void acpi_ex_release_all_mutexes(struct acpi_thread_state *thread)
|
||||
/* Mark mutex unowned */
|
||||
|
||||
obj_desc->mutex.owner_thread = NULL;
|
||||
obj_desc->mutex.thread_id = NULL;
|
||||
obj_desc->mutex.thread_id = 0;
|
||||
|
||||
/* Update Thread sync_level (Last mutex is the important one) */
|
||||
|
||||
|
@ -355,12 +355,10 @@ acpi_ex_prep_common_field_object(union acpi_operand_object *obj_desc,
|
||||
return_ACPI_STATUS(AE_AML_OPERAND_VALUE);
|
||||
}
|
||||
|
||||
/* Setup width (access granularity) fields */
|
||||
/* Setup width (access granularity) fields (values are: 1, 2, 4, 8) */
|
||||
|
||||
obj_desc->common_field.access_byte_width = (u8)
|
||||
ACPI_DIV_8(access_bit_width); /* 1, 2, 4, 8 */
|
||||
|
||||
obj_desc->common_field.access_bit_width = (u8) access_bit_width;
|
||||
ACPI_DIV_8(access_bit_width);
|
||||
|
||||
/*
|
||||
* base_byte_offset is the address of the start of the field within the
|
||||
@ -405,8 +403,9 @@ acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info)
|
||||
{
|
||||
union acpi_operand_object *obj_desc;
|
||||
union acpi_operand_object *second_desc = NULL;
|
||||
u32 type;
|
||||
acpi_status status;
|
||||
u32 access_byte_width;
|
||||
u32 type;
|
||||
|
||||
ACPI_FUNCTION_TRACE(ex_prep_field_value);
|
||||
|
||||
@ -421,8 +420,8 @@ acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info)
|
||||
type = acpi_ns_get_type(info->region_node);
|
||||
if (type != ACPI_TYPE_REGION) {
|
||||
ACPI_ERROR((AE_INFO,
|
||||
"Needed Region, found type 0x%X (%s)",
|
||||
type, acpi_ut_get_type_name(type)));
|
||||
"Needed Region, found type 0x%X (%s)", type,
|
||||
acpi_ut_get_type_name(type)));
|
||||
|
||||
return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
|
||||
}
|
||||
@ -438,7 +437,8 @@ acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info)
|
||||
/* Initialize areas of the object that are common to all fields */
|
||||
|
||||
obj_desc->common_field.node = info->field_node;
|
||||
status = acpi_ex_prep_common_field_object(obj_desc, info->field_flags,
|
||||
status = acpi_ex_prep_common_field_object(obj_desc,
|
||||
info->field_flags,
|
||||
info->attribute,
|
||||
info->field_bit_position,
|
||||
info->field_bit_length);
|
||||
@ -455,27 +455,26 @@ acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info)
|
||||
obj_desc->field.region_obj =
|
||||
acpi_ns_get_attached_object(info->region_node);
|
||||
|
||||
/* Allow full data read from EC address space */
|
||||
|
||||
if ((obj_desc->field.region_obj->region.space_id ==
|
||||
ACPI_ADR_SPACE_EC)
|
||||
&& (obj_desc->common_field.bit_length > 8)) {
|
||||
access_byte_width =
|
||||
ACPI_ROUND_BITS_UP_TO_BYTES(obj_desc->common_field.
|
||||
bit_length);
|
||||
|
||||
/* Maximum byte width supported is 255 */
|
||||
|
||||
if (access_byte_width < 256) {
|
||||
obj_desc->common_field.access_byte_width =
|
||||
(u8)access_byte_width;
|
||||
}
|
||||
}
|
||||
/* An additional reference for the container */
|
||||
|
||||
acpi_ut_add_reference(obj_desc->field.region_obj);
|
||||
|
||||
/* allow full data read from EC address space */
|
||||
if (obj_desc->field.region_obj->region.space_id ==
|
||||
ACPI_ADR_SPACE_EC) {
|
||||
if (obj_desc->common_field.bit_length > 8) {
|
||||
unsigned width =
|
||||
ACPI_ROUND_BITS_UP_TO_BYTES(
|
||||
obj_desc->common_field.bit_length);
|
||||
// access_bit_width is u8, don't overflow it
|
||||
if (width > 8)
|
||||
width = 8;
|
||||
obj_desc->common_field.access_byte_width =
|
||||
width;
|
||||
obj_desc->common_field.access_bit_width =
|
||||
8 * width;
|
||||
}
|
||||
}
|
||||
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
|
||||
"RegionField: BitOff %X, Off %X, Gran %X, Region %p\n",
|
||||
obj_desc->field.start_field_bit_offset,
|
||||
|
@ -353,7 +353,6 @@ acpi_ex_pci_config_space_handler(u32 function,
|
||||
acpi_status status = AE_OK;
|
||||
struct acpi_pci_id *pci_id;
|
||||
u16 pci_register;
|
||||
u32 value32;
|
||||
|
||||
ACPI_FUNCTION_TRACE(ex_pci_config_space_handler);
|
||||
|
||||
@ -381,8 +380,7 @@ acpi_ex_pci_config_space_handler(u32 function,
|
||||
case ACPI_READ:
|
||||
|
||||
status = acpi_os_read_pci_configuration(pci_id, pci_register,
|
||||
&value32, bit_width);
|
||||
*value = value32;
|
||||
value, bit_width);
|
||||
break;
|
||||
|
||||
case ACPI_WRITE:
|
||||
|
412
drivers/acpi/acpica/hwpci.c
Normal file
412
drivers/acpi/acpica/hwpci.c
Normal file
@ -0,0 +1,412 @@
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Module Name: hwpci - Obtain PCI bus, device, and function numbers
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2000 - 2010, 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_NAMESPACE
|
||||
ACPI_MODULE_NAME("hwpci")
|
||||
|
||||
/* PCI configuration space values */
|
||||
#define PCI_CFG_HEADER_TYPE_REG 0x0E
|
||||
#define PCI_CFG_PRIMARY_BUS_NUMBER_REG 0x18
|
||||
#define PCI_CFG_SECONDARY_BUS_NUMBER_REG 0x19
|
||||
/* PCI header values */
|
||||
#define PCI_HEADER_TYPE_MASK 0x7F
|
||||
#define PCI_TYPE_BRIDGE 0x01
|
||||
#define PCI_TYPE_CARDBUS_BRIDGE 0x02
|
||||
typedef struct acpi_pci_device {
|
||||
acpi_handle device;
|
||||
struct acpi_pci_device *next;
|
||||
|
||||
} acpi_pci_device;
|
||||
|
||||
/* Local prototypes */
|
||||
|
||||
static acpi_status
|
||||
acpi_hw_build_pci_list(acpi_handle root_pci_device,
|
||||
acpi_handle pci_region,
|
||||
struct acpi_pci_device **return_list_head);
|
||||
|
||||
static acpi_status
|
||||
acpi_hw_process_pci_list(struct acpi_pci_id *pci_id,
|
||||
struct acpi_pci_device *list_head);
|
||||
|
||||
static void acpi_hw_delete_pci_list(struct acpi_pci_device *list_head);
|
||||
|
||||
static acpi_status
|
||||
acpi_hw_get_pci_device_info(struct acpi_pci_id *pci_id,
|
||||
acpi_handle pci_device,
|
||||
u16 *bus_number, u8 *is_bridge);
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_hw_derive_pci_id
|
||||
*
|
||||
* PARAMETERS: pci_id - Initial values for the PCI ID. May be
|
||||
* modified by this function.
|
||||
* root_pci_device - A handle to a PCI device object. This
|
||||
* object must be a PCI Root Bridge having a
|
||||
* _HID value of either PNP0A03 or PNP0A08
|
||||
* pci_region - A handle to a PCI configuration space
|
||||
* Operation Region being initialized
|
||||
*
|
||||
* RETURN: Status
|
||||
*
|
||||
* DESCRIPTION: This function derives a full PCI ID for a PCI device,
|
||||
* consisting of a Segment number, Bus number, Device number,
|
||||
* and function code.
|
||||
*
|
||||
* The PCI hardware dynamically configures PCI bus numbers
|
||||
* depending on the bus topology discovered during system
|
||||
* initialization. This function is invoked during configuration
|
||||
* of a PCI_Config Operation Region in order to (possibly) update
|
||||
* the Bus/Device/Function numbers in the pci_id with the actual
|
||||
* values as determined by the hardware and operating system
|
||||
* configuration.
|
||||
*
|
||||
* The pci_id parameter is initially populated during the Operation
|
||||
* Region initialization. This function is then called, and is
|
||||
* will make any necessary modifications to the Bus, Device, or
|
||||
* Function number PCI ID subfields as appropriate for the
|
||||
* current hardware and OS configuration.
|
||||
*
|
||||
* NOTE: Created 08/2010. Replaces the previous OSL acpi_os_derive_pci_id
|
||||
* interface since this feature is OS-independent. This module
|
||||
* specifically avoids any use of recursion by building a local
|
||||
* temporary device list.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
acpi_status
|
||||
acpi_hw_derive_pci_id(struct acpi_pci_id *pci_id,
|
||||
acpi_handle root_pci_device, acpi_handle pci_region)
|
||||
{
|
||||
acpi_status status;
|
||||
struct acpi_pci_device *list_head = NULL;
|
||||
|
||||
ACPI_FUNCTION_TRACE(hw_derive_pci_id);
|
||||
|
||||
if (!pci_id) {
|
||||
return_ACPI_STATUS(AE_BAD_PARAMETER);
|
||||
}
|
||||
|
||||
/* Build a list of PCI devices, from pci_region up to root_pci_device */
|
||||
|
||||
status =
|
||||
acpi_hw_build_pci_list(root_pci_device, pci_region, &list_head);
|
||||
if (ACPI_SUCCESS(status)) {
|
||||
|
||||
/* Walk the list, updating the PCI device/function/bus numbers */
|
||||
|
||||
status = acpi_hw_process_pci_list(pci_id, list_head);
|
||||
}
|
||||
|
||||
/* Always delete the list */
|
||||
|
||||
acpi_hw_delete_pci_list(list_head);
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_hw_build_pci_list
|
||||
*
|
||||
* PARAMETERS: root_pci_device - A handle to a PCI device object. This
|
||||
* object is guaranteed to be a PCI Root
|
||||
* Bridge having a _HID value of either
|
||||
* PNP0A03 or PNP0A08
|
||||
* pci_region - A handle to the PCI configuration space
|
||||
* Operation Region
|
||||
* return_list_head - Where the PCI device list is returned
|
||||
*
|
||||
* RETURN: Status
|
||||
*
|
||||
* DESCRIPTION: Builds a list of devices from the input PCI region up to the
|
||||
* Root PCI device for this namespace subtree.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
static acpi_status
|
||||
acpi_hw_build_pci_list(acpi_handle root_pci_device,
|
||||
acpi_handle pci_region,
|
||||
struct acpi_pci_device **return_list_head)
|
||||
{
|
||||
acpi_handle current_device;
|
||||
acpi_handle parent_device;
|
||||
acpi_status status;
|
||||
struct acpi_pci_device *list_element;
|
||||
struct acpi_pci_device *list_head = NULL;
|
||||
|
||||
/*
|
||||
* Ascend namespace branch until the root_pci_device is reached, building
|
||||
* a list of device nodes. Loop will exit when either the PCI device is
|
||||
* found, or the root of the namespace is reached.
|
||||
*/
|
||||
current_device = pci_region;
|
||||
while (1) {
|
||||
status = acpi_get_parent(current_device, &parent_device);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
return (status);
|
||||
}
|
||||
|
||||
/* Finished when we reach the PCI root device (PNP0A03 or PNP0A08) */
|
||||
|
||||
if (parent_device == root_pci_device) {
|
||||
*return_list_head = list_head;
|
||||
return (AE_OK);
|
||||
}
|
||||
|
||||
list_element = ACPI_ALLOCATE(sizeof(struct acpi_pci_device));
|
||||
if (!list_element) {
|
||||
return (AE_NO_MEMORY);
|
||||
}
|
||||
|
||||
/* Put new element at the head of the list */
|
||||
|
||||
list_element->next = list_head;
|
||||
list_element->device = parent_device;
|
||||
list_head = list_element;
|
||||
|
||||
current_device = parent_device;
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_hw_process_pci_list
|
||||
*
|
||||
* PARAMETERS: pci_id - Initial values for the PCI ID. May be
|
||||
* modified by this function.
|
||||
* list_head - Device list created by
|
||||
* acpi_hw_build_pci_list
|
||||
*
|
||||
* RETURN: Status
|
||||
*
|
||||
* DESCRIPTION: Walk downward through the PCI device list, getting the device
|
||||
* info for each, via the PCI configuration space and updating
|
||||
* the PCI ID as necessary. Deletes the list during traversal.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
static acpi_status
|
||||
acpi_hw_process_pci_list(struct acpi_pci_id *pci_id,
|
||||
struct acpi_pci_device *list_head)
|
||||
{
|
||||
acpi_status status = AE_OK;
|
||||
struct acpi_pci_device *info;
|
||||
u16 bus_number;
|
||||
u8 is_bridge = TRUE;
|
||||
|
||||
ACPI_FUNCTION_NAME(hw_process_pci_list);
|
||||
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
|
||||
"Input PciId: Seg %4.4X Bus %4.4X Dev %4.4X Func %4.4X\n",
|
||||
pci_id->segment, pci_id->bus, pci_id->device,
|
||||
pci_id->function));
|
||||
|
||||
bus_number = pci_id->bus;
|
||||
|
||||
/*
|
||||
* Descend down the namespace tree, collecting PCI device, function,
|
||||
* and bus numbers. bus_number is only important for PCI bridges.
|
||||
* Algorithm: As we descend the tree, use the last valid PCI device,
|
||||
* function, and bus numbers that are discovered, and assign them
|
||||
* to the PCI ID for the target device.
|
||||
*/
|
||||
info = list_head;
|
||||
while (info) {
|
||||
status = acpi_hw_get_pci_device_info(pci_id, info->device,
|
||||
&bus_number, &is_bridge);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
info = info->next;
|
||||
}
|
||||
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
|
||||
"Output PciId: Seg %4.4X Bus %4.4X Dev %4.4X Func %4.4X "
|
||||
"Status %X BusNumber %X IsBridge %X\n",
|
||||
pci_id->segment, pci_id->bus, pci_id->device,
|
||||
pci_id->function, status, bus_number, is_bridge));
|
||||
|
||||
return_ACPI_STATUS(AE_OK);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_hw_delete_pci_list
|
||||
*
|
||||
* PARAMETERS: list_head - Device list created by
|
||||
* acpi_hw_build_pci_list
|
||||
*
|
||||
* RETURN: None
|
||||
*
|
||||
* DESCRIPTION: Free the entire PCI list.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
static void acpi_hw_delete_pci_list(struct acpi_pci_device *list_head)
|
||||
{
|
||||
struct acpi_pci_device *next;
|
||||
struct acpi_pci_device *previous;
|
||||
|
||||
next = list_head;
|
||||
while (next) {
|
||||
previous = next;
|
||||
next = previous->next;
|
||||
ACPI_FREE(previous);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_hw_get_pci_device_info
|
||||
*
|
||||
* PARAMETERS: pci_id - Initial values for the PCI ID. May be
|
||||
* modified by this function.
|
||||
* pci_device - Handle for the PCI device object
|
||||
* bus_number - Where a PCI bridge bus number is returned
|
||||
* is_bridge - Return value, indicates if this PCI
|
||||
* device is a PCI bridge
|
||||
*
|
||||
* RETURN: Status
|
||||
*
|
||||
* DESCRIPTION: Get the device info for a single PCI device object. Get the
|
||||
* _ADR (contains PCI device and function numbers), and for PCI
|
||||
* bridge devices, get the bus number from PCI configuration
|
||||
* space.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
static acpi_status
|
||||
acpi_hw_get_pci_device_info(struct acpi_pci_id *pci_id,
|
||||
acpi_handle pci_device,
|
||||
u16 *bus_number, u8 *is_bridge)
|
||||
{
|
||||
acpi_status status;
|
||||
acpi_object_type object_type;
|
||||
u64 return_value;
|
||||
u64 pci_value;
|
||||
|
||||
/* We only care about objects of type Device */
|
||||
|
||||
status = acpi_get_type(pci_device, &object_type);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
return (status);
|
||||
}
|
||||
|
||||
if (object_type != ACPI_TYPE_DEVICE) {
|
||||
return (AE_OK);
|
||||
}
|
||||
|
||||
/* We need an _ADR. Ignore device if not present */
|
||||
|
||||
status = acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR,
|
||||
pci_device, &return_value);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
return (AE_OK);
|
||||
}
|
||||
|
||||
/*
|
||||
* From _ADR, get the PCI Device and Function and
|
||||
* update the PCI ID.
|
||||
*/
|
||||
pci_id->device = ACPI_HIWORD(ACPI_LODWORD(return_value));
|
||||
pci_id->function = ACPI_LOWORD(ACPI_LODWORD(return_value));
|
||||
|
||||
/*
|
||||
* If the previous device was a bridge, use the previous
|
||||
* device bus number
|
||||
*/
|
||||
if (*is_bridge) {
|
||||
pci_id->bus = *bus_number;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the bus numbers from PCI Config space:
|
||||
*
|
||||
* First, get the PCI header_type
|
||||
*/
|
||||
*is_bridge = FALSE;
|
||||
status = acpi_os_read_pci_configuration(pci_id,
|
||||
PCI_CFG_HEADER_TYPE_REG,
|
||||
&pci_value, 8);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
return (status);
|
||||
}
|
||||
|
||||
/* We only care about bridges (1=pci_bridge, 2=card_bus_bridge) */
|
||||
|
||||
pci_value &= PCI_HEADER_TYPE_MASK;
|
||||
|
||||
if ((pci_value != PCI_TYPE_BRIDGE) &&
|
||||
(pci_value != PCI_TYPE_CARDBUS_BRIDGE)) {
|
||||
return (AE_OK);
|
||||
}
|
||||
|
||||
/* Bridge: Get the Primary bus_number */
|
||||
|
||||
status = acpi_os_read_pci_configuration(pci_id,
|
||||
PCI_CFG_PRIMARY_BUS_NUMBER_REG,
|
||||
&pci_value, 8);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
return (status);
|
||||
}
|
||||
|
||||
*is_bridge = TRUE;
|
||||
pci_id->bus = (u16)pci_value;
|
||||
|
||||
/* Bridge: Get the Secondary bus_number */
|
||||
|
||||
status = acpi_os_read_pci_configuration(pci_id,
|
||||
PCI_CFG_SECONDARY_BUS_NUMBER_REG,
|
||||
&pci_value, 8);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
return (status);
|
||||
}
|
||||
|
||||
*bus_number = (u16)pci_value;
|
||||
return (AE_OK);
|
||||
}
|
@ -73,10 +73,18 @@ static acpi_status
|
||||
acpi_ns_repair_ALR(struct acpi_predefined_data *data,
|
||||
union acpi_operand_object **return_object_ptr);
|
||||
|
||||
static acpi_status
|
||||
acpi_ns_repair_CID(struct acpi_predefined_data *data,
|
||||
union acpi_operand_object **return_object_ptr);
|
||||
|
||||
static acpi_status
|
||||
acpi_ns_repair_FDE(struct acpi_predefined_data *data,
|
||||
union acpi_operand_object **return_object_ptr);
|
||||
|
||||
static acpi_status
|
||||
acpi_ns_repair_HID(struct acpi_predefined_data *data,
|
||||
union acpi_operand_object **return_object_ptr);
|
||||
|
||||
static acpi_status
|
||||
acpi_ns_repair_PSS(struct acpi_predefined_data *data,
|
||||
union acpi_operand_object **return_object_ptr);
|
||||
@ -108,8 +116,10 @@ acpi_ns_sort_list(union acpi_operand_object **elements,
|
||||
* As necessary:
|
||||
*
|
||||
* _ALR: Sort the list ascending by ambient_illuminance
|
||||
* _CID: Strings: uppercase all, remove any leading asterisk
|
||||
* _FDE: Convert Buffer of BYTEs to a Buffer of DWORDs
|
||||
* _GTM: Convert Buffer of BYTEs to a Buffer of DWORDs
|
||||
* _HID: Strings: uppercase all, remove any leading asterisk
|
||||
* _PSS: Sort the list descending by Power
|
||||
* _TSS: Sort the list descending by Power
|
||||
*
|
||||
@ -122,8 +132,10 @@ acpi_ns_sort_list(union acpi_operand_object **elements,
|
||||
*/
|
||||
static const struct acpi_repair_info acpi_ns_repairable_names[] = {
|
||||
{"_ALR", acpi_ns_repair_ALR},
|
||||
{"_CID", acpi_ns_repair_CID},
|
||||
{"_FDE", acpi_ns_repair_FDE},
|
||||
{"_GTM", acpi_ns_repair_FDE}, /* _GTM has same repair as _FDE */
|
||||
{"_HID", acpi_ns_repair_HID},
|
||||
{"_PSS", acpi_ns_repair_PSS},
|
||||
{"_TSS", acpi_ns_repair_TSS},
|
||||
{{0, 0, 0, 0}, NULL} /* Table terminator */
|
||||
@ -319,6 +331,157 @@ acpi_ns_repair_FDE(struct acpi_predefined_data *data,
|
||||
return (AE_OK);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_ns_repair_CID
|
||||
*
|
||||
* PARAMETERS: Data - Pointer to validation data structure
|
||||
* return_object_ptr - Pointer to the object returned from the
|
||||
* evaluation of a method or object
|
||||
*
|
||||
* RETURN: Status. AE_OK if object is OK or was repaired successfully
|
||||
*
|
||||
* DESCRIPTION: Repair for the _CID object. If a string, ensure that all
|
||||
* letters are uppercase and that there is no leading asterisk.
|
||||
* If a Package, ensure same for all string elements.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
static acpi_status
|
||||
acpi_ns_repair_CID(struct acpi_predefined_data *data,
|
||||
union acpi_operand_object **return_object_ptr)
|
||||
{
|
||||
acpi_status status;
|
||||
union acpi_operand_object *return_object = *return_object_ptr;
|
||||
union acpi_operand_object **element_ptr;
|
||||
union acpi_operand_object *original_element;
|
||||
u16 original_ref_count;
|
||||
u32 i;
|
||||
|
||||
/* Check for _CID as a simple string */
|
||||
|
||||
if (return_object->common.type == ACPI_TYPE_STRING) {
|
||||
status = acpi_ns_repair_HID(data, return_object_ptr);
|
||||
return (status);
|
||||
}
|
||||
|
||||
/* Exit if not a Package */
|
||||
|
||||
if (return_object->common.type != ACPI_TYPE_PACKAGE) {
|
||||
return (AE_OK);
|
||||
}
|
||||
|
||||
/* Examine each element of the _CID package */
|
||||
|
||||
element_ptr = return_object->package.elements;
|
||||
for (i = 0; i < return_object->package.count; i++) {
|
||||
original_element = *element_ptr;
|
||||
original_ref_count = original_element->common.reference_count;
|
||||
|
||||
status = acpi_ns_repair_HID(data, element_ptr);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
return (status);
|
||||
}
|
||||
|
||||
/* Take care with reference counts */
|
||||
|
||||
if (original_element != *element_ptr) {
|
||||
|
||||
/* Element was replaced */
|
||||
|
||||
(*element_ptr)->common.reference_count =
|
||||
original_ref_count;
|
||||
|
||||
acpi_ut_remove_reference(original_element);
|
||||
}
|
||||
|
||||
element_ptr++;
|
||||
}
|
||||
|
||||
return (AE_OK);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_ns_repair_HID
|
||||
*
|
||||
* PARAMETERS: Data - Pointer to validation data structure
|
||||
* return_object_ptr - Pointer to the object returned from the
|
||||
* evaluation of a method or object
|
||||
*
|
||||
* RETURN: Status. AE_OK if object is OK or was repaired successfully
|
||||
*
|
||||
* DESCRIPTION: Repair for the _HID object. If a string, ensure that all
|
||||
* letters are uppercase and that there is no leading asterisk.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
static acpi_status
|
||||
acpi_ns_repair_HID(struct acpi_predefined_data *data,
|
||||
union acpi_operand_object **return_object_ptr)
|
||||
{
|
||||
union acpi_operand_object *return_object = *return_object_ptr;
|
||||
union acpi_operand_object *new_string;
|
||||
char *source;
|
||||
char *dest;
|
||||
|
||||
ACPI_FUNCTION_NAME(ns_repair_HID);
|
||||
|
||||
/* We only care about string _HID objects (not integers) */
|
||||
|
||||
if (return_object->common.type != ACPI_TYPE_STRING) {
|
||||
return (AE_OK);
|
||||
}
|
||||
|
||||
if (return_object->string.length == 0) {
|
||||
ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags,
|
||||
"Invalid zero-length _HID or _CID string"));
|
||||
|
||||
/* Return AE_OK anyway, let driver handle it */
|
||||
|
||||
data->flags |= ACPI_OBJECT_REPAIRED;
|
||||
return (AE_OK);
|
||||
}
|
||||
|
||||
/* It is simplest to always create a new string object */
|
||||
|
||||
new_string = acpi_ut_create_string_object(return_object->string.length);
|
||||
if (!new_string) {
|
||||
return (AE_NO_MEMORY);
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove a leading asterisk if present. For some unknown reason, there
|
||||
* are many machines in the field that contains IDs like this.
|
||||
*
|
||||
* Examples: "*PNP0C03", "*ACPI0003"
|
||||
*/
|
||||
source = return_object->string.pointer;
|
||||
if (*source == '*') {
|
||||
source++;
|
||||
new_string->string.length--;
|
||||
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
|
||||
"%s: Removed invalid leading asterisk\n",
|
||||
data->pathname));
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy and uppercase the string. From the ACPI specification:
|
||||
*
|
||||
* A valid PNP ID must be of the form "AAA####" where A is an uppercase
|
||||
* letter and # is a hex digit. A valid ACPI ID must be of the form
|
||||
* "ACPI####" where # is a hex digit.
|
||||
*/
|
||||
for (dest = new_string->string.pointer; *source; dest++, source++) {
|
||||
*dest = (char)ACPI_TOUPPER(*source);
|
||||
}
|
||||
|
||||
acpi_ut_remove_reference(return_object);
|
||||
*return_object_ptr = new_string;
|
||||
return (AE_OK);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_ns_repair_TSS
|
||||
|
@ -58,104 +58,6 @@ static u8 acpi_ns_valid_path_separator(char sep);
|
||||
acpi_name acpi_ns_find_parent_name(struct acpi_namespace_node *node_to_search);
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_ns_report_error
|
||||
*
|
||||
* PARAMETERS: module_name - Caller's module name (for error output)
|
||||
* line_number - Caller's line number (for error output)
|
||||
* internal_name - Name or path of the namespace node
|
||||
* lookup_status - Exception code from NS lookup
|
||||
*
|
||||
* RETURN: None
|
||||
*
|
||||
* DESCRIPTION: Print warning message with full pathname
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void
|
||||
acpi_ns_report_error(const char *module_name,
|
||||
u32 line_number,
|
||||
const char *internal_name, acpi_status lookup_status)
|
||||
{
|
||||
acpi_status status;
|
||||
u32 bad_name;
|
||||
char *name = NULL;
|
||||
|
||||
acpi_os_printf("ACPI Error (%s-%04d): ", module_name, line_number);
|
||||
|
||||
if (lookup_status == AE_BAD_CHARACTER) {
|
||||
|
||||
/* There is a non-ascii character in the name */
|
||||
|
||||
ACPI_MOVE_32_TO_32(&bad_name,
|
||||
ACPI_CAST_PTR(u32, internal_name));
|
||||
acpi_os_printf("[0x%4.4X] (NON-ASCII)", bad_name);
|
||||
} else {
|
||||
/* Convert path to external format */
|
||||
|
||||
status = acpi_ns_externalize_name(ACPI_UINT32_MAX,
|
||||
internal_name, NULL, &name);
|
||||
|
||||
/* Print target name */
|
||||
|
||||
if (ACPI_SUCCESS(status)) {
|
||||
acpi_os_printf("[%s]", name);
|
||||
} else {
|
||||
acpi_os_printf("[COULD NOT EXTERNALIZE NAME]");
|
||||
}
|
||||
|
||||
if (name) {
|
||||
ACPI_FREE(name);
|
||||
}
|
||||
}
|
||||
|
||||
acpi_os_printf(" Namespace lookup failure, %s\n",
|
||||
acpi_format_exception(lookup_status));
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_ns_report_method_error
|
||||
*
|
||||
* PARAMETERS: module_name - Caller's module name (for error output)
|
||||
* line_number - Caller's line number (for error output)
|
||||
* Message - Error message to use on failure
|
||||
* prefix_node - Prefix relative to the path
|
||||
* Path - Path to the node (optional)
|
||||
* method_status - Execution status
|
||||
*
|
||||
* RETURN: None
|
||||
*
|
||||
* DESCRIPTION: Print warning message with full pathname
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void
|
||||
acpi_ns_report_method_error(const char *module_name,
|
||||
u32 line_number,
|
||||
const char *message,
|
||||
struct acpi_namespace_node *prefix_node,
|
||||
const char *path, acpi_status method_status)
|
||||
{
|
||||
acpi_status status;
|
||||
struct acpi_namespace_node *node = prefix_node;
|
||||
|
||||
acpi_os_printf("ACPI Error (%s-%04d): ", module_name, line_number);
|
||||
|
||||
if (path) {
|
||||
status =
|
||||
acpi_ns_get_node(prefix_node, path, ACPI_NS_NO_UPSEARCH,
|
||||
&node);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
acpi_os_printf("[Could not get node by pathname]");
|
||||
}
|
||||
}
|
||||
|
||||
acpi_ns_print_node_pathname(node, message);
|
||||
acpi_os_printf(", %s\n", acpi_format_exception(method_status));
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_ns_print_node_pathname
|
||||
|
@ -49,7 +49,7 @@
|
||||
ACPI_MODULE_NAME("tbfadt")
|
||||
|
||||
/* Local prototypes */
|
||||
static inline void
|
||||
static ACPI_INLINE void
|
||||
acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
|
||||
u8 space_id, u8 byte_width, u64 address);
|
||||
|
||||
@ -181,7 +181,7 @@ static struct acpi_fadt_pm_info fadt_pm_info_table[] = {
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
static inline void
|
||||
static ACPI_INLINE void
|
||||
acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
|
||||
u8 space_id, u8 byte_width, u64 address)
|
||||
{
|
||||
|
@ -179,9 +179,8 @@ acpi_debug_print(u32 requested_debug_level,
|
||||
if (thread_id != acpi_gbl_prev_thread_id) {
|
||||
if (ACPI_LV_THREADS & acpi_dbg_level) {
|
||||
acpi_os_printf
|
||||
("\n**** Context Switch from TID %p to TID %p ****\n\n",
|
||||
ACPI_CAST_PTR(void, acpi_gbl_prev_thread_id),
|
||||
ACPI_CAST_PTR(void, thread_id));
|
||||
("\n**** Context Switch from TID %u to TID %u ****\n\n",
|
||||
(u32)acpi_gbl_prev_thread_id, (u32)thread_id);
|
||||
}
|
||||
|
||||
acpi_gbl_prev_thread_id = thread_id;
|
||||
@ -194,7 +193,7 @@ acpi_debug_print(u32 requested_debug_level,
|
||||
acpi_os_printf("%8s-%04ld ", module_name, line_number);
|
||||
|
||||
if (ACPI_LV_THREADS & acpi_dbg_level) {
|
||||
acpi_os_printf("[%p] ", ACPI_CAST_PTR(void, thread_id));
|
||||
acpi_os_printf("[%u] ", (u32)thread_id);
|
||||
}
|
||||
|
||||
acpi_os_printf("[%02ld] %-22.22s: ",
|
||||
|
@ -48,153 +48,6 @@
|
||||
#define _COMPONENT ACPI_UTILITIES
|
||||
ACPI_MODULE_NAME("uteval")
|
||||
|
||||
/*
|
||||
* Strings supported by the _OSI predefined (internal) method.
|
||||
*
|
||||
* March 2009: Removed "Linux" as this host no longer wants to respond true
|
||||
* for this string. Basically, the only safe OS strings are windows-related
|
||||
* and in many or most cases represent the only test path within the
|
||||
* BIOS-provided ASL code.
|
||||
*
|
||||
* The second element of each entry is used to track the newest version of
|
||||
* Windows that the BIOS has requested.
|
||||
*/
|
||||
static struct acpi_interface_info acpi_interfaces_supported[] = {
|
||||
/* Operating System Vendor Strings */
|
||||
|
||||
{"Windows 2000", ACPI_OSI_WIN_2000}, /* Windows 2000 */
|
||||
{"Windows 2001", ACPI_OSI_WIN_XP}, /* Windows XP */
|
||||
{"Windows 2001 SP1", ACPI_OSI_WIN_XP_SP1}, /* Windows XP SP1 */
|
||||
{"Windows 2001.1", ACPI_OSI_WINSRV_2003}, /* Windows Server 2003 */
|
||||
{"Windows 2001 SP2", ACPI_OSI_WIN_XP_SP2}, /* Windows XP SP2 */
|
||||
{"Windows 2001.1 SP1", ACPI_OSI_WINSRV_2003_SP1}, /* Windows Server 2003 SP1 - Added 03/2006 */
|
||||
{"Windows 2006", ACPI_OSI_WIN_VISTA}, /* Windows Vista - Added 03/2006 */
|
||||
{"Windows 2006.1", ACPI_OSI_WINSRV_2008}, /* Windows Server 2008 - Added 09/2009 */
|
||||
{"Windows 2006 SP1", ACPI_OSI_WIN_VISTA_SP1}, /* Windows Vista SP1 - Added 09/2009 */
|
||||
{"Windows 2009", ACPI_OSI_WIN_7}, /* Windows 7 and Server 2008 R2 - Added 09/2009 */
|
||||
|
||||
/* Feature Group Strings */
|
||||
|
||||
{"Extended Address Space Descriptor", 0}
|
||||
|
||||
/*
|
||||
* All "optional" feature group strings (features that are implemented
|
||||
* by the host) should be implemented in the host version of
|
||||
* acpi_os_validate_interface and should not be added here.
|
||||
*/
|
||||
};
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_ut_osi_implementation
|
||||
*
|
||||
* PARAMETERS: walk_state - Current walk state
|
||||
*
|
||||
* RETURN: Status
|
||||
*
|
||||
* DESCRIPTION: Implementation of the _OSI predefined control method
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state)
|
||||
{
|
||||
acpi_status status;
|
||||
union acpi_operand_object *string_desc;
|
||||
union acpi_operand_object *return_desc;
|
||||
u32 return_value;
|
||||
u32 i;
|
||||
|
||||
ACPI_FUNCTION_TRACE(ut_osi_implementation);
|
||||
|
||||
/* Validate the string input argument */
|
||||
|
||||
string_desc = walk_state->arguments[0].object;
|
||||
if (!string_desc || (string_desc->common.type != ACPI_TYPE_STRING)) {
|
||||
return_ACPI_STATUS(AE_TYPE);
|
||||
}
|
||||
|
||||
/* Create a return object */
|
||||
|
||||
return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
|
||||
if (!return_desc) {
|
||||
return_ACPI_STATUS(AE_NO_MEMORY);
|
||||
}
|
||||
|
||||
/* Default return value is 0, NOT SUPPORTED */
|
||||
|
||||
return_value = 0;
|
||||
|
||||
/* Compare input string to static table of supported interfaces */
|
||||
|
||||
for (i = 0; i < ACPI_ARRAY_LENGTH(acpi_interfaces_supported); i++) {
|
||||
if (!ACPI_STRCMP(string_desc->string.pointer,
|
||||
acpi_interfaces_supported[i].name)) {
|
||||
/*
|
||||
* The interface is supported.
|
||||
* Update the osi_data if necessary. We keep track of the latest
|
||||
* version of Windows that has been requested by the BIOS.
|
||||
*/
|
||||
if (acpi_interfaces_supported[i].value >
|
||||
acpi_gbl_osi_data) {
|
||||
acpi_gbl_osi_data =
|
||||
acpi_interfaces_supported[i].value;
|
||||
}
|
||||
|
||||
return_value = ACPI_UINT32_MAX;
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Did not match the string in the static table, call the host OSL to
|
||||
* check for a match with one of the optional strings (such as
|
||||
* "Module Device", "3.0 Thermal Model", etc.)
|
||||
*/
|
||||
status = acpi_os_validate_interface(string_desc->string.pointer);
|
||||
if (ACPI_SUCCESS(status)) {
|
||||
|
||||
/* The interface is supported */
|
||||
|
||||
return_value = ACPI_UINT32_MAX;
|
||||
}
|
||||
|
||||
exit:
|
||||
ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO,
|
||||
"ACPI: BIOS _OSI(%s) is %ssupported\n",
|
||||
string_desc->string.pointer, return_value == 0 ? "not " : ""));
|
||||
|
||||
/* Complete the return value */
|
||||
|
||||
return_desc->integer.value = return_value;
|
||||
walk_state->return_desc = return_desc;
|
||||
return_ACPI_STATUS (AE_OK);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_osi_invalidate
|
||||
*
|
||||
* PARAMETERS: interface_string
|
||||
*
|
||||
* RETURN: Status
|
||||
*
|
||||
* DESCRIPTION: invalidate string in pre-defiend _OSI string list
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
acpi_status acpi_osi_invalidate(char *interface)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ACPI_ARRAY_LENGTH(acpi_interfaces_supported); i++) {
|
||||
if (!ACPI_STRCMP(interface, acpi_interfaces_supported[i].name)) {
|
||||
*acpi_interfaces_supported[i].name = '\0';
|
||||
return AE_OK;
|
||||
}
|
||||
}
|
||||
return AE_NOT_FOUND;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_ut_evaluate_object
|
||||
|
@ -154,14 +154,16 @@ ACPI_EXPORT_SYMBOL(acpi_format_exception)
|
||||
* 1) _SB_ is defined to be a device to allow \_SB_._INI to be run
|
||||
* during the initialization sequence.
|
||||
* 2) _TZ_ is defined to be a thermal zone in order to allow ASL code to
|
||||
* perform a Notify() operation on it.
|
||||
* perform a Notify() operation on it. 09/2010: Changed to type Device.
|
||||
* This still allows notifies, but does not confuse host code that
|
||||
* searches for valid thermal_zone objects.
|
||||
*/
|
||||
const struct acpi_predefined_names acpi_gbl_pre_defined_names[] = {
|
||||
{"_GPE", ACPI_TYPE_LOCAL_SCOPE, NULL},
|
||||
{"_PR_", ACPI_TYPE_LOCAL_SCOPE, NULL},
|
||||
{"_SB_", ACPI_TYPE_DEVICE, NULL},
|
||||
{"_SI_", ACPI_TYPE_LOCAL_SCOPE, NULL},
|
||||
{"_TZ_", ACPI_TYPE_THERMAL, NULL},
|
||||
{"_TZ_", ACPI_TYPE_DEVICE, NULL},
|
||||
{"_REV", ACPI_TYPE_INTEGER, (char *)ACPI_CA_SUPPORT_LEVEL},
|
||||
{"_OS_", ACPI_TYPE_STRING, ACPI_OS_NAME},
|
||||
{"_GL_", ACPI_TYPE_MUTEX, (char *)1},
|
||||
@ -766,6 +768,7 @@ acpi_status acpi_ut_init_globals(void)
|
||||
acpi_gbl_gpe_fadt_blocks[0] = NULL;
|
||||
acpi_gbl_gpe_fadt_blocks[1] = NULL;
|
||||
acpi_current_gpe_count = 0;
|
||||
acpi_all_gpes_initialized = FALSE;
|
||||
|
||||
/* Global handlers */
|
||||
|
||||
@ -774,6 +777,7 @@ acpi_status acpi_ut_init_globals(void)
|
||||
acpi_gbl_exception_handler = NULL;
|
||||
acpi_gbl_init_handler = NULL;
|
||||
acpi_gbl_table_handler = NULL;
|
||||
acpi_gbl_interface_handler = NULL;
|
||||
|
||||
/* Global Lock support */
|
||||
|
||||
@ -800,6 +804,7 @@ acpi_status acpi_ut_init_globals(void)
|
||||
acpi_gbl_debugger_configuration = DEBUGGER_THREADING;
|
||||
acpi_gbl_db_output_flags = ACPI_DB_CONSOLE_OUTPUT;
|
||||
acpi_gbl_osi_data = 0;
|
||||
acpi_gbl_osi_mutex = NULL;
|
||||
|
||||
/* Hardware oriented */
|
||||
|
||||
|
@ -48,42 +48,6 @@
|
||||
#define _COMPONENT ACPI_UTILITIES
|
||||
ACPI_MODULE_NAME("utids")
|
||||
|
||||
/* Local prototypes */
|
||||
static void acpi_ut_copy_id_string(char *destination, char *source);
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_ut_copy_id_string
|
||||
*
|
||||
* PARAMETERS: Destination - Where to copy the string
|
||||
* Source - Source string
|
||||
*
|
||||
* RETURN: None
|
||||
*
|
||||
* DESCRIPTION: Copies an ID string for the _HID, _CID, and _UID methods.
|
||||
* Performs removal of a leading asterisk if present -- workaround
|
||||
* for a known issue on a bunch of machines.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
static void acpi_ut_copy_id_string(char *destination, char *source)
|
||||
{
|
||||
|
||||
/*
|
||||
* Workaround for ID strings that have a leading asterisk. This construct
|
||||
* is not allowed by the ACPI specification (ID strings must be
|
||||
* alphanumeric), but enough existing machines have this embedded in their
|
||||
* ID strings that the following code is useful.
|
||||
*/
|
||||
if (*source == '*') {
|
||||
source++;
|
||||
}
|
||||
|
||||
/* Do the actual copy */
|
||||
|
||||
ACPI_STRCPY(destination, source);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_ut_execute_HID
|
||||
@ -101,7 +65,6 @@ static void acpi_ut_copy_id_string(char *destination, char *source)
|
||||
* NOTE: Internal function, no parameter validation
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
acpi_status
|
||||
acpi_ut_execute_HID(struct acpi_namespace_node *device_node,
|
||||
struct acpica_device_id **return_id)
|
||||
@ -147,7 +110,7 @@ acpi_ut_execute_HID(struct acpi_namespace_node *device_node,
|
||||
if (obj_desc->common.type == ACPI_TYPE_INTEGER) {
|
||||
acpi_ex_eisa_id_to_string(hid->string, obj_desc->integer.value);
|
||||
} else {
|
||||
acpi_ut_copy_id_string(hid->string, obj_desc->string.pointer);
|
||||
ACPI_STRCPY(hid->string, obj_desc->string.pointer);
|
||||
}
|
||||
|
||||
hid->length = length;
|
||||
@ -224,7 +187,7 @@ acpi_ut_execute_UID(struct acpi_namespace_node *device_node,
|
||||
if (obj_desc->common.type == ACPI_TYPE_INTEGER) {
|
||||
acpi_ex_integer_to_string(uid->string, obj_desc->integer.value);
|
||||
} else {
|
||||
acpi_ut_copy_id_string(uid->string, obj_desc->string.pointer);
|
||||
ACPI_STRCPY(uid->string, obj_desc->string.pointer);
|
||||
}
|
||||
|
||||
uid->length = length;
|
||||
@ -357,8 +320,8 @@ acpi_ut_execute_CID(struct acpi_namespace_node *device_node,
|
||||
|
||||
/* Copy the String CID from the returned object */
|
||||
|
||||
acpi_ut_copy_id_string(next_id_string,
|
||||
cid_objects[i]->string.pointer);
|
||||
ACPI_STRCPY(next_id_string,
|
||||
cid_objects[i]->string.pointer);
|
||||
length = cid_objects[i]->string.length + 1;
|
||||
}
|
||||
|
||||
|
@ -117,6 +117,10 @@ void acpi_ut_subsystem_shutdown(void)
|
||||
/* Close the acpi_event Handling */
|
||||
|
||||
acpi_ev_terminate();
|
||||
|
||||
/* Delete any dynamic _OSI interfaces */
|
||||
|
||||
acpi_ut_interface_terminate();
|
||||
#endif
|
||||
|
||||
/* Close the Namespace */
|
||||
|
@ -48,11 +48,27 @@
|
||||
ACPI_MODULE_NAME("utmath")
|
||||
|
||||
/*
|
||||
* Support for double-precision integer divide. This code is included here
|
||||
* in order to support kernel environments where the double-precision math
|
||||
* library is not available.
|
||||
* Optional support for 64-bit double-precision integer divide. This code
|
||||
* is configurable and is implemented in order to support 32-bit kernel
|
||||
* environments where a 64-bit double-precision math library is not available.
|
||||
*
|
||||
* Support for a more normal 64-bit divide/modulo (with check for a divide-
|
||||
* by-zero) appears after this optional section of code.
|
||||
*/
|
||||
#ifndef ACPI_USE_NATIVE_DIVIDE
|
||||
/* Structures used only for 64-bit divide */
|
||||
typedef struct uint64_struct {
|
||||
u32 lo;
|
||||
u32 hi;
|
||||
|
||||
} uint64_struct;
|
||||
|
||||
typedef union uint64_overlay {
|
||||
u64 full;
|
||||
struct uint64_struct part;
|
||||
|
||||
} uint64_overlay;
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_ut_short_divide
|
||||
@ -69,6 +85,7 @@ ACPI_MODULE_NAME("utmath")
|
||||
* 32-bit remainder.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
acpi_status
|
||||
acpi_ut_short_divide(u64 dividend,
|
||||
u32 divisor, u64 *out_quotient, u32 *out_remainder)
|
||||
|
@ -50,11 +50,6 @@
|
||||
#define _COMPONENT ACPI_UTILITIES
|
||||
ACPI_MODULE_NAME("utmisc")
|
||||
|
||||
/*
|
||||
* Common suffix for messages
|
||||
*/
|
||||
#define ACPI_COMMON_MSG_SUFFIX \
|
||||
acpi_os_printf(" (%8.8X/%s-%u)\n", ACPI_CA_VERSION, module_name, line_number)
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_ut_validate_exception
|
||||
@ -1044,160 +1039,3 @@ acpi_ut_walk_package_tree(union acpi_operand_object * source_object,
|
||||
|
||||
return_ACPI_STATUS(AE_AML_INTERNAL);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_error, acpi_exception, acpi_warning, acpi_info
|
||||
*
|
||||
* PARAMETERS: module_name - Caller's module name (for error output)
|
||||
* line_number - Caller's line number (for error output)
|
||||
* Format - Printf format string + additional args
|
||||
*
|
||||
* RETURN: None
|
||||
*
|
||||
* DESCRIPTION: Print message with module/line/version info
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void ACPI_INTERNAL_VAR_XFACE
|
||||
acpi_error(const char *module_name, u32 line_number, const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
acpi_os_printf("ACPI Error: ");
|
||||
|
||||
va_start(args, format);
|
||||
acpi_os_vprintf(format, args);
|
||||
ACPI_COMMON_MSG_SUFFIX;
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void ACPI_INTERNAL_VAR_XFACE
|
||||
acpi_exception(const char *module_name,
|
||||
u32 line_number, acpi_status status, const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
acpi_os_printf("ACPI Exception: %s, ", acpi_format_exception(status));
|
||||
|
||||
va_start(args, format);
|
||||
acpi_os_vprintf(format, args);
|
||||
ACPI_COMMON_MSG_SUFFIX;
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void ACPI_INTERNAL_VAR_XFACE
|
||||
acpi_warning(const char *module_name, u32 line_number, const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
acpi_os_printf("ACPI Warning: ");
|
||||
|
||||
va_start(args, format);
|
||||
acpi_os_vprintf(format, args);
|
||||
ACPI_COMMON_MSG_SUFFIX;
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void ACPI_INTERNAL_VAR_XFACE
|
||||
acpi_info(const char *module_name, u32 line_number, const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
acpi_os_printf("ACPI: ");
|
||||
|
||||
va_start(args, format);
|
||||
acpi_os_vprintf(format, args);
|
||||
acpi_os_printf("\n");
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
ACPI_EXPORT_SYMBOL(acpi_error)
|
||||
ACPI_EXPORT_SYMBOL(acpi_exception)
|
||||
ACPI_EXPORT_SYMBOL(acpi_warning)
|
||||
ACPI_EXPORT_SYMBOL(acpi_info)
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_ut_predefined_warning
|
||||
*
|
||||
* PARAMETERS: module_name - Caller's module name (for error output)
|
||||
* line_number - Caller's line number (for error output)
|
||||
* Pathname - Full pathname to the node
|
||||
* node_flags - From Namespace node for the method/object
|
||||
* Format - Printf format string + additional args
|
||||
*
|
||||
* RETURN: None
|
||||
*
|
||||
* DESCRIPTION: Warnings for the predefined validation module. Messages are
|
||||
* only emitted the first time a problem with a particular
|
||||
* method/object is detected. This prevents a flood of error
|
||||
* messages for methods that are repeatedly evaluated.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void ACPI_INTERNAL_VAR_XFACE
|
||||
acpi_ut_predefined_warning(const char *module_name,
|
||||
u32 line_number,
|
||||
char *pathname,
|
||||
u8 node_flags, const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
/*
|
||||
* Warning messages for this method/object will be disabled after the
|
||||
* first time a validation fails or an object is successfully repaired.
|
||||
*/
|
||||
if (node_flags & ANOBJ_EVALUATED) {
|
||||
return;
|
||||
}
|
||||
|
||||
acpi_os_printf("ACPI Warning for %s: ", pathname);
|
||||
|
||||
va_start(args, format);
|
||||
acpi_os_vprintf(format, args);
|
||||
ACPI_COMMON_MSG_SUFFIX;
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_ut_predefined_info
|
||||
*
|
||||
* PARAMETERS: module_name - Caller's module name (for error output)
|
||||
* line_number - Caller's line number (for error output)
|
||||
* Pathname - Full pathname to the node
|
||||
* node_flags - From Namespace node for the method/object
|
||||
* Format - Printf format string + additional args
|
||||
*
|
||||
* RETURN: None
|
||||
*
|
||||
* DESCRIPTION: Info messages for the predefined validation module. Messages
|
||||
* are only emitted the first time a problem with a particular
|
||||
* method/object is detected. This prevents a flood of
|
||||
* messages for methods that are repeatedly evaluated.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void ACPI_INTERNAL_VAR_XFACE
|
||||
acpi_ut_predefined_info(const char *module_name,
|
||||
u32 line_number,
|
||||
char *pathname, u8 node_flags, const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
/*
|
||||
* Warning messages for this method/object will be disabled after the
|
||||
* first time a validation fails or an object is successfully repaired.
|
||||
*/
|
||||
if (node_flags & ANOBJ_EVALUATED) {
|
||||
return;
|
||||
}
|
||||
|
||||
acpi_os_printf("ACPI Info for %s: ", pathname);
|
||||
|
||||
va_start(args, format);
|
||||
acpi_os_vprintf(format, args);
|
||||
ACPI_COMMON_MSG_SUFFIX;
|
||||
va_end(args);
|
||||
}
|
||||
|
@ -86,6 +86,12 @@ acpi_status acpi_ut_mutex_initialize(void)
|
||||
spin_lock_init(acpi_gbl_gpe_lock);
|
||||
spin_lock_init(acpi_gbl_hardware_lock);
|
||||
|
||||
/* Mutex for _OSI support */
|
||||
status = acpi_os_create_mutex(&acpi_gbl_osi_mutex);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
/* Create the reader/writer lock for namespace access */
|
||||
|
||||
status = acpi_ut_create_rw_lock(&acpi_gbl_namespace_rw_lock);
|
||||
@ -117,6 +123,8 @@ void acpi_ut_mutex_terminate(void)
|
||||
acpi_ut_delete_mutex(i);
|
||||
}
|
||||
|
||||
acpi_os_delete_mutex(acpi_gbl_osi_mutex);
|
||||
|
||||
/* Delete the spinlocks */
|
||||
|
||||
acpi_os_delete_lock(acpi_gbl_gpe_lock);
|
||||
@ -220,18 +228,17 @@ acpi_status acpi_ut_acquire_mutex(acpi_mutex_handle mutex_id)
|
||||
if (acpi_gbl_mutex_info[i].thread_id == this_thread_id) {
|
||||
if (i == mutex_id) {
|
||||
ACPI_ERROR((AE_INFO,
|
||||
"Mutex [%s] already acquired by this thread [%p]",
|
||||
"Mutex [%s] already acquired by this thread [%u]",
|
||||
acpi_ut_get_mutex_name
|
||||
(mutex_id),
|
||||
ACPI_CAST_PTR(void,
|
||||
this_thread_id)));
|
||||
(u32)this_thread_id));
|
||||
|
||||
return (AE_ALREADY_ACQUIRED);
|
||||
}
|
||||
|
||||
ACPI_ERROR((AE_INFO,
|
||||
"Invalid acquire order: Thread %p owns [%s], wants [%s]",
|
||||
ACPI_CAST_PTR(void, this_thread_id),
|
||||
"Invalid acquire order: Thread %u owns [%s], wants [%s]",
|
||||
(u32)this_thread_id,
|
||||
acpi_ut_get_mutex_name(i),
|
||||
acpi_ut_get_mutex_name(mutex_id)));
|
||||
|
||||
@ -242,24 +249,24 @@ acpi_status acpi_ut_acquire_mutex(acpi_mutex_handle mutex_id)
|
||||
#endif
|
||||
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
|
||||
"Thread %p attempting to acquire Mutex [%s]\n",
|
||||
ACPI_CAST_PTR(void, this_thread_id),
|
||||
"Thread %u attempting to acquire Mutex [%s]\n",
|
||||
(u32)this_thread_id,
|
||||
acpi_ut_get_mutex_name(mutex_id)));
|
||||
|
||||
status = acpi_os_acquire_mutex(acpi_gbl_mutex_info[mutex_id].mutex,
|
||||
ACPI_WAIT_FOREVER);
|
||||
if (ACPI_SUCCESS(status)) {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
|
||||
"Thread %p acquired Mutex [%s]\n",
|
||||
ACPI_CAST_PTR(void, this_thread_id),
|
||||
"Thread %u acquired Mutex [%s]\n",
|
||||
(u32)this_thread_id,
|
||||
acpi_ut_get_mutex_name(mutex_id)));
|
||||
|
||||
acpi_gbl_mutex_info[mutex_id].use_count++;
|
||||
acpi_gbl_mutex_info[mutex_id].thread_id = this_thread_id;
|
||||
} else {
|
||||
ACPI_EXCEPTION((AE_INFO, status,
|
||||
"Thread %p could not acquire Mutex [0x%X]",
|
||||
ACPI_CAST_PTR(void, this_thread_id), mutex_id));
|
||||
"Thread %u could not acquire Mutex [0x%X]",
|
||||
(u32)this_thread_id, mutex_id));
|
||||
}
|
||||
|
||||
return (status);
|
||||
@ -279,10 +286,14 @@ acpi_status acpi_ut_acquire_mutex(acpi_mutex_handle mutex_id)
|
||||
|
||||
acpi_status acpi_ut_release_mutex(acpi_mutex_handle mutex_id)
|
||||
{
|
||||
acpi_thread_id this_thread_id;
|
||||
|
||||
ACPI_FUNCTION_NAME(ut_release_mutex);
|
||||
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Thread %p releasing Mutex [%s]\n",
|
||||
ACPI_CAST_PTR(void, acpi_os_get_thread_id()),
|
||||
this_thread_id = acpi_os_get_thread_id();
|
||||
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Thread %u releasing Mutex [%s]\n",
|
||||
(u32)this_thread_id,
|
||||
acpi_ut_get_mutex_name(mutex_id)));
|
||||
|
||||
if (mutex_id > ACPI_MAX_MUTEX) {
|
||||
|
380
drivers/acpi/acpica/utosi.c
Normal file
380
drivers/acpi/acpica/utosi.c
Normal file
@ -0,0 +1,380 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Module Name: utosi - Support for the _OSI predefined control method
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2000 - 2010, 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_UTILITIES
|
||||
ACPI_MODULE_NAME("utosi")
|
||||
|
||||
/*
|
||||
* Strings supported by the _OSI predefined control method (which is
|
||||
* implemented internally within this module.)
|
||||
*
|
||||
* March 2009: Removed "Linux" as this host no longer wants to respond true
|
||||
* for this string. Basically, the only safe OS strings are windows-related
|
||||
* and in many or most cases represent the only test path within the
|
||||
* BIOS-provided ASL code.
|
||||
*
|
||||
* The last element of each entry is used to track the newest version of
|
||||
* Windows that the BIOS has requested.
|
||||
*/
|
||||
static struct acpi_interface_info acpi_default_supported_interfaces[] = {
|
||||
/* Operating System Vendor Strings */
|
||||
|
||||
{"Windows 2000", NULL, 0, ACPI_OSI_WIN_2000}, /* Windows 2000 */
|
||||
{"Windows 2001", NULL, 0, ACPI_OSI_WIN_XP}, /* Windows XP */
|
||||
{"Windows 2001 SP1", NULL, 0, ACPI_OSI_WIN_XP_SP1}, /* Windows XP SP1 */
|
||||
{"Windows 2001.1", NULL, 0, ACPI_OSI_WINSRV_2003}, /* Windows Server 2003 */
|
||||
{"Windows 2001 SP2", NULL, 0, ACPI_OSI_WIN_XP_SP2}, /* Windows XP SP2 */
|
||||
{"Windows 2001.1 SP1", NULL, 0, ACPI_OSI_WINSRV_2003_SP1}, /* Windows Server 2003 SP1 - Added 03/2006 */
|
||||
{"Windows 2006", NULL, 0, ACPI_OSI_WIN_VISTA}, /* Windows Vista - Added 03/2006 */
|
||||
{"Windows 2006.1", NULL, 0, ACPI_OSI_WINSRV_2008}, /* Windows Server 2008 - Added 09/2009 */
|
||||
{"Windows 2006 SP1", NULL, 0, ACPI_OSI_WIN_VISTA_SP1}, /* Windows Vista SP1 - Added 09/2009 */
|
||||
{"Windows 2006 SP2", NULL, 0, ACPI_OSI_WIN_VISTA_SP2}, /* Windows Vista SP2 - Added 09/2010 */
|
||||
{"Windows 2009", NULL, 0, ACPI_OSI_WIN_7}, /* Windows 7 and Server 2008 R2 - Added 09/2009 */
|
||||
|
||||
/* Feature Group Strings */
|
||||
|
||||
{"Extended Address Space Descriptor", NULL, 0, 0}
|
||||
|
||||
/*
|
||||
* All "optional" feature group strings (features that are implemented
|
||||
* by the host) should be dynamically added by the host via
|
||||
* acpi_install_interface and should not be manually added here.
|
||||
*
|
||||
* Examples of optional feature group strings:
|
||||
*
|
||||
* "Module Device"
|
||||
* "Processor Device"
|
||||
* "3.0 Thermal Model"
|
||||
* "3.0 _SCP Extensions"
|
||||
* "Processor Aggregator Device"
|
||||
*/
|
||||
};
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_ut_initialize_interfaces
|
||||
*
|
||||
* PARAMETERS: None
|
||||
*
|
||||
* RETURN: Status
|
||||
*
|
||||
* DESCRIPTION: Initialize the global _OSI supported interfaces list
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
acpi_status acpi_ut_initialize_interfaces(void)
|
||||
{
|
||||
u32 i;
|
||||
|
||||
(void)acpi_os_acquire_mutex(acpi_gbl_osi_mutex, ACPI_WAIT_FOREVER);
|
||||
acpi_gbl_supported_interfaces = acpi_default_supported_interfaces;
|
||||
|
||||
/* Link the static list of supported interfaces */
|
||||
|
||||
for (i = 0;
|
||||
i < (ACPI_ARRAY_LENGTH(acpi_default_supported_interfaces) - 1);
|
||||
i++) {
|
||||
acpi_default_supported_interfaces[i].next =
|
||||
&acpi_default_supported_interfaces[(acpi_size) i + 1];
|
||||
}
|
||||
|
||||
acpi_os_release_mutex(acpi_gbl_osi_mutex);
|
||||
return (AE_OK);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_ut_interface_terminate
|
||||
*
|
||||
* PARAMETERS: None
|
||||
*
|
||||
* RETURN: None
|
||||
*
|
||||
* DESCRIPTION: Delete all interfaces in the global list. Sets
|
||||
* acpi_gbl_supported_interfaces to NULL.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void acpi_ut_interface_terminate(void)
|
||||
{
|
||||
struct acpi_interface_info *next_interface;
|
||||
|
||||
(void)acpi_os_acquire_mutex(acpi_gbl_osi_mutex, ACPI_WAIT_FOREVER);
|
||||
next_interface = acpi_gbl_supported_interfaces;
|
||||
|
||||
while (next_interface) {
|
||||
acpi_gbl_supported_interfaces = next_interface->next;
|
||||
|
||||
/* Only interfaces added at runtime can be freed */
|
||||
|
||||
if (next_interface->flags & ACPI_OSI_DYNAMIC) {
|
||||
ACPI_FREE(next_interface->name);
|
||||
ACPI_FREE(next_interface);
|
||||
}
|
||||
|
||||
next_interface = acpi_gbl_supported_interfaces;
|
||||
}
|
||||
|
||||
acpi_os_release_mutex(acpi_gbl_osi_mutex);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_ut_install_interface
|
||||
*
|
||||
* PARAMETERS: interface_name - The interface to install
|
||||
*
|
||||
* RETURN: Status
|
||||
*
|
||||
* DESCRIPTION: Install the interface into the global interface list.
|
||||
* Caller MUST hold acpi_gbl_osi_mutex
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
acpi_status acpi_ut_install_interface(acpi_string interface_name)
|
||||
{
|
||||
struct acpi_interface_info *interface_info;
|
||||
|
||||
/* Allocate info block and space for the name string */
|
||||
|
||||
interface_info =
|
||||
ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_interface_info));
|
||||
if (!interface_info) {
|
||||
return (AE_NO_MEMORY);
|
||||
}
|
||||
|
||||
interface_info->name =
|
||||
ACPI_ALLOCATE_ZEROED(ACPI_STRLEN(interface_name) + 1);
|
||||
if (!interface_info->name) {
|
||||
ACPI_FREE(interface_info);
|
||||
return (AE_NO_MEMORY);
|
||||
}
|
||||
|
||||
/* Initialize new info and insert at the head of the global list */
|
||||
|
||||
ACPI_STRCPY(interface_info->name, interface_name);
|
||||
interface_info->flags = ACPI_OSI_DYNAMIC;
|
||||
interface_info->next = acpi_gbl_supported_interfaces;
|
||||
|
||||
acpi_gbl_supported_interfaces = interface_info;
|
||||
return (AE_OK);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_ut_remove_interface
|
||||
*
|
||||
* PARAMETERS: interface_name - The interface to remove
|
||||
*
|
||||
* RETURN: Status
|
||||
*
|
||||
* DESCRIPTION: Remove the interface from the global interface list.
|
||||
* Caller MUST hold acpi_gbl_osi_mutex
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
acpi_status acpi_ut_remove_interface(acpi_string interface_name)
|
||||
{
|
||||
struct acpi_interface_info *previous_interface;
|
||||
struct acpi_interface_info *next_interface;
|
||||
|
||||
previous_interface = next_interface = acpi_gbl_supported_interfaces;
|
||||
while (next_interface) {
|
||||
if (!ACPI_STRCMP(interface_name, next_interface->name)) {
|
||||
|
||||
/* Found: name is in either the static list or was added at runtime */
|
||||
|
||||
if (next_interface->flags & ACPI_OSI_DYNAMIC) {
|
||||
|
||||
/* Interface was added dynamically, remove and free it */
|
||||
|
||||
if (previous_interface == next_interface) {
|
||||
acpi_gbl_supported_interfaces =
|
||||
next_interface->next;
|
||||
} else {
|
||||
previous_interface->next =
|
||||
next_interface->next;
|
||||
}
|
||||
|
||||
ACPI_FREE(next_interface->name);
|
||||
ACPI_FREE(next_interface);
|
||||
} else {
|
||||
/*
|
||||
* Interface is in static list. If marked invalid, then it
|
||||
* does not actually exist. Else, mark it invalid.
|
||||
*/
|
||||
if (next_interface->flags & ACPI_OSI_INVALID) {
|
||||
return (AE_NOT_EXIST);
|
||||
}
|
||||
|
||||
next_interface->flags |= ACPI_OSI_INVALID;
|
||||
}
|
||||
|
||||
return (AE_OK);
|
||||
}
|
||||
|
||||
previous_interface = next_interface;
|
||||
next_interface = next_interface->next;
|
||||
}
|
||||
|
||||
/* Interface was not found */
|
||||
|
||||
return (AE_NOT_EXIST);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_ut_get_interface
|
||||
*
|
||||
* PARAMETERS: interface_name - The interface to find
|
||||
*
|
||||
* RETURN: struct acpi_interface_info if found. NULL if not found.
|
||||
*
|
||||
* DESCRIPTION: Search for the specified interface name in the global list.
|
||||
* Caller MUST hold acpi_gbl_osi_mutex
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
struct acpi_interface_info *acpi_ut_get_interface(acpi_string interface_name)
|
||||
{
|
||||
struct acpi_interface_info *next_interface;
|
||||
|
||||
next_interface = acpi_gbl_supported_interfaces;
|
||||
while (next_interface) {
|
||||
if (!ACPI_STRCMP(interface_name, next_interface->name)) {
|
||||
return (next_interface);
|
||||
}
|
||||
|
||||
next_interface = next_interface->next;
|
||||
}
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_ut_osi_implementation
|
||||
*
|
||||
* PARAMETERS: walk_state - Current walk state
|
||||
*
|
||||
* RETURN: Status
|
||||
*
|
||||
* DESCRIPTION: Implementation of the _OSI predefined control method. When
|
||||
* an invocation of _OSI is encountered in the system AML,
|
||||
* control is transferred to this function.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
acpi_status acpi_ut_osi_implementation(struct acpi_walk_state * walk_state)
|
||||
{
|
||||
union acpi_operand_object *string_desc;
|
||||
union acpi_operand_object *return_desc;
|
||||
struct acpi_interface_info *interface_info;
|
||||
acpi_interface_handler interface_handler;
|
||||
u32 return_value;
|
||||
|
||||
ACPI_FUNCTION_TRACE(ut_osi_implementation);
|
||||
|
||||
/* Validate the string input argument (from the AML caller) */
|
||||
|
||||
string_desc = walk_state->arguments[0].object;
|
||||
if (!string_desc || (string_desc->common.type != ACPI_TYPE_STRING)) {
|
||||
return_ACPI_STATUS(AE_TYPE);
|
||||
}
|
||||
|
||||
/* Create a return object */
|
||||
|
||||
return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
|
||||
if (!return_desc) {
|
||||
return_ACPI_STATUS(AE_NO_MEMORY);
|
||||
}
|
||||
|
||||
/* Default return value is 0, NOT SUPPORTED */
|
||||
|
||||
return_value = 0;
|
||||
(void)acpi_os_acquire_mutex(acpi_gbl_osi_mutex, ACPI_WAIT_FOREVER);
|
||||
|
||||
/* Lookup the interface in the global _OSI list */
|
||||
|
||||
interface_info = acpi_ut_get_interface(string_desc->string.pointer);
|
||||
if (interface_info && !(interface_info->flags & ACPI_OSI_INVALID)) {
|
||||
/*
|
||||
* The interface is supported.
|
||||
* Update the osi_data if necessary. We keep track of the latest
|
||||
* version of Windows that has been requested by the BIOS.
|
||||
*/
|
||||
if (interface_info->value > acpi_gbl_osi_data) {
|
||||
acpi_gbl_osi_data = interface_info->value;
|
||||
}
|
||||
|
||||
return_value = ACPI_UINT32_MAX;
|
||||
}
|
||||
|
||||
acpi_os_release_mutex(acpi_gbl_osi_mutex);
|
||||
|
||||
/*
|
||||
* Invoke an optional _OSI interface handler. The host OS may wish
|
||||
* to do some interface-specific handling. For example, warn about
|
||||
* certain interfaces or override the true/false support value.
|
||||
*/
|
||||
interface_handler = acpi_gbl_interface_handler;
|
||||
if (interface_handler) {
|
||||
return_value =
|
||||
interface_handler(string_desc->string.pointer,
|
||||
return_value);
|
||||
}
|
||||
|
||||
ACPI_DEBUG_PRINT_RAW((ACPI_DB_INFO,
|
||||
"ACPI: BIOS _OSI(\"%s\") is %ssupported\n",
|
||||
string_desc->string.pointer,
|
||||
return_value == 0 ? "not " : ""));
|
||||
|
||||
/* Complete the return object */
|
||||
|
||||
return_desc->integer.value = return_value;
|
||||
walk_state->return_desc = return_desc;
|
||||
return_ACPI_STATUS(AE_OK);
|
||||
}
|
@ -110,6 +110,15 @@ acpi_status __init acpi_initialize_subsystem(void)
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
/* Initialize the global OSI interfaces list with the static names */
|
||||
|
||||
status = acpi_ut_initialize_interfaces();
|
||||
if (ACPI_FAILURE(status)) {
|
||||
ACPI_EXCEPTION((AE_INFO, status,
|
||||
"During OSI interfaces initialization"));
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
/* If configured, initialize the AML debugger */
|
||||
|
||||
ACPI_DEBUGGER_EXEC(status = acpi_db_initialize());
|
||||
@ -289,19 +298,6 @@ acpi_status acpi_initialize_objects(u32 flags)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Complete the GPE initialization for the GPE blocks defined in the FADT
|
||||
* (GPE block 0 and 1).
|
||||
*
|
||||
* NOTE: Currently, there seems to be no need to run the _REG methods
|
||||
* before enabling the GPEs.
|
||||
*/
|
||||
if (!(flags & ACPI_NO_EVENT_INIT)) {
|
||||
status = acpi_ev_install_fadt_gpes();
|
||||
if (ACPI_FAILURE(status))
|
||||
return (status);
|
||||
}
|
||||
|
||||
/*
|
||||
* Empty the caches (delete the cached objects) on the assumption that
|
||||
* the table load filled them up more than they will be at runtime --
|
||||
@ -506,6 +502,7 @@ acpi_install_initialization_handler(acpi_init_handler handler, u32 function)
|
||||
|
||||
ACPI_EXPORT_SYMBOL(acpi_install_initialization_handler)
|
||||
#endif /* ACPI_FUTURE_USAGE */
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_purge_cached_objects
|
||||
@ -529,4 +526,117 @@ acpi_status acpi_purge_cached_objects(void)
|
||||
}
|
||||
|
||||
ACPI_EXPORT_SYMBOL(acpi_purge_cached_objects)
|
||||
#endif
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_install_interface
|
||||
*
|
||||
* PARAMETERS: interface_name - The interface to install
|
||||
*
|
||||
* RETURN: Status
|
||||
*
|
||||
* DESCRIPTION: Install an _OSI interface to the global list
|
||||
*
|
||||
****************************************************************************/
|
||||
acpi_status acpi_install_interface(acpi_string interface_name)
|
||||
{
|
||||
acpi_status status;
|
||||
struct acpi_interface_info *interface_info;
|
||||
|
||||
/* Parameter validation */
|
||||
|
||||
if (!interface_name || (ACPI_STRLEN(interface_name) == 0)) {
|
||||
return (AE_BAD_PARAMETER);
|
||||
}
|
||||
|
||||
(void)acpi_os_acquire_mutex(acpi_gbl_osi_mutex, ACPI_WAIT_FOREVER);
|
||||
|
||||
/* Check if the interface name is already in the global list */
|
||||
|
||||
interface_info = acpi_ut_get_interface(interface_name);
|
||||
if (interface_info) {
|
||||
/*
|
||||
* The interface already exists in the list. This is OK if the
|
||||
* interface has been marked invalid -- just clear the bit.
|
||||
*/
|
||||
if (interface_info->flags & ACPI_OSI_INVALID) {
|
||||
interface_info->flags &= ~ACPI_OSI_INVALID;
|
||||
status = AE_OK;
|
||||
} else {
|
||||
status = AE_ALREADY_EXISTS;
|
||||
}
|
||||
} else {
|
||||
/* New interface name, install into the global list */
|
||||
|
||||
status = acpi_ut_install_interface(interface_name);
|
||||
}
|
||||
|
||||
acpi_os_release_mutex(acpi_gbl_osi_mutex);
|
||||
return (status);
|
||||
}
|
||||
|
||||
ACPI_EXPORT_SYMBOL(acpi_install_interface)
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_remove_interface
|
||||
*
|
||||
* PARAMETERS: interface_name - The interface to remove
|
||||
*
|
||||
* RETURN: Status
|
||||
*
|
||||
* DESCRIPTION: Remove an _OSI interface from the global list
|
||||
*
|
||||
****************************************************************************/
|
||||
acpi_status acpi_remove_interface(acpi_string interface_name)
|
||||
{
|
||||
acpi_status status;
|
||||
|
||||
/* Parameter validation */
|
||||
|
||||
if (!interface_name || (ACPI_STRLEN(interface_name) == 0)) {
|
||||
return (AE_BAD_PARAMETER);
|
||||
}
|
||||
|
||||
(void)acpi_os_acquire_mutex(acpi_gbl_osi_mutex, ACPI_WAIT_FOREVER);
|
||||
|
||||
status = acpi_ut_remove_interface(interface_name);
|
||||
|
||||
acpi_os_release_mutex(acpi_gbl_osi_mutex);
|
||||
return (status);
|
||||
}
|
||||
|
||||
ACPI_EXPORT_SYMBOL(acpi_remove_interface)
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_install_interface_handler
|
||||
*
|
||||
* PARAMETERS: Handler - The _OSI interface handler to install
|
||||
* NULL means "remove existing handler"
|
||||
*
|
||||
* RETURN: Status
|
||||
*
|
||||
* DESCRIPTION: Install a handler for the predefined _OSI ACPI method.
|
||||
* invoked during execution of the internal implementation of
|
||||
* _OSI. A NULL handler simply removes any existing handler.
|
||||
*
|
||||
****************************************************************************/
|
||||
acpi_status acpi_install_interface_handler(acpi_interface_handler handler)
|
||||
{
|
||||
acpi_status status = AE_OK;
|
||||
|
||||
(void)acpi_os_acquire_mutex(acpi_gbl_osi_mutex, ACPI_WAIT_FOREVER);
|
||||
|
||||
if (handler && acpi_gbl_interface_handler) {
|
||||
status = AE_ALREADY_EXISTS;
|
||||
} else {
|
||||
acpi_gbl_interface_handler = handler;
|
||||
}
|
||||
|
||||
acpi_os_release_mutex(acpi_gbl_osi_mutex);
|
||||
return (status);
|
||||
}
|
||||
|
||||
ACPI_EXPORT_SYMBOL(acpi_install_interface_handler)
|
||||
#endif /* !ACPI_ASL_COMPILER */
|
||||
|
415
drivers/acpi/acpica/utxferror.c
Normal file
415
drivers/acpi/acpica/utxferror.c
Normal file
@ -0,0 +1,415 @@
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Module Name: utxferror - Various error/warning output functions
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2000 - 2010, 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 "acnamesp.h"
|
||||
|
||||
#define _COMPONENT ACPI_UTILITIES
|
||||
ACPI_MODULE_NAME("utxferror")
|
||||
|
||||
/*
|
||||
* This module is used for the in-kernel ACPICA as well as the ACPICA
|
||||
* tools/applications.
|
||||
*
|
||||
* For the i_aSL compiler case, the output is redirected to stderr so that
|
||||
* any of the various ACPI errors and warnings do not appear in the output
|
||||
* files, for either the compiler or disassembler portions of the tool.
|
||||
*/
|
||||
#ifdef ACPI_ASL_COMPILER
|
||||
#include <stdio.h>
|
||||
extern FILE *acpi_gbl_output_file;
|
||||
|
||||
#define ACPI_MSG_REDIRECT_BEGIN \
|
||||
FILE *output_file = acpi_gbl_output_file; \
|
||||
acpi_os_redirect_output (stderr);
|
||||
|
||||
#define ACPI_MSG_REDIRECT_END \
|
||||
acpi_os_redirect_output (output_file);
|
||||
|
||||
#else
|
||||
/*
|
||||
* non-i_aSL case - no redirection, nothing to do
|
||||
*/
|
||||
#define ACPI_MSG_REDIRECT_BEGIN
|
||||
#define ACPI_MSG_REDIRECT_END
|
||||
#endif
|
||||
/*
|
||||
* Common message prefixes
|
||||
*/
|
||||
#define ACPI_MSG_ERROR "ACPI Error: "
|
||||
#define ACPI_MSG_EXCEPTION "ACPI Exception: "
|
||||
#define ACPI_MSG_WARNING "ACPI Warning: "
|
||||
#define ACPI_MSG_INFO "ACPI: "
|
||||
/*
|
||||
* Common message suffix
|
||||
*/
|
||||
#define ACPI_MSG_SUFFIX \
|
||||
acpi_os_printf (" (%8.8X/%s-%u)\n", ACPI_CA_VERSION, module_name, line_number)
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_error
|
||||
*
|
||||
* PARAMETERS: module_name - Caller's module name (for error output)
|
||||
* line_number - Caller's line number (for error output)
|
||||
* Format - Printf format string + additional args
|
||||
*
|
||||
* RETURN: None
|
||||
*
|
||||
* DESCRIPTION: Print "ACPI Error" message with module/line/version info
|
||||
*
|
||||
******************************************************************************/
|
||||
void ACPI_INTERNAL_VAR_XFACE
|
||||
acpi_error(const char *module_name, u32 line_number, const char *format, ...)
|
||||
{
|
||||
va_list arg_list;
|
||||
|
||||
ACPI_MSG_REDIRECT_BEGIN;
|
||||
acpi_os_printf(ACPI_MSG_ERROR);
|
||||
|
||||
va_start(arg_list, format);
|
||||
acpi_os_vprintf(format, arg_list);
|
||||
ACPI_MSG_SUFFIX;
|
||||
va_end(arg_list);
|
||||
|
||||
ACPI_MSG_REDIRECT_END;
|
||||
}
|
||||
|
||||
ACPI_EXPORT_SYMBOL(acpi_error)
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_exception
|
||||
*
|
||||
* PARAMETERS: module_name - Caller's module name (for error output)
|
||||
* line_number - Caller's line number (for error output)
|
||||
* Status - Status to be formatted
|
||||
* Format - Printf format string + additional args
|
||||
*
|
||||
* RETURN: None
|
||||
*
|
||||
* DESCRIPTION: Print "ACPI Exception" message with module/line/version info
|
||||
* and decoded acpi_status.
|
||||
*
|
||||
******************************************************************************/
|
||||
void ACPI_INTERNAL_VAR_XFACE
|
||||
acpi_exception(const char *module_name,
|
||||
u32 line_number, acpi_status status, const char *format, ...)
|
||||
{
|
||||
va_list arg_list;
|
||||
|
||||
ACPI_MSG_REDIRECT_BEGIN;
|
||||
acpi_os_printf(ACPI_MSG_EXCEPTION "%s, ",
|
||||
acpi_format_exception(status));
|
||||
|
||||
va_start(arg_list, format);
|
||||
acpi_os_vprintf(format, arg_list);
|
||||
ACPI_MSG_SUFFIX;
|
||||
va_end(arg_list);
|
||||
|
||||
ACPI_MSG_REDIRECT_END;
|
||||
}
|
||||
|
||||
ACPI_EXPORT_SYMBOL(acpi_exception)
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_warning
|
||||
*
|
||||
* PARAMETERS: module_name - Caller's module name (for error output)
|
||||
* line_number - Caller's line number (for error output)
|
||||
* Format - Printf format string + additional args
|
||||
*
|
||||
* RETURN: None
|
||||
*
|
||||
* DESCRIPTION: Print "ACPI Warning" message with module/line/version info
|
||||
*
|
||||
******************************************************************************/
|
||||
void ACPI_INTERNAL_VAR_XFACE
|
||||
acpi_warning(const char *module_name, u32 line_number, const char *format, ...)
|
||||
{
|
||||
va_list arg_list;
|
||||
|
||||
ACPI_MSG_REDIRECT_BEGIN;
|
||||
acpi_os_printf(ACPI_MSG_WARNING);
|
||||
|
||||
va_start(arg_list, format);
|
||||
acpi_os_vprintf(format, arg_list);
|
||||
ACPI_MSG_SUFFIX;
|
||||
va_end(arg_list);
|
||||
|
||||
ACPI_MSG_REDIRECT_END;
|
||||
}
|
||||
|
||||
ACPI_EXPORT_SYMBOL(acpi_warning)
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_info
|
||||
*
|
||||
* PARAMETERS: module_name - Caller's module name (for error output)
|
||||
* line_number - Caller's line number (for error output)
|
||||
* Format - Printf format string + additional args
|
||||
*
|
||||
* RETURN: None
|
||||
*
|
||||
* DESCRIPTION: Print generic "ACPI:" information message. There is no
|
||||
* module/line/version info in order to keep the message simple.
|
||||
*
|
||||
* TBD: module_name and line_number args are not needed, should be removed.
|
||||
*
|
||||
******************************************************************************/
|
||||
void ACPI_INTERNAL_VAR_XFACE
|
||||
acpi_info(const char *module_name, u32 line_number, const char *format, ...)
|
||||
{
|
||||
va_list arg_list;
|
||||
|
||||
ACPI_MSG_REDIRECT_BEGIN;
|
||||
acpi_os_printf(ACPI_MSG_INFO);
|
||||
|
||||
va_start(arg_list, format);
|
||||
acpi_os_vprintf(format, arg_list);
|
||||
acpi_os_printf("\n");
|
||||
va_end(arg_list);
|
||||
|
||||
ACPI_MSG_REDIRECT_END;
|
||||
}
|
||||
|
||||
ACPI_EXPORT_SYMBOL(acpi_info)
|
||||
|
||||
/*
|
||||
* The remainder of this module contains internal error functions that may
|
||||
* be configured out.
|
||||
*/
|
||||
#if !defined (ACPI_NO_ERROR_MESSAGES) && !defined (ACPI_BIN_APP)
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_ut_predefined_warning
|
||||
*
|
||||
* PARAMETERS: module_name - Caller's module name (for error output)
|
||||
* line_number - Caller's line number (for error output)
|
||||
* Pathname - Full pathname to the node
|
||||
* node_flags - From Namespace node for the method/object
|
||||
* Format - Printf format string + additional args
|
||||
*
|
||||
* RETURN: None
|
||||
*
|
||||
* DESCRIPTION: Warnings for the predefined validation module. Messages are
|
||||
* only emitted the first time a problem with a particular
|
||||
* method/object is detected. This prevents a flood of error
|
||||
* messages for methods that are repeatedly evaluated.
|
||||
*
|
||||
******************************************************************************/
|
||||
void ACPI_INTERNAL_VAR_XFACE
|
||||
acpi_ut_predefined_warning(const char *module_name,
|
||||
u32 line_number,
|
||||
char *pathname,
|
||||
u8 node_flags, const char *format, ...)
|
||||
{
|
||||
va_list arg_list;
|
||||
|
||||
/*
|
||||
* Warning messages for this method/object will be disabled after the
|
||||
* first time a validation fails or an object is successfully repaired.
|
||||
*/
|
||||
if (node_flags & ANOBJ_EVALUATED) {
|
||||
return;
|
||||
}
|
||||
|
||||
acpi_os_printf(ACPI_MSG_WARNING "For %s: ", pathname);
|
||||
|
||||
va_start(arg_list, format);
|
||||
acpi_os_vprintf(format, arg_list);
|
||||
ACPI_MSG_SUFFIX;
|
||||
va_end(arg_list);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_ut_predefined_info
|
||||
*
|
||||
* PARAMETERS: module_name - Caller's module name (for error output)
|
||||
* line_number - Caller's line number (for error output)
|
||||
* Pathname - Full pathname to the node
|
||||
* node_flags - From Namespace node for the method/object
|
||||
* Format - Printf format string + additional args
|
||||
*
|
||||
* RETURN: None
|
||||
*
|
||||
* DESCRIPTION: Info messages for the predefined validation module. Messages
|
||||
* are only emitted the first time a problem with a particular
|
||||
* method/object is detected. This prevents a flood of
|
||||
* messages for methods that are repeatedly evaluated.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void ACPI_INTERNAL_VAR_XFACE
|
||||
acpi_ut_predefined_info(const char *module_name,
|
||||
u32 line_number,
|
||||
char *pathname, u8 node_flags, const char *format, ...)
|
||||
{
|
||||
va_list arg_list;
|
||||
|
||||
/*
|
||||
* Warning messages for this method/object will be disabled after the
|
||||
* first time a validation fails or an object is successfully repaired.
|
||||
*/
|
||||
if (node_flags & ANOBJ_EVALUATED) {
|
||||
return;
|
||||
}
|
||||
|
||||
acpi_os_printf(ACPI_MSG_INFO "For %s: ", pathname);
|
||||
|
||||
va_start(arg_list, format);
|
||||
acpi_os_vprintf(format, arg_list);
|
||||
ACPI_MSG_SUFFIX;
|
||||
va_end(arg_list);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_ut_namespace_error
|
||||
*
|
||||
* PARAMETERS: module_name - Caller's module name (for error output)
|
||||
* line_number - Caller's line number (for error output)
|
||||
* internal_name - Name or path of the namespace node
|
||||
* lookup_status - Exception code from NS lookup
|
||||
*
|
||||
* RETURN: None
|
||||
*
|
||||
* DESCRIPTION: Print error message with the full pathname for the NS node.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void
|
||||
acpi_ut_namespace_error(const char *module_name,
|
||||
u32 line_number,
|
||||
const char *internal_name, acpi_status lookup_status)
|
||||
{
|
||||
acpi_status status;
|
||||
u32 bad_name;
|
||||
char *name = NULL;
|
||||
|
||||
ACPI_MSG_REDIRECT_BEGIN;
|
||||
acpi_os_printf(ACPI_MSG_ERROR);
|
||||
|
||||
if (lookup_status == AE_BAD_CHARACTER) {
|
||||
|
||||
/* There is a non-ascii character in the name */
|
||||
|
||||
ACPI_MOVE_32_TO_32(&bad_name,
|
||||
ACPI_CAST_PTR(u32, internal_name));
|
||||
acpi_os_printf("[0x%4.4X] (NON-ASCII)", bad_name);
|
||||
} else {
|
||||
/* Convert path to external format */
|
||||
|
||||
status = acpi_ns_externalize_name(ACPI_UINT32_MAX,
|
||||
internal_name, NULL, &name);
|
||||
|
||||
/* Print target name */
|
||||
|
||||
if (ACPI_SUCCESS(status)) {
|
||||
acpi_os_printf("[%s]", name);
|
||||
} else {
|
||||
acpi_os_printf("[COULD NOT EXTERNALIZE NAME]");
|
||||
}
|
||||
|
||||
if (name) {
|
||||
ACPI_FREE(name);
|
||||
}
|
||||
}
|
||||
|
||||
acpi_os_printf(" Namespace lookup failure, %s",
|
||||
acpi_format_exception(lookup_status));
|
||||
|
||||
ACPI_MSG_SUFFIX;
|
||||
ACPI_MSG_REDIRECT_END;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_ut_method_error
|
||||
*
|
||||
* PARAMETERS: module_name - Caller's module name (for error output)
|
||||
* line_number - Caller's line number (for error output)
|
||||
* Message - Error message to use on failure
|
||||
* prefix_node - Prefix relative to the path
|
||||
* Path - Path to the node (optional)
|
||||
* method_status - Execution status
|
||||
*
|
||||
* RETURN: None
|
||||
*
|
||||
* DESCRIPTION: Print error message with the full pathname for the method.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void
|
||||
acpi_ut_method_error(const char *module_name,
|
||||
u32 line_number,
|
||||
const char *message,
|
||||
struct acpi_namespace_node *prefix_node,
|
||||
const char *path, acpi_status method_status)
|
||||
{
|
||||
acpi_status status;
|
||||
struct acpi_namespace_node *node = prefix_node;
|
||||
|
||||
ACPI_MSG_REDIRECT_BEGIN;
|
||||
acpi_os_printf(ACPI_MSG_ERROR);
|
||||
|
||||
if (path) {
|
||||
status =
|
||||
acpi_ns_get_node(prefix_node, path, ACPI_NS_NO_UPSEARCH,
|
||||
&node);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
acpi_os_printf("[Could not get node by pathname]");
|
||||
}
|
||||
}
|
||||
|
||||
acpi_ns_print_node_pathname(node, message);
|
||||
acpi_os_printf(", %s", acpi_format_exception(method_status));
|
||||
|
||||
ACPI_MSG_SUFFIX;
|
||||
ACPI_MSG_REDIRECT_END;
|
||||
}
|
||||
|
||||
#endif /* ACPI_NO_ERROR_MESSAGES */
|
@ -42,10 +42,7 @@
|
||||
|
||||
#include <acpi/acpi_bus.h>
|
||||
#include <acpi/acpi_drivers.h>
|
||||
|
||||
#ifdef CONFIG_ACPI_SYSFS_POWER
|
||||
#include <linux/power_supply.h>
|
||||
#endif
|
||||
|
||||
#define PREFIX "ACPI: "
|
||||
|
||||
@ -98,13 +95,12 @@ enum {
|
||||
* due to bad math.
|
||||
*/
|
||||
ACPI_BATTERY_QUIRK_SIGNED16_CURRENT,
|
||||
ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY,
|
||||
};
|
||||
|
||||
struct acpi_battery {
|
||||
struct mutex lock;
|
||||
#ifdef CONFIG_ACPI_SYSFS_POWER
|
||||
struct power_supply bat;
|
||||
#endif
|
||||
struct acpi_device *device;
|
||||
unsigned long update_time;
|
||||
int rate_now;
|
||||
@ -141,7 +137,6 @@ inline int acpi_battery_present(struct acpi_battery *battery)
|
||||
return battery->device->status.battery_present;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ACPI_SYSFS_POWER
|
||||
static int acpi_battery_technology(struct acpi_battery *battery)
|
||||
{
|
||||
if (!strcasecmp("NiCd", battery->type))
|
||||
@ -186,6 +181,7 @@ static int acpi_battery_get_property(struct power_supply *psy,
|
||||
enum power_supply_property psp,
|
||||
union power_supply_propval *val)
|
||||
{
|
||||
int ret = 0;
|
||||
struct acpi_battery *battery = to_acpi_battery(psy);
|
||||
|
||||
if (acpi_battery_present(battery)) {
|
||||
@ -214,26 +210,44 @@ static int acpi_battery_get_property(struct power_supply *psy,
|
||||
val->intval = battery->cycle_count;
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
|
||||
val->intval = battery->design_voltage * 1000;
|
||||
if (battery->design_voltage == ACPI_BATTERY_VALUE_UNKNOWN)
|
||||
ret = -ENODEV;
|
||||
else
|
||||
val->intval = battery->design_voltage * 1000;
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_VOLTAGE_NOW:
|
||||
val->intval = battery->voltage_now * 1000;
|
||||
if (battery->voltage_now == ACPI_BATTERY_VALUE_UNKNOWN)
|
||||
ret = -ENODEV;
|
||||
else
|
||||
val->intval = battery->voltage_now * 1000;
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_CURRENT_NOW:
|
||||
case POWER_SUPPLY_PROP_POWER_NOW:
|
||||
val->intval = battery->rate_now * 1000;
|
||||
if (battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN)
|
||||
ret = -ENODEV;
|
||||
else
|
||||
val->intval = battery->rate_now * 1000;
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
|
||||
case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN:
|
||||
val->intval = battery->design_capacity * 1000;
|
||||
if (battery->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
|
||||
ret = -ENODEV;
|
||||
else
|
||||
val->intval = battery->design_capacity * 1000;
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_CHARGE_FULL:
|
||||
case POWER_SUPPLY_PROP_ENERGY_FULL:
|
||||
val->intval = battery->full_charge_capacity * 1000;
|
||||
if (battery->full_charge_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
|
||||
ret = -ENODEV;
|
||||
else
|
||||
val->intval = battery->full_charge_capacity * 1000;
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_CHARGE_NOW:
|
||||
case POWER_SUPPLY_PROP_ENERGY_NOW:
|
||||
val->intval = battery->capacity_now * 1000;
|
||||
if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN)
|
||||
ret = -ENODEV;
|
||||
else
|
||||
val->intval = battery->capacity_now * 1000;
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_MODEL_NAME:
|
||||
val->strval = battery->model_number;
|
||||
@ -245,9 +259,9 @@ static int acpi_battery_get_property(struct power_supply *psy,
|
||||
val->strval = battery->serial_number;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
ret = -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static enum power_supply_property charge_battery_props[] = {
|
||||
@ -281,7 +295,6 @@ static enum power_supply_property energy_battery_props[] = {
|
||||
POWER_SUPPLY_PROP_MANUFACTURER,
|
||||
POWER_SUPPLY_PROP_SERIAL_NUMBER,
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ACPI_PROCFS_POWER
|
||||
inline char *acpi_battery_units(struct acpi_battery *battery)
|
||||
@ -412,6 +425,8 @@ static int acpi_battery_get_info(struct acpi_battery *battery)
|
||||
result = extract_package(battery, buffer.pointer,
|
||||
info_offsets, ARRAY_SIZE(info_offsets));
|
||||
kfree(buffer.pointer);
|
||||
if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags))
|
||||
battery->full_charge_capacity = battery->design_capacity;
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -448,6 +463,10 @@ static int acpi_battery_get_state(struct acpi_battery *battery)
|
||||
battery->rate_now != -1)
|
||||
battery->rate_now = abs((s16)battery->rate_now);
|
||||
|
||||
if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags)
|
||||
&& battery->capacity_now >= 0 && battery->capacity_now <= 100)
|
||||
battery->capacity_now = (battery->capacity_now *
|
||||
battery->full_charge_capacity) / 100;
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -492,7 +511,6 @@ static int acpi_battery_init_alarm(struct acpi_battery *battery)
|
||||
return acpi_battery_set_alarm(battery);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ACPI_SYSFS_POWER
|
||||
static ssize_t acpi_battery_alarm_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
@ -552,7 +570,6 @@ static void sysfs_remove_battery(struct acpi_battery *battery)
|
||||
power_supply_unregister(&battery->bat);
|
||||
battery->bat.dev = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void acpi_battery_quirks(struct acpi_battery *battery)
|
||||
{
|
||||
@ -561,6 +578,33 @@ static void acpi_battery_quirks(struct acpi_battery *battery)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* According to the ACPI spec, some kinds of primary batteries can
|
||||
* report percentage battery remaining capacity directly to OS.
|
||||
* In this case, it reports the Last Full Charged Capacity == 100
|
||||
* and BatteryPresentRate == 0xFFFFFFFF.
|
||||
*
|
||||
* Now we found some battery reports percentage remaining capacity
|
||||
* even if it's rechargeable.
|
||||
* https://bugzilla.kernel.org/show_bug.cgi?id=15979
|
||||
*
|
||||
* Handle this correctly so that they won't break userspace.
|
||||
*/
|
||||
static void acpi_battery_quirks2(struct acpi_battery *battery)
|
||||
{
|
||||
if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags))
|
||||
return ;
|
||||
|
||||
if (battery->full_charge_capacity == 100 &&
|
||||
battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN &&
|
||||
battery->capacity_now >=0 && battery->capacity_now <= 100) {
|
||||
set_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags);
|
||||
battery->full_charge_capacity = battery->design_capacity;
|
||||
battery->capacity_now = (battery->capacity_now *
|
||||
battery->full_charge_capacity) / 100;
|
||||
}
|
||||
}
|
||||
|
||||
static int acpi_battery_update(struct acpi_battery *battery)
|
||||
{
|
||||
int result, old_present = acpi_battery_present(battery);
|
||||
@ -568,9 +612,7 @@ static int acpi_battery_update(struct acpi_battery *battery)
|
||||
if (result)
|
||||
return result;
|
||||
if (!acpi_battery_present(battery)) {
|
||||
#ifdef CONFIG_ACPI_SYSFS_POWER
|
||||
sysfs_remove_battery(battery);
|
||||
#endif
|
||||
battery->update_time = 0;
|
||||
return 0;
|
||||
}
|
||||
@ -582,11 +624,11 @@ static int acpi_battery_update(struct acpi_battery *battery)
|
||||
acpi_battery_quirks(battery);
|
||||
acpi_battery_init_alarm(battery);
|
||||
}
|
||||
#ifdef CONFIG_ACPI_SYSFS_POWER
|
||||
if (!battery->bat.dev)
|
||||
sysfs_add_battery(battery);
|
||||
#endif
|
||||
return acpi_battery_get_state(battery);
|
||||
result = acpi_battery_get_state(battery);
|
||||
acpi_battery_quirks2(battery);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------
|
||||
@ -867,26 +909,20 @@ static void acpi_battery_remove_fs(struct acpi_device *device)
|
||||
static void acpi_battery_notify(struct acpi_device *device, u32 event)
|
||||
{
|
||||
struct acpi_battery *battery = acpi_driver_data(device);
|
||||
#ifdef CONFIG_ACPI_SYSFS_POWER
|
||||
struct device *old;
|
||||
#endif
|
||||
|
||||
if (!battery)
|
||||
return;
|
||||
#ifdef CONFIG_ACPI_SYSFS_POWER
|
||||
old = battery->bat.dev;
|
||||
#endif
|
||||
acpi_battery_update(battery);
|
||||
acpi_bus_generate_proc_event(device, event,
|
||||
acpi_battery_present(battery));
|
||||
acpi_bus_generate_netlink_event(device->pnp.device_class,
|
||||
dev_name(&device->dev), event,
|
||||
acpi_battery_present(battery));
|
||||
#ifdef CONFIG_ACPI_SYSFS_POWER
|
||||
/* acpi_battery_update could remove power_supply object */
|
||||
if (old && battery->bat.dev)
|
||||
power_supply_changed(&battery->bat);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int acpi_battery_add(struct acpi_device *device)
|
||||
@ -934,9 +970,7 @@ static int acpi_battery_remove(struct acpi_device *device, int type)
|
||||
#ifdef CONFIG_ACPI_PROCFS_POWER
|
||||
acpi_battery_remove_fs(device);
|
||||
#endif
|
||||
#ifdef CONFIG_ACPI_SYSFS_POWER
|
||||
sysfs_remove_battery(battery);
|
||||
#endif
|
||||
mutex_destroy(&battery->lock);
|
||||
kfree(battery);
|
||||
return 0;
|
||||
|
@ -935,6 +935,12 @@ static int __init acpi_bus_init(void)
|
||||
goto error1;
|
||||
}
|
||||
|
||||
/*
|
||||
* _PDC control method may load dynamic SSDT tables,
|
||||
* and we need to install the table handler before that.
|
||||
*/
|
||||
acpi_sysfs_init();
|
||||
|
||||
acpi_early_processor_set_pdc();
|
||||
|
||||
/*
|
||||
@ -1026,7 +1032,6 @@ static int __init acpi_init(void)
|
||||
acpi_scan_init();
|
||||
acpi_ec_init();
|
||||
acpi_power_init();
|
||||
acpi_sysfs_init();
|
||||
acpi_debugfs_init();
|
||||
acpi_sleep_proc_init();
|
||||
acpi_wakeup_device_init();
|
||||
|
@ -338,7 +338,8 @@ static int acpi_button_add(struct acpi_device *device)
|
||||
{
|
||||
struct acpi_button *button;
|
||||
struct input_dev *input;
|
||||
char *hid, *name, *class;
|
||||
const char *hid = acpi_device_hid(device);
|
||||
char *name, *class;
|
||||
int error;
|
||||
|
||||
button = kzalloc(sizeof(struct acpi_button), GFP_KERNEL);
|
||||
@ -353,7 +354,6 @@ static int acpi_button_add(struct acpi_device *device)
|
||||
goto err_free_button;
|
||||
}
|
||||
|
||||
hid = acpi_device_hid(device);
|
||||
name = acpi_device_name(device);
|
||||
class = acpi_device_class(device);
|
||||
|
||||
|
@ -725,6 +725,7 @@ static void dock_notify(acpi_handle handle, u32 event, void *data)
|
||||
complete_dock(ds);
|
||||
dock_event(ds, event, DOCK_EVENT);
|
||||
dock_lock(ds, 1);
|
||||
acpi_update_gpes();
|
||||
break;
|
||||
}
|
||||
if (dock_present(ds) || dock_in_progress(ds))
|
||||
@ -929,7 +930,7 @@ static struct attribute_group dock_attribute_group = {
|
||||
* allocated and initialize a new dock station device. Find all devices
|
||||
* that are on the dock station, and register for dock event notifications.
|
||||
*/
|
||||
static int dock_add(acpi_handle handle)
|
||||
static int __init dock_add(acpi_handle handle)
|
||||
{
|
||||
int ret, id;
|
||||
struct dock_station ds, *dock_station;
|
||||
@ -1023,7 +1024,7 @@ static int dock_remove(struct dock_station *ds)
|
||||
*
|
||||
* This is called by acpi_walk_namespace to look for dock stations.
|
||||
*/
|
||||
static acpi_status
|
||||
static __init acpi_status
|
||||
find_dock(acpi_handle handle, u32 lvl, void *context, void **rv)
|
||||
{
|
||||
if (is_dock(handle))
|
||||
@ -1032,7 +1033,7 @@ find_dock(acpi_handle handle, u32 lvl, void *context, void **rv)
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
static acpi_status
|
||||
static __init acpi_status
|
||||
find_bay(acpi_handle handle, u32 lvl, void *context, void **rv)
|
||||
{
|
||||
/* If bay is a dock, it's already handled */
|
||||
|
@ -83,6 +83,11 @@ enum {
|
||||
EC_FLAGS_BLOCKED, /* Transactions are blocked */
|
||||
};
|
||||
|
||||
/* ec.c is compiled in acpi namespace so this shows up as acpi.ec_delay param */
|
||||
static unsigned int ec_delay __read_mostly = ACPI_EC_DELAY;
|
||||
module_param(ec_delay, uint, 0644);
|
||||
MODULE_PARM_DESC(ec_delay, "Timeout(ms) waited until an EC command completes");
|
||||
|
||||
/* If we find an EC via the ECDT, we need to keep a ptr to its context */
|
||||
/* External interfaces use first EC only, so remember */
|
||||
typedef int (*acpi_ec_query_func) (void *data);
|
||||
@ -210,7 +215,7 @@ static int ec_poll(struct acpi_ec *ec)
|
||||
int repeat = 2; /* number of command restarts */
|
||||
while (repeat--) {
|
||||
unsigned long delay = jiffies +
|
||||
msecs_to_jiffies(ACPI_EC_DELAY);
|
||||
msecs_to_jiffies(ec_delay);
|
||||
do {
|
||||
/* don't sleep with disabled interrupts */
|
||||
if (EC_FLAGS_MSI || irqs_disabled()) {
|
||||
@ -265,7 +270,7 @@ static int ec_check_ibf0(struct acpi_ec *ec)
|
||||
|
||||
static int ec_wait_ibf0(struct acpi_ec *ec)
|
||||
{
|
||||
unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY);
|
||||
unsigned long delay = jiffies + msecs_to_jiffies(ec_delay);
|
||||
/* interrupt wait manually if GPE mode is not active */
|
||||
while (time_before(jiffies, delay))
|
||||
if (wait_event_timeout(ec->wait, ec_check_ibf0(ec),
|
||||
|
@ -27,8 +27,6 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <linux/thermal.h>
|
||||
#include <acpi/acpi_bus.h>
|
||||
@ -118,122 +116,6 @@ static struct thermal_cooling_device_ops fan_cooling_ops = {
|
||||
.set_cur_state = fan_set_cur_state,
|
||||
};
|
||||
|
||||
/* --------------------------------------------------------------------------
|
||||
FS Interface (/proc)
|
||||
-------------------------------------------------------------------------- */
|
||||
#ifdef CONFIG_ACPI_PROCFS
|
||||
|
||||
static struct proc_dir_entry *acpi_fan_dir;
|
||||
|
||||
static int acpi_fan_read_state(struct seq_file *seq, void *offset)
|
||||
{
|
||||
struct acpi_device *device = seq->private;
|
||||
int state = 0;
|
||||
|
||||
|
||||
if (device) {
|
||||
if (acpi_bus_get_power(device->handle, &state))
|
||||
seq_printf(seq, "status: ERROR\n");
|
||||
else
|
||||
seq_printf(seq, "status: %s\n",
|
||||
!state ? "on" : "off");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int acpi_fan_state_open_fs(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, acpi_fan_read_state, PDE(inode)->data);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
acpi_fan_write_state(struct file *file, const char __user * buffer,
|
||||
size_t count, loff_t * ppos)
|
||||
{
|
||||
int result = 0;
|
||||
struct seq_file *m = file->private_data;
|
||||
struct acpi_device *device = m->private;
|
||||
char state_string[3] = { '\0' };
|
||||
|
||||
if (count > sizeof(state_string) - 1)
|
||||
return -EINVAL;
|
||||
|
||||
if (copy_from_user(state_string, buffer, count))
|
||||
return -EFAULT;
|
||||
|
||||
state_string[count] = '\0';
|
||||
if ((state_string[0] < '0') || (state_string[0] > '3'))
|
||||
return -EINVAL;
|
||||
if (state_string[1] == '\n')
|
||||
state_string[1] = '\0';
|
||||
if (state_string[1] != '\0')
|
||||
return -EINVAL;
|
||||
|
||||
result = acpi_bus_set_power(device->handle,
|
||||
simple_strtoul(state_string, NULL, 0));
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static const struct file_operations acpi_fan_state_ops = {
|
||||
.open = acpi_fan_state_open_fs,
|
||||
.read = seq_read,
|
||||
.write = acpi_fan_write_state,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
static int acpi_fan_add_fs(struct acpi_device *device)
|
||||
{
|
||||
struct proc_dir_entry *entry = NULL;
|
||||
|
||||
|
||||
if (!device)
|
||||
return -EINVAL;
|
||||
|
||||
if (!acpi_device_dir(device)) {
|
||||
acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
|
||||
acpi_fan_dir);
|
||||
if (!acpi_device_dir(device))
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* 'status' [R/W] */
|
||||
entry = proc_create_data(ACPI_FAN_FILE_STATE,
|
||||
S_IFREG | S_IRUGO | S_IWUSR,
|
||||
acpi_device_dir(device),
|
||||
&acpi_fan_state_ops,
|
||||
device);
|
||||
if (!entry)
|
||||
return -ENODEV;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int acpi_fan_remove_fs(struct acpi_device *device)
|
||||
{
|
||||
|
||||
if (acpi_device_dir(device)) {
|
||||
remove_proc_entry(ACPI_FAN_FILE_STATE, acpi_device_dir(device));
|
||||
remove_proc_entry(acpi_device_bid(device), acpi_fan_dir);
|
||||
acpi_device_dir(device) = NULL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
static int acpi_fan_add_fs(struct acpi_device *device)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int acpi_fan_remove_fs(struct acpi_device *device)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
/* --------------------------------------------------------------------------
|
||||
Driver Interface
|
||||
-------------------------------------------------------------------------- */
|
||||
@ -284,10 +166,6 @@ static int acpi_fan_add(struct acpi_device *device)
|
||||
dev_err(&device->dev, "Failed to create sysfs link "
|
||||
"'device'\n");
|
||||
|
||||
result = acpi_fan_add_fs(device);
|
||||
if (result)
|
||||
goto end;
|
||||
|
||||
printk(KERN_INFO PREFIX "%s [%s] (%s)\n",
|
||||
acpi_device_name(device), acpi_device_bid(device),
|
||||
!device->power.state ? "on" : "off");
|
||||
@ -303,7 +181,6 @@ static int acpi_fan_remove(struct acpi_device *device, int type)
|
||||
if (!device || !cdev)
|
||||
return -EINVAL;
|
||||
|
||||
acpi_fan_remove_fs(device);
|
||||
sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
|
||||
sysfs_remove_link(&cdev->device.kobj, "device");
|
||||
thermal_cooling_device_unregister(cdev);
|
||||
@ -347,19 +224,9 @@ static int __init acpi_fan_init(void)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
#ifdef CONFIG_ACPI_PROCFS
|
||||
acpi_fan_dir = proc_mkdir(ACPI_FAN_CLASS, acpi_root_dir);
|
||||
if (!acpi_fan_dir)
|
||||
return -ENODEV;
|
||||
#endif
|
||||
|
||||
result = acpi_bus_register_driver(&acpi_fan_driver);
|
||||
if (result < 0) {
|
||||
#ifdef CONFIG_ACPI_PROCFS
|
||||
remove_proc_entry(ACPI_FAN_CLASS, acpi_root_dir);
|
||||
#endif
|
||||
if (result < 0)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -369,10 +236,6 @@ static void __exit acpi_fan_exit(void)
|
||||
|
||||
acpi_bus_unregister_driver(&acpi_fan_driver);
|
||||
|
||||
#ifdef CONFIG_ACPI_PROCFS
|
||||
remove_proc_entry(ACPI_FAN_CLASS, acpi_root_dir);
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -95,8 +95,25 @@ struct acpi_res_list {
|
||||
static LIST_HEAD(resource_list_head);
|
||||
static DEFINE_SPINLOCK(acpi_res_lock);
|
||||
|
||||
/*
|
||||
* This list of permanent mappings is for memory that may be accessed from
|
||||
* interrupt context, where we can't do the ioremap().
|
||||
*/
|
||||
struct acpi_ioremap {
|
||||
struct list_head list;
|
||||
void __iomem *virt;
|
||||
acpi_physical_address phys;
|
||||
acpi_size size;
|
||||
struct kref ref;
|
||||
};
|
||||
|
||||
static LIST_HEAD(acpi_ioremaps);
|
||||
static DEFINE_SPINLOCK(acpi_ioremap_lock);
|
||||
|
||||
#define OSI_STRING_LENGTH_MAX 64 /* arbitrary */
|
||||
static char osi_additional_string[OSI_STRING_LENGTH_MAX];
|
||||
static char osi_setup_string[OSI_STRING_LENGTH_MAX];
|
||||
|
||||
static void __init acpi_osi_setup_late(void);
|
||||
|
||||
/*
|
||||
* The story of _OSI(Linux)
|
||||
@ -138,6 +155,20 @@ static struct osi_linux {
|
||||
unsigned int known:1;
|
||||
} osi_linux = { 0, 0, 0, 0};
|
||||
|
||||
static u32 acpi_osi_handler(acpi_string interface, u32 supported)
|
||||
{
|
||||
if (!strcmp("Linux", interface)) {
|
||||
|
||||
printk(KERN_NOTICE FW_BUG PREFIX
|
||||
"BIOS _OSI(Linux) query %s%s\n",
|
||||
osi_linux.enable ? "honored" : "ignored",
|
||||
osi_linux.cmdline ? " via cmdline" :
|
||||
osi_linux.dmi ? " via DMI" : "");
|
||||
}
|
||||
|
||||
return supported;
|
||||
}
|
||||
|
||||
static void __init acpi_request_region (struct acpi_generic_address *addr,
|
||||
unsigned int length, char *desc)
|
||||
{
|
||||
@ -185,36 +216,6 @@ static int __init acpi_reserve_resources(void)
|
||||
}
|
||||
device_initcall(acpi_reserve_resources);
|
||||
|
||||
acpi_status __init acpi_os_initialize(void)
|
||||
{
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
acpi_status acpi_os_initialize1(void)
|
||||
{
|
||||
kacpid_wq = create_workqueue("kacpid");
|
||||
kacpi_notify_wq = create_workqueue("kacpi_notify");
|
||||
kacpi_hotplug_wq = create_workqueue("kacpi_hotplug");
|
||||
BUG_ON(!kacpid_wq);
|
||||
BUG_ON(!kacpi_notify_wq);
|
||||
BUG_ON(!kacpi_hotplug_wq);
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
acpi_status acpi_os_terminate(void)
|
||||
{
|
||||
if (acpi_irq_handler) {
|
||||
acpi_os_remove_interrupt_handler(acpi_irq_irq,
|
||||
acpi_irq_handler);
|
||||
}
|
||||
|
||||
destroy_workqueue(kacpid_wq);
|
||||
destroy_workqueue(kacpi_notify_wq);
|
||||
destroy_workqueue(kacpi_hotplug_wq);
|
||||
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
void acpi_os_printf(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
@ -260,29 +261,135 @@ acpi_physical_address __init acpi_os_get_root_pointer(void)
|
||||
}
|
||||
}
|
||||
|
||||
/* Must be called with 'acpi_ioremap_lock' or RCU read lock held. */
|
||||
static struct acpi_ioremap *
|
||||
acpi_map_lookup(acpi_physical_address phys, acpi_size size)
|
||||
{
|
||||
struct acpi_ioremap *map;
|
||||
|
||||
list_for_each_entry_rcu(map, &acpi_ioremaps, list)
|
||||
if (map->phys <= phys &&
|
||||
phys + size <= map->phys + map->size)
|
||||
return map;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Must be called with 'acpi_ioremap_lock' or RCU read lock held. */
|
||||
static void __iomem *
|
||||
acpi_map_vaddr_lookup(acpi_physical_address phys, unsigned int size)
|
||||
{
|
||||
struct acpi_ioremap *map;
|
||||
|
||||
map = acpi_map_lookup(phys, size);
|
||||
if (map)
|
||||
return map->virt + (phys - map->phys);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Must be called with 'acpi_ioremap_lock' or RCU read lock held. */
|
||||
static struct acpi_ioremap *
|
||||
acpi_map_lookup_virt(void __iomem *virt, acpi_size size)
|
||||
{
|
||||
struct acpi_ioremap *map;
|
||||
|
||||
list_for_each_entry_rcu(map, &acpi_ioremaps, list)
|
||||
if (map->virt <= virt &&
|
||||
virt + size <= map->virt + map->size)
|
||||
return map;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void __iomem *__init_refok
|
||||
acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
|
||||
{
|
||||
struct acpi_ioremap *map, *tmp_map;
|
||||
unsigned long flags, pg_sz;
|
||||
void __iomem *virt;
|
||||
phys_addr_t pg_off;
|
||||
|
||||
if (phys > ULONG_MAX) {
|
||||
printk(KERN_ERR PREFIX "Cannot map memory that high\n");
|
||||
return NULL;
|
||||
}
|
||||
if (acpi_gbl_permanent_mmap)
|
||||
/*
|
||||
* ioremap checks to ensure this is in reserved space
|
||||
*/
|
||||
return ioremap((unsigned long)phys, size);
|
||||
else
|
||||
|
||||
if (!acpi_gbl_permanent_mmap)
|
||||
return __acpi_map_table((unsigned long)phys, size);
|
||||
|
||||
map = kzalloc(sizeof(*map), GFP_KERNEL);
|
||||
if (!map)
|
||||
return NULL;
|
||||
|
||||
pg_off = round_down(phys, PAGE_SIZE);
|
||||
pg_sz = round_up(phys + size, PAGE_SIZE) - pg_off;
|
||||
virt = ioremap(pg_off, pg_sz);
|
||||
if (!virt) {
|
||||
kfree(map);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
INIT_LIST_HEAD(&map->list);
|
||||
map->virt = virt;
|
||||
map->phys = pg_off;
|
||||
map->size = pg_sz;
|
||||
kref_init(&map->ref);
|
||||
|
||||
spin_lock_irqsave(&acpi_ioremap_lock, flags);
|
||||
/* Check if page has already been mapped. */
|
||||
tmp_map = acpi_map_lookup(phys, size);
|
||||
if (tmp_map) {
|
||||
kref_get(&tmp_map->ref);
|
||||
spin_unlock_irqrestore(&acpi_ioremap_lock, flags);
|
||||
iounmap(map->virt);
|
||||
kfree(map);
|
||||
return tmp_map->virt + (phys - tmp_map->phys);
|
||||
}
|
||||
list_add_tail_rcu(&map->list, &acpi_ioremaps);
|
||||
spin_unlock_irqrestore(&acpi_ioremap_lock, flags);
|
||||
|
||||
return map->virt + (phys - map->phys);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_os_map_memory);
|
||||
|
||||
static void acpi_kref_del_iomap(struct kref *ref)
|
||||
{
|
||||
struct acpi_ioremap *map;
|
||||
|
||||
map = container_of(ref, struct acpi_ioremap, ref);
|
||||
list_del_rcu(&map->list);
|
||||
}
|
||||
|
||||
void __ref acpi_os_unmap_memory(void __iomem *virt, acpi_size size)
|
||||
{
|
||||
if (acpi_gbl_permanent_mmap)
|
||||
iounmap(virt);
|
||||
else
|
||||
struct acpi_ioremap *map;
|
||||
unsigned long flags;
|
||||
int del;
|
||||
|
||||
if (!acpi_gbl_permanent_mmap) {
|
||||
__acpi_unmap_table(virt, size);
|
||||
return;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&acpi_ioremap_lock, flags);
|
||||
map = acpi_map_lookup_virt(virt, size);
|
||||
if (!map) {
|
||||
spin_unlock_irqrestore(&acpi_ioremap_lock, flags);
|
||||
printk(KERN_ERR PREFIX "%s: bad address %p\n", __func__, virt);
|
||||
dump_stack();
|
||||
return;
|
||||
}
|
||||
|
||||
del = kref_put(&map->ref, acpi_kref_del_iomap);
|
||||
spin_unlock_irqrestore(&acpi_ioremap_lock, flags);
|
||||
|
||||
if (!del)
|
||||
return;
|
||||
|
||||
synchronize_rcu();
|
||||
iounmap(map->virt);
|
||||
kfree(map);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
|
||||
|
||||
@ -292,6 +399,44 @@ void __init early_acpi_os_unmap_memory(void __iomem *virt, acpi_size size)
|
||||
__acpi_unmap_table(virt, size);
|
||||
}
|
||||
|
||||
int acpi_os_map_generic_address(struct acpi_generic_address *addr)
|
||||
{
|
||||
void __iomem *virt;
|
||||
|
||||
if (addr->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY)
|
||||
return 0;
|
||||
|
||||
if (!addr->address || !addr->bit_width)
|
||||
return -EINVAL;
|
||||
|
||||
virt = acpi_os_map_memory(addr->address, addr->bit_width / 8);
|
||||
if (!virt)
|
||||
return -EIO;
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_os_map_generic_address);
|
||||
|
||||
void acpi_os_unmap_generic_address(struct acpi_generic_address *addr)
|
||||
{
|
||||
void __iomem *virt;
|
||||
unsigned long flags;
|
||||
acpi_size size = addr->bit_width / 8;
|
||||
|
||||
if (addr->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY)
|
||||
return;
|
||||
|
||||
if (!addr->address || !addr->bit_width)
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(&acpi_ioremap_lock, flags);
|
||||
virt = acpi_map_vaddr_lookup(addr->address, size);
|
||||
spin_unlock_irqrestore(&acpi_ioremap_lock, flags);
|
||||
|
||||
acpi_os_unmap_memory(virt, size);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_os_unmap_generic_address);
|
||||
|
||||
#ifdef ACPI_FUTURE_USAGE
|
||||
acpi_status
|
||||
acpi_os_get_physical_address(void *virt, acpi_physical_address * phys)
|
||||
@ -495,8 +640,15 @@ acpi_os_read_memory(acpi_physical_address phys_addr, u32 * value, u32 width)
|
||||
{
|
||||
u32 dummy;
|
||||
void __iomem *virt_addr;
|
||||
int size = width / 8, unmap = 0;
|
||||
|
||||
virt_addr = ioremap(phys_addr, width);
|
||||
rcu_read_lock();
|
||||
virt_addr = acpi_map_vaddr_lookup(phys_addr, size);
|
||||
rcu_read_unlock();
|
||||
if (!virt_addr) {
|
||||
virt_addr = ioremap(phys_addr, size);
|
||||
unmap = 1;
|
||||
}
|
||||
if (!value)
|
||||
value = &dummy;
|
||||
|
||||
@ -514,7 +666,8 @@ acpi_os_read_memory(acpi_physical_address phys_addr, u32 * value, u32 width)
|
||||
BUG();
|
||||
}
|
||||
|
||||
iounmap(virt_addr);
|
||||
if (unmap)
|
||||
iounmap(virt_addr);
|
||||
|
||||
return AE_OK;
|
||||
}
|
||||
@ -523,8 +676,15 @@ acpi_status
|
||||
acpi_os_write_memory(acpi_physical_address phys_addr, u32 value, u32 width)
|
||||
{
|
||||
void __iomem *virt_addr;
|
||||
int size = width / 8, unmap = 0;
|
||||
|
||||
virt_addr = ioremap(phys_addr, width);
|
||||
rcu_read_lock();
|
||||
virt_addr = acpi_map_vaddr_lookup(phys_addr, size);
|
||||
rcu_read_unlock();
|
||||
if (!virt_addr) {
|
||||
virt_addr = ioremap(phys_addr, size);
|
||||
unmap = 1;
|
||||
}
|
||||
|
||||
switch (width) {
|
||||
case 8:
|
||||
@ -540,16 +700,18 @@ acpi_os_write_memory(acpi_physical_address phys_addr, u32 value, u32 width)
|
||||
BUG();
|
||||
}
|
||||
|
||||
iounmap(virt_addr);
|
||||
if (unmap)
|
||||
iounmap(virt_addr);
|
||||
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
acpi_status
|
||||
acpi_os_read_pci_configuration(struct acpi_pci_id * pci_id, u32 reg,
|
||||
u32 *value, u32 width)
|
||||
u64 *value, u32 width)
|
||||
{
|
||||
int result, size;
|
||||
u32 value32;
|
||||
|
||||
if (!value)
|
||||
return AE_BAD_PARAMETER;
|
||||
@ -570,7 +732,8 @@ acpi_os_read_pci_configuration(struct acpi_pci_id * pci_id, u32 reg,
|
||||
|
||||
result = raw_pci_read(pci_id->segment, pci_id->bus,
|
||||
PCI_DEVFN(pci_id->device, pci_id->function),
|
||||
reg, size, value);
|
||||
reg, size, &value32);
|
||||
*value = value32;
|
||||
|
||||
return (result ? AE_ERROR : AE_OK);
|
||||
}
|
||||
@ -602,74 +765,6 @@ acpi_os_write_pci_configuration(struct acpi_pci_id * pci_id, u32 reg,
|
||||
return (result ? AE_ERROR : AE_OK);
|
||||
}
|
||||
|
||||
/* TODO: Change code to take advantage of driver model more */
|
||||
static void acpi_os_derive_pci_id_2(acpi_handle rhandle, /* upper bound */
|
||||
acpi_handle chandle, /* current node */
|
||||
struct acpi_pci_id **id,
|
||||
int *is_bridge, u8 * bus_number)
|
||||
{
|
||||
acpi_handle handle;
|
||||
struct acpi_pci_id *pci_id = *id;
|
||||
acpi_status status;
|
||||
unsigned long long temp;
|
||||
acpi_object_type type;
|
||||
|
||||
acpi_get_parent(chandle, &handle);
|
||||
if (handle != rhandle) {
|
||||
acpi_os_derive_pci_id_2(rhandle, handle, &pci_id, is_bridge,
|
||||
bus_number);
|
||||
|
||||
status = acpi_get_type(handle, &type);
|
||||
if ((ACPI_FAILURE(status)) || (type != ACPI_TYPE_DEVICE))
|
||||
return;
|
||||
|
||||
status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL,
|
||||
&temp);
|
||||
if (ACPI_SUCCESS(status)) {
|
||||
u32 val;
|
||||
pci_id->device = ACPI_HIWORD(ACPI_LODWORD(temp));
|
||||
pci_id->function = ACPI_LOWORD(ACPI_LODWORD(temp));
|
||||
|
||||
if (*is_bridge)
|
||||
pci_id->bus = *bus_number;
|
||||
|
||||
/* any nicer way to get bus number of bridge ? */
|
||||
status =
|
||||
acpi_os_read_pci_configuration(pci_id, 0x0e, &val,
|
||||
8);
|
||||
if (ACPI_SUCCESS(status)
|
||||
&& ((val & 0x7f) == 1 || (val & 0x7f) == 2)) {
|
||||
status =
|
||||
acpi_os_read_pci_configuration(pci_id, 0x18,
|
||||
&val, 8);
|
||||
if (!ACPI_SUCCESS(status)) {
|
||||
/* Certainly broken... FIX ME */
|
||||
return;
|
||||
}
|
||||
*is_bridge = 1;
|
||||
pci_id->bus = val;
|
||||
status =
|
||||
acpi_os_read_pci_configuration(pci_id, 0x19,
|
||||
&val, 8);
|
||||
if (ACPI_SUCCESS(status)) {
|
||||
*bus_number = val;
|
||||
}
|
||||
} else
|
||||
*is_bridge = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void acpi_os_derive_pci_id(acpi_handle rhandle, /* upper bound */
|
||||
acpi_handle chandle, /* current node */
|
||||
struct acpi_pci_id **id)
|
||||
{
|
||||
int is_bridge = 1;
|
||||
u8 bus_number = (*id)->bus;
|
||||
|
||||
acpi_os_derive_pci_id_2(rhandle, chandle, id, &is_bridge, &bus_number);
|
||||
}
|
||||
|
||||
static void acpi_os_execute_deferred(struct work_struct *work)
|
||||
{
|
||||
struct acpi_os_dpc *dpc = container_of(work, struct acpi_os_dpc, work);
|
||||
@ -779,16 +874,6 @@ void acpi_os_wait_events_complete(void *context)
|
||||
|
||||
EXPORT_SYMBOL(acpi_os_wait_events_complete);
|
||||
|
||||
/*
|
||||
* Allocate the memory for a spinlock and initialize it.
|
||||
*/
|
||||
acpi_status acpi_os_create_lock(acpi_spinlock * handle)
|
||||
{
|
||||
spin_lock_init(*handle);
|
||||
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Deallocate the memory for a spinlock.
|
||||
*/
|
||||
@ -977,6 +1062,12 @@ static void __init set_osi_linux(unsigned int enable)
|
||||
printk(KERN_NOTICE PREFIX "%sed _OSI(Linux)\n",
|
||||
enable ? "Add": "Delet");
|
||||
}
|
||||
|
||||
if (osi_linux.enable)
|
||||
acpi_osi_setup("Linux");
|
||||
else
|
||||
acpi_osi_setup("!Linux");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1011,21 +1102,33 @@ void __init acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d)
|
||||
* string starting with '!' disables that string
|
||||
* otherwise string is added to list, augmenting built-in strings
|
||||
*/
|
||||
static void __init acpi_osi_setup_late(void)
|
||||
{
|
||||
char *str = osi_setup_string;
|
||||
|
||||
if (*str == '\0')
|
||||
return;
|
||||
|
||||
if (!strcmp("!Linux", str)) {
|
||||
acpi_cmdline_osi_linux(0); /* !enable */
|
||||
} else if (*str == '!') {
|
||||
if (acpi_remove_interface(++str) == AE_OK)
|
||||
printk(KERN_INFO PREFIX "Deleted _OSI(%s)\n", str);
|
||||
} else if (!strcmp("Linux", str)) {
|
||||
acpi_cmdline_osi_linux(1); /* enable */
|
||||
} else {
|
||||
if (acpi_install_interface(str) == AE_OK)
|
||||
printk(KERN_INFO PREFIX "Added _OSI(%s)\n", str);
|
||||
}
|
||||
}
|
||||
|
||||
int __init acpi_osi_setup(char *str)
|
||||
{
|
||||
if (str == NULL || *str == '\0') {
|
||||
printk(KERN_INFO PREFIX "_OSI method disabled\n");
|
||||
acpi_gbl_create_osi_method = FALSE;
|
||||
} else if (!strcmp("!Linux", str)) {
|
||||
acpi_cmdline_osi_linux(0); /* !enable */
|
||||
} else if (*str == '!') {
|
||||
if (acpi_osi_invalidate(++str) == AE_OK)
|
||||
printk(KERN_INFO PREFIX "Deleted _OSI(%s)\n", str);
|
||||
} else if (!strcmp("Linux", str)) {
|
||||
acpi_cmdline_osi_linux(1); /* enable */
|
||||
} else if (*osi_additional_string == '\0') {
|
||||
strncpy(osi_additional_string, str, OSI_STRING_LENGTH_MAX);
|
||||
printk(KERN_INFO PREFIX "Added _OSI(%s)\n", str);
|
||||
} else {
|
||||
strncpy(osi_setup_string, str, OSI_STRING_LENGTH_MAX);
|
||||
}
|
||||
|
||||
return 1;
|
||||
@ -1152,21 +1255,6 @@ int acpi_check_region(resource_size_t start, resource_size_t n,
|
||||
}
|
||||
EXPORT_SYMBOL(acpi_check_region);
|
||||
|
||||
int acpi_check_mem_region(resource_size_t start, resource_size_t n,
|
||||
const char *name)
|
||||
{
|
||||
struct resource res = {
|
||||
.start = start,
|
||||
.end = start + n - 1,
|
||||
.name = name,
|
||||
.flags = IORESOURCE_MEM,
|
||||
};
|
||||
|
||||
return acpi_check_resource_conflict(&res);
|
||||
|
||||
}
|
||||
EXPORT_SYMBOL(acpi_check_mem_region);
|
||||
|
||||
/*
|
||||
* Let drivers know whether the resource checks are effective
|
||||
*/
|
||||
@ -1282,38 +1370,6 @@ acpi_status acpi_os_release_object(acpi_cache_t * cache, void *object)
|
||||
return (AE_OK);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_os_validate_interface
|
||||
*
|
||||
* PARAMETERS: interface - Requested interface to be validated
|
||||
*
|
||||
* RETURN: AE_OK if interface is supported, AE_SUPPORT otherwise
|
||||
*
|
||||
* DESCRIPTION: Match an interface string to the interfaces supported by the
|
||||
* host. Strings originate from an AML call to the _OSI method.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
acpi_status
|
||||
acpi_os_validate_interface (char *interface)
|
||||
{
|
||||
if (!strncmp(osi_additional_string, interface, OSI_STRING_LENGTH_MAX))
|
||||
return AE_OK;
|
||||
if (!strcmp("Linux", interface)) {
|
||||
|
||||
printk(KERN_NOTICE PREFIX
|
||||
"BIOS _OSI(Linux) query %s%s\n",
|
||||
osi_linux.enable ? "honored" : "ignored",
|
||||
osi_linux.cmdline ? " via cmdline" :
|
||||
osi_linux.dmi ? " via DMI" : "");
|
||||
|
||||
if (osi_linux.enable)
|
||||
return AE_OK;
|
||||
}
|
||||
return AE_SUPPORT;
|
||||
}
|
||||
|
||||
static inline int acpi_res_list_add(struct acpi_res_list *res)
|
||||
{
|
||||
struct acpi_res_list *res_list_elem;
|
||||
@ -1462,5 +1518,46 @@ acpi_os_validate_address (
|
||||
}
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
acpi_status __init acpi_os_initialize(void)
|
||||
{
|
||||
acpi_os_map_generic_address(&acpi_gbl_FADT.xpm1a_event_block);
|
||||
acpi_os_map_generic_address(&acpi_gbl_FADT.xpm1b_event_block);
|
||||
acpi_os_map_generic_address(&acpi_gbl_FADT.xgpe0_block);
|
||||
acpi_os_map_generic_address(&acpi_gbl_FADT.xgpe1_block);
|
||||
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
acpi_status acpi_os_initialize1(void)
|
||||
{
|
||||
kacpid_wq = create_workqueue("kacpid");
|
||||
kacpi_notify_wq = create_workqueue("kacpi_notify");
|
||||
kacpi_hotplug_wq = create_workqueue("kacpi_hotplug");
|
||||
BUG_ON(!kacpid_wq);
|
||||
BUG_ON(!kacpi_notify_wq);
|
||||
BUG_ON(!kacpi_hotplug_wq);
|
||||
acpi_install_interface_handler(acpi_osi_handler);
|
||||
acpi_osi_setup_late();
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
acpi_status acpi_os_terminate(void)
|
||||
{
|
||||
if (acpi_irq_handler) {
|
||||
acpi_os_remove_interrupt_handler(acpi_irq_irq,
|
||||
acpi_irq_handler);
|
||||
}
|
||||
|
||||
acpi_os_unmap_generic_address(&acpi_gbl_FADT.xgpe1_block);
|
||||
acpi_os_unmap_generic_address(&acpi_gbl_FADT.xgpe0_block);
|
||||
acpi_os_unmap_generic_address(&acpi_gbl_FADT.xpm1b_event_block);
|
||||
acpi_os_unmap_generic_address(&acpi_gbl_FADT.xpm1a_event_block);
|
||||
|
||||
destroy_workqueue(kacpid_wq);
|
||||
destroy_workqueue(kacpi_notify_wq);
|
||||
destroy_workqueue(kacpi_hotplug_wq);
|
||||
|
||||
return AE_OK;
|
||||
}
|
||||
|
@ -32,7 +32,6 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/pci.h>
|
||||
|
@ -34,7 +34,6 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/pci.h>
|
||||
|
@ -27,7 +27,6 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
|
@ -80,18 +80,13 @@ static struct acpi_driver acpi_power_driver = {
|
||||
},
|
||||
};
|
||||
|
||||
struct acpi_power_reference {
|
||||
struct list_head node;
|
||||
struct acpi_device *device;
|
||||
};
|
||||
|
||||
struct acpi_power_resource {
|
||||
struct acpi_device * device;
|
||||
acpi_bus_id name;
|
||||
u32 system_level;
|
||||
u32 order;
|
||||
unsigned int ref_count;
|
||||
struct mutex resource_lock;
|
||||
struct list_head reference;
|
||||
};
|
||||
|
||||
static struct list_head acpi_power_resource_list;
|
||||
@ -184,45 +179,9 @@ static int acpi_power_get_list_state(struct acpi_handle_list *list, int *state)
|
||||
return result;
|
||||
}
|
||||
|
||||
static int acpi_power_on(acpi_handle handle, struct acpi_device *dev)
|
||||
static int __acpi_power_on(struct acpi_power_resource *resource)
|
||||
{
|
||||
int result = 0;
|
||||
int found = 0;
|
||||
acpi_status status = AE_OK;
|
||||
struct acpi_power_resource *resource = NULL;
|
||||
struct list_head *node, *next;
|
||||
struct acpi_power_reference *ref;
|
||||
|
||||
|
||||
result = acpi_power_get_context(handle, &resource);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
mutex_lock(&resource->resource_lock);
|
||||
list_for_each_safe(node, next, &resource->reference) {
|
||||
ref = container_of(node, struct acpi_power_reference, node);
|
||||
if (dev->handle == ref->device->handle) {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] already referenced by resource [%s]\n",
|
||||
dev->pnp.bus_id, resource->name));
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
ref = kmalloc(sizeof (struct acpi_power_reference),
|
||||
irqs_disabled() ? GFP_ATOMIC : GFP_KERNEL);
|
||||
if (!ref) {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "kmalloc() failed\n"));
|
||||
mutex_unlock(&resource->resource_lock);
|
||||
return -ENOMEM;
|
||||
}
|
||||
list_add_tail(&ref->node, &resource->reference);
|
||||
ref->device = dev;
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] added to resource [%s] references\n",
|
||||
dev->pnp.bus_id, resource->name));
|
||||
}
|
||||
mutex_unlock(&resource->resource_lock);
|
||||
|
||||
status = acpi_evaluate_object(resource->device->handle, "_ON", NULL, NULL);
|
||||
if (ACPI_FAILURE(status))
|
||||
@ -231,56 +190,80 @@ static int acpi_power_on(acpi_handle handle, struct acpi_device *dev)
|
||||
/* Update the power resource's _device_ power state */
|
||||
resource->device->power.state = ACPI_STATE_D0;
|
||||
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] turned on\n",
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Power resource [%s] turned on\n",
|
||||
resource->name));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int acpi_power_off_device(acpi_handle handle, struct acpi_device *dev)
|
||||
static int acpi_power_on(acpi_handle handle)
|
||||
{
|
||||
int result = 0;
|
||||
acpi_status status = AE_OK;
|
||||
struct acpi_power_resource *resource = NULL;
|
||||
struct list_head *node, *next;
|
||||
struct acpi_power_reference *ref;
|
||||
|
||||
result = acpi_power_get_context(handle, &resource);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
mutex_lock(&resource->resource_lock);
|
||||
list_for_each_safe(node, next, &resource->reference) {
|
||||
ref = container_of(node, struct acpi_power_reference, node);
|
||||
if (dev->handle == ref->device->handle) {
|
||||
list_del(&ref->node);
|
||||
kfree(ref);
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] removed from resource [%s] references\n",
|
||||
dev->pnp.bus_id, resource->name));
|
||||
break;
|
||||
}
|
||||
|
||||
if (resource->ref_count++) {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
||||
"Power resource [%s] already on",
|
||||
resource->name));
|
||||
} else {
|
||||
result = __acpi_power_on(resource);
|
||||
}
|
||||
|
||||
if (!list_empty(&resource->reference)) {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Cannot turn resource [%s] off - resource is in use\n",
|
||||
resource->name));
|
||||
mutex_unlock(&resource->resource_lock);
|
||||
return 0;
|
||||
}
|
||||
mutex_unlock(&resource->resource_lock);
|
||||
|
||||
status = acpi_evaluate_object(resource->device->handle, "_OFF", NULL, NULL);
|
||||
if (ACPI_FAILURE(status))
|
||||
return -ENODEV;
|
||||
|
||||
/* Update the power resource's _device_ power state */
|
||||
resource->device->power.state = ACPI_STATE_D3;
|
||||
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] turned off\n",
|
||||
resource->name));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int acpi_power_off_device(acpi_handle handle)
|
||||
{
|
||||
int result = 0;
|
||||
acpi_status status = AE_OK;
|
||||
struct acpi_power_resource *resource = NULL;
|
||||
|
||||
result = acpi_power_get_context(handle, &resource);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
mutex_lock(&resource->resource_lock);
|
||||
|
||||
if (!resource->ref_count) {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
||||
"Power resource [%s] already off",
|
||||
resource->name));
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
if (--resource->ref_count) {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
||||
"Power resource [%s] still in use\n",
|
||||
resource->name));
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
status = acpi_evaluate_object(resource->device->handle, "_OFF", NULL, NULL);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
result = -ENODEV;
|
||||
} else {
|
||||
/* Update the power resource's _device_ power state */
|
||||
resource->device->power.state = ACPI_STATE_D3;
|
||||
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
||||
"Power resource [%s] turned off\n",
|
||||
resource->name));
|
||||
}
|
||||
|
||||
unlock:
|
||||
mutex_unlock(&resource->resource_lock);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* acpi_device_sleep_wake - execute _DSW (Device Sleep Wake) or (deprecated in
|
||||
* ACPI 3.0) _PSW (Power State Wake)
|
||||
@ -364,7 +347,7 @@ int acpi_enable_wakeup_device_power(struct acpi_device *dev, int sleep_state)
|
||||
|
||||
/* Open power resource */
|
||||
for (i = 0; i < dev->wakeup.resources.count; i++) {
|
||||
int ret = acpi_power_on(dev->wakeup.resources.handles[i], dev);
|
||||
int ret = acpi_power_on(dev->wakeup.resources.handles[i]);
|
||||
if (ret) {
|
||||
printk(KERN_ERR PREFIX "Transition power state\n");
|
||||
dev->wakeup.flags.valid = 0;
|
||||
@ -420,7 +403,7 @@ int acpi_disable_wakeup_device_power(struct acpi_device *dev)
|
||||
/* Close power resource */
|
||||
for (i = 0; i < dev->wakeup.resources.count; i++) {
|
||||
int ret = acpi_power_off_device(
|
||||
dev->wakeup.resources.handles[i], dev);
|
||||
dev->wakeup.resources.handles[i]);
|
||||
if (ret) {
|
||||
printk(KERN_ERR PREFIX "Transition power state\n");
|
||||
dev->wakeup.flags.valid = 0;
|
||||
@ -500,7 +483,7 @@ int acpi_power_transition(struct acpi_device *device, int state)
|
||||
* (e.g. so the device doesn't lose power while transitioning).
|
||||
*/
|
||||
for (i = 0; i < tl->count; i++) {
|
||||
result = acpi_power_on(tl->handles[i], device);
|
||||
result = acpi_power_on(tl->handles[i]);
|
||||
if (result)
|
||||
goto end;
|
||||
}
|
||||
@ -513,7 +496,7 @@ int acpi_power_transition(struct acpi_device *device, int state)
|
||||
* Then we dereference all power resources used in the current list.
|
||||
*/
|
||||
for (i = 0; i < cl->count; i++) {
|
||||
result = acpi_power_off_device(cl->handles[i], device);
|
||||
result = acpi_power_off_device(cl->handles[i]);
|
||||
if (result)
|
||||
goto end;
|
||||
}
|
||||
@ -551,7 +534,6 @@ static int acpi_power_add(struct acpi_device *device)
|
||||
|
||||
resource->device = device;
|
||||
mutex_init(&resource->resource_lock);
|
||||
INIT_LIST_HEAD(&resource->reference);
|
||||
strcpy(resource->name, device->pnp.bus_id);
|
||||
strcpy(acpi_device_name(device), ACPI_POWER_DEVICE_NAME);
|
||||
strcpy(acpi_device_class(device), ACPI_POWER_CLASS);
|
||||
@ -594,22 +576,14 @@ static int acpi_power_add(struct acpi_device *device)
|
||||
|
||||
static int acpi_power_remove(struct acpi_device *device, int type)
|
||||
{
|
||||
struct acpi_power_resource *resource = NULL;
|
||||
struct list_head *node, *next;
|
||||
struct acpi_power_resource *resource;
|
||||
|
||||
|
||||
if (!device || !acpi_driver_data(device))
|
||||
if (!device)
|
||||
return -EINVAL;
|
||||
|
||||
resource = acpi_driver_data(device);
|
||||
|
||||
mutex_lock(&resource->resource_lock);
|
||||
list_for_each_safe(node, next, &resource->reference) {
|
||||
struct acpi_power_reference *ref = container_of(node, struct acpi_power_reference, node);
|
||||
list_del(&ref->node);
|
||||
kfree(ref);
|
||||
}
|
||||
mutex_unlock(&resource->resource_lock);
|
||||
if (!resource)
|
||||
return -EINVAL;
|
||||
|
||||
kfree(resource);
|
||||
|
||||
@ -619,29 +593,28 @@ static int acpi_power_remove(struct acpi_device *device, int type)
|
||||
static int acpi_power_resume(struct acpi_device *device)
|
||||
{
|
||||
int result = 0, state;
|
||||
struct acpi_power_resource *resource = NULL;
|
||||
struct acpi_power_reference *ref;
|
||||
struct acpi_power_resource *resource;
|
||||
|
||||
if (!device || !acpi_driver_data(device))
|
||||
if (!device)
|
||||
return -EINVAL;
|
||||
|
||||
resource = acpi_driver_data(device);
|
||||
if (!resource)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&resource->resource_lock);
|
||||
|
||||
result = acpi_power_get_state(device->handle, &state);
|
||||
if (result)
|
||||
return result;
|
||||
goto unlock;
|
||||
|
||||
mutex_lock(&resource->resource_lock);
|
||||
if (state == ACPI_POWER_RESOURCE_STATE_OFF &&
|
||||
!list_empty(&resource->reference)) {
|
||||
ref = container_of(resource->reference.next, struct acpi_power_reference, node);
|
||||
mutex_unlock(&resource->resource_lock);
|
||||
result = acpi_power_on(device->handle, ref->device);
|
||||
return result;
|
||||
}
|
||||
if (state == ACPI_POWER_RESOURCE_STATE_OFF && resource->ref_count)
|
||||
result = __acpi_power_on(resource);
|
||||
|
||||
unlock:
|
||||
mutex_unlock(&resource->resource_lock);
|
||||
return 0;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int __init acpi_power_init(void)
|
||||
|
@ -40,8 +40,10 @@
|
||||
#include <linux/pm.h>
|
||||
#include <linux/cpufreq.h>
|
||||
#include <linux/cpu.h>
|
||||
#ifdef CONFIG_ACPI_PROCFS
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/seq_file.h>
|
||||
#endif
|
||||
#include <linux/dmi.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/cpuidle.h>
|
||||
@ -244,6 +246,7 @@ static int acpi_processor_errata(struct acpi_processor *pr)
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ACPI_PROCFS
|
||||
static struct proc_dir_entry *acpi_processor_dir = NULL;
|
||||
|
||||
static int __cpuinit acpi_processor_add_fs(struct acpi_device *device)
|
||||
@ -280,7 +283,16 @@ static int acpi_processor_remove_fs(struct acpi_device *device)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
static inline int acpi_processor_add_fs(struct acpi_device *device)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline int acpi_processor_remove_fs(struct acpi_device *device)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
/* --------------------------------------------------------------------------
|
||||
Driver Interface
|
||||
-------------------------------------------------------------------------- */
|
||||
@ -842,9 +854,11 @@ static int __init acpi_processor_init(void)
|
||||
|
||||
memset(&errata, 0, sizeof(errata));
|
||||
|
||||
#ifdef CONFIG_ACPI_PROCFS
|
||||
acpi_processor_dir = proc_mkdir(ACPI_PROCESSOR_CLASS, acpi_root_dir);
|
||||
if (!acpi_processor_dir)
|
||||
return -ENOMEM;
|
||||
#endif
|
||||
|
||||
if (!cpuidle_register_driver(&acpi_idle_driver)) {
|
||||
printk(KERN_DEBUG "ACPI: %s registered with cpuidle\n",
|
||||
@ -871,7 +885,9 @@ static int __init acpi_processor_init(void)
|
||||
out_cpuidle:
|
||||
cpuidle_unregister_driver(&acpi_idle_driver);
|
||||
|
||||
#ifdef CONFIG_ACPI_PROCFS
|
||||
remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir);
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -891,7 +907,9 @@ static void __exit acpi_processor_exit(void)
|
||||
|
||||
cpuidle_unregister_driver(&acpi_idle_driver);
|
||||
|
||||
#ifdef CONFIG_ACPI_PROCFS
|
||||
remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir);
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
@ -899,6 +917,4 @@ static void __exit acpi_processor_exit(void)
|
||||
module_init(acpi_processor_init);
|
||||
module_exit(acpi_processor_exit);
|
||||
|
||||
EXPORT_SYMBOL(acpi_processor_set_thermal_limit);
|
||||
|
||||
MODULE_ALIAS("processor");
|
||||
|
@ -64,7 +64,6 @@
|
||||
#define ACPI_PROCESSOR_CLASS "processor"
|
||||
#define _COMPONENT ACPI_PROCESSOR_COMPONENT
|
||||
ACPI_MODULE_NAME("processor_idle");
|
||||
#define ACPI_PROCESSOR_FILE_POWER "power"
|
||||
#define PM_TIMER_TICK_NS (1000000000ULL/PM_TIMER_FREQUENCY)
|
||||
#define C2_OVERHEAD 1 /* 1us */
|
||||
#define C3_OVERHEAD 1 /* 1us */
|
||||
|
@ -44,47 +44,6 @@
|
||||
#define _COMPONENT ACPI_PROCESSOR_COMPONENT
|
||||
ACPI_MODULE_NAME("processor_thermal");
|
||||
|
||||
/* --------------------------------------------------------------------------
|
||||
Limit Interface
|
||||
-------------------------------------------------------------------------- */
|
||||
static int acpi_processor_apply_limit(struct acpi_processor *pr)
|
||||
{
|
||||
int result = 0;
|
||||
u16 px = 0;
|
||||
u16 tx = 0;
|
||||
|
||||
|
||||
if (!pr)
|
||||
return -EINVAL;
|
||||
|
||||
if (!pr->flags.limit)
|
||||
return -ENODEV;
|
||||
|
||||
if (pr->flags.throttling) {
|
||||
if (pr->limit.user.tx > tx)
|
||||
tx = pr->limit.user.tx;
|
||||
if (pr->limit.thermal.tx > tx)
|
||||
tx = pr->limit.thermal.tx;
|
||||
|
||||
result = acpi_processor_set_throttling(pr, tx, false);
|
||||
if (result)
|
||||
goto end;
|
||||
}
|
||||
|
||||
pr->limit.state.px = px;
|
||||
pr->limit.state.tx = tx;
|
||||
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
||||
"Processor [%d] limit set to (P%d:T%d)\n", pr->id,
|
||||
pr->limit.state.px, pr->limit.state.tx));
|
||||
|
||||
end:
|
||||
if (result)
|
||||
printk(KERN_ERR PREFIX "Unable to set limit\n");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CPU_FREQ
|
||||
|
||||
/* If a passive cooling situation is detected, primarily CPUfreq is used, as it
|
||||
@ -107,36 +66,6 @@ static int cpu_has_cpufreq(unsigned int cpu)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int acpi_thermal_cpufreq_increase(unsigned int cpu)
|
||||
{
|
||||
if (!cpu_has_cpufreq(cpu))
|
||||
return -ENODEV;
|
||||
|
||||
if (per_cpu(cpufreq_thermal_reduction_pctg, cpu) <
|
||||
CPUFREQ_THERMAL_MAX_STEP) {
|
||||
per_cpu(cpufreq_thermal_reduction_pctg, cpu)++;
|
||||
cpufreq_update_policy(cpu);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -ERANGE;
|
||||
}
|
||||
|
||||
static int acpi_thermal_cpufreq_decrease(unsigned int cpu)
|
||||
{
|
||||
if (!cpu_has_cpufreq(cpu))
|
||||
return -ENODEV;
|
||||
|
||||
if (per_cpu(cpufreq_thermal_reduction_pctg, cpu) >
|
||||
(CPUFREQ_THERMAL_MIN_STEP + 1))
|
||||
per_cpu(cpufreq_thermal_reduction_pctg, cpu)--;
|
||||
else
|
||||
per_cpu(cpufreq_thermal_reduction_pctg, cpu) = 0;
|
||||
cpufreq_update_policy(cpu);
|
||||
/* We reached max freq again and can leave passive mode */
|
||||
return !per_cpu(cpufreq_thermal_reduction_pctg, cpu);
|
||||
}
|
||||
|
||||
static int acpi_thermal_cpufreq_notifier(struct notifier_block *nb,
|
||||
unsigned long event, void *data)
|
||||
{
|
||||
@ -238,113 +167,6 @@ static int acpi_thermal_cpufreq_decrease(unsigned int cpu)
|
||||
|
||||
#endif
|
||||
|
||||
int acpi_processor_set_thermal_limit(acpi_handle handle, int type)
|
||||
{
|
||||
int result = 0;
|
||||
struct acpi_processor *pr = NULL;
|
||||
struct acpi_device *device = NULL;
|
||||
int tx = 0, max_tx_px = 0;
|
||||
|
||||
|
||||
if ((type < ACPI_PROCESSOR_LIMIT_NONE)
|
||||
|| (type > ACPI_PROCESSOR_LIMIT_DECREMENT))
|
||||
return -EINVAL;
|
||||
|
||||
result = acpi_bus_get_device(handle, &device);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
pr = acpi_driver_data(device);
|
||||
if (!pr)
|
||||
return -ENODEV;
|
||||
|
||||
/* Thermal limits are always relative to the current Px/Tx state. */
|
||||
if (pr->flags.throttling)
|
||||
pr->limit.thermal.tx = pr->throttling.state;
|
||||
|
||||
/*
|
||||
* Our default policy is to only use throttling at the lowest
|
||||
* performance state.
|
||||
*/
|
||||
|
||||
tx = pr->limit.thermal.tx;
|
||||
|
||||
switch (type) {
|
||||
|
||||
case ACPI_PROCESSOR_LIMIT_NONE:
|
||||
do {
|
||||
result = acpi_thermal_cpufreq_decrease(pr->id);
|
||||
} while (!result);
|
||||
tx = 0;
|
||||
break;
|
||||
|
||||
case ACPI_PROCESSOR_LIMIT_INCREMENT:
|
||||
/* if going up: P-states first, T-states later */
|
||||
|
||||
result = acpi_thermal_cpufreq_increase(pr->id);
|
||||
if (!result)
|
||||
goto end;
|
||||
else if (result == -ERANGE)
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
||||
"At maximum performance state\n"));
|
||||
|
||||
if (pr->flags.throttling) {
|
||||
if (tx == (pr->throttling.state_count - 1))
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
||||
"At maximum throttling state\n"));
|
||||
else
|
||||
tx++;
|
||||
}
|
||||
break;
|
||||
|
||||
case ACPI_PROCESSOR_LIMIT_DECREMENT:
|
||||
/* if going down: T-states first, P-states later */
|
||||
|
||||
if (pr->flags.throttling) {
|
||||
if (tx == 0) {
|
||||
max_tx_px = 1;
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
||||
"At minimum throttling state\n"));
|
||||
} else {
|
||||
tx--;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
result = acpi_thermal_cpufreq_decrease(pr->id);
|
||||
if (result) {
|
||||
/*
|
||||
* We only could get -ERANGE, 1 or 0.
|
||||
* In the first two cases we reached max freq again.
|
||||
*/
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
||||
"At minimum performance state\n"));
|
||||
max_tx_px = 1;
|
||||
} else
|
||||
max_tx_px = 0;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
end:
|
||||
if (pr->flags.throttling) {
|
||||
pr->limit.thermal.px = 0;
|
||||
pr->limit.thermal.tx = tx;
|
||||
|
||||
result = acpi_processor_apply_limit(pr);
|
||||
if (result)
|
||||
printk(KERN_ERR PREFIX "Unable to set thermal limit\n");
|
||||
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Thermal limit now (P%d:T%d)\n",
|
||||
pr->limit.thermal.px, pr->limit.thermal.tx));
|
||||
} else
|
||||
result = 0;
|
||||
if (max_tx_px)
|
||||
return 1;
|
||||
else
|
||||
return result;
|
||||
}
|
||||
|
||||
int acpi_processor_get_limit_info(struct acpi_processor *pr)
|
||||
{
|
||||
|
||||
|
@ -32,8 +32,10 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/cpufreq.h>
|
||||
#ifdef CONFIG_ACPI_PROCFS
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/seq_file.h>
|
||||
#endif
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <asm/uaccess.h>
|
||||
@ -1214,6 +1216,7 @@ int acpi_processor_get_throttling_info(struct acpi_processor *pr)
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ACPI_PROCFS
|
||||
/* proc interface */
|
||||
static int acpi_processor_throttling_seq_show(struct seq_file *seq,
|
||||
void *offset)
|
||||
@ -1322,3 +1325,4 @@ const struct file_operations acpi_processor_throttling_fops = {
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
};
|
||||
#endif
|
||||
|
@ -40,10 +40,7 @@
|
||||
#include <linux/timer.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
#ifdef CONFIG_ACPI_SYSFS_POWER
|
||||
#include <linux/power_supply.h>
|
||||
#endif
|
||||
|
||||
#include "sbshc.h"
|
||||
|
||||
@ -85,9 +82,7 @@ static const struct acpi_device_id sbs_device_ids[] = {
|
||||
MODULE_DEVICE_TABLE(acpi, sbs_device_ids);
|
||||
|
||||
struct acpi_battery {
|
||||
#ifdef CONFIG_ACPI_SYSFS_POWER
|
||||
struct power_supply bat;
|
||||
#endif
|
||||
struct acpi_sbs *sbs;
|
||||
#ifdef CONFIG_ACPI_PROCFS_POWER
|
||||
struct proc_dir_entry *proc_entry;
|
||||
@ -120,9 +115,7 @@ struct acpi_battery {
|
||||
#define to_acpi_battery(x) container_of(x, struct acpi_battery, bat);
|
||||
|
||||
struct acpi_sbs {
|
||||
#ifdef CONFIG_ACPI_SYSFS_POWER
|
||||
struct power_supply charger;
|
||||
#endif
|
||||
struct acpi_device *device;
|
||||
struct acpi_smb_hc *hc;
|
||||
struct mutex lock;
|
||||
@ -166,7 +159,6 @@ static inline int acpi_battery_scale(struct acpi_battery *battery)
|
||||
acpi_battery_ipscale(battery);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ACPI_SYSFS_POWER
|
||||
static int sbs_get_ac_property(struct power_supply *psy,
|
||||
enum power_supply_property psp,
|
||||
union power_supply_propval *val)
|
||||
@ -313,7 +305,6 @@ static enum power_supply_property sbs_energy_battery_props[] = {
|
||||
POWER_SUPPLY_PROP_MANUFACTURER,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/* --------------------------------------------------------------------------
|
||||
Smart Battery System Management
|
||||
@ -449,7 +440,6 @@ static int acpi_ac_get_present(struct acpi_sbs *sbs)
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ACPI_SYSFS_POWER
|
||||
static ssize_t acpi_battery_alarm_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
@ -479,7 +469,6 @@ static struct device_attribute alarm_attr = {
|
||||
.show = acpi_battery_alarm_show,
|
||||
.store = acpi_battery_alarm_store,
|
||||
};
|
||||
#endif
|
||||
|
||||
/* --------------------------------------------------------------------------
|
||||
FS Interface (/proc/acpi)
|
||||
@ -798,7 +787,6 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id)
|
||||
&acpi_battery_state_fops, &acpi_battery_alarm_fops,
|
||||
battery);
|
||||
#endif
|
||||
#ifdef CONFIG_ACPI_SYSFS_POWER
|
||||
battery->bat.name = battery->name;
|
||||
battery->bat.type = POWER_SUPPLY_TYPE_BATTERY;
|
||||
if (!acpi_battery_mode(battery)) {
|
||||
@ -819,7 +807,6 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id)
|
||||
goto end;
|
||||
battery->have_sysfs_alarm = 1;
|
||||
end:
|
||||
#endif
|
||||
printk(KERN_INFO PREFIX "%s [%s]: Battery Slot [%s] (battery %s)\n",
|
||||
ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device),
|
||||
battery->name, battery->present ? "present" : "absent");
|
||||
@ -828,17 +815,13 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id)
|
||||
|
||||
static void acpi_battery_remove(struct acpi_sbs *sbs, int id)
|
||||
{
|
||||
#if defined(CONFIG_ACPI_SYSFS_POWER) || defined(CONFIG_ACPI_PROCFS_POWER)
|
||||
struct acpi_battery *battery = &sbs->battery[id];
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ACPI_SYSFS_POWER
|
||||
if (battery->bat.dev) {
|
||||
if (battery->have_sysfs_alarm)
|
||||
device_remove_file(battery->bat.dev, &alarm_attr);
|
||||
power_supply_unregister(&battery->bat);
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_ACPI_PROCFS_POWER
|
||||
if (battery->proc_entry)
|
||||
acpi_sbs_remove_fs(&battery->proc_entry, acpi_battery_dir);
|
||||
@ -859,14 +842,12 @@ static int acpi_charger_add(struct acpi_sbs *sbs)
|
||||
if (result)
|
||||
goto end;
|
||||
#endif
|
||||
#ifdef CONFIG_ACPI_SYSFS_POWER
|
||||
sbs->charger.name = "sbs-charger";
|
||||
sbs->charger.type = POWER_SUPPLY_TYPE_MAINS;
|
||||
sbs->charger.properties = sbs_ac_props;
|
||||
sbs->charger.num_properties = ARRAY_SIZE(sbs_ac_props);
|
||||
sbs->charger.get_property = sbs_get_ac_property;
|
||||
power_supply_register(&sbs->device->dev, &sbs->charger);
|
||||
#endif
|
||||
printk(KERN_INFO PREFIX "%s [%s]: AC Adapter [%s] (%s)\n",
|
||||
ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device),
|
||||
ACPI_AC_DIR_NAME, sbs->charger_present ? "on-line" : "off-line");
|
||||
@ -876,10 +857,8 @@ static int acpi_charger_add(struct acpi_sbs *sbs)
|
||||
|
||||
static void acpi_charger_remove(struct acpi_sbs *sbs)
|
||||
{
|
||||
#ifdef CONFIG_ACPI_SYSFS_POWER
|
||||
if (sbs->charger.dev)
|
||||
power_supply_unregister(&sbs->charger);
|
||||
#endif
|
||||
#ifdef CONFIG_ACPI_PROCFS_POWER
|
||||
if (sbs->charger_entry)
|
||||
acpi_sbs_remove_fs(&sbs->charger_entry, acpi_ac_dir);
|
||||
@ -900,9 +879,7 @@ static void acpi_sbs_callback(void *context)
|
||||
ACPI_SBS_NOTIFY_STATUS,
|
||||
sbs->charger_present);
|
||||
#endif
|
||||
#ifdef CONFIG_ACPI_SYSFS_POWER
|
||||
kobject_uevent(&sbs->charger.dev->kobj, KOBJ_CHANGE);
|
||||
#endif
|
||||
}
|
||||
if (sbs->manager_present) {
|
||||
for (id = 0; id < MAX_SBS_BAT; ++id) {
|
||||
@ -919,9 +896,7 @@ static void acpi_sbs_callback(void *context)
|
||||
ACPI_SBS_NOTIFY_STATUS,
|
||||
bat->present);
|
||||
#endif
|
||||
#ifdef CONFIG_ACPI_SYSFS_POWER
|
||||
kobject_uevent(&bat->bat.dev->kobj, KOBJ_CHANGE);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -26,6 +26,8 @@ extern struct acpi_device *acpi_root;
|
||||
|
||||
#define ACPI_IS_ROOT_DEVICE(device) (!(device)->parent)
|
||||
|
||||
static const char *dummy_hid = "device";
|
||||
|
||||
static LIST_HEAD(acpi_device_list);
|
||||
static LIST_HEAD(acpi_bus_id_list);
|
||||
DEFINE_MUTEX(acpi_device_lock);
|
||||
@ -49,6 +51,9 @@ static int create_modalias(struct acpi_device *acpi_dev, char *modalias,
|
||||
int count;
|
||||
struct acpi_hardware_id *id;
|
||||
|
||||
if (list_empty(&acpi_dev->pnp.ids))
|
||||
return 0;
|
||||
|
||||
len = snprintf(modalias, size, "acpi:");
|
||||
size -= len;
|
||||
|
||||
@ -202,13 +207,15 @@ static int acpi_device_setup_files(struct acpi_device *dev)
|
||||
goto end;
|
||||
}
|
||||
|
||||
result = device_create_file(&dev->dev, &dev_attr_hid);
|
||||
if (result)
|
||||
goto end;
|
||||
if (!list_empty(&dev->pnp.ids)) {
|
||||
result = device_create_file(&dev->dev, &dev_attr_hid);
|
||||
if (result)
|
||||
goto end;
|
||||
|
||||
result = device_create_file(&dev->dev, &dev_attr_modalias);
|
||||
if (result)
|
||||
goto end;
|
||||
result = device_create_file(&dev->dev, &dev_attr_modalias);
|
||||
if (result)
|
||||
goto end;
|
||||
}
|
||||
|
||||
/*
|
||||
* If device has _EJ0, 'eject' file is created that is used to trigger
|
||||
@ -316,6 +323,9 @@ static int acpi_device_uevent(struct device *dev, struct kobj_uevent_env *env)
|
||||
struct acpi_device *acpi_dev = to_acpi_device(dev);
|
||||
int len;
|
||||
|
||||
if (list_empty(&acpi_dev->pnp.ids))
|
||||
return 0;
|
||||
|
||||
if (add_uevent_var(env, "MODALIAS="))
|
||||
return -ENOMEM;
|
||||
len = create_modalias(acpi_dev, &env->buf[env->buflen - 1],
|
||||
@ -1010,10 +1020,13 @@ static int acpi_dock_match(struct acpi_device *device)
|
||||
return acpi_get_handle(device->handle, "_DCK", &tmp);
|
||||
}
|
||||
|
||||
char *acpi_device_hid(struct acpi_device *device)
|
||||
const char *acpi_device_hid(struct acpi_device *device)
|
||||
{
|
||||
struct acpi_hardware_id *hid;
|
||||
|
||||
if (list_empty(&device->pnp.ids))
|
||||
return dummy_hid;
|
||||
|
||||
hid = list_first_entry(&device->pnp.ids, struct acpi_hardware_id, list);
|
||||
return hid->id;
|
||||
}
|
||||
@ -1142,16 +1155,6 @@ static void acpi_device_set_id(struct acpi_device *device)
|
||||
acpi_add_id(device, ACPI_BUTTON_HID_SLEEPF);
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* We build acpi_devices for some objects that don't have _HID or _CID,
|
||||
* e.g., PCI bridges and slots. Drivers can't bind to these objects,
|
||||
* but we do use them indirectly by traversing the acpi_device tree.
|
||||
* This generic ID isn't useful for driver binding, but it provides
|
||||
* the useful property that "every acpi_device has an ID."
|
||||
*/
|
||||
if (list_empty(&device->pnp.ids))
|
||||
acpi_add_id(device, "device");
|
||||
}
|
||||
|
||||
static int acpi_device_set_context(struct acpi_device *device)
|
||||
@ -1431,6 +1434,7 @@ EXPORT_SYMBOL(acpi_bus_add);
|
||||
int acpi_bus_start(struct acpi_device *device)
|
||||
{
|
||||
struct acpi_bus_ops ops;
|
||||
int result;
|
||||
|
||||
if (!device)
|
||||
return -EINVAL;
|
||||
@ -1438,7 +1442,11 @@ int acpi_bus_start(struct acpi_device *device)
|
||||
memset(&ops, 0, sizeof(ops));
|
||||
ops.acpi_op_start = 1;
|
||||
|
||||
return acpi_bus_scan(device->handle, &ops, NULL);
|
||||
result = acpi_bus_scan(device->handle, &ops, NULL);
|
||||
|
||||
acpi_update_gpes();
|
||||
|
||||
return result;
|
||||
}
|
||||
EXPORT_SYMBOL(acpi_bus_start);
|
||||
|
||||
@ -1552,6 +1560,8 @@ int __init acpi_scan_init(void)
|
||||
|
||||
if (result)
|
||||
acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL);
|
||||
else
|
||||
acpi_update_gpes();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -25,7 +25,9 @@
|
||||
#include "internal.h"
|
||||
#include "sleep.h"
|
||||
|
||||
u8 sleep_states[ACPI_S_STATE_COUNT];
|
||||
static u8 sleep_states[ACPI_S_STATE_COUNT];
|
||||
|
||||
static u32 acpi_target_sleep_state = ACPI_STATE_S0;
|
||||
|
||||
static void acpi_sleep_tts_switch(u32 acpi_state)
|
||||
{
|
||||
@ -79,8 +81,6 @@ static int acpi_sleep_prepare(u32 acpi_state)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ACPI_SLEEP
|
||||
static u32 acpi_target_sleep_state = ACPI_STATE_S0;
|
||||
|
||||
/*
|
||||
* The ACPI specification wants us to save NVS memory regions during hibernation
|
||||
* and to restore them during the subsequent resume. Windows does that also for
|
||||
@ -419,6 +419,14 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Everex StepNote Series"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = init_nvs_nosave,
|
||||
.ident = "Sony Vaio VPCEB1Z1E",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "VPCEB1Z1E"),
|
||||
},
|
||||
},
|
||||
{},
|
||||
};
|
||||
#endif /* CONFIG_SUSPEND */
|
||||
@ -562,7 +570,7 @@ int acpi_suspend(u32 acpi_state)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
#ifdef CONFIG_PM_OPS
|
||||
/**
|
||||
* acpi_pm_device_sleep_state - return preferred power state of ACPI device
|
||||
* in the system sleep state given by %acpi_target_sleep_state
|
||||
@ -624,7 +632,7 @@ int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p)
|
||||
* can wake the system. _S0W may be valid, too.
|
||||
*/
|
||||
if (acpi_target_sleep_state == ACPI_STATE_S0 ||
|
||||
(device_may_wakeup(dev) && adev->wakeup.state.enabled &&
|
||||
(device_may_wakeup(dev) &&
|
||||
adev->wakeup.sleep_state <= acpi_target_sleep_state)) {
|
||||
acpi_status status;
|
||||
|
||||
@ -632,7 +640,9 @@ int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p)
|
||||
status = acpi_evaluate_integer(handle, acpi_method, NULL,
|
||||
&d_max);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
d_max = d_min;
|
||||
if (acpi_target_sleep_state != ACPI_STATE_S0 ||
|
||||
status != AE_NOT_FOUND)
|
||||
d_max = d_min;
|
||||
} else if (d_max < d_min) {
|
||||
/* Warn the user of the broken DSDT */
|
||||
printk(KERN_WARNING "ACPI: Wrong value from %s\n",
|
||||
@ -646,7 +656,9 @@ int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p)
|
||||
*d_min_p = d_min;
|
||||
return d_max;
|
||||
}
|
||||
#endif /* CONFIG_PM_OPS */
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
/**
|
||||
* acpi_pm_device_sleep_wake - enable or disable the system wake-up
|
||||
* capability of given device
|
||||
@ -677,7 +689,7 @@ int acpi_pm_device_sleep_wake(struct device *dev, bool enable)
|
||||
|
||||
return error;
|
||||
}
|
||||
#endif
|
||||
#endif /* CONFIG_PM_SLEEP */
|
||||
|
||||
static void acpi_power_off_prepare(void)
|
||||
{
|
||||
@ -702,7 +714,7 @@ static void acpi_power_off(void)
|
||||
* paths through the BIOS, so disable _GTS and _BFS by default,
|
||||
* but do speak up and offer the option to enable them.
|
||||
*/
|
||||
void __init acpi_gts_bfs_check(void)
|
||||
static void __init acpi_gts_bfs_check(void)
|
||||
{
|
||||
acpi_handle dummy;
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
|
||||
extern u8 sleep_states[];
|
||||
extern int acpi_suspend(u32 state);
|
||||
|
||||
extern void acpi_enable_wakeup_devices(u8 sleep_state);
|
||||
|
@ -37,12 +37,6 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#ifdef CONFIG_ACPI_PROCFS
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/seq_file.h>
|
||||
#endif
|
||||
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/kmod.h>
|
||||
#include <linux/reboot.h>
|
||||
@ -195,61 +189,6 @@ struct acpi_thermal {
|
||||
struct mutex lock;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_ACPI_PROCFS
|
||||
static int acpi_thermal_state_open_fs(struct inode *inode, struct file *file);
|
||||
static int acpi_thermal_temp_open_fs(struct inode *inode, struct file *file);
|
||||
static int acpi_thermal_trip_open_fs(struct inode *inode, struct file *file);
|
||||
static int acpi_thermal_cooling_open_fs(struct inode *inode, struct file *file);
|
||||
static ssize_t acpi_thermal_write_cooling_mode(struct file *,
|
||||
const char __user *, size_t,
|
||||
loff_t *);
|
||||
static int acpi_thermal_polling_open_fs(struct inode *inode, struct file *file);
|
||||
static ssize_t acpi_thermal_write_polling(struct file *, const char __user *,
|
||||
size_t, loff_t *);
|
||||
|
||||
static const struct file_operations acpi_thermal_state_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = acpi_thermal_state_open_fs,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
};
|
||||
|
||||
static const struct file_operations acpi_thermal_temp_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = acpi_thermal_temp_open_fs,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
};
|
||||
|
||||
static const struct file_operations acpi_thermal_trip_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = acpi_thermal_trip_open_fs,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
};
|
||||
|
||||
static const struct file_operations acpi_thermal_cooling_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = acpi_thermal_cooling_open_fs,
|
||||
.read = seq_read,
|
||||
.write = acpi_thermal_write_cooling_mode,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
};
|
||||
|
||||
static const struct file_operations acpi_thermal_polling_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = acpi_thermal_polling_open_fs,
|
||||
.read = seq_read,
|
||||
.write = acpi_thermal_write_polling,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
};
|
||||
#endif /* CONFIG_ACPI_PROCFS*/
|
||||
|
||||
/* --------------------------------------------------------------------------
|
||||
Thermal Zone Management
|
||||
-------------------------------------------------------------------------- */
|
||||
@ -957,358 +896,6 @@ static void acpi_thermal_unregister_thermal_zone(struct acpi_thermal *tz)
|
||||
}
|
||||
|
||||
|
||||
/* --------------------------------------------------------------------------
|
||||
FS Interface (/proc)
|
||||
-------------------------------------------------------------------------- */
|
||||
#ifdef CONFIG_ACPI_PROCFS
|
||||
static struct proc_dir_entry *acpi_thermal_dir;
|
||||
|
||||
static int acpi_thermal_state_seq_show(struct seq_file *seq, void *offset)
|
||||
{
|
||||
struct acpi_thermal *tz = seq->private;
|
||||
|
||||
|
||||
if (!tz)
|
||||
goto end;
|
||||
|
||||
seq_puts(seq, "state: ");
|
||||
|
||||
if (!tz->state.critical && !tz->state.hot && !tz->state.passive
|
||||
&& !tz->state.active)
|
||||
seq_puts(seq, "ok\n");
|
||||
else {
|
||||
if (tz->state.critical)
|
||||
seq_puts(seq, "critical ");
|
||||
if (tz->state.hot)
|
||||
seq_puts(seq, "hot ");
|
||||
if (tz->state.passive)
|
||||
seq_puts(seq, "passive ");
|
||||
if (tz->state.active)
|
||||
seq_printf(seq, "active[%d]", tz->state.active_index);
|
||||
seq_puts(seq, "\n");
|
||||
}
|
||||
|
||||
end:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int acpi_thermal_state_open_fs(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, acpi_thermal_state_seq_show, PDE(inode)->data);
|
||||
}
|
||||
|
||||
static int acpi_thermal_temp_seq_show(struct seq_file *seq, void *offset)
|
||||
{
|
||||
int result = 0;
|
||||
struct acpi_thermal *tz = seq->private;
|
||||
|
||||
|
||||
if (!tz)
|
||||
goto end;
|
||||
|
||||
result = acpi_thermal_get_temperature(tz);
|
||||
if (result)
|
||||
goto end;
|
||||
|
||||
seq_printf(seq, "temperature: %ld C\n",
|
||||
KELVIN_TO_CELSIUS(tz->temperature));
|
||||
|
||||
end:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int acpi_thermal_temp_open_fs(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, acpi_thermal_temp_seq_show, PDE(inode)->data);
|
||||
}
|
||||
|
||||
static int acpi_thermal_trip_seq_show(struct seq_file *seq, void *offset)
|
||||
{
|
||||
struct acpi_thermal *tz = seq->private;
|
||||
struct acpi_device *device;
|
||||
acpi_status status;
|
||||
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
|
||||
|
||||
if (!tz)
|
||||
goto end;
|
||||
|
||||
if (tz->trips.critical.flags.valid)
|
||||
seq_printf(seq, "critical (S5): %ld C%s",
|
||||
KELVIN_TO_CELSIUS(tz->trips.critical.temperature),
|
||||
nocrt ? " <disabled>\n" : "\n");
|
||||
|
||||
if (tz->trips.hot.flags.valid)
|
||||
seq_printf(seq, "hot (S4): %ld C%s",
|
||||
KELVIN_TO_CELSIUS(tz->trips.hot.temperature),
|
||||
nocrt ? " <disabled>\n" : "\n");
|
||||
|
||||
if (tz->trips.passive.flags.valid) {
|
||||
seq_printf(seq,
|
||||
"passive: %ld C: tc1=%lu tc2=%lu tsp=%lu devices=",
|
||||
KELVIN_TO_CELSIUS(tz->trips.passive.temperature),
|
||||
tz->trips.passive.tc1, tz->trips.passive.tc2,
|
||||
tz->trips.passive.tsp);
|
||||
for (j = 0; j < tz->trips.passive.devices.count; j++) {
|
||||
status = acpi_bus_get_device(tz->trips.passive.devices.
|
||||
handles[j], &device);
|
||||
seq_printf(seq, "%4.4s ", status ? "" :
|
||||
acpi_device_bid(device));
|
||||
}
|
||||
seq_puts(seq, "\n");
|
||||
} else {
|
||||
seq_printf(seq, "passive (forced):");
|
||||
if (tz->thermal_zone->forced_passive)
|
||||
seq_printf(seq, " %i C\n",
|
||||
tz->thermal_zone->forced_passive / 1000);
|
||||
else
|
||||
seq_printf(seq, "<not set>\n");
|
||||
}
|
||||
|
||||
for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) {
|
||||
if (!(tz->trips.active[i].flags.valid))
|
||||
break;
|
||||
seq_printf(seq, "active[%d]: %ld C: devices=",
|
||||
i,
|
||||
KELVIN_TO_CELSIUS(tz->trips.active[i].temperature));
|
||||
for (j = 0; j < tz->trips.active[i].devices.count; j++){
|
||||
status = acpi_bus_get_device(tz->trips.active[i].
|
||||
devices.handles[j],
|
||||
&device);
|
||||
seq_printf(seq, "%4.4s ", status ? "" :
|
||||
acpi_device_bid(device));
|
||||
}
|
||||
seq_puts(seq, "\n");
|
||||
}
|
||||
|
||||
end:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int acpi_thermal_trip_open_fs(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, acpi_thermal_trip_seq_show, PDE(inode)->data);
|
||||
}
|
||||
|
||||
static int acpi_thermal_cooling_seq_show(struct seq_file *seq, void *offset)
|
||||
{
|
||||
struct acpi_thermal *tz = seq->private;
|
||||
|
||||
|
||||
if (!tz)
|
||||
goto end;
|
||||
|
||||
if (!tz->flags.cooling_mode)
|
||||
seq_puts(seq, "<setting not supported>\n");
|
||||
else
|
||||
seq_puts(seq, "0 - Active; 1 - Passive\n");
|
||||
|
||||
end:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int acpi_thermal_cooling_open_fs(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, acpi_thermal_cooling_seq_show,
|
||||
PDE(inode)->data);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
acpi_thermal_write_cooling_mode(struct file *file,
|
||||
const char __user * buffer,
|
||||
size_t count, loff_t * ppos)
|
||||
{
|
||||
struct seq_file *m = file->private_data;
|
||||
struct acpi_thermal *tz = m->private;
|
||||
int result = 0;
|
||||
char mode_string[12] = { '\0' };
|
||||
|
||||
|
||||
if (!tz || (count > sizeof(mode_string) - 1))
|
||||
return -EINVAL;
|
||||
|
||||
if (!tz->flags.cooling_mode)
|
||||
return -ENODEV;
|
||||
|
||||
if (copy_from_user(mode_string, buffer, count))
|
||||
return -EFAULT;
|
||||
|
||||
mode_string[count] = '\0';
|
||||
|
||||
result = acpi_thermal_set_cooling_mode(tz,
|
||||
simple_strtoul(mode_string, NULL,
|
||||
0));
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
acpi_thermal_check(tz);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static int acpi_thermal_polling_seq_show(struct seq_file *seq, void *offset)
|
||||
{
|
||||
struct acpi_thermal *tz = seq->private;
|
||||
|
||||
|
||||
if (!tz)
|
||||
goto end;
|
||||
|
||||
if (!tz->thermal_zone->polling_delay) {
|
||||
seq_puts(seq, "<polling disabled>\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
seq_printf(seq, "polling frequency: %d seconds\n",
|
||||
(tz->thermal_zone->polling_delay / 1000));
|
||||
|
||||
end:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int acpi_thermal_polling_open_fs(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, acpi_thermal_polling_seq_show,
|
||||
PDE(inode)->data);
|
||||
}
|
||||
|
||||
static int acpi_thermal_set_polling(struct acpi_thermal *tz, int seconds)
|
||||
{
|
||||
if (!tz)
|
||||
return -EINVAL;
|
||||
|
||||
/* Convert value to deci-seconds */
|
||||
tz->polling_frequency = seconds * 10;
|
||||
|
||||
tz->thermal_zone->polling_delay = seconds * 1000;
|
||||
|
||||
if (tz->tz_enabled)
|
||||
thermal_zone_device_update(tz->thermal_zone);
|
||||
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
||||
"Polling frequency set to %lu seconds\n",
|
||||
tz->polling_frequency/10));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
acpi_thermal_write_polling(struct file *file,
|
||||
const char __user * buffer,
|
||||
size_t count, loff_t * ppos)
|
||||
{
|
||||
struct seq_file *m = file->private_data;
|
||||
struct acpi_thermal *tz = m->private;
|
||||
int result = 0;
|
||||
char polling_string[12] = { '\0' };
|
||||
int seconds = 0;
|
||||
|
||||
|
||||
if (!tz || (count > sizeof(polling_string) - 1))
|
||||
return -EINVAL;
|
||||
|
||||
if (copy_from_user(polling_string, buffer, count))
|
||||
return -EFAULT;
|
||||
|
||||
polling_string[count] = '\0';
|
||||
|
||||
seconds = simple_strtoul(polling_string, NULL, 0);
|
||||
|
||||
result = acpi_thermal_set_polling(tz, seconds);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
acpi_thermal_check(tz);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static int acpi_thermal_add_fs(struct acpi_device *device)
|
||||
{
|
||||
struct proc_dir_entry *entry = NULL;
|
||||
|
||||
|
||||
if (!acpi_device_dir(device)) {
|
||||
acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
|
||||
acpi_thermal_dir);
|
||||
if (!acpi_device_dir(device))
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* 'state' [R] */
|
||||
entry = proc_create_data(ACPI_THERMAL_FILE_STATE,
|
||||
S_IRUGO, acpi_device_dir(device),
|
||||
&acpi_thermal_state_fops,
|
||||
acpi_driver_data(device));
|
||||
if (!entry)
|
||||
return -ENODEV;
|
||||
|
||||
/* 'temperature' [R] */
|
||||
entry = proc_create_data(ACPI_THERMAL_FILE_TEMPERATURE,
|
||||
S_IRUGO, acpi_device_dir(device),
|
||||
&acpi_thermal_temp_fops,
|
||||
acpi_driver_data(device));
|
||||
if (!entry)
|
||||
return -ENODEV;
|
||||
|
||||
/* 'trip_points' [R] */
|
||||
entry = proc_create_data(ACPI_THERMAL_FILE_TRIP_POINTS,
|
||||
S_IRUGO,
|
||||
acpi_device_dir(device),
|
||||
&acpi_thermal_trip_fops,
|
||||
acpi_driver_data(device));
|
||||
if (!entry)
|
||||
return -ENODEV;
|
||||
|
||||
/* 'cooling_mode' [R/W] */
|
||||
entry = proc_create_data(ACPI_THERMAL_FILE_COOLING_MODE,
|
||||
S_IFREG | S_IRUGO | S_IWUSR,
|
||||
acpi_device_dir(device),
|
||||
&acpi_thermal_cooling_fops,
|
||||
acpi_driver_data(device));
|
||||
if (!entry)
|
||||
return -ENODEV;
|
||||
|
||||
/* 'polling_frequency' [R/W] */
|
||||
entry = proc_create_data(ACPI_THERMAL_FILE_POLLING_FREQ,
|
||||
S_IFREG | S_IRUGO | S_IWUSR,
|
||||
acpi_device_dir(device),
|
||||
&acpi_thermal_polling_fops,
|
||||
acpi_driver_data(device));
|
||||
if (!entry)
|
||||
return -ENODEV;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int acpi_thermal_remove_fs(struct acpi_device *device)
|
||||
{
|
||||
|
||||
if (acpi_device_dir(device)) {
|
||||
remove_proc_entry(ACPI_THERMAL_FILE_POLLING_FREQ,
|
||||
acpi_device_dir(device));
|
||||
remove_proc_entry(ACPI_THERMAL_FILE_COOLING_MODE,
|
||||
acpi_device_dir(device));
|
||||
remove_proc_entry(ACPI_THERMAL_FILE_TRIP_POINTS,
|
||||
acpi_device_dir(device));
|
||||
remove_proc_entry(ACPI_THERMAL_FILE_TEMPERATURE,
|
||||
acpi_device_dir(device));
|
||||
remove_proc_entry(ACPI_THERMAL_FILE_STATE,
|
||||
acpi_device_dir(device));
|
||||
remove_proc_entry(acpi_device_bid(device), acpi_thermal_dir);
|
||||
acpi_device_dir(device) = NULL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
static inline int acpi_thermal_add_fs(struct acpi_device *device) { return 0; }
|
||||
static inline int acpi_thermal_remove_fs(struct acpi_device *device)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_ACPI_PROCFS */
|
||||
/* --------------------------------------------------------------------------
|
||||
Driver Interface
|
||||
-------------------------------------------------------------------------- */
|
||||
@ -1428,17 +1015,11 @@ static int acpi_thermal_add(struct acpi_device *device)
|
||||
if (result)
|
||||
goto free_memory;
|
||||
|
||||
result = acpi_thermal_add_fs(device);
|
||||
if (result)
|
||||
goto unregister_thermal_zone;
|
||||
|
||||
printk(KERN_INFO PREFIX "%s [%s] (%ld C)\n",
|
||||
acpi_device_name(device), acpi_device_bid(device),
|
||||
KELVIN_TO_CELSIUS(tz->temperature));
|
||||
goto end;
|
||||
|
||||
unregister_thermal_zone:
|
||||
thermal_zone_device_unregister(tz->thermal_zone);
|
||||
free_memory:
|
||||
kfree(tz);
|
||||
end:
|
||||
@ -1454,7 +1035,6 @@ static int acpi_thermal_remove(struct acpi_device *device, int type)
|
||||
|
||||
tz = acpi_driver_data(device);
|
||||
|
||||
acpi_thermal_remove_fs(device);
|
||||
acpi_thermal_unregister_thermal_zone(tz);
|
||||
mutex_destroy(&tz->lock);
|
||||
kfree(tz);
|
||||
@ -1580,19 +1160,9 @@ static int __init acpi_thermal_init(void)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ACPI_PROCFS
|
||||
acpi_thermal_dir = proc_mkdir(ACPI_THERMAL_CLASS, acpi_root_dir);
|
||||
if (!acpi_thermal_dir)
|
||||
return -ENODEV;
|
||||
#endif
|
||||
|
||||
result = acpi_bus_register_driver(&acpi_thermal_driver);
|
||||
if (result < 0) {
|
||||
#ifdef CONFIG_ACPI_PROCFS
|
||||
remove_proc_entry(ACPI_THERMAL_CLASS, acpi_root_dir);
|
||||
#endif
|
||||
if (result < 0)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1602,10 +1172,6 @@ static void __exit acpi_thermal_exit(void)
|
||||
|
||||
acpi_bus_unregister_driver(&acpi_thermal_driver);
|
||||
|
||||
#ifdef CONFIG_ACPI_PROCFS
|
||||
remove_proc_entry(ACPI_THERMAL_CLASS, acpi_root_dir);
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -30,8 +30,6 @@
|
||||
#include <linux/types.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/backlight.h>
|
||||
#include <linux/thermal.h>
|
||||
@ -152,9 +150,6 @@ struct acpi_video_bus {
|
||||
struct acpi_video_bus_flags flags;
|
||||
struct list_head video_device_list;
|
||||
struct mutex device_list_lock; /* protects video_device_list */
|
||||
#ifdef CONFIG_ACPI_PROCFS
|
||||
struct proc_dir_entry *dir;
|
||||
#endif
|
||||
struct input_dev *input;
|
||||
char phys[32]; /* for input device */
|
||||
struct notifier_block pm_nb;
|
||||
@ -210,108 +205,6 @@ struct acpi_video_device {
|
||||
struct output_device *output_dev;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_ACPI_PROCFS
|
||||
/* bus */
|
||||
static int acpi_video_bus_info_open_fs(struct inode *inode, struct file *file);
|
||||
static const struct file_operations acpi_video_bus_info_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = acpi_video_bus_info_open_fs,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
};
|
||||
|
||||
static int acpi_video_bus_ROM_open_fs(struct inode *inode, struct file *file);
|
||||
static const struct file_operations acpi_video_bus_ROM_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = acpi_video_bus_ROM_open_fs,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
};
|
||||
|
||||
static int acpi_video_bus_POST_info_open_fs(struct inode *inode,
|
||||
struct file *file);
|
||||
static const struct file_operations acpi_video_bus_POST_info_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = acpi_video_bus_POST_info_open_fs,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
};
|
||||
|
||||
static int acpi_video_bus_POST_open_fs(struct inode *inode, struct file *file);
|
||||
static ssize_t acpi_video_bus_write_POST(struct file *file,
|
||||
const char __user *buffer, size_t count, loff_t *data);
|
||||
static const struct file_operations acpi_video_bus_POST_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = acpi_video_bus_POST_open_fs,
|
||||
.read = seq_read,
|
||||
.write = acpi_video_bus_write_POST,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
};
|
||||
|
||||
static int acpi_video_bus_DOS_open_fs(struct inode *inode, struct file *file);
|
||||
static ssize_t acpi_video_bus_write_DOS(struct file *file,
|
||||
const char __user *buffer, size_t count, loff_t *data);
|
||||
static const struct file_operations acpi_video_bus_DOS_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = acpi_video_bus_DOS_open_fs,
|
||||
.read = seq_read,
|
||||
.write = acpi_video_bus_write_DOS,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
};
|
||||
|
||||
/* device */
|
||||
static int acpi_video_device_info_open_fs(struct inode *inode,
|
||||
struct file *file);
|
||||
static const struct file_operations acpi_video_device_info_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = acpi_video_device_info_open_fs,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
};
|
||||
|
||||
static int acpi_video_device_state_open_fs(struct inode *inode,
|
||||
struct file *file);
|
||||
static ssize_t acpi_video_device_write_state(struct file *file,
|
||||
const char __user *buffer, size_t count, loff_t *data);
|
||||
static const struct file_operations acpi_video_device_state_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = acpi_video_device_state_open_fs,
|
||||
.read = seq_read,
|
||||
.write = acpi_video_device_write_state,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
};
|
||||
|
||||
static int acpi_video_device_brightness_open_fs(struct inode *inode,
|
||||
struct file *file);
|
||||
static ssize_t acpi_video_device_write_brightness(struct file *file,
|
||||
const char __user *buffer, size_t count, loff_t *data);
|
||||
static const struct file_operations acpi_video_device_brightness_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = acpi_video_device_brightness_open_fs,
|
||||
.read = seq_read,
|
||||
.write = acpi_video_device_write_brightness,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
};
|
||||
|
||||
static int acpi_video_device_EDID_open_fs(struct inode *inode,
|
||||
struct file *file);
|
||||
static const struct file_operations acpi_video_device_EDID_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = acpi_video_device_EDID_open_fs,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
};
|
||||
#endif /* CONFIG_ACPI_PROCFS */
|
||||
|
||||
static const char device_decode[][30] = {
|
||||
"motherboard VGA device",
|
||||
"PCI VGA device",
|
||||
@ -1110,646 +1003,6 @@ static int acpi_video_bus_check(struct acpi_video_bus *video)
|
||||
return status;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------
|
||||
FS Interface (/proc)
|
||||
-------------------------------------------------------------------------- */
|
||||
#ifdef CONFIG_ACPI_PROCFS
|
||||
|
||||
static struct proc_dir_entry *acpi_video_dir;
|
||||
|
||||
/* video devices */
|
||||
|
||||
static int acpi_video_device_info_seq_show(struct seq_file *seq, void *offset)
|
||||
{
|
||||
struct acpi_video_device *dev = seq->private;
|
||||
|
||||
|
||||
if (!dev)
|
||||
goto end;
|
||||
|
||||
seq_printf(seq, "device_id: 0x%04x\n", (u32) dev->device_id);
|
||||
seq_printf(seq, "type: ");
|
||||
if (dev->flags.crt)
|
||||
seq_printf(seq, "CRT\n");
|
||||
else if (dev->flags.lcd)
|
||||
seq_printf(seq, "LCD\n");
|
||||
else if (dev->flags.tvout)
|
||||
seq_printf(seq, "TVOUT\n");
|
||||
else if (dev->flags.dvi)
|
||||
seq_printf(seq, "DVI\n");
|
||||
else
|
||||
seq_printf(seq, "UNKNOWN\n");
|
||||
|
||||
seq_printf(seq, "known by bios: %s\n", dev->flags.bios ? "yes" : "no");
|
||||
|
||||
end:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
acpi_video_device_info_open_fs(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, acpi_video_device_info_seq_show,
|
||||
PDE(inode)->data);
|
||||
}
|
||||
|
||||
static int
|
||||
acpi_video_device_query(struct acpi_video_device *device,
|
||||
unsigned long long *state)
|
||||
{
|
||||
int status;
|
||||
|
||||
status = acpi_evaluate_integer(device->dev->handle, "_DGS",
|
||||
NULL, state);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static int acpi_video_device_state_seq_show(struct seq_file *seq, void *offset)
|
||||
{
|
||||
int status;
|
||||
struct acpi_video_device *dev = seq->private;
|
||||
unsigned long long state;
|
||||
|
||||
|
||||
if (!dev)
|
||||
goto end;
|
||||
|
||||
status = acpi_video_device_get_state(dev, &state);
|
||||
seq_printf(seq, "state: ");
|
||||
if (ACPI_SUCCESS(status))
|
||||
seq_printf(seq, "0x%02llx\n", state);
|
||||
else
|
||||
seq_printf(seq, "<not supported>\n");
|
||||
|
||||
status = acpi_video_device_query(dev, &state);
|
||||
seq_printf(seq, "query: ");
|
||||
if (ACPI_SUCCESS(status))
|
||||
seq_printf(seq, "0x%02llx\n", state);
|
||||
else
|
||||
seq_printf(seq, "<not supported>\n");
|
||||
|
||||
end:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
acpi_video_device_state_open_fs(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, acpi_video_device_state_seq_show,
|
||||
PDE(inode)->data);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
acpi_video_device_write_state(struct file *file,
|
||||
const char __user * buffer,
|
||||
size_t count, loff_t * data)
|
||||
{
|
||||
int status;
|
||||
struct seq_file *m = file->private_data;
|
||||
struct acpi_video_device *dev = m->private;
|
||||
char str[12] = { 0 };
|
||||
u32 state = 0;
|
||||
|
||||
|
||||
if (!dev || count >= sizeof(str))
|
||||
return -EINVAL;
|
||||
|
||||
if (copy_from_user(str, buffer, count))
|
||||
return -EFAULT;
|
||||
|
||||
str[count] = 0;
|
||||
state = simple_strtoul(str, NULL, 0);
|
||||
state &= ((1ul << 31) | (1ul << 30) | (1ul << 0));
|
||||
|
||||
status = acpi_video_device_set_state(dev, state);
|
||||
|
||||
if (status)
|
||||
return -EFAULT;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static int
|
||||
acpi_video_device_brightness_seq_show(struct seq_file *seq, void *offset)
|
||||
{
|
||||
struct acpi_video_device *dev = seq->private;
|
||||
int i;
|
||||
|
||||
|
||||
if (!dev || !dev->brightness) {
|
||||
seq_printf(seq, "<not supported>\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
seq_printf(seq, "levels: ");
|
||||
for (i = 2; i < dev->brightness->count; i++)
|
||||
seq_printf(seq, " %d", dev->brightness->levels[i]);
|
||||
seq_printf(seq, "\ncurrent: %d\n", dev->brightness->curr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
acpi_video_device_brightness_open_fs(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, acpi_video_device_brightness_seq_show,
|
||||
PDE(inode)->data);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
acpi_video_device_write_brightness(struct file *file,
|
||||
const char __user * buffer,
|
||||
size_t count, loff_t * data)
|
||||
{
|
||||
struct seq_file *m = file->private_data;
|
||||
struct acpi_video_device *dev = m->private;
|
||||
char str[5] = { 0 };
|
||||
unsigned int level = 0;
|
||||
int i;
|
||||
|
||||
|
||||
if (!dev || !dev->brightness || count >= sizeof(str))
|
||||
return -EINVAL;
|
||||
|
||||
if (copy_from_user(str, buffer, count))
|
||||
return -EFAULT;
|
||||
|
||||
str[count] = 0;
|
||||
level = simple_strtoul(str, NULL, 0);
|
||||
|
||||
if (level > 100)
|
||||
return -EFAULT;
|
||||
|
||||
/* validate through the list of available levels */
|
||||
for (i = 2; i < dev->brightness->count; i++)
|
||||
if (level == dev->brightness->levels[i]) {
|
||||
if (!acpi_video_device_lcd_set_level(dev, level))
|
||||
return count;
|
||||
break;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int acpi_video_device_EDID_seq_show(struct seq_file *seq, void *offset)
|
||||
{
|
||||
struct acpi_video_device *dev = seq->private;
|
||||
int status;
|
||||
int i;
|
||||
union acpi_object *edid = NULL;
|
||||
|
||||
|
||||
if (!dev)
|
||||
goto out;
|
||||
|
||||
status = acpi_video_device_EDID(dev, &edid, 128);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
status = acpi_video_device_EDID(dev, &edid, 256);
|
||||
}
|
||||
|
||||
if (ACPI_FAILURE(status)) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (edid && edid->type == ACPI_TYPE_BUFFER) {
|
||||
for (i = 0; i < edid->buffer.length; i++)
|
||||
seq_putc(seq, edid->buffer.pointer[i]);
|
||||
}
|
||||
|
||||
out:
|
||||
if (!edid)
|
||||
seq_printf(seq, "<not supported>\n");
|
||||
else
|
||||
kfree(edid);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
acpi_video_device_EDID_open_fs(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, acpi_video_device_EDID_seq_show,
|
||||
PDE(inode)->data);
|
||||
}
|
||||
|
||||
static int acpi_video_device_add_fs(struct acpi_device *device)
|
||||
{
|
||||
struct proc_dir_entry *entry, *device_dir;
|
||||
struct acpi_video_device *vid_dev;
|
||||
|
||||
vid_dev = acpi_driver_data(device);
|
||||
if (!vid_dev)
|
||||
return -ENODEV;
|
||||
|
||||
device_dir = proc_mkdir(acpi_device_bid(device),
|
||||
vid_dev->video->dir);
|
||||
if (!device_dir)
|
||||
return -ENOMEM;
|
||||
|
||||
/* 'info' [R] */
|
||||
entry = proc_create_data("info", S_IRUGO, device_dir,
|
||||
&acpi_video_device_info_fops, acpi_driver_data(device));
|
||||
if (!entry)
|
||||
goto err_remove_dir;
|
||||
|
||||
/* 'state' [R/W] */
|
||||
entry = proc_create_data("state", S_IFREG | S_IRUGO | S_IWUSR,
|
||||
device_dir,
|
||||
&acpi_video_device_state_fops,
|
||||
acpi_driver_data(device));
|
||||
if (!entry)
|
||||
goto err_remove_info;
|
||||
|
||||
/* 'brightness' [R/W] */
|
||||
entry = proc_create_data("brightness", S_IFREG | S_IRUGO | S_IWUSR,
|
||||
device_dir,
|
||||
&acpi_video_device_brightness_fops,
|
||||
acpi_driver_data(device));
|
||||
if (!entry)
|
||||
goto err_remove_state;
|
||||
|
||||
/* 'EDID' [R] */
|
||||
entry = proc_create_data("EDID", S_IRUGO, device_dir,
|
||||
&acpi_video_device_EDID_fops,
|
||||
acpi_driver_data(device));
|
||||
if (!entry)
|
||||
goto err_remove_brightness;
|
||||
|
||||
acpi_device_dir(device) = device_dir;
|
||||
|
||||
return 0;
|
||||
|
||||
err_remove_brightness:
|
||||
remove_proc_entry("brightness", device_dir);
|
||||
err_remove_state:
|
||||
remove_proc_entry("state", device_dir);
|
||||
err_remove_info:
|
||||
remove_proc_entry("info", device_dir);
|
||||
err_remove_dir:
|
||||
remove_proc_entry(acpi_device_bid(device), vid_dev->video->dir);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
static int acpi_video_device_remove_fs(struct acpi_device *device)
|
||||
{
|
||||
struct acpi_video_device *vid_dev;
|
||||
struct proc_dir_entry *device_dir;
|
||||
|
||||
vid_dev = acpi_driver_data(device);
|
||||
if (!vid_dev || !vid_dev->video || !vid_dev->video->dir)
|
||||
return -ENODEV;
|
||||
|
||||
device_dir = acpi_device_dir(device);
|
||||
if (device_dir) {
|
||||
remove_proc_entry("info", device_dir);
|
||||
remove_proc_entry("state", device_dir);
|
||||
remove_proc_entry("brightness", device_dir);
|
||||
remove_proc_entry("EDID", device_dir);
|
||||
remove_proc_entry(acpi_device_bid(device), vid_dev->video->dir);
|
||||
acpi_device_dir(device) = NULL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* video bus */
|
||||
static int acpi_video_bus_info_seq_show(struct seq_file *seq, void *offset)
|
||||
{
|
||||
struct acpi_video_bus *video = seq->private;
|
||||
|
||||
|
||||
if (!video)
|
||||
goto end;
|
||||
|
||||
seq_printf(seq, "Switching heads: %s\n",
|
||||
video->flags.multihead ? "yes" : "no");
|
||||
seq_printf(seq, "Video ROM: %s\n",
|
||||
video->flags.rom ? "yes" : "no");
|
||||
seq_printf(seq, "Device to be POSTed on boot: %s\n",
|
||||
video->flags.post ? "yes" : "no");
|
||||
|
||||
end:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int acpi_video_bus_info_open_fs(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, acpi_video_bus_info_seq_show,
|
||||
PDE(inode)->data);
|
||||
}
|
||||
|
||||
static int acpi_video_bus_ROM_seq_show(struct seq_file *seq, void *offset)
|
||||
{
|
||||
struct acpi_video_bus *video = seq->private;
|
||||
|
||||
|
||||
if (!video)
|
||||
goto end;
|
||||
|
||||
printk(KERN_INFO PREFIX "Please implement %s\n", __func__);
|
||||
seq_printf(seq, "<TODO>\n");
|
||||
|
||||
end:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int acpi_video_bus_ROM_open_fs(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, acpi_video_bus_ROM_seq_show, PDE(inode)->data);
|
||||
}
|
||||
|
||||
static int
|
||||
acpi_video_bus_POST_options(struct acpi_video_bus *video,
|
||||
unsigned long long *options)
|
||||
{
|
||||
int status;
|
||||
|
||||
status = acpi_evaluate_integer(video->device->handle, "_VPO",
|
||||
NULL, options);
|
||||
*options &= 3;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static int acpi_video_bus_POST_info_seq_show(struct seq_file *seq, void *offset)
|
||||
{
|
||||
struct acpi_video_bus *video = seq->private;
|
||||
unsigned long long options;
|
||||
int status;
|
||||
|
||||
|
||||
if (!video)
|
||||
goto end;
|
||||
|
||||
status = acpi_video_bus_POST_options(video, &options);
|
||||
if (ACPI_SUCCESS(status)) {
|
||||
if (!(options & 1)) {
|
||||
printk(KERN_WARNING PREFIX
|
||||
"The motherboard VGA device is not listed as a possible POST device.\n");
|
||||
printk(KERN_WARNING PREFIX
|
||||
"This indicates a BIOS bug. Please contact the manufacturer.\n");
|
||||
}
|
||||
printk(KERN_WARNING "%llx\n", options);
|
||||
seq_printf(seq, "can POST: <integrated video>");
|
||||
if (options & 2)
|
||||
seq_printf(seq, " <PCI video>");
|
||||
if (options & 4)
|
||||
seq_printf(seq, " <AGP video>");
|
||||
seq_putc(seq, '\n');
|
||||
} else
|
||||
seq_printf(seq, "<not supported>\n");
|
||||
end:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
acpi_video_bus_POST_info_open_fs(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, acpi_video_bus_POST_info_seq_show,
|
||||
PDE(inode)->data);
|
||||
}
|
||||
|
||||
static int
|
||||
acpi_video_bus_get_POST(struct acpi_video_bus *video, unsigned long long *id)
|
||||
{
|
||||
int status;
|
||||
|
||||
status = acpi_evaluate_integer(video->device->handle, "_GPD", NULL, id);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static int acpi_video_bus_POST_seq_show(struct seq_file *seq, void *offset)
|
||||
{
|
||||
struct acpi_video_bus *video = seq->private;
|
||||
int status;
|
||||
unsigned long long id;
|
||||
|
||||
|
||||
if (!video)
|
||||
goto end;
|
||||
|
||||
status = acpi_video_bus_get_POST(video, &id);
|
||||
if (!ACPI_SUCCESS(status)) {
|
||||
seq_printf(seq, "<not supported>\n");
|
||||
goto end;
|
||||
}
|
||||
seq_printf(seq, "device POSTed is <%s>\n", device_decode[id & 3]);
|
||||
|
||||
end:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int acpi_video_bus_DOS_seq_show(struct seq_file *seq, void *offset)
|
||||
{
|
||||
struct acpi_video_bus *video = seq->private;
|
||||
|
||||
|
||||
seq_printf(seq, "DOS setting: <%d>\n", video->dos_setting);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int acpi_video_bus_POST_open_fs(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, acpi_video_bus_POST_seq_show,
|
||||
PDE(inode)->data);
|
||||
}
|
||||
|
||||
static int acpi_video_bus_DOS_open_fs(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, acpi_video_bus_DOS_seq_show, PDE(inode)->data);
|
||||
}
|
||||
|
||||
static int
|
||||
acpi_video_bus_set_POST(struct acpi_video_bus *video, unsigned long option)
|
||||
{
|
||||
int status;
|
||||
unsigned long long tmp;
|
||||
union acpi_object arg0 = { ACPI_TYPE_INTEGER };
|
||||
struct acpi_object_list args = { 1, &arg0 };
|
||||
|
||||
|
||||
arg0.integer.value = option;
|
||||
|
||||
status = acpi_evaluate_integer(video->device->handle, "_SPD",
|
||||
&args, &tmp);
|
||||
if (ACPI_SUCCESS(status))
|
||||
status = tmp ? (-EINVAL) : (AE_OK);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
acpi_video_bus_write_POST(struct file *file,
|
||||
const char __user * buffer,
|
||||
size_t count, loff_t * data)
|
||||
{
|
||||
int status;
|
||||
struct seq_file *m = file->private_data;
|
||||
struct acpi_video_bus *video = m->private;
|
||||
char str[12] = { 0 };
|
||||
unsigned long long opt, options;
|
||||
|
||||
|
||||
if (!video || count >= sizeof(str))
|
||||
return -EINVAL;
|
||||
|
||||
status = acpi_video_bus_POST_options(video, &options);
|
||||
if (!ACPI_SUCCESS(status))
|
||||
return -EINVAL;
|
||||
|
||||
if (copy_from_user(str, buffer, count))
|
||||
return -EFAULT;
|
||||
|
||||
str[count] = 0;
|
||||
opt = strtoul(str, NULL, 0);
|
||||
if (opt > 3)
|
||||
return -EFAULT;
|
||||
|
||||
/* just in case an OEM 'forgot' the motherboard... */
|
||||
options |= 1;
|
||||
|
||||
if (options & (1ul << opt)) {
|
||||
status = acpi_video_bus_set_POST(video, opt);
|
||||
if (!ACPI_SUCCESS(status))
|
||||
return -EFAULT;
|
||||
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
acpi_video_bus_write_DOS(struct file *file,
|
||||
const char __user * buffer,
|
||||
size_t count, loff_t * data)
|
||||
{
|
||||
int status;
|
||||
struct seq_file *m = file->private_data;
|
||||
struct acpi_video_bus *video = m->private;
|
||||
char str[12] = { 0 };
|
||||
unsigned long opt;
|
||||
|
||||
|
||||
if (!video || count >= sizeof(str))
|
||||
return -EINVAL;
|
||||
|
||||
if (copy_from_user(str, buffer, count))
|
||||
return -EFAULT;
|
||||
|
||||
str[count] = 0;
|
||||
opt = strtoul(str, NULL, 0);
|
||||
if (opt > 7)
|
||||
return -EFAULT;
|
||||
|
||||
status = acpi_video_bus_DOS(video, opt & 0x3, (opt & 0x4) >> 2);
|
||||
|
||||
if (!ACPI_SUCCESS(status))
|
||||
return -EFAULT;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static int acpi_video_bus_add_fs(struct acpi_device *device)
|
||||
{
|
||||
struct acpi_video_bus *video = acpi_driver_data(device);
|
||||
struct proc_dir_entry *device_dir;
|
||||
struct proc_dir_entry *entry;
|
||||
|
||||
device_dir = proc_mkdir(acpi_device_bid(device), acpi_video_dir);
|
||||
if (!device_dir)
|
||||
return -ENOMEM;
|
||||
|
||||
/* 'info' [R] */
|
||||
entry = proc_create_data("info", S_IRUGO, device_dir,
|
||||
&acpi_video_bus_info_fops,
|
||||
acpi_driver_data(device));
|
||||
if (!entry)
|
||||
goto err_remove_dir;
|
||||
|
||||
/* 'ROM' [R] */
|
||||
entry = proc_create_data("ROM", S_IRUGO, device_dir,
|
||||
&acpi_video_bus_ROM_fops,
|
||||
acpi_driver_data(device));
|
||||
if (!entry)
|
||||
goto err_remove_info;
|
||||
|
||||
/* 'POST_info' [R] */
|
||||
entry = proc_create_data("POST_info", S_IRUGO, device_dir,
|
||||
&acpi_video_bus_POST_info_fops,
|
||||
acpi_driver_data(device));
|
||||
if (!entry)
|
||||
goto err_remove_rom;
|
||||
|
||||
/* 'POST' [R/W] */
|
||||
entry = proc_create_data("POST", S_IFREG | S_IRUGO | S_IWUSR,
|
||||
device_dir,
|
||||
&acpi_video_bus_POST_fops,
|
||||
acpi_driver_data(device));
|
||||
if (!entry)
|
||||
goto err_remove_post_info;
|
||||
|
||||
/* 'DOS' [R/W] */
|
||||
entry = proc_create_data("DOS", S_IFREG | S_IRUGO | S_IWUSR,
|
||||
device_dir,
|
||||
&acpi_video_bus_DOS_fops,
|
||||
acpi_driver_data(device));
|
||||
if (!entry)
|
||||
goto err_remove_post;
|
||||
|
||||
video->dir = acpi_device_dir(device) = device_dir;
|
||||
return 0;
|
||||
|
||||
err_remove_post:
|
||||
remove_proc_entry("POST", device_dir);
|
||||
err_remove_post_info:
|
||||
remove_proc_entry("POST_info", device_dir);
|
||||
err_remove_rom:
|
||||
remove_proc_entry("ROM", device_dir);
|
||||
err_remove_info:
|
||||
remove_proc_entry("info", device_dir);
|
||||
err_remove_dir:
|
||||
remove_proc_entry(acpi_device_bid(device), acpi_video_dir);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
static int acpi_video_bus_remove_fs(struct acpi_device *device)
|
||||
{
|
||||
struct proc_dir_entry *device_dir = acpi_device_dir(device);
|
||||
|
||||
if (device_dir) {
|
||||
remove_proc_entry("info", device_dir);
|
||||
remove_proc_entry("ROM", device_dir);
|
||||
remove_proc_entry("POST_info", device_dir);
|
||||
remove_proc_entry("POST", device_dir);
|
||||
remove_proc_entry("DOS", device_dir);
|
||||
remove_proc_entry(acpi_device_bid(device), acpi_video_dir);
|
||||
acpi_device_dir(device) = NULL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
static inline int acpi_video_device_add_fs(struct acpi_device *device)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline int acpi_video_device_remove_fs(struct acpi_device *device)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline int acpi_video_bus_add_fs(struct acpi_device *device)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline int acpi_video_bus_remove_fs(struct acpi_device *device)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_ACPI_PROCFS */
|
||||
|
||||
/* --------------------------------------------------------------------------
|
||||
Driver Interface
|
||||
-------------------------------------------------------------------------- */
|
||||
@ -1877,8 +1130,6 @@ acpi_video_bus_get_one_device(struct acpi_device *device,
|
||||
list_add_tail(&data->entry, &video->video_device_list);
|
||||
mutex_unlock(&video->device_list_lock);
|
||||
|
||||
acpi_video_device_add_fs(device);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2181,8 +1432,6 @@ static int acpi_video_bus_put_one_device(struct acpi_video_device *device)
|
||||
if (!device || !device->video)
|
||||
return -ENOENT;
|
||||
|
||||
acpi_video_device_remove_fs(device->dev);
|
||||
|
||||
status = acpi_remove_notify_handler(device->dev->handle,
|
||||
ACPI_DEVICE_NOTIFY,
|
||||
acpi_video_device_notify);
|
||||
@ -2466,10 +1715,6 @@ static int acpi_video_bus_add(struct acpi_device *device)
|
||||
if (error)
|
||||
goto err_free_video;
|
||||
|
||||
error = acpi_video_bus_add_fs(device);
|
||||
if (error)
|
||||
goto err_free_video;
|
||||
|
||||
mutex_init(&video->device_list_lock);
|
||||
INIT_LIST_HEAD(&video->video_device_list);
|
||||
|
||||
@ -2522,7 +1767,6 @@ static int acpi_video_bus_add(struct acpi_device *device)
|
||||
acpi_video_bus_stop_devices(video);
|
||||
acpi_video_bus_put_devices(video);
|
||||
kfree(video->attached_array);
|
||||
acpi_video_bus_remove_fs(device);
|
||||
err_free_video:
|
||||
kfree(video);
|
||||
device->driver_data = NULL;
|
||||
@ -2544,7 +1788,6 @@ static int acpi_video_bus_remove(struct acpi_device *device, int type)
|
||||
|
||||
acpi_video_bus_stop_devices(video);
|
||||
acpi_video_bus_put_devices(video);
|
||||
acpi_video_bus_remove_fs(device);
|
||||
|
||||
input_unregister_device(video->input);
|
||||
kfree(video->attached_array);
|
||||
@ -2584,17 +1827,9 @@ int acpi_video_register(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ACPI_PROCFS
|
||||
acpi_video_dir = proc_mkdir(ACPI_VIDEO_CLASS, acpi_root_dir);
|
||||
if (!acpi_video_dir)
|
||||
return -ENODEV;
|
||||
#endif
|
||||
|
||||
result = acpi_bus_register_driver(&acpi_video_bus);
|
||||
if (result < 0) {
|
||||
remove_proc_entry(ACPI_VIDEO_CLASS, acpi_root_dir);
|
||||
if (result < 0)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/*
|
||||
* When the acpi_video_bus is loaded successfully, increase
|
||||
@ -2617,10 +1852,6 @@ void acpi_video_unregister(void)
|
||||
}
|
||||
acpi_bus_unregister_driver(&acpi_video_bus);
|
||||
|
||||
#ifdef CONFIG_ACPI_PROCFS
|
||||
remove_proc_entry(ACPI_VIDEO_CLASS, acpi_root_dir);
|
||||
#endif
|
||||
|
||||
register_count = 0;
|
||||
|
||||
return;
|
||||
|
@ -12,11 +12,12 @@ void pnp_unregister_protocol(struct pnp_protocol *protocol);
|
||||
|
||||
#define PNP_EISA_ID_MASK 0x7fffffff
|
||||
void pnp_eisa_id_to_string(u32 id, char *str);
|
||||
struct pnp_dev *pnp_alloc_dev(struct pnp_protocol *, int id, char *pnpid);
|
||||
struct pnp_dev *pnp_alloc_dev(struct pnp_protocol *, int id,
|
||||
const char *pnpid);
|
||||
struct pnp_card *pnp_alloc_card(struct pnp_protocol *, int id, char *pnpid);
|
||||
|
||||
int pnp_add_device(struct pnp_dev *dev);
|
||||
struct pnp_id *pnp_add_id(struct pnp_dev *dev, char *id);
|
||||
struct pnp_id *pnp_add_id(struct pnp_dev *dev, const char *id);
|
||||
|
||||
int pnp_add_card(struct pnp_card *card);
|
||||
void pnp_remove_card(struct pnp_card *card);
|
||||
|
@ -124,7 +124,8 @@ static void pnp_release_device(struct device *dmdev)
|
||||
kfree(dev);
|
||||
}
|
||||
|
||||
struct pnp_dev *pnp_alloc_dev(struct pnp_protocol *protocol, int id, char *pnpid)
|
||||
struct pnp_dev *pnp_alloc_dev(struct pnp_protocol *protocol, int id,
|
||||
const char *pnpid)
|
||||
{
|
||||
struct pnp_dev *dev;
|
||||
struct pnp_id *dev_id;
|
||||
@ -194,8 +195,9 @@ int pnp_add_device(struct pnp_dev *dev)
|
||||
for (id = dev->id; id; id = id->next)
|
||||
len += scnprintf(buf + len, sizeof(buf) - len, " %s", id->id);
|
||||
|
||||
pnp_dbg(&dev->dev, "%s device, IDs%s (%s)\n",
|
||||
dev->protocol->name, buf, dev->active ? "active" : "disabled");
|
||||
dev_printk(KERN_DEBUG, &dev->dev, "%s device, IDs%s (%s)\n",
|
||||
dev->protocol->name, buf,
|
||||
dev->active ? "active" : "disabled");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -236,7 +236,7 @@ void pnp_unregister_driver(struct pnp_driver *drv)
|
||||
* @dev: pointer to the desired device
|
||||
* @id: pointer to an EISA id string
|
||||
*/
|
||||
struct pnp_id *pnp_add_id(struct pnp_dev *dev, char *id)
|
||||
struct pnp_id *pnp_add_id(struct pnp_dev *dev, const char *id)
|
||||
{
|
||||
struct pnp_id *dev_id, *ptr;
|
||||
|
||||
|
@ -28,7 +28,7 @@
|
||||
#include "../base.h"
|
||||
#include "pnpacpi.h"
|
||||
|
||||
static int num = 0;
|
||||
static int num;
|
||||
|
||||
/* We need only to blacklist devices that have already an acpi driver that
|
||||
* can't use pnp layer. We don't need to blacklist device that are directly
|
||||
@ -59,7 +59,7 @@ static inline int __init is_exclusive_device(struct acpi_device *dev)
|
||||
#define TEST_ALPHA(c) \
|
||||
if (!('@' <= (c) || (c) <= 'Z')) \
|
||||
return 0
|
||||
static int __init ispnpidacpi(char *id)
|
||||
static int __init ispnpidacpi(const char *id)
|
||||
{
|
||||
TEST_ALPHA(id[0]);
|
||||
TEST_ALPHA(id[1]);
|
||||
@ -180,11 +180,24 @@ struct pnp_protocol pnpacpi_protocol = {
|
||||
};
|
||||
EXPORT_SYMBOL(pnpacpi_protocol);
|
||||
|
||||
static char *pnpacpi_get_id(struct acpi_device *device)
|
||||
{
|
||||
struct acpi_hardware_id *id;
|
||||
|
||||
list_for_each_entry(id, &device->pnp.ids, list) {
|
||||
if (ispnpidacpi(id->id))
|
||||
return id->id;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int __init pnpacpi_add_device(struct acpi_device *device)
|
||||
{
|
||||
acpi_handle temp = NULL;
|
||||
acpi_status status;
|
||||
struct pnp_dev *dev;
|
||||
char *pnpid;
|
||||
struct acpi_hardware_id *id;
|
||||
|
||||
/*
|
||||
@ -192,11 +205,17 @@ static int __init pnpacpi_add_device(struct acpi_device *device)
|
||||
* driver should not be loaded.
|
||||
*/
|
||||
status = acpi_get_handle(device->handle, "_CRS", &temp);
|
||||
if (ACPI_FAILURE(status) || !ispnpidacpi(acpi_device_hid(device)) ||
|
||||
is_exclusive_device(device) || (!device->status.present))
|
||||
if (ACPI_FAILURE(status))
|
||||
return 0;
|
||||
|
||||
dev = pnp_alloc_dev(&pnpacpi_protocol, num, acpi_device_hid(device));
|
||||
pnpid = pnpacpi_get_id(device);
|
||||
if (!pnpid)
|
||||
return 0;
|
||||
|
||||
if (is_exclusive_device(device) || !device->status.present)
|
||||
return 0;
|
||||
|
||||
dev = pnp_alloc_dev(&pnpacpi_protocol, num, pnpid);
|
||||
if (!dev)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -227,7 +246,7 @@ static int __init pnpacpi_add_device(struct acpi_device *device)
|
||||
pnpacpi_parse_resource_option_data(dev);
|
||||
|
||||
list_for_each_entry(id, &device->pnp.ids, list) {
|
||||
if (!strcmp(id->id, acpi_device_hid(device)))
|
||||
if (!strcmp(id->id, pnpid))
|
||||
continue;
|
||||
if (!ispnpidacpi(id->id))
|
||||
continue;
|
||||
|
@ -523,7 +523,7 @@ struct pnp_resource *pnp_add_irq_resource(struct pnp_dev *dev, int irq,
|
||||
res->start = irq;
|
||||
res->end = irq;
|
||||
|
||||
pnp_dbg(&dev->dev, " add %pr\n", res);
|
||||
dev_printk(KERN_DEBUG, &dev->dev, "%pR\n", res);
|
||||
return pnp_res;
|
||||
}
|
||||
|
||||
@ -544,7 +544,7 @@ struct pnp_resource *pnp_add_dma_resource(struct pnp_dev *dev, int dma,
|
||||
res->start = dma;
|
||||
res->end = dma;
|
||||
|
||||
pnp_dbg(&dev->dev, " add %pr\n", res);
|
||||
dev_printk(KERN_DEBUG, &dev->dev, "%pR\n", res);
|
||||
return pnp_res;
|
||||
}
|
||||
|
||||
@ -568,7 +568,7 @@ struct pnp_resource *pnp_add_io_resource(struct pnp_dev *dev,
|
||||
res->start = start;
|
||||
res->end = end;
|
||||
|
||||
pnp_dbg(&dev->dev, " add %pr\n", res);
|
||||
dev_printk(KERN_DEBUG, &dev->dev, "%pR\n", res);
|
||||
return pnp_res;
|
||||
}
|
||||
|
||||
@ -592,7 +592,7 @@ struct pnp_resource *pnp_add_mem_resource(struct pnp_dev *dev,
|
||||
res->start = start;
|
||||
res->end = end;
|
||||
|
||||
pnp_dbg(&dev->dev, " add %pr\n", res);
|
||||
dev_printk(KERN_DEBUG, &dev->dev, "%pR\n", res);
|
||||
return pnp_res;
|
||||
}
|
||||
|
||||
@ -616,7 +616,7 @@ struct pnp_resource *pnp_add_bus_resource(struct pnp_dev *dev,
|
||||
res->start = start;
|
||||
res->end = end;
|
||||
|
||||
pnp_dbg(&dev->dev, " add %pr\n", res);
|
||||
dev_printk(KERN_DEBUG, &dev->dev, "%pR\n", res);
|
||||
return pnp_res;
|
||||
}
|
||||
|
||||
|
@ -184,7 +184,7 @@ struct acpi_device_pnp {
|
||||
|
||||
#define acpi_device_bid(d) ((d)->pnp.bus_id)
|
||||
#define acpi_device_adr(d) ((d)->pnp.bus_address)
|
||||
char *acpi_device_hid(struct acpi_device *device);
|
||||
const char *acpi_device_hid(struct acpi_device *device);
|
||||
#define acpi_device_name(d) ((d)->pnp.device_name)
|
||||
#define acpi_device_class(d) ((d)->pnp.device_class)
|
||||
|
||||
@ -389,21 +389,25 @@ struct acpi_pci_root *acpi_pci_find_root(acpi_handle handle);
|
||||
int acpi_enable_wakeup_device_power(struct acpi_device *dev, int state);
|
||||
int acpi_disable_wakeup_device_power(struct acpi_device *dev);
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
#ifdef CONFIG_PM_OPS
|
||||
int acpi_pm_device_sleep_state(struct device *, int *);
|
||||
int acpi_pm_device_sleep_wake(struct device *, bool);
|
||||
#else /* !CONFIG_PM_SLEEP */
|
||||
#else
|
||||
static inline int acpi_pm_device_sleep_state(struct device *d, int *p)
|
||||
{
|
||||
if (p)
|
||||
*p = ACPI_STATE_D0;
|
||||
return ACPI_STATE_D3;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
int acpi_pm_device_sleep_wake(struct device *, bool);
|
||||
#else
|
||||
static inline int acpi_pm_device_sleep_wake(struct device *dev, bool enable)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
#endif /* !CONFIG_PM_SLEEP */
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_ACPI */
|
||||
|
||||
|
@ -115,8 +115,6 @@ void pci_acpi_crs_quirks(void);
|
||||
#define ACPI_PROCESSOR_LIMIT_INCREMENT 0x01
|
||||
#define ACPI_PROCESSOR_LIMIT_DECREMENT 0x02
|
||||
|
||||
int acpi_processor_set_thermal_limit(acpi_handle handle, int type);
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
Dock Station
|
||||
-------------------------------------------------------------------------- */
|
||||
|
@ -98,8 +98,6 @@ acpi_os_table_override(struct acpi_table_header *existing_table,
|
||||
/*
|
||||
* Spinlock primitives
|
||||
*/
|
||||
acpi_status acpi_os_create_lock(acpi_spinlock * out_handle);
|
||||
|
||||
void acpi_os_delete_lock(acpi_spinlock handle);
|
||||
|
||||
acpi_cpu_flags acpi_os_acquire_lock(acpi_spinlock handle);
|
||||
@ -223,25 +221,15 @@ acpi_os_write_memory(acpi_physical_address address, u32 value, u32 width);
|
||||
*/
|
||||
acpi_status
|
||||
acpi_os_read_pci_configuration(struct acpi_pci_id *pci_id,
|
||||
u32 reg, u32 *value, u32 width);
|
||||
u32 reg, u64 *value, u32 width);
|
||||
|
||||
acpi_status
|
||||
acpi_os_write_pci_configuration(struct acpi_pci_id *pci_id,
|
||||
u32 reg, u64 value, u32 width);
|
||||
|
||||
/*
|
||||
* Interim function needed for PCI IRQ routing
|
||||
*/
|
||||
void
|
||||
acpi_os_derive_pci_id(acpi_handle device,
|
||||
acpi_handle region, struct acpi_pci_id **pci_id);
|
||||
|
||||
/*
|
||||
* Miscellaneous
|
||||
*/
|
||||
acpi_status acpi_os_validate_interface(char *interface);
|
||||
acpi_status acpi_osi_invalidate(char* interface);
|
||||
|
||||
acpi_status
|
||||
acpi_os_validate_address(u8 space_id, acpi_physical_address address,
|
||||
acpi_size length, char *name);
|
||||
|
@ -47,7 +47,7 @@
|
||||
|
||||
/* Current ACPICA subsystem version in YYYYMMDD format */
|
||||
|
||||
#define ACPI_CA_VERSION 0x20100702
|
||||
#define ACPI_CA_VERSION 0x20101013
|
||||
|
||||
#include "actypes.h"
|
||||
#include "actbl.h"
|
||||
@ -72,6 +72,7 @@ extern u8 acpi_gbl_truncate_io_addresses;
|
||||
|
||||
extern u32 acpi_current_gpe_count;
|
||||
extern struct acpi_table_fadt acpi_gbl_FADT;
|
||||
extern u8 acpi_gbl_system_awake_and_running;
|
||||
|
||||
extern u32 acpi_rsdt_forced;
|
||||
/*
|
||||
@ -105,6 +106,10 @@ const char *acpi_format_exception(acpi_status exception);
|
||||
|
||||
acpi_status acpi_purge_cached_objects(void);
|
||||
|
||||
acpi_status acpi_install_interface(acpi_string interface_name);
|
||||
|
||||
acpi_status acpi_remove_interface(acpi_string interface_name);
|
||||
|
||||
/*
|
||||
* ACPI Memory management
|
||||
*/
|
||||
@ -263,6 +268,8 @@ acpi_remove_gpe_handler(acpi_handle gpe_device,
|
||||
acpi_status acpi_install_exception_handler(acpi_exception_handler handler);
|
||||
#endif
|
||||
|
||||
acpi_status acpi_install_interface_handler(acpi_interface_handler handler);
|
||||
|
||||
/*
|
||||
* Event interfaces
|
||||
*/
|
||||
@ -308,6 +315,8 @@ acpi_install_gpe_block(acpi_handle gpe_device,
|
||||
|
||||
acpi_status acpi_remove_gpe_block(acpi_handle gpe_device);
|
||||
|
||||
acpi_status acpi_update_gpes(void);
|
||||
|
||||
/*
|
||||
* Resource interfaces
|
||||
*/
|
||||
|
@ -115,7 +115,6 @@
|
||||
*
|
||||
* ACPI_SIZE 16/32/64-bit unsigned value
|
||||
* ACPI_NATIVE_INT 16/32/64-bit signed value
|
||||
*
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
@ -132,6 +131,16 @@ typedef COMPILER_DEPENDENT_INT64 INT64;
|
||||
|
||||
/*! [End] no source code translation !*/
|
||||
|
||||
/*
|
||||
* Value returned by acpi_os_get_thread_id. There is no standard "thread_id"
|
||||
* across operating systems or even the various UNIX systems. Since ACPICA
|
||||
* only needs the thread ID as a unique thread identifier, we use a u64
|
||||
* as the only common data type - it will accommodate any type of pointer or
|
||||
* any type of integer. It is up to the host-dependent OSL to cast the
|
||||
* native thread ID type to a u64 (in acpi_os_get_thread_id).
|
||||
*/
|
||||
#define acpi_thread_id u64
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Types specific to 64-bit targets
|
||||
@ -211,12 +220,6 @@ typedef u32 acpi_physical_address;
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/* Value returned by acpi_os_get_thread_id */
|
||||
|
||||
#ifndef acpi_thread_id
|
||||
#define acpi_thread_id acpi_size
|
||||
#endif
|
||||
|
||||
/* Flags for acpi_os_acquire_lock/acpi_os_release_lock */
|
||||
|
||||
#ifndef acpi_cpu_flags
|
||||
@ -375,16 +378,6 @@ typedef void *acpi_handle; /* Actually a ptr to a NS Node */
|
||||
typedef u8 acpi_owner_id;
|
||||
#define ACPI_OWNER_ID_MAX 0xFF
|
||||
|
||||
struct uint64_struct {
|
||||
u32 lo;
|
||||
u32 hi;
|
||||
};
|
||||
|
||||
union uint64_overlay {
|
||||
u64 full;
|
||||
struct uint64_struct part;
|
||||
};
|
||||
|
||||
#define ACPI_INTEGER_BIT_SIZE 64
|
||||
#define ACPI_MAX_DECIMAL_DIGITS 20 /* 2^64 = 18,446,744,073,709,551,616 */
|
||||
|
||||
@ -950,6 +943,9 @@ acpi_status(*acpi_walk_callback) (acpi_handle object,
|
||||
u32 nesting_level,
|
||||
void *context, void **return_value);
|
||||
|
||||
typedef
|
||||
u32 (*acpi_interface_handler) (acpi_string interface_name, u32 supported);
|
||||
|
||||
/* Interrupt handler return values */
|
||||
|
||||
#define ACPI_INTERRUPT_NOT_HANDLED 0x00
|
||||
|
@ -193,6 +193,12 @@
|
||||
#define ACPI_MUTEX_TYPE ACPI_BINARY_SEMAPHORE
|
||||
#endif
|
||||
|
||||
/* "inline" keywords - configurable since inline is not standardized */
|
||||
|
||||
#ifndef ACPI_INLINE
|
||||
#define ACPI_INLINE
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Debugger threading model
|
||||
* Use single threaded if the entire subsystem is contained in an application
|
||||
|
@ -44,6 +44,8 @@
|
||||
#ifndef __ACGCC_H__
|
||||
#define __ACGCC_H__
|
||||
|
||||
#define ACPI_INLINE __inline__
|
||||
|
||||
/* Function name is used for debug output. Non-ANSI, compiler-dependent */
|
||||
|
||||
#define ACPI_GET_FUNCTION_NAME __func__
|
||||
|
@ -75,7 +75,6 @@
|
||||
#define acpi_cache_t struct kmem_cache
|
||||
#define acpi_spinlock spinlock_t *
|
||||
#define acpi_cpu_flags unsigned long
|
||||
#define acpi_thread_id struct task_struct *
|
||||
|
||||
#else /* !__KERNEL__ */
|
||||
|
||||
@ -88,7 +87,7 @@
|
||||
/* Host-dependent types and defines for user-space ACPICA */
|
||||
|
||||
#define ACPI_FLUSH_CPU_CACHE()
|
||||
#define acpi_thread_id pthread_t
|
||||
#define ACPI_CAST_PTHREAD_T(pthread) ((acpi_thread_id) (pthread))
|
||||
|
||||
#if defined(__ia64__) || defined(__x86_64__)
|
||||
#define ACPI_MACHINE_WIDTH 64
|
||||
@ -113,12 +112,13 @@
|
||||
|
||||
|
||||
#ifdef __KERNEL__
|
||||
#include <acpi/actypes.h>
|
||||
/*
|
||||
* Overrides for in-kernel ACPICA
|
||||
*/
|
||||
static inline acpi_thread_id acpi_os_get_thread_id(void)
|
||||
{
|
||||
return current;
|
||||
return (acpi_thread_id)(unsigned long)current;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -127,7 +127,6 @@ static inline acpi_thread_id acpi_os_get_thread_id(void)
|
||||
* However, boot has (system_state != SYSTEM_RUNNING)
|
||||
* to quiet __might_sleep() in kmalloc() and resume does not.
|
||||
*/
|
||||
#include <acpi/actypes.h>
|
||||
static inline void *acpi_os_allocate(acpi_size size)
|
||||
{
|
||||
return kmalloc(size, irqs_disabled() ? GFP_ATOMIC : GFP_KERNEL);
|
||||
|
@ -245,8 +245,6 @@ int acpi_check_resource_conflict(const struct resource *res);
|
||||
|
||||
int acpi_check_region(resource_size_t start, resource_size_t n,
|
||||
const char *name);
|
||||
int acpi_check_mem_region(resource_size_t start, resource_size_t n,
|
||||
const char *name);
|
||||
|
||||
int acpi_resources_are_enforced(void);
|
||||
|
||||
@ -308,6 +306,9 @@ extern acpi_status acpi_pci_osc_control_set(acpi_handle handle,
|
||||
u32 *mask, u32 req);
|
||||
extern void acpi_early_init(void);
|
||||
|
||||
int acpi_os_map_generic_address(struct acpi_generic_address *addr);
|
||||
void acpi_os_unmap_generic_address(struct acpi_generic_address *addr);
|
||||
|
||||
#else /* !CONFIG_ACPI */
|
||||
|
||||
#define acpi_disabled 1
|
||||
@ -344,12 +345,6 @@ static inline int acpi_check_region(resource_size_t start, resource_size_t n,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int acpi_check_mem_region(resource_size_t start,
|
||||
resource_size_t n, const char *name)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct acpi_table_header;
|
||||
static inline int acpi_table_parse(char *id,
|
||||
int (*handler)(struct acpi_table_header *))
|
||||
|
Loading…
Reference in New Issue
Block a user