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:
Linus Torvalds 2010-10-26 17:28:37 -07:00
commit 474829e875
78 changed files with 2431 additions and 2721 deletions

View File

@ -243,21 +243,6 @@ F: drivers/pnp/pnpacpi/
F: include/linux/acpi.h F: include/linux/acpi.h
F: include/acpi/ 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 ACPI FAN DRIVER
M: Zhang Rui <rui.zhang@intel.com> M: Zhang Rui <rui.zhang@intel.com>
L: linux-acpi@vger.kernel.org L: linux-acpi@vger.kernel.org

View File

@ -701,6 +701,7 @@ static int acpi_cpufreq_cpu_exit(struct cpufreq_policy *policy)
per_cpu(acfreq_data, policy->cpu) = NULL; per_cpu(acfreq_data, policy->cpu) = NULL;
acpi_processor_unregister_performance(data->acpi_data, acpi_processor_unregister_performance(data->acpi_data,
policy->cpu); policy->cpu);
kfree(data->freq_table);
kfree(data); kfree(data);
} }

View File

@ -9,7 +9,6 @@ menuconfig ACPI
depends on PCI depends on PCI
depends on PM depends on PM
select PNP select PNP
select CPU_IDLE
default y default y
help help
Advanced Configuration and Power Interface (ACPI) support for Advanced Configuration and Power Interface (ACPI) support for
@ -66,7 +65,6 @@ config ACPI_PROCFS
config ACPI_PROCFS_POWER config ACPI_PROCFS_POWER
bool "Deprecated power /proc/acpi directories" bool "Deprecated power /proc/acpi directories"
depends on PROC_FS depends on PROC_FS
default y
help help
For backwards compatibility, this option allows For backwards compatibility, this option allows
deprecated power /proc/acpi/ directories to exist, even when 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: To compile this driver as a module, choose M here:
the module will be called power-meter. 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 config ACPI_EC_DEBUGFS
tristate "EC read/write access through /sys/kernel/debug/ec" tristate "EC read/write access through /sys/kernel/debug/ec"
default n default n
@ -136,6 +127,7 @@ config ACPI_PROC_EVENT
config ACPI_AC config ACPI_AC
tristate "AC Adapter" tristate "AC Adapter"
depends on X86 depends on X86
select POWER_SUPPLY
default y default y
help help
This driver supports the AC Adapter object, which indicates This driver supports the AC Adapter object, which indicates
@ -148,6 +140,7 @@ config ACPI_AC
config ACPI_BATTERY config ACPI_BATTERY
tristate "Battery" tristate "Battery"
depends on X86 depends on X86
select POWER_SUPPLY
default y default y
help help
This driver adds support for battery information through This driver adds support for battery information through
@ -206,6 +199,7 @@ config ACPI_DOCK
config ACPI_PROCESSOR config ACPI_PROCESSOR
tristate "Processor" tristate "Processor"
select THERMAL select THERMAL
select CPU_IDLE
default y default y
help help
This driver installs ACPI as the idle handler for Linux and uses This driver installs ACPI as the idle handler for Linux and uses
@ -364,6 +358,7 @@ config ACPI_HOTPLUG_MEMORY
config ACPI_SBS config ACPI_SBS
tristate "Smart Battery System" tristate "Smart Battery System"
depends on X86 depends on X86
select POWER_SUPPLY
help help
This driver supports the Smart Battery System, another This driver supports the Smart Battery System, another
type of access to battery information, found on some laptops. type of access to battery information, found on some laptops.

View File

@ -32,9 +32,7 @@
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/seq_file.h> #include <linux/seq_file.h>
#endif #endif
#ifdef CONFIG_ACPI_SYSFS_POWER
#include <linux/power_supply.h> #include <linux/power_supply.h>
#endif
#include <acpi/acpi_bus.h> #include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h> #include <acpi/acpi_drivers.h>
@ -86,9 +84,7 @@ static struct acpi_driver acpi_ac_driver = {
}; };
struct acpi_ac { struct acpi_ac {
#ifdef CONFIG_ACPI_SYSFS_POWER
struct power_supply charger; struct power_supply charger;
#endif
struct acpi_device * device; struct acpi_device * device;
unsigned long long state; unsigned long long state;
}; };
@ -104,7 +100,6 @@ static const struct file_operations acpi_ac_fops = {
.release = single_release, .release = single_release,
}; };
#endif #endif
#ifdef CONFIG_ACPI_SYSFS_POWER
static int get_ac_property(struct power_supply *psy, static int get_ac_property(struct power_supply *psy,
enum power_supply_property psp, enum power_supply_property psp,
union power_supply_propval *val) 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[] = { static enum power_supply_property ac_props[] = {
POWER_SUPPLY_PROP_ONLINE, POWER_SUPPLY_PROP_ONLINE,
}; };
#endif
/* -------------------------------------------------------------------------- /* --------------------------------------------------------------------------
AC Adapter Management AC Adapter Management
-------------------------------------------------------------------------- */ -------------------------------------------------------------------------- */
@ -247,9 +241,7 @@ static void acpi_ac_notify(struct acpi_device *device, u32 event)
dev_name(&device->dev), event, dev_name(&device->dev), event,
(u32) ac->state); (u32) ac->state);
acpi_notifier_call_chain(device, 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); kobject_uevent(&ac->charger.dev->kobj, KOBJ_CHANGE);
#endif
} }
return; return;
@ -282,14 +274,12 @@ static int acpi_ac_add(struct acpi_device *device)
#endif #endif
if (result) if (result)
goto end; goto end;
#ifdef CONFIG_ACPI_SYSFS_POWER
ac->charger.name = acpi_device_bid(device); ac->charger.name = acpi_device_bid(device);
ac->charger.type = POWER_SUPPLY_TYPE_MAINS; ac->charger.type = POWER_SUPPLY_TYPE_MAINS;
ac->charger.properties = ac_props; ac->charger.properties = ac_props;
ac->charger.num_properties = ARRAY_SIZE(ac_props); ac->charger.num_properties = ARRAY_SIZE(ac_props);
ac->charger.get_property = get_ac_property; ac->charger.get_property = get_ac_property;
power_supply_register(&ac->device->dev, &ac->charger); power_supply_register(&ac->device->dev, &ac->charger);
#endif
printk(KERN_INFO PREFIX "%s [%s] (%s)\n", printk(KERN_INFO PREFIX "%s [%s] (%s)\n",
acpi_device_name(device), acpi_device_bid(device), 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; old_state = ac->state;
if (acpi_ac_get_state(ac)) if (acpi_ac_get_state(ac))
return 0; return 0;
#ifdef CONFIG_ACPI_SYSFS_POWER
if (old_state != ac->state) if (old_state != ac->state)
kobject_uevent(&ac->charger.dev->kobj, KOBJ_CHANGE); kobject_uevent(&ac->charger.dev->kobj, KOBJ_CHANGE);
#endif
return 0; return 0;
} }
@ -333,10 +321,8 @@ static int acpi_ac_remove(struct acpi_device *device, int type)
ac = acpi_driver_data(device); ac = acpi_driver_data(device);
#ifdef CONFIG_ACPI_SYSFS_POWER
if (ac->charger.dev) if (ac->charger.dev)
power_supply_unregister(&ac->charger); power_supply_unregister(&ac->charger);
#endif
#ifdef CONFIG_ACPI_PROCFS_POWER #ifdef CONFIG_ACPI_PROCFS_POWER
acpi_ac_remove_fs(device); acpi_ac_remove_fs(device);
#endif #endif

View File

@ -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 \ excreate.o exmisc.o exoparg2.o exregion.o exstore.o exutils.o \
exdump.o exmutex.o exoparg3.o exresnte.o exstoren.o exdebug.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 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 \ acpi-y += utalloc.o utdebug.o uteval.o utinit.o utmisc.o utxface.o \
utcopy.o utdelete.o utglobal.o utmath.o utobject.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

View File

@ -105,6 +105,8 @@ void acpi_db_set_method_data(char *type_arg, char *index_arg, char *value_arg);
acpi_status acpi_status
acpi_db_display_objects(char *obj_type_arg, char *display_count_arg); 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); acpi_status acpi_db_find_name_in_namespace(char *name_arg);
void acpi_db_set_scope(char *name); void acpi_db_set_scope(char *name);

View File

@ -105,8 +105,9 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device,
struct acpi_gpe_block_info **return_gpe_block); struct acpi_gpe_block_info **return_gpe_block);
acpi_status acpi_status
acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device, acpi_ev_initialize_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
struct acpi_gpe_block_info *gpe_block); struct acpi_gpe_block_info *gpe_block,
void *ignored);
acpi_status acpi_ev_delete_gpe_block(struct acpi_gpe_block_info *gpe_block); acpi_status acpi_ev_delete_gpe_block(struct acpi_gpe_block_info *gpe_block);

View File

@ -132,6 +132,7 @@ struct acpi_table_fadt acpi_gbl_FADT;
u32 acpi_current_gpe_count; u32 acpi_current_gpe_count;
u32 acpi_gbl_trace_flags; u32 acpi_gbl_trace_flags;
acpi_name acpi_gbl_trace_method_name; acpi_name acpi_gbl_trace_method_name;
u8 acpi_gbl_system_awake_and_running;
#endif #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_byte_width;
ACPI_EXTERN u8 acpi_gbl_integer_nybble_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 */ /* Reader/Writer lock is used for namespace walk and dynamic table unload */
ACPI_EXTERN struct acpi_rw_lock acpi_gbl_namespace_rw_lock; 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 acpi_tbl_handler acpi_gbl_table_handler;
ACPI_EXTERN void *acpi_gbl_table_handler_context; ACPI_EXTERN void *acpi_gbl_table_handler_context;
ACPI_EXTERN struct acpi_walk_state *acpi_gbl_breakpoint_walk; ACPI_EXTERN struct acpi_walk_state *acpi_gbl_breakpoint_walk;
ACPI_EXTERN acpi_interface_handler acpi_gbl_interface_handler;
/* Owner ID support */ /* 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_step_to_next_call;
ACPI_EXTERN u8 acpi_gbl_acpi_hardware_present; ACPI_EXTERN u8 acpi_gbl_acpi_hardware_present;
ACPI_EXTERN u8 acpi_gbl_events_initialized; 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 u8 acpi_gbl_osi_data;
ACPI_EXTERN struct acpi_interface_info *acpi_gbl_supported_interfaces;
#ifndef DEFINE_ACPI_GLOBALS #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_xrupt_info *acpi_gbl_gpe_xrupt_list_head;
ACPI_EXTERN struct acpi_gpe_block_info ACPI_EXTERN struct acpi_gpe_block_info
*acpi_gbl_gpe_fadt_blocks[ACPI_MAX_GPE_BLOCKS]; *acpi_gbl_gpe_fadt_blocks[ACPI_MAX_GPE_BLOCKS];
ACPI_EXTERN u8 acpi_all_gpes_initialized;
/***************************************************************************** /*****************************************************************************
* *

View File

@ -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, struct acpi_gpe_block_info *gpe_block,
void *context); 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 #ifdef ACPI_FUTURE_USAGE
/* /*
* hwtimer - ACPI Timer prototypes * hwtimer - ACPI Timer prototypes

View File

@ -413,6 +413,7 @@ struct acpi_handler_info {
void *context; /* Context to be passed to handler */ void *context; /* Context to be passed to handler */
struct acpi_namespace_node *method_node; /* Method node for this GPE level (saved) */ struct acpi_namespace_node *method_node; /* Method node for this GPE level (saved) */
u8 orig_flags; /* Original misc info about this GPE */ u8 orig_flags; /* Original misc info about this GPE */
u8 orig_enabled; /* Set if the GPE was originally enabled */
}; };
union acpi_gpe_dispatch_info { union acpi_gpe_dispatch_info {
@ -457,6 +458,7 @@ struct acpi_gpe_block_info {
u32 register_count; /* Number of register pairs in block */ u32 register_count; /* Number of register pairs in block */
u16 gpe_count; /* Number of individual GPEs in block */ u16 gpe_count; /* Number of individual GPEs in block */
u8 block_base_number; /* Base GPE number for this 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 */ /* 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; struct acpi_gpe_block_info *gpe_block;
u16 count; u16 count;
acpi_owner_id owner_id; acpi_owner_id owner_id;
u8 enable_this_gpe;
u8 execute_by_owner_id; u8 execute_by_owner_id;
}; };
@ -854,7 +855,7 @@ struct acpi_bit_register_info {
ACPI_BITMASK_POWER_BUTTON_STATUS | \ ACPI_BITMASK_POWER_BUTTON_STATUS | \
ACPI_BITMASK_SLEEP_BUTTON_STATUS | \ ACPI_BITMASK_SLEEP_BUTTON_STATUS | \
ACPI_BITMASK_RT_CLOCK_STATUS | \ ACPI_BITMASK_RT_CLOCK_STATUS | \
ACPI_BITMASK_PCIEXP_WAKE_DISABLE | \ ACPI_BITMASK_PCIEXP_WAKE_STATUS | \
ACPI_BITMASK_WAKE_STATUS) ACPI_BITMASK_WAKE_STATUS)
#define ACPI_BITMASK_TIMER_ENABLE 0x0001 #define ACPI_BITMASK_TIMER_ENABLE 0x0001
@ -909,15 +910,21 @@ struct acpi_bit_register_info {
#define ACPI_OSI_WIN_VISTA 0x07 #define ACPI_OSI_WIN_VISTA 0x07
#define ACPI_OSI_WINSRV_2008 0x08 #define ACPI_OSI_WINSRV_2008 0x08
#define ACPI_OSI_WIN_VISTA_SP1 0x09 #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 #define ACPI_ALWAYS_ILLEGAL 0x00
struct acpi_interface_info { struct acpi_interface_info {
char *name; char *name;
struct acpi_interface_info *next;
u8 flags;
u8 value; u8 value;
}; };
#define ACPI_OSI_INVALID 0x01
#define ACPI_OSI_DYNAMIC 0x02
struct acpi_port_info { struct acpi_port_info {
char *name; char *name;
u16 start; u16 start;
@ -997,7 +1004,7 @@ struct acpi_port_info {
struct acpi_db_method_info { struct acpi_db_method_info {
acpi_handle main_thread_gate; acpi_handle main_thread_gate;
acpi_handle thread_complete_gate; acpi_handle thread_complete_gate;
u32 *threads; acpi_thread_id *threads;
u32 num_threads; u32 num_threads;
u32 num_created; u32 num_created;
u32 num_completed; u32 num_completed;

View File

@ -338,8 +338,8 @@
* the plist contains a set of parens to allow variable-length lists. * 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. * 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_NAMESPACE(s, e) acpi_ut_namespace_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_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_WARN_PREDEFINED(plist) acpi_ut_predefined_warning plist
#define ACPI_INFO_PREDEFINED(plist) acpi_ut_predefined_info plist #define ACPI_INFO_PREDEFINED(plist) acpi_ut_predefined_info plist

View File

@ -338,18 +338,6 @@ acpi_object_type acpi_ns_get_type(struct acpi_namespace_node *node);
u32 acpi_ns_local(acpi_object_type type); 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 void
acpi_ns_print_node_pathname(struct acpi_namespace_node *node, const char *msg); acpi_ns_print_node_pathname(struct acpi_namespace_node *node, const char *msg);

View File

@ -248,7 +248,7 @@ ACPI_OBJECT_COMMON_HEADER ACPI_COMMON_NOTIFY_INFO};
u32 base_byte_offset; /* Byte offset within containing object */\ u32 base_byte_offset; /* Byte offset within containing object */\
u32 value; /* Value to store into the Bank or Index register */\ 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 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) */ 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) */ ACPI_OBJECT_COMMON_HEADER ACPI_COMMON_FIELD_INFO union acpi_operand_object *region_obj; /* Parent Operation Region object (REGION/BANK fields only) */

View File

@ -312,8 +312,6 @@ void acpi_ut_delete_internal_object_list(union acpi_operand_object **obj_list);
/* /*
* uteval - object evaluation * uteval - object evaluation
*/ */
acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state);
acpi_status acpi_status
acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node, acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node,
char *path, char *path,
@ -394,6 +392,21 @@ union acpi_operand_object *acpi_ut_create_string_object(acpi_size string_size);
acpi_status acpi_status
acpi_ut_get_object_size(union acpi_operand_object *obj, acpi_size * obj_length); 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 * 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); 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) */ /* Values for Base above (16=Hex, 10=Decimal) */
#define ACPI_ANY_BASE 0 #define ACPI_ANY_BASE 0
@ -574,6 +576,32 @@ acpi_status
acpi_ut_create_list(char *list_name, acpi_ut_create_list(char *list_name,
u16 object_size, struct acpi_memory_list **return_cache); 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 */ #endif /* _ACUTILS_H */

View File

@ -573,7 +573,7 @@ acpi_ds_terminate_control_method(union acpi_operand_object *method_desc,
acpi_os_release_mutex(method_desc->method. acpi_os_release_mutex(method_desc->method.
mutex->mutex.os_mutex); mutex->mutex.os_mutex);
method_desc->method.mutex->mutex.thread_id = NULL; method_desc->method.mutex->mutex.thread_id = 0;
} }
} }

View File

@ -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 * we must enter this object into the namespace. The created
* object is temporary and will be deleted upon completion of * object is temporary and will be deleted upon completion of
* the execution of this method. * 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; break;
case AML_CLASS_EXECUTE: case AML_CLASS_EXECUTE:

View File

@ -93,47 +93,6 @@ acpi_status acpi_ev_initialize_events(void)
return_ACPI_STATUS(status); 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 * FUNCTION: acpi_ev_install_xrupt_handlers

View File

@ -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->gpe_count = (u16)(register_count * ACPI_GPE_REGISTER_WIDTH);
gpe_block->register_count = register_count; gpe_block->register_count = register_count;
gpe_block->block_base_number = gpe_block_base_number; gpe_block->block_base_number = gpe_block_base_number;
gpe_block->initialized = FALSE;
ACPI_MEMCPY(&gpe_block->block_address, gpe_block_address, ACPI_MEMCPY(&gpe_block->block_address, gpe_block_address,
sizeof(struct acpi_generic_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); return_ACPI_STATUS(status);
} }
acpi_all_gpes_initialized = FALSE;
/* Find all GPE methods (_Lxx or_Exx) for this block */ /* Find all GPE methods (_Lxx or_Exx) for this block */
walk_info.gpe_block = gpe_block; walk_info.gpe_block = gpe_block;
walk_info.gpe_device = gpe_device; walk_info.gpe_device = gpe_device;
walk_info.enable_this_gpe = FALSE;
walk_info.execute_by_owner_id = FALSE; walk_info.execute_by_owner_id = FALSE;
status = acpi_ns_walk_namespace(ACPI_TYPE_METHOD, gpe_device, 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_status
acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device, acpi_ev_initialize_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
struct acpi_gpe_block_info *gpe_block) struct acpi_gpe_block_info *gpe_block,
void *ignored)
{ {
acpi_status status; acpi_status status;
struct acpi_gpe_event_info *gpe_event_info; struct acpi_gpe_event_info *gpe_event_info;
u32 gpe_enabled_count; u32 gpe_enabled_count;
u32 gpe_index; u32 gpe_index;
u32 gpe_number;
u32 i; u32 i;
u32 j; u32 j;
ACPI_FUNCTION_TRACE(ev_initialize_gpe_block); ACPI_FUNCTION_TRACE(ev_initialize_gpe_block);
/* Ignore a null GPE block (e.g., if no GPE block 1 exists) */ /*
* Ignore a null GPE block (e.g., if no GPE block 1 exists) and
if (!gpe_block) { * GPE blocks that have been initialized already.
*/
if (!gpe_block || gpe_block->initialized) {
return_ACPI_STATUS(AE_OK); return_ACPI_STATUS(AE_OK);
} }
/* /*
* Enable all GPEs that have a corresponding method. Any other GPEs * Enable all GPEs that have a corresponding method and have the
* within this block must be enabled via the acpi_enable_gpe interface. * 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; 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 (i = 0; i < gpe_block->register_count; i++) {
for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) { 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_index = (i * ACPI_GPE_REGISTER_WIDTH) + j;
gpe_event_info = &gpe_block->event_info[gpe_index]; 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 */ /* 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; continue;
} }
/* status = acpi_raw_enable_gpe(gpe_event_info);
* 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);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
ACPI_EXCEPTION((AE_INFO, status, ACPI_EXCEPTION((AE_INFO, status,
"Could not enable GPE 0x%02X", "Could not enable GPE 0x%02X",
gpe_number)); gpe_index + gpe_block->block_base_number));
continue; continue;
} }
@ -504,5 +497,7 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device,
gpe_enabled_count)); gpe_enabled_count));
} }
gpe_block->initialized = TRUE;
return_ACPI_STATUS(AE_OK); return_ACPI_STATUS(AE_OK);
} }

View File

@ -210,8 +210,7 @@ acpi_status acpi_ev_gpe_initialize(void)
* *
* DESCRIPTION: Check for new GPE methods (_Lxx/_Exx) made available as a * DESCRIPTION: Check for new GPE methods (_Lxx/_Exx) made available as a
* result of a Load() or load_table() operation. If new GPE * result of a Load() or load_table() operation. If new GPE
* methods have been installed, register the new methods and * methods have been installed, register the new methods.
* enable and runtime GPEs that are associated with them.
* *
******************************************************************************/ ******************************************************************************/
@ -239,7 +238,6 @@ void acpi_ev_update_gpes(acpi_owner_id table_owner_id)
walk_info.owner_id = table_owner_id; walk_info.owner_id = table_owner_id;
walk_info.execute_by_owner_id = TRUE; walk_info.execute_by_owner_id = TRUE;
walk_info.count = 0; walk_info.count = 0;
walk_info.enable_this_gpe = TRUE;
/* Walk the interrupt level descriptor list */ /* 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 * If walk_info->execute_by_owner_id is TRUE, we only execute examine GPE methods
* with that owner. * 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 = struct acpi_gpe_walk_info *walk_info =
ACPI_CAST_PTR(struct acpi_gpe_walk_info, context); ACPI_CAST_PTR(struct acpi_gpe_walk_info, context);
struct acpi_gpe_event_info *gpe_event_info; struct acpi_gpe_event_info *gpe_event_info;
struct acpi_namespace_node *gpe_device;
acpi_status status;
u32 gpe_number; u32 gpe_number;
char name[ACPI_NAME_SIZE + 1]; char name[ACPI_NAME_SIZE + 1];
u8 type; 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->flags |= (u8)(type | ACPI_GPE_DISPATCH_METHOD);
gpe_event_info->dispatch.method_node = method_node; 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, ACPI_DEBUG_PRINT((ACPI_DB_LOAD,
"Registered GPE method %s as GPE number 0x%.2X\n", "Registered GPE method %s as GPE number 0x%.2X\n",
name, gpe_number)); name, gpe_number));

View File

@ -553,7 +553,7 @@ acpi_status acpi_ev_release_global_lock(void)
acpi_gbl_global_lock_acquired = FALSE; acpi_gbl_global_lock_acquired = FALSE;
/* Release the local GL mutex */ /* 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_ev_global_lock_acquired = 0;
acpi_os_release_mutex(acpi_gbl_global_lock_mutex->mutex.os_mutex); acpi_os_release_mutex(acpi_gbl_global_lock_mutex->mutex.os_mutex);
return_ACPI_STATUS(status); return_ACPI_STATUS(status);

View File

@ -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 * Get the PCI device and function numbers from the _ADR object
* in the parent's scope. * contained in the parent's scope.
*/ */
status = acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR, status = acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR,
pci_device_node, &pci_value); 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); 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; *region_context = pci_id;
return_ACPI_STATUS(AE_OK); return_ACPI_STATUS(AE_OK);

View File

@ -726,15 +726,16 @@ acpi_install_gpe_handler(acpi_handle gpe_device,
(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK); (ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK);
/* /*
* If the GPE is associated with a method and it cannot wake up the * If the GPE is associated with a method, it might have been enabled
* system from sleep states, it was enabled automatically during * automatically during initialization, in which case it has to be
* initialization, so it has to be disabled now to avoid spurious * disabled now to avoid spurious execution of the handler.
* execution of the handler.
*/ */
if ((handler->orig_flags & ACPI_GPE_DISPATCH_METHOD) 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); (void)acpi_raw_disable_gpe(gpe_event_info);
}
/* Install the handler */ /* Install the handler */
@ -837,13 +838,13 @@ acpi_remove_gpe_handler(acpi_handle gpe_device,
gpe_event_info->flags |= handler->orig_flags; gpe_event_info->flags |= handler->orig_flags;
/* /*
* If the GPE was previously associated with a method and it cannot wake * If the GPE was previously associated with a method and it was
* up the system from sleep states, it should be enabled at this point * enabled, it should be enabled at this point to restore the
* to restore the post-initialization configuration. * post-initialization configuration.
*/ */
if ((handler->orig_flags & ACPI_GPE_DISPATCH_METHOD) 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); (void)acpi_raw_enable_gpe(gpe_event_info);
/* Now we can free the handler object */ /* Now we can free the handler object */

View File

@ -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 */ /* Ensure that we have a valid GPE number */
gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, 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; 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); acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
} }
@ -651,7 +642,7 @@ acpi_install_gpe_block(acpi_handle gpe_device,
struct acpi_generic_address *gpe_block_address, struct acpi_generic_address *gpe_block_address,
u32 register_count, u32 interrupt_number) u32 register_count, u32 interrupt_number)
{ {
acpi_status status; acpi_status status = AE_OK;
union acpi_operand_object *obj_desc; union acpi_operand_object *obj_desc;
struct acpi_namespace_node *node; struct acpi_namespace_node *node;
struct acpi_gpe_block_info *gpe_block; 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; 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: unlock_and_exit:
(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
@ -924,3 +911,43 @@ acpi_status acpi_enable_all_runtime_gpes(void)
return_ACPI_STATUS(status); 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);
}

View File

@ -64,6 +64,12 @@ ACPI_MODULE_NAME("evxfregn")
* *
* DESCRIPTION: Install a handler for all op_regions of a given space_id. * 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_status
acpi_install_address_space_handler(acpi_handle device, acpi_install_address_space_handler(acpi_handle device,

View File

@ -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 * Exit now for SMBus or IPMI address space, it has a non-linear
* and the request cannot be directly validated * address space and the request cannot be directly validated
*/ */
if (rgn_desc->region.space_id == ACPI_ADR_SPACE_SMBUS || if (rgn_desc->region.space_id == ACPI_ADR_SPACE_SMBUS ||
rgn_desc->region.space_id == ACPI_ADR_SPACE_IPMI) { 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) * (Region length is specified in bytes)
*/ */
if (rgn_desc->region.length < if (rgn_desc->region.length <
(obj_desc->common_field.base_byte_offset + (obj_desc->common_field.base_byte_offset + field_datum_byte_offset +
field_datum_byte_offset +
obj_desc->common_field.access_byte_width)) { obj_desc->common_field.access_byte_width)) {
if (acpi_gbl_enable_interpreter_slack) { 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 buffer_tail_bits;
u32 datum_count; u32 datum_count;
u32 field_datum_count; u32 field_datum_count;
u32 access_bit_width;
u32 i; u32 i;
ACPI_FUNCTION_TRACE(ex_extract_from_field); 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); return_ACPI_STATUS(AE_BUFFER_OVERFLOW);
} }
ACPI_MEMSET(buffer, 0, buffer_length); 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) */ /* Compute the number of datums (access width data items) */
datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length, datum_count =
obj_desc->common_field.access_bit_width); 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 + field_datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length +
obj_desc->common_field. obj_desc->common_field.
start_field_bit_offset, start_field_bit_offset,
obj_desc->common_field.
access_bit_width); access_bit_width);
/* Priming read from the field */ /* 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 * This avoids the differences in behavior between different compilers
* concerning shift values larger than the target data width. * 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) < obj_desc->common_field.start_field_bit_offset <
ACPI_INTEGER_BIT_SIZE) { ACPI_INTEGER_BIT_SIZE) {
merged_datum |= merged_datum |=
raw_datum << (obj_desc->common_field. raw_datum << (access_bit_width -
access_bit_width -
obj_desc->common_field. obj_desc->common_field.
start_field_bit_offset); 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 */ /* Mask off any extra bits in the last datum */
buffer_tail_bits = obj_desc->common_field.bit_length % buffer_tail_bits = obj_desc->common_field.bit_length % access_bit_width;
obj_desc->common_field.access_bit_width;
if (buffer_tail_bits) { if (buffer_tail_bits) {
merged_datum &= ACPI_MASK_BITS_ABOVE(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, acpi_ex_insert_into_field(union acpi_operand_object *obj_desc,
void *buffer, u32 buffer_length) void *buffer, u32 buffer_length)
{ {
void *new_buffer;
acpi_status status; acpi_status status;
u64 mask; u64 mask;
u64 width_mask; u64 width_mask;
@ -808,9 +827,9 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc,
u32 buffer_tail_bits; u32 buffer_tail_bits;
u32 datum_count; u32 datum_count;
u32 field_datum_count; u32 field_datum_count;
u32 i; u32 access_bit_width;
u32 required_length; u32 required_length;
void *new_buffer; u32 i;
ACPI_FUNCTION_TRACE(ex_insert_into_field); 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; 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. * Create the bitmasks used for bit insertion.
* Note: This if/else is used to bypass compiler differences with the * Note: This if/else is used to bypass compiler differences with the
* shift operator * 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; width_mask = ACPI_UINT64_MAX;
} else { } else {
width_mask = width_mask = ACPI_MASK_BITS_ABOVE(access_bit_width);
ACPI_MASK_BITS_ABOVE(obj_desc->common_field.
access_bit_width);
} }
mask = width_mask & 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) */ /* Compute the number of datums (access width data items) */
datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length, 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 + field_datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length +
obj_desc->common_field. obj_desc->common_field.
start_field_bit_offset, start_field_bit_offset,
obj_desc->common_field.
access_bit_width); access_bit_width);
/* Get initial Datum from the input buffer */ /* 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 * This avoids the differences in behavior between different compilers
* concerning shift values larger than the target data width. * 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) < obj_desc->common_field.start_field_bit_offset) <
ACPI_INTEGER_BIT_SIZE) { ACPI_INTEGER_BIT_SIZE) {
merged_datum = merged_datum =
raw_datum >> (obj_desc->common_field. raw_datum >> (access_bit_width -
access_bit_width -
obj_desc->common_field. obj_desc->common_field.
start_field_bit_offset); start_field_bit_offset);
} else { } 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_MEMCPY(&raw_datum, ((char *)buffer) + buffer_offset,
ACPI_MIN(obj_desc->common_field.access_byte_width, ACPI_MIN(obj_desc->common_field.access_byte_width,
buffer_length - buffer_offset)); buffer_length - buffer_offset));
merged_datum |= merged_datum |=
raw_datum << obj_desc->common_field.start_field_bit_offset; 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 + buffer_tail_bits = (obj_desc->common_field.bit_length +
obj_desc->common_field.start_field_bit_offset) % obj_desc->common_field.start_field_bit_offset) %
obj_desc->common_field.access_bit_width; access_bit_width;
if (buffer_tail_bits) { if (buffer_tail_bits) {
mask &= ACPI_MASK_BITS_ABOVE(buffer_tail_bits); mask &= ACPI_MASK_BITS_ABOVE(buffer_tail_bits);
} }

View File

@ -336,7 +336,7 @@ acpi_status acpi_ex_release_mutex_object(union acpi_operand_object *obj_desc)
/* Clear mutex info */ /* Clear mutex info */
obj_desc->mutex.thread_id = NULL; obj_desc->mutex.thread_id = 0;
return_ACPI_STATUS(status); 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) && if ((owner_thread->thread_id != walk_state->thread->thread_id) &&
(obj_desc != acpi_gbl_global_lock_mutex)) { (obj_desc != acpi_gbl_global_lock_mutex)) {
ACPI_ERROR((AE_INFO, ACPI_ERROR((AE_INFO,
"Thread %p cannot release Mutex [%4.4s] acquired by thread %p", "Thread %u cannot release Mutex [%4.4s] acquired by thread %u",
ACPI_CAST_PTR(void, walk_state->thread->thread_id), (u32)walk_state->thread->thread_id,
acpi_ut_get_node_name(obj_desc->mutex.node), 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); 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 */ /* Mark mutex unowned */
obj_desc->mutex.owner_thread = NULL; 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) */ /* Update Thread sync_level (Last mutex is the important one) */

View File

@ -355,12 +355,10 @@ acpi_ex_prep_common_field_object(union acpi_operand_object *obj_desc,
return_ACPI_STATUS(AE_AML_OPERAND_VALUE); 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) obj_desc->common_field.access_byte_width = (u8)
ACPI_DIV_8(access_bit_width); /* 1, 2, 4, 8 */ ACPI_DIV_8(access_bit_width);
obj_desc->common_field.access_bit_width = (u8) access_bit_width;
/* /*
* base_byte_offset is the address of the start of the field within the * 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 *obj_desc;
union acpi_operand_object *second_desc = NULL; union acpi_operand_object *second_desc = NULL;
u32 type;
acpi_status status; acpi_status status;
u32 access_byte_width;
u32 type;
ACPI_FUNCTION_TRACE(ex_prep_field_value); 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); type = acpi_ns_get_type(info->region_node);
if (type != ACPI_TYPE_REGION) { if (type != ACPI_TYPE_REGION) {
ACPI_ERROR((AE_INFO, ACPI_ERROR((AE_INFO,
"Needed Region, found type 0x%X (%s)", "Needed Region, found type 0x%X (%s)", type,
type, acpi_ut_get_type_name(type))); acpi_ut_get_type_name(type)));
return_ACPI_STATUS(AE_AML_OPERAND_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 */ /* Initialize areas of the object that are common to all fields */
obj_desc->common_field.node = info->field_node; 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->attribute,
info->field_bit_position, info->field_bit_position,
info->field_bit_length); 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 = obj_desc->field.region_obj =
acpi_ns_get_attached_object(info->region_node); 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 */ /* An additional reference for the container */
acpi_ut_add_reference(obj_desc->field.region_obj); 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, ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
"RegionField: BitOff %X, Off %X, Gran %X, Region %p\n", "RegionField: BitOff %X, Off %X, Gran %X, Region %p\n",
obj_desc->field.start_field_bit_offset, obj_desc->field.start_field_bit_offset,

View File

@ -353,7 +353,6 @@ acpi_ex_pci_config_space_handler(u32 function,
acpi_status status = AE_OK; acpi_status status = AE_OK;
struct acpi_pci_id *pci_id; struct acpi_pci_id *pci_id;
u16 pci_register; u16 pci_register;
u32 value32;
ACPI_FUNCTION_TRACE(ex_pci_config_space_handler); ACPI_FUNCTION_TRACE(ex_pci_config_space_handler);
@ -381,8 +380,7 @@ acpi_ex_pci_config_space_handler(u32 function,
case ACPI_READ: case ACPI_READ:
status = acpi_os_read_pci_configuration(pci_id, pci_register, status = acpi_os_read_pci_configuration(pci_id, pci_register,
&value32, bit_width); value, bit_width);
*value = value32;
break; break;
case ACPI_WRITE: case ACPI_WRITE:

412
drivers/acpi/acpica/hwpci.c Normal file
View 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);
}

View File

@ -73,10 +73,18 @@ static acpi_status
acpi_ns_repair_ALR(struct acpi_predefined_data *data, acpi_ns_repair_ALR(struct acpi_predefined_data *data,
union acpi_operand_object **return_object_ptr); 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 static acpi_status
acpi_ns_repair_FDE(struct acpi_predefined_data *data, acpi_ns_repair_FDE(struct acpi_predefined_data *data,
union acpi_operand_object **return_object_ptr); 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 static acpi_status
acpi_ns_repair_PSS(struct acpi_predefined_data *data, acpi_ns_repair_PSS(struct acpi_predefined_data *data,
union acpi_operand_object **return_object_ptr); union acpi_operand_object **return_object_ptr);
@ -108,8 +116,10 @@ acpi_ns_sort_list(union acpi_operand_object **elements,
* As necessary: * As necessary:
* *
* _ALR: Sort the list ascending by ambient_illuminance * _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 * _FDE: Convert Buffer of BYTEs to a Buffer of DWORDs
* _GTM: 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 * _PSS: Sort the list descending by Power
* _TSS: 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[] = { static const struct acpi_repair_info acpi_ns_repairable_names[] = {
{"_ALR", acpi_ns_repair_ALR}, {"_ALR", acpi_ns_repair_ALR},
{"_CID", acpi_ns_repair_CID},
{"_FDE", acpi_ns_repair_FDE}, {"_FDE", acpi_ns_repair_FDE},
{"_GTM", acpi_ns_repair_FDE}, /* _GTM has same repair as _FDE */ {"_GTM", acpi_ns_repair_FDE}, /* _GTM has same repair as _FDE */
{"_HID", acpi_ns_repair_HID},
{"_PSS", acpi_ns_repair_PSS}, {"_PSS", acpi_ns_repair_PSS},
{"_TSS", acpi_ns_repair_TSS}, {"_TSS", acpi_ns_repair_TSS},
{{0, 0, 0, 0}, NULL} /* Table terminator */ {{0, 0, 0, 0}, NULL} /* Table terminator */
@ -319,6 +331,157 @@ acpi_ns_repair_FDE(struct acpi_predefined_data *data,
return (AE_OK); 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 * FUNCTION: acpi_ns_repair_TSS

View File

@ -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); acpi_name acpi_ns_find_parent_name(struct acpi_namespace_node *node_to_search);
#endif #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 * FUNCTION: acpi_ns_print_node_pathname

View File

@ -49,7 +49,7 @@
ACPI_MODULE_NAME("tbfadt") ACPI_MODULE_NAME("tbfadt")
/* Local prototypes */ /* Local prototypes */
static inline void static ACPI_INLINE void
acpi_tb_init_generic_address(struct acpi_generic_address *generic_address, acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
u8 space_id, u8 byte_width, u64 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, acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
u8 space_id, u8 byte_width, u64 address) u8 space_id, u8 byte_width, u64 address)
{ {

View File

@ -179,9 +179,8 @@ acpi_debug_print(u32 requested_debug_level,
if (thread_id != acpi_gbl_prev_thread_id) { if (thread_id != acpi_gbl_prev_thread_id) {
if (ACPI_LV_THREADS & acpi_dbg_level) { if (ACPI_LV_THREADS & acpi_dbg_level) {
acpi_os_printf acpi_os_printf
("\n**** Context Switch from TID %p to TID %p ****\n\n", ("\n**** Context Switch from TID %u to TID %u ****\n\n",
ACPI_CAST_PTR(void, acpi_gbl_prev_thread_id), (u32)acpi_gbl_prev_thread_id, (u32)thread_id);
ACPI_CAST_PTR(void, thread_id));
} }
acpi_gbl_prev_thread_id = 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); acpi_os_printf("%8s-%04ld ", module_name, line_number);
if (ACPI_LV_THREADS & acpi_dbg_level) { 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: ", acpi_os_printf("[%02ld] %-22.22s: ",

View File

@ -48,153 +48,6 @@
#define _COMPONENT ACPI_UTILITIES #define _COMPONENT ACPI_UTILITIES
ACPI_MODULE_NAME("uteval") 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 * FUNCTION: acpi_ut_evaluate_object

View File

@ -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 * 1) _SB_ is defined to be a device to allow \_SB_._INI to be run
* during the initialization sequence. * during the initialization sequence.
* 2) _TZ_ is defined to be a thermal zone in order to allow ASL code to * 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[] = { const struct acpi_predefined_names acpi_gbl_pre_defined_names[] = {
{"_GPE", ACPI_TYPE_LOCAL_SCOPE, NULL}, {"_GPE", ACPI_TYPE_LOCAL_SCOPE, NULL},
{"_PR_", ACPI_TYPE_LOCAL_SCOPE, NULL}, {"_PR_", ACPI_TYPE_LOCAL_SCOPE, NULL},
{"_SB_", ACPI_TYPE_DEVICE, NULL}, {"_SB_", ACPI_TYPE_DEVICE, NULL},
{"_SI_", ACPI_TYPE_LOCAL_SCOPE, 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}, {"_REV", ACPI_TYPE_INTEGER, (char *)ACPI_CA_SUPPORT_LEVEL},
{"_OS_", ACPI_TYPE_STRING, ACPI_OS_NAME}, {"_OS_", ACPI_TYPE_STRING, ACPI_OS_NAME},
{"_GL_", ACPI_TYPE_MUTEX, (char *)1}, {"_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[0] = NULL;
acpi_gbl_gpe_fadt_blocks[1] = NULL; acpi_gbl_gpe_fadt_blocks[1] = NULL;
acpi_current_gpe_count = 0; acpi_current_gpe_count = 0;
acpi_all_gpes_initialized = FALSE;
/* Global handlers */ /* Global handlers */
@ -774,6 +777,7 @@ acpi_status acpi_ut_init_globals(void)
acpi_gbl_exception_handler = NULL; acpi_gbl_exception_handler = NULL;
acpi_gbl_init_handler = NULL; acpi_gbl_init_handler = NULL;
acpi_gbl_table_handler = NULL; acpi_gbl_table_handler = NULL;
acpi_gbl_interface_handler = NULL;
/* Global Lock support */ /* Global Lock support */
@ -800,6 +804,7 @@ acpi_status acpi_ut_init_globals(void)
acpi_gbl_debugger_configuration = DEBUGGER_THREADING; acpi_gbl_debugger_configuration = DEBUGGER_THREADING;
acpi_gbl_db_output_flags = ACPI_DB_CONSOLE_OUTPUT; acpi_gbl_db_output_flags = ACPI_DB_CONSOLE_OUTPUT;
acpi_gbl_osi_data = 0; acpi_gbl_osi_data = 0;
acpi_gbl_osi_mutex = NULL;
/* Hardware oriented */ /* Hardware oriented */

View File

@ -48,42 +48,6 @@
#define _COMPONENT ACPI_UTILITIES #define _COMPONENT ACPI_UTILITIES
ACPI_MODULE_NAME("utids") 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 * 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 * NOTE: Internal function, no parameter validation
* *
******************************************************************************/ ******************************************************************************/
acpi_status acpi_status
acpi_ut_execute_HID(struct acpi_namespace_node *device_node, acpi_ut_execute_HID(struct acpi_namespace_node *device_node,
struct acpica_device_id **return_id) 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) { if (obj_desc->common.type == ACPI_TYPE_INTEGER) {
acpi_ex_eisa_id_to_string(hid->string, obj_desc->integer.value); acpi_ex_eisa_id_to_string(hid->string, obj_desc->integer.value);
} else { } else {
acpi_ut_copy_id_string(hid->string, obj_desc->string.pointer); ACPI_STRCPY(hid->string, obj_desc->string.pointer);
} }
hid->length = length; 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) { if (obj_desc->common.type == ACPI_TYPE_INTEGER) {
acpi_ex_integer_to_string(uid->string, obj_desc->integer.value); acpi_ex_integer_to_string(uid->string, obj_desc->integer.value);
} else { } else {
acpi_ut_copy_id_string(uid->string, obj_desc->string.pointer); ACPI_STRCPY(uid->string, obj_desc->string.pointer);
} }
uid->length = length; 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 */ /* Copy the String CID from the returned object */
acpi_ut_copy_id_string(next_id_string, ACPI_STRCPY(next_id_string,
cid_objects[i]->string.pointer); cid_objects[i]->string.pointer);
length = cid_objects[i]->string.length + 1; length = cid_objects[i]->string.length + 1;
} }

View File

@ -117,6 +117,10 @@ void acpi_ut_subsystem_shutdown(void)
/* Close the acpi_event Handling */ /* Close the acpi_event Handling */
acpi_ev_terminate(); acpi_ev_terminate();
/* Delete any dynamic _OSI interfaces */
acpi_ut_interface_terminate();
#endif #endif
/* Close the Namespace */ /* Close the Namespace */

View File

@ -48,11 +48,27 @@
ACPI_MODULE_NAME("utmath") ACPI_MODULE_NAME("utmath")
/* /*
* Support for double-precision integer divide. This code is included here * Optional support for 64-bit double-precision integer divide. This code
* in order to support kernel environments where the double-precision math * is configurable and is implemented in order to support 32-bit kernel
* library is not available. * 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 #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 * FUNCTION: acpi_ut_short_divide
@ -69,6 +85,7 @@ ACPI_MODULE_NAME("utmath")
* 32-bit remainder. * 32-bit remainder.
* *
******************************************************************************/ ******************************************************************************/
acpi_status acpi_status
acpi_ut_short_divide(u64 dividend, acpi_ut_short_divide(u64 dividend,
u32 divisor, u64 *out_quotient, u32 *out_remainder) u32 divisor, u64 *out_quotient, u32 *out_remainder)

View File

@ -50,11 +50,6 @@
#define _COMPONENT ACPI_UTILITIES #define _COMPONENT ACPI_UTILITIES
ACPI_MODULE_NAME("utmisc") 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 * 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); 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);
}

View File

@ -86,6 +86,12 @@ acpi_status acpi_ut_mutex_initialize(void)
spin_lock_init(acpi_gbl_gpe_lock); spin_lock_init(acpi_gbl_gpe_lock);
spin_lock_init(acpi_gbl_hardware_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 */ /* Create the reader/writer lock for namespace access */
status = acpi_ut_create_rw_lock(&acpi_gbl_namespace_rw_lock); 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_ut_delete_mutex(i);
} }
acpi_os_delete_mutex(acpi_gbl_osi_mutex);
/* Delete the spinlocks */ /* Delete the spinlocks */
acpi_os_delete_lock(acpi_gbl_gpe_lock); 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 (acpi_gbl_mutex_info[i].thread_id == this_thread_id) {
if (i == mutex_id) { if (i == mutex_id) {
ACPI_ERROR((AE_INFO, 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 acpi_ut_get_mutex_name
(mutex_id), (mutex_id),
ACPI_CAST_PTR(void, (u32)this_thread_id));
this_thread_id)));
return (AE_ALREADY_ACQUIRED); return (AE_ALREADY_ACQUIRED);
} }
ACPI_ERROR((AE_INFO, ACPI_ERROR((AE_INFO,
"Invalid acquire order: Thread %p owns [%s], wants [%s]", "Invalid acquire order: Thread %u owns [%s], wants [%s]",
ACPI_CAST_PTR(void, this_thread_id), (u32)this_thread_id,
acpi_ut_get_mutex_name(i), acpi_ut_get_mutex_name(i),
acpi_ut_get_mutex_name(mutex_id))); acpi_ut_get_mutex_name(mutex_id)));
@ -242,24 +249,24 @@ acpi_status acpi_ut_acquire_mutex(acpi_mutex_handle mutex_id)
#endif #endif
ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
"Thread %p attempting to acquire Mutex [%s]\n", "Thread %u attempting to acquire Mutex [%s]\n",
ACPI_CAST_PTR(void, this_thread_id), (u32)this_thread_id,
acpi_ut_get_mutex_name(mutex_id))); acpi_ut_get_mutex_name(mutex_id)));
status = acpi_os_acquire_mutex(acpi_gbl_mutex_info[mutex_id].mutex, status = acpi_os_acquire_mutex(acpi_gbl_mutex_info[mutex_id].mutex,
ACPI_WAIT_FOREVER); ACPI_WAIT_FOREVER);
if (ACPI_SUCCESS(status)) { if (ACPI_SUCCESS(status)) {
ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
"Thread %p acquired Mutex [%s]\n", "Thread %u acquired Mutex [%s]\n",
ACPI_CAST_PTR(void, this_thread_id), (u32)this_thread_id,
acpi_ut_get_mutex_name(mutex_id))); acpi_ut_get_mutex_name(mutex_id)));
acpi_gbl_mutex_info[mutex_id].use_count++; acpi_gbl_mutex_info[mutex_id].use_count++;
acpi_gbl_mutex_info[mutex_id].thread_id = this_thread_id; acpi_gbl_mutex_info[mutex_id].thread_id = this_thread_id;
} else { } else {
ACPI_EXCEPTION((AE_INFO, status, ACPI_EXCEPTION((AE_INFO, status,
"Thread %p could not acquire Mutex [0x%X]", "Thread %u could not acquire Mutex [0x%X]",
ACPI_CAST_PTR(void, this_thread_id), mutex_id)); (u32)this_thread_id, mutex_id));
} }
return (status); 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_status acpi_ut_release_mutex(acpi_mutex_handle mutex_id)
{ {
acpi_thread_id this_thread_id;
ACPI_FUNCTION_NAME(ut_release_mutex); ACPI_FUNCTION_NAME(ut_release_mutex);
ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Thread %p releasing Mutex [%s]\n", this_thread_id = acpi_os_get_thread_id();
ACPI_CAST_PTR(void, 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))); acpi_ut_get_mutex_name(mutex_id)));
if (mutex_id > ACPI_MAX_MUTEX) { if (mutex_id > ACPI_MAX_MUTEX) {

380
drivers/acpi/acpica/utosi.c Normal file
View 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);
}

View File

@ -110,6 +110,15 @@ acpi_status __init acpi_initialize_subsystem(void)
return_ACPI_STATUS(status); 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 */ /* If configured, initialize the AML debugger */
ACPI_DEBUGGER_EXEC(status = acpi_db_initialize()); 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 * Empty the caches (delete the cached objects) on the assumption that
* the table load filled them up more than they will be at runtime -- * 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) ACPI_EXPORT_SYMBOL(acpi_install_initialization_handler)
#endif /* ACPI_FUTURE_USAGE */ #endif /* ACPI_FUTURE_USAGE */
/***************************************************************************** /*****************************************************************************
* *
* FUNCTION: acpi_purge_cached_objects * FUNCTION: acpi_purge_cached_objects
@ -529,4 +526,117 @@ acpi_status acpi_purge_cached_objects(void)
} }
ACPI_EXPORT_SYMBOL(acpi_purge_cached_objects) 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 */

View 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 */

View File

@ -42,10 +42,7 @@
#include <acpi/acpi_bus.h> #include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h> #include <acpi/acpi_drivers.h>
#ifdef CONFIG_ACPI_SYSFS_POWER
#include <linux/power_supply.h> #include <linux/power_supply.h>
#endif
#define PREFIX "ACPI: " #define PREFIX "ACPI: "
@ -98,13 +95,12 @@ enum {
* due to bad math. * due to bad math.
*/ */
ACPI_BATTERY_QUIRK_SIGNED16_CURRENT, ACPI_BATTERY_QUIRK_SIGNED16_CURRENT,
ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY,
}; };
struct acpi_battery { struct acpi_battery {
struct mutex lock; struct mutex lock;
#ifdef CONFIG_ACPI_SYSFS_POWER
struct power_supply bat; struct power_supply bat;
#endif
struct acpi_device *device; struct acpi_device *device;
unsigned long update_time; unsigned long update_time;
int rate_now; int rate_now;
@ -141,7 +137,6 @@ inline int acpi_battery_present(struct acpi_battery *battery)
return battery->device->status.battery_present; return battery->device->status.battery_present;
} }
#ifdef CONFIG_ACPI_SYSFS_POWER
static int acpi_battery_technology(struct acpi_battery *battery) static int acpi_battery_technology(struct acpi_battery *battery)
{ {
if (!strcasecmp("NiCd", battery->type)) if (!strcasecmp("NiCd", battery->type))
@ -186,6 +181,7 @@ static int acpi_battery_get_property(struct power_supply *psy,
enum power_supply_property psp, enum power_supply_property psp,
union power_supply_propval *val) union power_supply_propval *val)
{ {
int ret = 0;
struct acpi_battery *battery = to_acpi_battery(psy); struct acpi_battery *battery = to_acpi_battery(psy);
if (acpi_battery_present(battery)) { if (acpi_battery_present(battery)) {
@ -214,26 +210,44 @@ static int acpi_battery_get_property(struct power_supply *psy,
val->intval = battery->cycle_count; val->intval = battery->cycle_count;
break; break;
case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: 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; break;
case POWER_SUPPLY_PROP_VOLTAGE_NOW: 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; break;
case POWER_SUPPLY_PROP_CURRENT_NOW: case POWER_SUPPLY_PROP_CURRENT_NOW:
case POWER_SUPPLY_PROP_POWER_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; break;
case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
case POWER_SUPPLY_PROP_ENERGY_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; break;
case POWER_SUPPLY_PROP_CHARGE_FULL: case POWER_SUPPLY_PROP_CHARGE_FULL:
case POWER_SUPPLY_PROP_ENERGY_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; break;
case POWER_SUPPLY_PROP_CHARGE_NOW: case POWER_SUPPLY_PROP_CHARGE_NOW:
case POWER_SUPPLY_PROP_ENERGY_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; break;
case POWER_SUPPLY_PROP_MODEL_NAME: case POWER_SUPPLY_PROP_MODEL_NAME:
val->strval = battery->model_number; val->strval = battery->model_number;
@ -245,9 +259,9 @@ static int acpi_battery_get_property(struct power_supply *psy,
val->strval = battery->serial_number; val->strval = battery->serial_number;
break; break;
default: default:
return -EINVAL; ret = -EINVAL;
} }
return 0; return ret;
} }
static enum power_supply_property charge_battery_props[] = { 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_MANUFACTURER,
POWER_SUPPLY_PROP_SERIAL_NUMBER, POWER_SUPPLY_PROP_SERIAL_NUMBER,
}; };
#endif
#ifdef CONFIG_ACPI_PROCFS_POWER #ifdef CONFIG_ACPI_PROCFS_POWER
inline char *acpi_battery_units(struct acpi_battery *battery) 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, result = extract_package(battery, buffer.pointer,
info_offsets, ARRAY_SIZE(info_offsets)); info_offsets, ARRAY_SIZE(info_offsets));
kfree(buffer.pointer); kfree(buffer.pointer);
if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags))
battery->full_charge_capacity = battery->design_capacity;
return result; return result;
} }
@ -448,6 +463,10 @@ static int acpi_battery_get_state(struct acpi_battery *battery)
battery->rate_now != -1) battery->rate_now != -1)
battery->rate_now = abs((s16)battery->rate_now); 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; return result;
} }
@ -492,7 +511,6 @@ static int acpi_battery_init_alarm(struct acpi_battery *battery)
return acpi_battery_set_alarm(battery); return acpi_battery_set_alarm(battery);
} }
#ifdef CONFIG_ACPI_SYSFS_POWER
static ssize_t acpi_battery_alarm_show(struct device *dev, static ssize_t acpi_battery_alarm_show(struct device *dev,
struct device_attribute *attr, struct device_attribute *attr,
char *buf) char *buf)
@ -552,7 +570,6 @@ static void sysfs_remove_battery(struct acpi_battery *battery)
power_supply_unregister(&battery->bat); power_supply_unregister(&battery->bat);
battery->bat.dev = NULL; battery->bat.dev = NULL;
} }
#endif
static void acpi_battery_quirks(struct acpi_battery *battery) 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) static int acpi_battery_update(struct acpi_battery *battery)
{ {
int result, old_present = acpi_battery_present(battery); int result, old_present = acpi_battery_present(battery);
@ -568,9 +612,7 @@ static int acpi_battery_update(struct acpi_battery *battery)
if (result) if (result)
return result; return result;
if (!acpi_battery_present(battery)) { if (!acpi_battery_present(battery)) {
#ifdef CONFIG_ACPI_SYSFS_POWER
sysfs_remove_battery(battery); sysfs_remove_battery(battery);
#endif
battery->update_time = 0; battery->update_time = 0;
return 0; return 0;
} }
@ -582,11 +624,11 @@ static int acpi_battery_update(struct acpi_battery *battery)
acpi_battery_quirks(battery); acpi_battery_quirks(battery);
acpi_battery_init_alarm(battery); acpi_battery_init_alarm(battery);
} }
#ifdef CONFIG_ACPI_SYSFS_POWER
if (!battery->bat.dev) if (!battery->bat.dev)
sysfs_add_battery(battery); sysfs_add_battery(battery);
#endif result = acpi_battery_get_state(battery);
return 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) static void acpi_battery_notify(struct acpi_device *device, u32 event)
{ {
struct acpi_battery *battery = acpi_driver_data(device); struct acpi_battery *battery = acpi_driver_data(device);
#ifdef CONFIG_ACPI_SYSFS_POWER
struct device *old; struct device *old;
#endif
if (!battery) if (!battery)
return; return;
#ifdef CONFIG_ACPI_SYSFS_POWER
old = battery->bat.dev; old = battery->bat.dev;
#endif
acpi_battery_update(battery); acpi_battery_update(battery);
acpi_bus_generate_proc_event(device, event, acpi_bus_generate_proc_event(device, event,
acpi_battery_present(battery)); acpi_battery_present(battery));
acpi_bus_generate_netlink_event(device->pnp.device_class, acpi_bus_generate_netlink_event(device->pnp.device_class,
dev_name(&device->dev), event, dev_name(&device->dev), event,
acpi_battery_present(battery)); acpi_battery_present(battery));
#ifdef CONFIG_ACPI_SYSFS_POWER
/* acpi_battery_update could remove power_supply object */ /* acpi_battery_update could remove power_supply object */
if (old && battery->bat.dev) if (old && battery->bat.dev)
power_supply_changed(&battery->bat); power_supply_changed(&battery->bat);
#endif
} }
static int acpi_battery_add(struct acpi_device *device) 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 #ifdef CONFIG_ACPI_PROCFS_POWER
acpi_battery_remove_fs(device); acpi_battery_remove_fs(device);
#endif #endif
#ifdef CONFIG_ACPI_SYSFS_POWER
sysfs_remove_battery(battery); sysfs_remove_battery(battery);
#endif
mutex_destroy(&battery->lock); mutex_destroy(&battery->lock);
kfree(battery); kfree(battery);
return 0; return 0;

View File

@ -935,6 +935,12 @@ static int __init acpi_bus_init(void)
goto error1; 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(); acpi_early_processor_set_pdc();
/* /*
@ -1026,7 +1032,6 @@ static int __init acpi_init(void)
acpi_scan_init(); acpi_scan_init();
acpi_ec_init(); acpi_ec_init();
acpi_power_init(); acpi_power_init();
acpi_sysfs_init();
acpi_debugfs_init(); acpi_debugfs_init();
acpi_sleep_proc_init(); acpi_sleep_proc_init();
acpi_wakeup_device_init(); acpi_wakeup_device_init();

View File

@ -338,7 +338,8 @@ static int acpi_button_add(struct acpi_device *device)
{ {
struct acpi_button *button; struct acpi_button *button;
struct input_dev *input; struct input_dev *input;
char *hid, *name, *class; const char *hid = acpi_device_hid(device);
char *name, *class;
int error; int error;
button = kzalloc(sizeof(struct acpi_button), GFP_KERNEL); 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; goto err_free_button;
} }
hid = acpi_device_hid(device);
name = acpi_device_name(device); name = acpi_device_name(device);
class = acpi_device_class(device); class = acpi_device_class(device);

View File

@ -725,6 +725,7 @@ static void dock_notify(acpi_handle handle, u32 event, void *data)
complete_dock(ds); complete_dock(ds);
dock_event(ds, event, DOCK_EVENT); dock_event(ds, event, DOCK_EVENT);
dock_lock(ds, 1); dock_lock(ds, 1);
acpi_update_gpes();
break; break;
} }
if (dock_present(ds) || dock_in_progress(ds)) 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 * allocated and initialize a new dock station device. Find all devices
* that are on the dock station, and register for dock event notifications. * 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; int ret, id;
struct dock_station ds, *dock_station; 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. * 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) find_dock(acpi_handle handle, u32 lvl, void *context, void **rv)
{ {
if (is_dock(handle)) if (is_dock(handle))
@ -1032,7 +1033,7 @@ find_dock(acpi_handle handle, u32 lvl, void *context, void **rv)
return AE_OK; return AE_OK;
} }
static acpi_status static __init acpi_status
find_bay(acpi_handle handle, u32 lvl, void *context, void **rv) find_bay(acpi_handle handle, u32 lvl, void *context, void **rv)
{ {
/* If bay is a dock, it's already handled */ /* If bay is a dock, it's already handled */

View File

@ -83,6 +83,11 @@ enum {
EC_FLAGS_BLOCKED, /* Transactions are blocked */ 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 */ /* 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 */ /* External interfaces use first EC only, so remember */
typedef int (*acpi_ec_query_func) (void *data); 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 */ int repeat = 2; /* number of command restarts */
while (repeat--) { while (repeat--) {
unsigned long delay = jiffies + unsigned long delay = jiffies +
msecs_to_jiffies(ACPI_EC_DELAY); msecs_to_jiffies(ec_delay);
do { do {
/* don't sleep with disabled interrupts */ /* don't sleep with disabled interrupts */
if (EC_FLAGS_MSI || irqs_disabled()) { 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) 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 */ /* interrupt wait manually if GPE mode is not active */
while (time_before(jiffies, delay)) while (time_before(jiffies, delay))
if (wait_event_timeout(ec->wait, ec_check_ibf0(ec), if (wait_event_timeout(ec->wait, ec_check_ibf0(ec),

View File

@ -27,8 +27,6 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <linux/thermal.h> #include <linux/thermal.h>
#include <acpi/acpi_bus.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, .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 Driver Interface
-------------------------------------------------------------------------- */ -------------------------------------------------------------------------- */
@ -284,10 +166,6 @@ static int acpi_fan_add(struct acpi_device *device)
dev_err(&device->dev, "Failed to create sysfs link " dev_err(&device->dev, "Failed to create sysfs link "
"'device'\n"); "'device'\n");
result = acpi_fan_add_fs(device);
if (result)
goto end;
printk(KERN_INFO PREFIX "%s [%s] (%s)\n", printk(KERN_INFO PREFIX "%s [%s] (%s)\n",
acpi_device_name(device), acpi_device_bid(device), acpi_device_name(device), acpi_device_bid(device),
!device->power.state ? "on" : "off"); !device->power.state ? "on" : "off");
@ -303,7 +181,6 @@ static int acpi_fan_remove(struct acpi_device *device, int type)
if (!device || !cdev) if (!device || !cdev)
return -EINVAL; return -EINVAL;
acpi_fan_remove_fs(device);
sysfs_remove_link(&device->dev.kobj, "thermal_cooling"); sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
sysfs_remove_link(&cdev->device.kobj, "device"); sysfs_remove_link(&cdev->device.kobj, "device");
thermal_cooling_device_unregister(cdev); thermal_cooling_device_unregister(cdev);
@ -347,19 +224,9 @@ static int __init acpi_fan_init(void)
{ {
int result = 0; 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); result = acpi_bus_register_driver(&acpi_fan_driver);
if (result < 0) { if (result < 0)
#ifdef CONFIG_ACPI_PROCFS
remove_proc_entry(ACPI_FAN_CLASS, acpi_root_dir);
#endif
return -ENODEV; return -ENODEV;
}
return 0; return 0;
} }
@ -369,10 +236,6 @@ static void __exit acpi_fan_exit(void)
acpi_bus_unregister_driver(&acpi_fan_driver); acpi_bus_unregister_driver(&acpi_fan_driver);
#ifdef CONFIG_ACPI_PROCFS
remove_proc_entry(ACPI_FAN_CLASS, acpi_root_dir);
#endif
return; return;
} }

View File

@ -95,8 +95,25 @@ struct acpi_res_list {
static LIST_HEAD(resource_list_head); static LIST_HEAD(resource_list_head);
static DEFINE_SPINLOCK(acpi_res_lock); 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 */ #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) * The story of _OSI(Linux)
@ -138,6 +155,20 @@ static struct osi_linux {
unsigned int known:1; unsigned int known:1;
} osi_linux = { 0, 0, 0, 0}; } 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, static void __init acpi_request_region (struct acpi_generic_address *addr,
unsigned int length, char *desc) unsigned int length, char *desc)
{ {
@ -185,36 +216,6 @@ static int __init acpi_reserve_resources(void)
} }
device_initcall(acpi_reserve_resources); 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, ...) void acpi_os_printf(const char *fmt, ...)
{ {
va_list args; 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 void __iomem *__init_refok
acpi_os_map_memory(acpi_physical_address phys, acpi_size size) 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) { if (phys > ULONG_MAX) {
printk(KERN_ERR PREFIX "Cannot map memory that high\n"); printk(KERN_ERR PREFIX "Cannot map memory that high\n");
return NULL; return NULL;
} }
if (acpi_gbl_permanent_mmap)
/* if (!acpi_gbl_permanent_mmap)
* ioremap checks to ensure this is in reserved space
*/
return ioremap((unsigned long)phys, size);
else
return __acpi_map_table((unsigned long)phys, size); 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); 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) void __ref acpi_os_unmap_memory(void __iomem *virt, acpi_size size)
{ {
if (acpi_gbl_permanent_mmap) struct acpi_ioremap *map;
iounmap(virt); unsigned long flags;
else int del;
if (!acpi_gbl_permanent_mmap) {
__acpi_unmap_table(virt, size); __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); 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); __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 #ifdef ACPI_FUTURE_USAGE
acpi_status acpi_status
acpi_os_get_physical_address(void *virt, acpi_physical_address * phys) 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; u32 dummy;
void __iomem *virt_addr; 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) if (!value)
value = &dummy; value = &dummy;
@ -514,7 +666,8 @@ acpi_os_read_memory(acpi_physical_address phys_addr, u32 * value, u32 width)
BUG(); BUG();
} }
iounmap(virt_addr); if (unmap)
iounmap(virt_addr);
return AE_OK; return AE_OK;
} }
@ -523,8 +676,15 @@ acpi_status
acpi_os_write_memory(acpi_physical_address phys_addr, u32 value, u32 width) acpi_os_write_memory(acpi_physical_address phys_addr, u32 value, u32 width)
{ {
void __iomem *virt_addr; 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) { switch (width) {
case 8: case 8:
@ -540,16 +700,18 @@ acpi_os_write_memory(acpi_physical_address phys_addr, u32 value, u32 width)
BUG(); BUG();
} }
iounmap(virt_addr); if (unmap)
iounmap(virt_addr);
return AE_OK; return AE_OK;
} }
acpi_status acpi_status
acpi_os_read_pci_configuration(struct acpi_pci_id * pci_id, u32 reg, acpi_os_read_pci_configuration(struct acpi_pci_id * pci_id, u32 reg,
u32 *value, u32 width) u64 *value, u32 width)
{ {
int result, size; int result, size;
u32 value32;
if (!value) if (!value)
return AE_BAD_PARAMETER; 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, result = raw_pci_read(pci_id->segment, pci_id->bus,
PCI_DEVFN(pci_id->device, pci_id->function), PCI_DEVFN(pci_id->device, pci_id->function),
reg, size, value); reg, size, &value32);
*value = value32;
return (result ? AE_ERROR : AE_OK); 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); 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) static void acpi_os_execute_deferred(struct work_struct *work)
{ {
struct acpi_os_dpc *dpc = container_of(work, struct acpi_os_dpc, 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); 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. * 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", printk(KERN_NOTICE PREFIX "%sed _OSI(Linux)\n",
enable ? "Add": "Delet"); enable ? "Add": "Delet");
} }
if (osi_linux.enable)
acpi_osi_setup("Linux");
else
acpi_osi_setup("!Linux");
return; 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 * string starting with '!' disables that string
* otherwise string is added to list, augmenting built-in strings * 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) int __init acpi_osi_setup(char *str)
{ {
if (str == NULL || *str == '\0') { if (str == NULL || *str == '\0') {
printk(KERN_INFO PREFIX "_OSI method disabled\n"); printk(KERN_INFO PREFIX "_OSI method disabled\n");
acpi_gbl_create_osi_method = FALSE; acpi_gbl_create_osi_method = FALSE;
} else if (!strcmp("!Linux", str)) { } else {
acpi_cmdline_osi_linux(0); /* !enable */ strncpy(osi_setup_string, str, OSI_STRING_LENGTH_MAX);
} 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);
} }
return 1; return 1;
@ -1152,21 +1255,6 @@ int acpi_check_region(resource_size_t start, resource_size_t n,
} }
EXPORT_SYMBOL(acpi_check_region); 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 * 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); 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) static inline int acpi_res_list_add(struct acpi_res_list *res)
{ {
struct acpi_res_list *res_list_elem; struct acpi_res_list *res_list_elem;
@ -1462,5 +1518,46 @@ acpi_os_validate_address (
} }
return AE_OK; return AE_OK;
} }
#endif #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;
}

View File

@ -32,7 +32,6 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/proc_fs.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/pm.h> #include <linux/pm.h>
#include <linux/pci.h> #include <linux/pci.h>

View File

@ -34,7 +34,6 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/proc_fs.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/pm.h> #include <linux/pm.h>
#include <linux/pci.h> #include <linux/pci.h>

View File

@ -27,7 +27,6 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/proc_fs.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/pm.h> #include <linux/pm.h>
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>

View File

@ -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_power_resource {
struct acpi_device * device; struct acpi_device * device;
acpi_bus_id name; acpi_bus_id name;
u32 system_level; u32 system_level;
u32 order; u32 order;
unsigned int ref_count;
struct mutex resource_lock; struct mutex resource_lock;
struct list_head reference;
}; };
static struct list_head acpi_power_resource_list; 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; 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; 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); status = acpi_evaluate_object(resource->device->handle, "_ON", NULL, NULL);
if (ACPI_FAILURE(status)) 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 */ /* Update the power resource's _device_ power state */
resource->device->power.state = ACPI_STATE_D0; 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)); resource->name));
return 0; 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; int result = 0;
acpi_status status = AE_OK;
struct acpi_power_resource *resource = NULL; struct acpi_power_resource *resource = NULL;
struct list_head *node, *next;
struct acpi_power_reference *ref;
result = acpi_power_get_context(handle, &resource); result = acpi_power_get_context(handle, &resource);
if (result) if (result)
return result; return result;
mutex_lock(&resource->resource_lock); mutex_lock(&resource->resource_lock);
list_for_each_safe(node, next, &resource->reference) {
ref = container_of(node, struct acpi_power_reference, node); if (resource->ref_count++) {
if (dev->handle == ref->device->handle) { ACPI_DEBUG_PRINT((ACPI_DB_INFO,
list_del(&ref->node); "Power resource [%s] already on",
kfree(ref); resource->name));
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] removed from resource [%s] references\n", } else {
dev->pnp.bus_id, resource->name)); result = __acpi_power_on(resource);
break;
}
} }
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); 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; 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_device_sleep_wake - execute _DSW (Device Sleep Wake) or (deprecated in
* ACPI 3.0) _PSW (Power State Wake) * 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 */ /* Open power resource */
for (i = 0; i < dev->wakeup.resources.count; i++) { 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) { if (ret) {
printk(KERN_ERR PREFIX "Transition power state\n"); printk(KERN_ERR PREFIX "Transition power state\n");
dev->wakeup.flags.valid = 0; dev->wakeup.flags.valid = 0;
@ -420,7 +403,7 @@ int acpi_disable_wakeup_device_power(struct acpi_device *dev)
/* Close power resource */ /* Close power resource */
for (i = 0; i < dev->wakeup.resources.count; i++) { for (i = 0; i < dev->wakeup.resources.count; i++) {
int ret = acpi_power_off_device( int ret = acpi_power_off_device(
dev->wakeup.resources.handles[i], dev); dev->wakeup.resources.handles[i]);
if (ret) { if (ret) {
printk(KERN_ERR PREFIX "Transition power state\n"); printk(KERN_ERR PREFIX "Transition power state\n");
dev->wakeup.flags.valid = 0; 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). * (e.g. so the device doesn't lose power while transitioning).
*/ */
for (i = 0; i < tl->count; i++) { for (i = 0; i < tl->count; i++) {
result = acpi_power_on(tl->handles[i], device); result = acpi_power_on(tl->handles[i]);
if (result) if (result)
goto end; 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. * Then we dereference all power resources used in the current list.
*/ */
for (i = 0; i < cl->count; i++) { 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) if (result)
goto end; goto end;
} }
@ -551,7 +534,6 @@ static int acpi_power_add(struct acpi_device *device)
resource->device = device; resource->device = device;
mutex_init(&resource->resource_lock); mutex_init(&resource->resource_lock);
INIT_LIST_HEAD(&resource->reference);
strcpy(resource->name, device->pnp.bus_id); strcpy(resource->name, device->pnp.bus_id);
strcpy(acpi_device_name(device), ACPI_POWER_DEVICE_NAME); strcpy(acpi_device_name(device), ACPI_POWER_DEVICE_NAME);
strcpy(acpi_device_class(device), ACPI_POWER_CLASS); 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) static int acpi_power_remove(struct acpi_device *device, int type)
{ {
struct acpi_power_resource *resource = NULL; struct acpi_power_resource *resource;
struct list_head *node, *next;
if (!device)
if (!device || !acpi_driver_data(device))
return -EINVAL; return -EINVAL;
resource = acpi_driver_data(device); resource = acpi_driver_data(device);
if (!resource)
mutex_lock(&resource->resource_lock); return -EINVAL;
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);
kfree(resource); 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) static int acpi_power_resume(struct acpi_device *device)
{ {
int result = 0, state; int result = 0, state;
struct acpi_power_resource *resource = NULL; struct acpi_power_resource *resource;
struct acpi_power_reference *ref;
if (!device || !acpi_driver_data(device)) if (!device)
return -EINVAL; return -EINVAL;
resource = acpi_driver_data(device); resource = acpi_driver_data(device);
if (!resource)
return -EINVAL;
mutex_lock(&resource->resource_lock);
result = acpi_power_get_state(device->handle, &state); result = acpi_power_get_state(device->handle, &state);
if (result) if (result)
return result; goto unlock;
mutex_lock(&resource->resource_lock); if (state == ACPI_POWER_RESOURCE_STATE_OFF && resource->ref_count)
if (state == ACPI_POWER_RESOURCE_STATE_OFF && result = __acpi_power_on(resource);
!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;
}
unlock:
mutex_unlock(&resource->resource_lock); mutex_unlock(&resource->resource_lock);
return 0;
return result;
} }
int __init acpi_power_init(void) int __init acpi_power_init(void)

View File

@ -40,8 +40,10 @@
#include <linux/pm.h> #include <linux/pm.h>
#include <linux/cpufreq.h> #include <linux/cpufreq.h>
#include <linux/cpu.h> #include <linux/cpu.h>
#ifdef CONFIG_ACPI_PROCFS
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/seq_file.h> #include <linux/seq_file.h>
#endif
#include <linux/dmi.h> #include <linux/dmi.h>
#include <linux/moduleparam.h> #include <linux/moduleparam.h>
#include <linux/cpuidle.h> #include <linux/cpuidle.h>
@ -244,6 +246,7 @@ static int acpi_processor_errata(struct acpi_processor *pr)
return result; return result;
} }
#ifdef CONFIG_ACPI_PROCFS
static struct proc_dir_entry *acpi_processor_dir = NULL; static struct proc_dir_entry *acpi_processor_dir = NULL;
static int __cpuinit acpi_processor_add_fs(struct acpi_device *device) 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; 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 Driver Interface
-------------------------------------------------------------------------- */ -------------------------------------------------------------------------- */
@ -842,9 +854,11 @@ static int __init acpi_processor_init(void)
memset(&errata, 0, sizeof(errata)); memset(&errata, 0, sizeof(errata));
#ifdef CONFIG_ACPI_PROCFS
acpi_processor_dir = proc_mkdir(ACPI_PROCESSOR_CLASS, acpi_root_dir); acpi_processor_dir = proc_mkdir(ACPI_PROCESSOR_CLASS, acpi_root_dir);
if (!acpi_processor_dir) if (!acpi_processor_dir)
return -ENOMEM; return -ENOMEM;
#endif
if (!cpuidle_register_driver(&acpi_idle_driver)) { if (!cpuidle_register_driver(&acpi_idle_driver)) {
printk(KERN_DEBUG "ACPI: %s registered with cpuidle\n", printk(KERN_DEBUG "ACPI: %s registered with cpuidle\n",
@ -871,7 +885,9 @@ static int __init acpi_processor_init(void)
out_cpuidle: out_cpuidle:
cpuidle_unregister_driver(&acpi_idle_driver); cpuidle_unregister_driver(&acpi_idle_driver);
#ifdef CONFIG_ACPI_PROCFS
remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir); remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir);
#endif
return result; return result;
} }
@ -891,7 +907,9 @@ static void __exit acpi_processor_exit(void)
cpuidle_unregister_driver(&acpi_idle_driver); cpuidle_unregister_driver(&acpi_idle_driver);
#ifdef CONFIG_ACPI_PROCFS
remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir); remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir);
#endif
return; return;
} }
@ -899,6 +917,4 @@ static void __exit acpi_processor_exit(void)
module_init(acpi_processor_init); module_init(acpi_processor_init);
module_exit(acpi_processor_exit); module_exit(acpi_processor_exit);
EXPORT_SYMBOL(acpi_processor_set_thermal_limit);
MODULE_ALIAS("processor"); MODULE_ALIAS("processor");

View File

@ -64,7 +64,6 @@
#define ACPI_PROCESSOR_CLASS "processor" #define ACPI_PROCESSOR_CLASS "processor"
#define _COMPONENT ACPI_PROCESSOR_COMPONENT #define _COMPONENT ACPI_PROCESSOR_COMPONENT
ACPI_MODULE_NAME("processor_idle"); ACPI_MODULE_NAME("processor_idle");
#define ACPI_PROCESSOR_FILE_POWER "power"
#define PM_TIMER_TICK_NS (1000000000ULL/PM_TIMER_FREQUENCY) #define PM_TIMER_TICK_NS (1000000000ULL/PM_TIMER_FREQUENCY)
#define C2_OVERHEAD 1 /* 1us */ #define C2_OVERHEAD 1 /* 1us */
#define C3_OVERHEAD 1 /* 1us */ #define C3_OVERHEAD 1 /* 1us */

View File

@ -44,47 +44,6 @@
#define _COMPONENT ACPI_PROCESSOR_COMPONENT #define _COMPONENT ACPI_PROCESSOR_COMPONENT
ACPI_MODULE_NAME("processor_thermal"); 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 #ifdef CONFIG_CPU_FREQ
/* If a passive cooling situation is detected, primarily CPUfreq is used, as it /* 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; 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, static int acpi_thermal_cpufreq_notifier(struct notifier_block *nb,
unsigned long event, void *data) unsigned long event, void *data)
{ {
@ -238,113 +167,6 @@ static int acpi_thermal_cpufreq_decrease(unsigned int cpu)
#endif #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) int acpi_processor_get_limit_info(struct acpi_processor *pr)
{ {

View File

@ -32,8 +32,10 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/cpufreq.h> #include <linux/cpufreq.h>
#ifdef CONFIG_ACPI_PROCFS
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/seq_file.h> #include <linux/seq_file.h>
#endif
#include <asm/io.h> #include <asm/io.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
@ -1214,6 +1216,7 @@ int acpi_processor_get_throttling_info(struct acpi_processor *pr)
return result; return result;
} }
#ifdef CONFIG_ACPI_PROCFS
/* proc interface */ /* proc interface */
static int acpi_processor_throttling_seq_show(struct seq_file *seq, static int acpi_processor_throttling_seq_show(struct seq_file *seq,
void *offset) void *offset)
@ -1322,3 +1325,4 @@ const struct file_operations acpi_processor_throttling_fops = {
.llseek = seq_lseek, .llseek = seq_lseek,
.release = single_release, .release = single_release,
}; };
#endif

View File

@ -40,10 +40,7 @@
#include <linux/timer.h> #include <linux/timer.h>
#include <linux/jiffies.h> #include <linux/jiffies.h>
#include <linux/delay.h> #include <linux/delay.h>
#ifdef CONFIG_ACPI_SYSFS_POWER
#include <linux/power_supply.h> #include <linux/power_supply.h>
#endif
#include "sbshc.h" #include "sbshc.h"
@ -85,9 +82,7 @@ static const struct acpi_device_id sbs_device_ids[] = {
MODULE_DEVICE_TABLE(acpi, sbs_device_ids); MODULE_DEVICE_TABLE(acpi, sbs_device_ids);
struct acpi_battery { struct acpi_battery {
#ifdef CONFIG_ACPI_SYSFS_POWER
struct power_supply bat; struct power_supply bat;
#endif
struct acpi_sbs *sbs; struct acpi_sbs *sbs;
#ifdef CONFIG_ACPI_PROCFS_POWER #ifdef CONFIG_ACPI_PROCFS_POWER
struct proc_dir_entry *proc_entry; 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); #define to_acpi_battery(x) container_of(x, struct acpi_battery, bat);
struct acpi_sbs { struct acpi_sbs {
#ifdef CONFIG_ACPI_SYSFS_POWER
struct power_supply charger; struct power_supply charger;
#endif
struct acpi_device *device; struct acpi_device *device;
struct acpi_smb_hc *hc; struct acpi_smb_hc *hc;
struct mutex lock; struct mutex lock;
@ -166,7 +159,6 @@ static inline int acpi_battery_scale(struct acpi_battery *battery)
acpi_battery_ipscale(battery); acpi_battery_ipscale(battery);
} }
#ifdef CONFIG_ACPI_SYSFS_POWER
static int sbs_get_ac_property(struct power_supply *psy, static int sbs_get_ac_property(struct power_supply *psy,
enum power_supply_property psp, enum power_supply_property psp,
union power_supply_propval *val) union power_supply_propval *val)
@ -313,7 +305,6 @@ static enum power_supply_property sbs_energy_battery_props[] = {
POWER_SUPPLY_PROP_MANUFACTURER, POWER_SUPPLY_PROP_MANUFACTURER,
}; };
#endif
/* -------------------------------------------------------------------------- /* --------------------------------------------------------------------------
Smart Battery System Management Smart Battery System Management
@ -449,7 +440,6 @@ static int acpi_ac_get_present(struct acpi_sbs *sbs)
return result; return result;
} }
#ifdef CONFIG_ACPI_SYSFS_POWER
static ssize_t acpi_battery_alarm_show(struct device *dev, static ssize_t acpi_battery_alarm_show(struct device *dev,
struct device_attribute *attr, struct device_attribute *attr,
char *buf) char *buf)
@ -479,7 +469,6 @@ static struct device_attribute alarm_attr = {
.show = acpi_battery_alarm_show, .show = acpi_battery_alarm_show,
.store = acpi_battery_alarm_store, .store = acpi_battery_alarm_store,
}; };
#endif
/* -------------------------------------------------------------------------- /* --------------------------------------------------------------------------
FS Interface (/proc/acpi) 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, &acpi_battery_state_fops, &acpi_battery_alarm_fops,
battery); battery);
#endif #endif
#ifdef CONFIG_ACPI_SYSFS_POWER
battery->bat.name = battery->name; battery->bat.name = battery->name;
battery->bat.type = POWER_SUPPLY_TYPE_BATTERY; battery->bat.type = POWER_SUPPLY_TYPE_BATTERY;
if (!acpi_battery_mode(battery)) { if (!acpi_battery_mode(battery)) {
@ -819,7 +807,6 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id)
goto end; goto end;
battery->have_sysfs_alarm = 1; battery->have_sysfs_alarm = 1;
end: end:
#endif
printk(KERN_INFO PREFIX "%s [%s]: Battery Slot [%s] (battery %s)\n", printk(KERN_INFO PREFIX "%s [%s]: Battery Slot [%s] (battery %s)\n",
ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device), ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device),
battery->name, battery->present ? "present" : "absent"); 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) 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]; struct acpi_battery *battery = &sbs->battery[id];
#endif
#ifdef CONFIG_ACPI_SYSFS_POWER
if (battery->bat.dev) { if (battery->bat.dev) {
if (battery->have_sysfs_alarm) if (battery->have_sysfs_alarm)
device_remove_file(battery->bat.dev, &alarm_attr); device_remove_file(battery->bat.dev, &alarm_attr);
power_supply_unregister(&battery->bat); power_supply_unregister(&battery->bat);
} }
#endif
#ifdef CONFIG_ACPI_PROCFS_POWER #ifdef CONFIG_ACPI_PROCFS_POWER
if (battery->proc_entry) if (battery->proc_entry)
acpi_sbs_remove_fs(&battery->proc_entry, acpi_battery_dir); 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) if (result)
goto end; goto end;
#endif #endif
#ifdef CONFIG_ACPI_SYSFS_POWER
sbs->charger.name = "sbs-charger"; sbs->charger.name = "sbs-charger";
sbs->charger.type = POWER_SUPPLY_TYPE_MAINS; sbs->charger.type = POWER_SUPPLY_TYPE_MAINS;
sbs->charger.properties = sbs_ac_props; sbs->charger.properties = sbs_ac_props;
sbs->charger.num_properties = ARRAY_SIZE(sbs_ac_props); sbs->charger.num_properties = ARRAY_SIZE(sbs_ac_props);
sbs->charger.get_property = sbs_get_ac_property; sbs->charger.get_property = sbs_get_ac_property;
power_supply_register(&sbs->device->dev, &sbs->charger); power_supply_register(&sbs->device->dev, &sbs->charger);
#endif
printk(KERN_INFO PREFIX "%s [%s]: AC Adapter [%s] (%s)\n", printk(KERN_INFO PREFIX "%s [%s]: AC Adapter [%s] (%s)\n",
ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device), ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device),
ACPI_AC_DIR_NAME, sbs->charger_present ? "on-line" : "off-line"); 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) static void acpi_charger_remove(struct acpi_sbs *sbs)
{ {
#ifdef CONFIG_ACPI_SYSFS_POWER
if (sbs->charger.dev) if (sbs->charger.dev)
power_supply_unregister(&sbs->charger); power_supply_unregister(&sbs->charger);
#endif
#ifdef CONFIG_ACPI_PROCFS_POWER #ifdef CONFIG_ACPI_PROCFS_POWER
if (sbs->charger_entry) if (sbs->charger_entry)
acpi_sbs_remove_fs(&sbs->charger_entry, acpi_ac_dir); 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, ACPI_SBS_NOTIFY_STATUS,
sbs->charger_present); sbs->charger_present);
#endif #endif
#ifdef CONFIG_ACPI_SYSFS_POWER
kobject_uevent(&sbs->charger.dev->kobj, KOBJ_CHANGE); kobject_uevent(&sbs->charger.dev->kobj, KOBJ_CHANGE);
#endif
} }
if (sbs->manager_present) { if (sbs->manager_present) {
for (id = 0; id < MAX_SBS_BAT; ++id) { for (id = 0; id < MAX_SBS_BAT; ++id) {
@ -919,9 +896,7 @@ static void acpi_sbs_callback(void *context)
ACPI_SBS_NOTIFY_STATUS, ACPI_SBS_NOTIFY_STATUS,
bat->present); bat->present);
#endif #endif
#ifdef CONFIG_ACPI_SYSFS_POWER
kobject_uevent(&bat->bat.dev->kobj, KOBJ_CHANGE); kobject_uevent(&bat->bat.dev->kobj, KOBJ_CHANGE);
#endif
} }
} }
} }

View File

@ -26,6 +26,8 @@ extern struct acpi_device *acpi_root;
#define ACPI_IS_ROOT_DEVICE(device) (!(device)->parent) #define ACPI_IS_ROOT_DEVICE(device) (!(device)->parent)
static const char *dummy_hid = "device";
static LIST_HEAD(acpi_device_list); static LIST_HEAD(acpi_device_list);
static LIST_HEAD(acpi_bus_id_list); static LIST_HEAD(acpi_bus_id_list);
DEFINE_MUTEX(acpi_device_lock); DEFINE_MUTEX(acpi_device_lock);
@ -49,6 +51,9 @@ static int create_modalias(struct acpi_device *acpi_dev, char *modalias,
int count; int count;
struct acpi_hardware_id *id; struct acpi_hardware_id *id;
if (list_empty(&acpi_dev->pnp.ids))
return 0;
len = snprintf(modalias, size, "acpi:"); len = snprintf(modalias, size, "acpi:");
size -= len; size -= len;
@ -202,13 +207,15 @@ static int acpi_device_setup_files(struct acpi_device *dev)
goto end; goto end;
} }
result = device_create_file(&dev->dev, &dev_attr_hid); if (!list_empty(&dev->pnp.ids)) {
if (result) result = device_create_file(&dev->dev, &dev_attr_hid);
goto end; if (result)
goto end;
result = device_create_file(&dev->dev, &dev_attr_modalias); result = device_create_file(&dev->dev, &dev_attr_modalias);
if (result) if (result)
goto end; goto end;
}
/* /*
* If device has _EJ0, 'eject' file is created that is used to trigger * 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); struct acpi_device *acpi_dev = to_acpi_device(dev);
int len; int len;
if (list_empty(&acpi_dev->pnp.ids))
return 0;
if (add_uevent_var(env, "MODALIAS=")) if (add_uevent_var(env, "MODALIAS="))
return -ENOMEM; return -ENOMEM;
len = create_modalias(acpi_dev, &env->buf[env->buflen - 1], 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); 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; 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); hid = list_first_entry(&device->pnp.ids, struct acpi_hardware_id, list);
return hid->id; 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); acpi_add_id(device, ACPI_BUTTON_HID_SLEEPF);
break; 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) 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) int acpi_bus_start(struct acpi_device *device)
{ {
struct acpi_bus_ops ops; struct acpi_bus_ops ops;
int result;
if (!device) if (!device)
return -EINVAL; return -EINVAL;
@ -1438,7 +1442,11 @@ int acpi_bus_start(struct acpi_device *device)
memset(&ops, 0, sizeof(ops)); memset(&ops, 0, sizeof(ops));
ops.acpi_op_start = 1; 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); EXPORT_SYMBOL(acpi_bus_start);
@ -1552,6 +1560,8 @@ int __init acpi_scan_init(void)
if (result) if (result)
acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL); acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL);
else
acpi_update_gpes();
return result; return result;
} }

View File

@ -25,7 +25,9 @@
#include "internal.h" #include "internal.h"
#include "sleep.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) 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 #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 * 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 * 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"), 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 */ #endif /* CONFIG_SUSPEND */
@ -562,7 +570,7 @@ int acpi_suspend(u32 acpi_state)
return -EINVAL; return -EINVAL;
} }
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_OPS
/** /**
* acpi_pm_device_sleep_state - return preferred power state of ACPI device * acpi_pm_device_sleep_state - return preferred power state of ACPI device
* in the system sleep state given by %acpi_target_sleep_state * 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. * can wake the system. _S0W may be valid, too.
*/ */
if (acpi_target_sleep_state == ACPI_STATE_S0 || 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)) { adev->wakeup.sleep_state <= acpi_target_sleep_state)) {
acpi_status status; 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, status = acpi_evaluate_integer(handle, acpi_method, NULL,
&d_max); &d_max);
if (ACPI_FAILURE(status)) { 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) { } else if (d_max < d_min) {
/* Warn the user of the broken DSDT */ /* Warn the user of the broken DSDT */
printk(KERN_WARNING "ACPI: Wrong value from %s\n", 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; *d_min_p = d_min;
return d_max; return d_max;
} }
#endif /* CONFIG_PM_OPS */
#ifdef CONFIG_PM_SLEEP
/** /**
* acpi_pm_device_sleep_wake - enable or disable the system wake-up * acpi_pm_device_sleep_wake - enable or disable the system wake-up
* capability of given device * capability of given device
@ -677,7 +689,7 @@ int acpi_pm_device_sleep_wake(struct device *dev, bool enable)
return error; return error;
} }
#endif #endif /* CONFIG_PM_SLEEP */
static void acpi_power_off_prepare(void) 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, * paths through the BIOS, so disable _GTS and _BFS by default,
* but do speak up and offer the option to enable them. * 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; acpi_handle dummy;

View File

@ -1,5 +1,4 @@
extern u8 sleep_states[];
extern int acpi_suspend(u32 state); extern int acpi_suspend(u32 state);
extern void acpi_enable_wakeup_devices(u8 sleep_state); extern void acpi_enable_wakeup_devices(u8 sleep_state);

View File

@ -37,12 +37,6 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/types.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/jiffies.h>
#include <linux/kmod.h> #include <linux/kmod.h>
#include <linux/reboot.h> #include <linux/reboot.h>
@ -195,61 +189,6 @@ struct acpi_thermal {
struct mutex lock; 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 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 Driver Interface
-------------------------------------------------------------------------- */ -------------------------------------------------------------------------- */
@ -1428,17 +1015,11 @@ static int acpi_thermal_add(struct acpi_device *device)
if (result) if (result)
goto free_memory; goto free_memory;
result = acpi_thermal_add_fs(device);
if (result)
goto unregister_thermal_zone;
printk(KERN_INFO PREFIX "%s [%s] (%ld C)\n", printk(KERN_INFO PREFIX "%s [%s] (%ld C)\n",
acpi_device_name(device), acpi_device_bid(device), acpi_device_name(device), acpi_device_bid(device),
KELVIN_TO_CELSIUS(tz->temperature)); KELVIN_TO_CELSIUS(tz->temperature));
goto end; goto end;
unregister_thermal_zone:
thermal_zone_device_unregister(tz->thermal_zone);
free_memory: free_memory:
kfree(tz); kfree(tz);
end: end:
@ -1454,7 +1035,6 @@ static int acpi_thermal_remove(struct acpi_device *device, int type)
tz = acpi_driver_data(device); tz = acpi_driver_data(device);
acpi_thermal_remove_fs(device);
acpi_thermal_unregister_thermal_zone(tz); acpi_thermal_unregister_thermal_zone(tz);
mutex_destroy(&tz->lock); mutex_destroy(&tz->lock);
kfree(tz); kfree(tz);
@ -1580,19 +1160,9 @@ static int __init acpi_thermal_init(void)
return -ENODEV; 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); result = acpi_bus_register_driver(&acpi_thermal_driver);
if (result < 0) { if (result < 0)
#ifdef CONFIG_ACPI_PROCFS
remove_proc_entry(ACPI_THERMAL_CLASS, acpi_root_dir);
#endif
return -ENODEV; return -ENODEV;
}
return 0; return 0;
} }
@ -1602,10 +1172,6 @@ static void __exit acpi_thermal_exit(void)
acpi_bus_unregister_driver(&acpi_thermal_driver); acpi_bus_unregister_driver(&acpi_thermal_driver);
#ifdef CONFIG_ACPI_PROCFS
remove_proc_entry(ACPI_THERMAL_CLASS, acpi_root_dir);
#endif
return; return;
} }

View File

@ -30,8 +30,6 @@
#include <linux/types.h> #include <linux/types.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/input.h> #include <linux/input.h>
#include <linux/backlight.h> #include <linux/backlight.h>
#include <linux/thermal.h> #include <linux/thermal.h>
@ -152,9 +150,6 @@ struct acpi_video_bus {
struct acpi_video_bus_flags flags; struct acpi_video_bus_flags flags;
struct list_head video_device_list; struct list_head video_device_list;
struct mutex device_list_lock; /* protects 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; struct input_dev *input;
char phys[32]; /* for input device */ char phys[32]; /* for input device */
struct notifier_block pm_nb; struct notifier_block pm_nb;
@ -210,108 +205,6 @@ struct acpi_video_device {
struct output_device *output_dev; 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] = { static const char device_decode[][30] = {
"motherboard VGA device", "motherboard VGA device",
"PCI VGA device", "PCI VGA device",
@ -1110,646 +1003,6 @@ static int acpi_video_bus_check(struct acpi_video_bus *video)
return status; 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 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); list_add_tail(&data->entry, &video->video_device_list);
mutex_unlock(&video->device_list_lock); mutex_unlock(&video->device_list_lock);
acpi_video_device_add_fs(device);
return 0; return 0;
} }
@ -2181,8 +1432,6 @@ static int acpi_video_bus_put_one_device(struct acpi_video_device *device)
if (!device || !device->video) if (!device || !device->video)
return -ENOENT; return -ENOENT;
acpi_video_device_remove_fs(device->dev);
status = acpi_remove_notify_handler(device->dev->handle, status = acpi_remove_notify_handler(device->dev->handle,
ACPI_DEVICE_NOTIFY, ACPI_DEVICE_NOTIFY,
acpi_video_device_notify); acpi_video_device_notify);
@ -2466,10 +1715,6 @@ static int acpi_video_bus_add(struct acpi_device *device)
if (error) if (error)
goto err_free_video; goto err_free_video;
error = acpi_video_bus_add_fs(device);
if (error)
goto err_free_video;
mutex_init(&video->device_list_lock); mutex_init(&video->device_list_lock);
INIT_LIST_HEAD(&video->video_device_list); 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_stop_devices(video);
acpi_video_bus_put_devices(video); acpi_video_bus_put_devices(video);
kfree(video->attached_array); kfree(video->attached_array);
acpi_video_bus_remove_fs(device);
err_free_video: err_free_video:
kfree(video); kfree(video);
device->driver_data = NULL; 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_stop_devices(video);
acpi_video_bus_put_devices(video); acpi_video_bus_put_devices(video);
acpi_video_bus_remove_fs(device);
input_unregister_device(video->input); input_unregister_device(video->input);
kfree(video->attached_array); kfree(video->attached_array);
@ -2584,17 +1827,9 @@ int acpi_video_register(void)
return 0; 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); result = acpi_bus_register_driver(&acpi_video_bus);
if (result < 0) { if (result < 0)
remove_proc_entry(ACPI_VIDEO_CLASS, acpi_root_dir);
return -ENODEV; return -ENODEV;
}
/* /*
* When the acpi_video_bus is loaded successfully, increase * 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); acpi_bus_unregister_driver(&acpi_video_bus);
#ifdef CONFIG_ACPI_PROCFS
remove_proc_entry(ACPI_VIDEO_CLASS, acpi_root_dir);
#endif
register_count = 0; register_count = 0;
return; return;

View File

@ -12,11 +12,12 @@ void pnp_unregister_protocol(struct pnp_protocol *protocol);
#define PNP_EISA_ID_MASK 0x7fffffff #define PNP_EISA_ID_MASK 0x7fffffff
void pnp_eisa_id_to_string(u32 id, char *str); 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); struct pnp_card *pnp_alloc_card(struct pnp_protocol *, int id, char *pnpid);
int pnp_add_device(struct pnp_dev *dev); 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); int pnp_add_card(struct pnp_card *card);
void pnp_remove_card(struct pnp_card *card); void pnp_remove_card(struct pnp_card *card);

View File

@ -124,7 +124,8 @@ static void pnp_release_device(struct device *dmdev)
kfree(dev); 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_dev *dev;
struct pnp_id *dev_id; 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) for (id = dev->id; id; id = id->next)
len += scnprintf(buf + len, sizeof(buf) - len, " %s", id->id); len += scnprintf(buf + len, sizeof(buf) - len, " %s", id->id);
pnp_dbg(&dev->dev, "%s device, IDs%s (%s)\n", dev_printk(KERN_DEBUG, &dev->dev, "%s device, IDs%s (%s)\n",
dev->protocol->name, buf, dev->active ? "active" : "disabled"); dev->protocol->name, buf,
dev->active ? "active" : "disabled");
return 0; return 0;
} }

View File

@ -236,7 +236,7 @@ void pnp_unregister_driver(struct pnp_driver *drv)
* @dev: pointer to the desired device * @dev: pointer to the desired device
* @id: pointer to an EISA id string * @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; struct pnp_id *dev_id, *ptr;

View File

@ -28,7 +28,7 @@
#include "../base.h" #include "../base.h"
#include "pnpacpi.h" #include "pnpacpi.h"
static int num = 0; static int num;
/* We need only to blacklist devices that have already an acpi driver that /* 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 * 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) \ #define TEST_ALPHA(c) \
if (!('@' <= (c) || (c) <= 'Z')) \ if (!('@' <= (c) || (c) <= 'Z')) \
return 0 return 0
static int __init ispnpidacpi(char *id) static int __init ispnpidacpi(const char *id)
{ {
TEST_ALPHA(id[0]); TEST_ALPHA(id[0]);
TEST_ALPHA(id[1]); TEST_ALPHA(id[1]);
@ -180,11 +180,24 @@ struct pnp_protocol pnpacpi_protocol = {
}; };
EXPORT_SYMBOL(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) static int __init pnpacpi_add_device(struct acpi_device *device)
{ {
acpi_handle temp = NULL; acpi_handle temp = NULL;
acpi_status status; acpi_status status;
struct pnp_dev *dev; struct pnp_dev *dev;
char *pnpid;
struct acpi_hardware_id *id; struct acpi_hardware_id *id;
/* /*
@ -192,11 +205,17 @@ static int __init pnpacpi_add_device(struct acpi_device *device)
* driver should not be loaded. * driver should not be loaded.
*/ */
status = acpi_get_handle(device->handle, "_CRS", &temp); status = acpi_get_handle(device->handle, "_CRS", &temp);
if (ACPI_FAILURE(status) || !ispnpidacpi(acpi_device_hid(device)) || if (ACPI_FAILURE(status))
is_exclusive_device(device) || (!device->status.present))
return 0; 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) if (!dev)
return -ENOMEM; return -ENOMEM;
@ -227,7 +246,7 @@ static int __init pnpacpi_add_device(struct acpi_device *device)
pnpacpi_parse_resource_option_data(dev); pnpacpi_parse_resource_option_data(dev);
list_for_each_entry(id, &device->pnp.ids, list) { list_for_each_entry(id, &device->pnp.ids, list) {
if (!strcmp(id->id, acpi_device_hid(device))) if (!strcmp(id->id, pnpid))
continue; continue;
if (!ispnpidacpi(id->id)) if (!ispnpidacpi(id->id))
continue; continue;

View File

@ -523,7 +523,7 @@ struct pnp_resource *pnp_add_irq_resource(struct pnp_dev *dev, int irq,
res->start = irq; res->start = irq;
res->end = irq; res->end = irq;
pnp_dbg(&dev->dev, " add %pr\n", res); dev_printk(KERN_DEBUG, &dev->dev, "%pR\n", res);
return pnp_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->start = dma;
res->end = dma; res->end = dma;
pnp_dbg(&dev->dev, " add %pr\n", res); dev_printk(KERN_DEBUG, &dev->dev, "%pR\n", res);
return pnp_res; return pnp_res;
} }
@ -568,7 +568,7 @@ struct pnp_resource *pnp_add_io_resource(struct pnp_dev *dev,
res->start = start; res->start = start;
res->end = end; res->end = end;
pnp_dbg(&dev->dev, " add %pr\n", res); dev_printk(KERN_DEBUG, &dev->dev, "%pR\n", res);
return pnp_res; return pnp_res;
} }
@ -592,7 +592,7 @@ struct pnp_resource *pnp_add_mem_resource(struct pnp_dev *dev,
res->start = start; res->start = start;
res->end = end; res->end = end;
pnp_dbg(&dev->dev, " add %pr\n", res); dev_printk(KERN_DEBUG, &dev->dev, "%pR\n", res);
return pnp_res; return pnp_res;
} }
@ -616,7 +616,7 @@ struct pnp_resource *pnp_add_bus_resource(struct pnp_dev *dev,
res->start = start; res->start = start;
res->end = end; res->end = end;
pnp_dbg(&dev->dev, " add %pr\n", res); dev_printk(KERN_DEBUG, &dev->dev, "%pR\n", res);
return pnp_res; return pnp_res;
} }

View File

@ -184,7 +184,7 @@ struct acpi_device_pnp {
#define acpi_device_bid(d) ((d)->pnp.bus_id) #define acpi_device_bid(d) ((d)->pnp.bus_id)
#define acpi_device_adr(d) ((d)->pnp.bus_address) #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_name(d) ((d)->pnp.device_name)
#define acpi_device_class(d) ((d)->pnp.device_class) #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_enable_wakeup_device_power(struct acpi_device *dev, int state);
int acpi_disable_wakeup_device_power(struct acpi_device *dev); 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_state(struct device *, int *);
int acpi_pm_device_sleep_wake(struct device *, bool); #else
#else /* !CONFIG_PM_SLEEP */
static inline int acpi_pm_device_sleep_state(struct device *d, int *p) static inline int acpi_pm_device_sleep_state(struct device *d, int *p)
{ {
if (p) if (p)
*p = ACPI_STATE_D0; *p = ACPI_STATE_D0;
return ACPI_STATE_D3; 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) static inline int acpi_pm_device_sleep_wake(struct device *dev, bool enable)
{ {
return -ENODEV; return -ENODEV;
} }
#endif /* !CONFIG_PM_SLEEP */ #endif
#endif /* CONFIG_ACPI */ #endif /* CONFIG_ACPI */

View File

@ -115,8 +115,6 @@ void pci_acpi_crs_quirks(void);
#define ACPI_PROCESSOR_LIMIT_INCREMENT 0x01 #define ACPI_PROCESSOR_LIMIT_INCREMENT 0x01
#define ACPI_PROCESSOR_LIMIT_DECREMENT 0x02 #define ACPI_PROCESSOR_LIMIT_DECREMENT 0x02
int acpi_processor_set_thermal_limit(acpi_handle handle, int type);
/*-------------------------------------------------------------------------- /*--------------------------------------------------------------------------
Dock Station Dock Station
-------------------------------------------------------------------------- */ -------------------------------------------------------------------------- */

View File

@ -98,8 +98,6 @@ acpi_os_table_override(struct acpi_table_header *existing_table,
/* /*
* Spinlock primitives * Spinlock primitives
*/ */
acpi_status acpi_os_create_lock(acpi_spinlock * out_handle);
void acpi_os_delete_lock(acpi_spinlock handle); void acpi_os_delete_lock(acpi_spinlock handle);
acpi_cpu_flags acpi_os_acquire_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_status
acpi_os_read_pci_configuration(struct acpi_pci_id *pci_id, 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_status
acpi_os_write_pci_configuration(struct acpi_pci_id *pci_id, acpi_os_write_pci_configuration(struct acpi_pci_id *pci_id,
u32 reg, u64 value, u32 width); 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 * Miscellaneous
*/ */
acpi_status acpi_os_validate_interface(char *interface);
acpi_status acpi_osi_invalidate(char* interface);
acpi_status acpi_status
acpi_os_validate_address(u8 space_id, acpi_physical_address address, acpi_os_validate_address(u8 space_id, acpi_physical_address address,
acpi_size length, char *name); acpi_size length, char *name);

View File

@ -47,7 +47,7 @@
/* Current ACPICA subsystem version in YYYYMMDD format */ /* Current ACPICA subsystem version in YYYYMMDD format */
#define ACPI_CA_VERSION 0x20100702 #define ACPI_CA_VERSION 0x20101013
#include "actypes.h" #include "actypes.h"
#include "actbl.h" #include "actbl.h"
@ -72,6 +72,7 @@ extern u8 acpi_gbl_truncate_io_addresses;
extern u32 acpi_current_gpe_count; extern u32 acpi_current_gpe_count;
extern struct acpi_table_fadt acpi_gbl_FADT; extern struct acpi_table_fadt acpi_gbl_FADT;
extern u8 acpi_gbl_system_awake_and_running;
extern u32 acpi_rsdt_forced; 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_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 * 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); acpi_status acpi_install_exception_handler(acpi_exception_handler handler);
#endif #endif
acpi_status acpi_install_interface_handler(acpi_interface_handler handler);
/* /*
* Event interfaces * 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_remove_gpe_block(acpi_handle gpe_device);
acpi_status acpi_update_gpes(void);
/* /*
* Resource interfaces * Resource interfaces
*/ */

View File

@ -115,7 +115,6 @@
* *
* ACPI_SIZE 16/32/64-bit unsigned value * ACPI_SIZE 16/32/64-bit unsigned value
* ACPI_NATIVE_INT 16/32/64-bit signed value * ACPI_NATIVE_INT 16/32/64-bit signed value
*
*/ */
/******************************************************************************* /*******************************************************************************
@ -132,6 +131,16 @@ typedef COMPILER_DEPENDENT_INT64 INT64;
/*! [End] no source code translation !*/ /*! [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 * 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 */ /* Flags for acpi_os_acquire_lock/acpi_os_release_lock */
#ifndef acpi_cpu_flags #ifndef acpi_cpu_flags
@ -375,16 +378,6 @@ typedef void *acpi_handle; /* Actually a ptr to a NS Node */
typedef u8 acpi_owner_id; typedef u8 acpi_owner_id;
#define ACPI_OWNER_ID_MAX 0xFF #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_INTEGER_BIT_SIZE 64
#define ACPI_MAX_DECIMAL_DIGITS 20 /* 2^64 = 18,446,744,073,709,551,616 */ #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, u32 nesting_level,
void *context, void **return_value); void *context, void **return_value);
typedef
u32 (*acpi_interface_handler) (acpi_string interface_name, u32 supported);
/* Interrupt handler return values */ /* Interrupt handler return values */
#define ACPI_INTERRUPT_NOT_HANDLED 0x00 #define ACPI_INTERRUPT_NOT_HANDLED 0x00

View File

@ -193,6 +193,12 @@
#define ACPI_MUTEX_TYPE ACPI_BINARY_SEMAPHORE #define ACPI_MUTEX_TYPE ACPI_BINARY_SEMAPHORE
#endif #endif
/* "inline" keywords - configurable since inline is not standardized */
#ifndef ACPI_INLINE
#define ACPI_INLINE
#endif
/* /*
* Debugger threading model * Debugger threading model
* Use single threaded if the entire subsystem is contained in an application * Use single threaded if the entire subsystem is contained in an application

View File

@ -44,6 +44,8 @@
#ifndef __ACGCC_H__ #ifndef __ACGCC_H__
#define __ACGCC_H__ #define __ACGCC_H__
#define ACPI_INLINE __inline__
/* Function name is used for debug output. Non-ANSI, compiler-dependent */ /* Function name is used for debug output. Non-ANSI, compiler-dependent */
#define ACPI_GET_FUNCTION_NAME __func__ #define ACPI_GET_FUNCTION_NAME __func__

View File

@ -75,7 +75,6 @@
#define acpi_cache_t struct kmem_cache #define acpi_cache_t struct kmem_cache
#define acpi_spinlock spinlock_t * #define acpi_spinlock spinlock_t *
#define acpi_cpu_flags unsigned long #define acpi_cpu_flags unsigned long
#define acpi_thread_id struct task_struct *
#else /* !__KERNEL__ */ #else /* !__KERNEL__ */
@ -88,7 +87,7 @@
/* Host-dependent types and defines for user-space ACPICA */ /* Host-dependent types and defines for user-space ACPICA */
#define ACPI_FLUSH_CPU_CACHE() #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__) #if defined(__ia64__) || defined(__x86_64__)
#define ACPI_MACHINE_WIDTH 64 #define ACPI_MACHINE_WIDTH 64
@ -113,12 +112,13 @@
#ifdef __KERNEL__ #ifdef __KERNEL__
#include <acpi/actypes.h>
/* /*
* Overrides for in-kernel ACPICA * Overrides for in-kernel ACPICA
*/ */
static inline acpi_thread_id acpi_os_get_thread_id(void) 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) * However, boot has (system_state != SYSTEM_RUNNING)
* to quiet __might_sleep() in kmalloc() and resume does not. * to quiet __might_sleep() in kmalloc() and resume does not.
*/ */
#include <acpi/actypes.h>
static inline void *acpi_os_allocate(acpi_size size) static inline void *acpi_os_allocate(acpi_size size)
{ {
return kmalloc(size, irqs_disabled() ? GFP_ATOMIC : GFP_KERNEL); return kmalloc(size, irqs_disabled() ? GFP_ATOMIC : GFP_KERNEL);

View File

@ -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, int acpi_check_region(resource_size_t start, resource_size_t n,
const char *name); 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); 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); u32 *mask, u32 req);
extern void acpi_early_init(void); 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 */ #else /* !CONFIG_ACPI */
#define acpi_disabled 1 #define acpi_disabled 1
@ -344,12 +345,6 @@ static inline int acpi_check_region(resource_size_t start, resource_size_t n,
return 0; 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; struct acpi_table_header;
static inline int acpi_table_parse(char *id, static inline int acpi_table_parse(char *id,
int (*handler)(struct acpi_table_header *)) int (*handler)(struct acpi_table_header *))