diff options
Diffstat (limited to 'drivers/acpi')
73 files changed, 2177 insertions, 2345 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index b811f2173f6..0f9de2b44c0 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig | |||
@@ -66,7 +66,6 @@ config ACPI_PROCFS | |||
66 | config ACPI_PROCFS_POWER | 66 | config ACPI_PROCFS_POWER |
67 | bool "Deprecated power /proc/acpi directories" | 67 | bool "Deprecated power /proc/acpi directories" |
68 | depends on PROC_FS | 68 | depends on PROC_FS |
69 | default y | ||
70 | help | 69 | help |
71 | For backwards compatibility, this option allows | 70 | For backwards compatibility, this option allows |
72 | deprecated power /proc/acpi/ directories to exist, even when | 71 | deprecated power /proc/acpi/ directories to exist, even when |
@@ -90,13 +89,6 @@ config ACPI_POWER_METER | |||
90 | To compile this driver as a module, choose M here: | 89 | To compile this driver as a module, choose M here: |
91 | the module will be called power-meter. | 90 | the module will be called power-meter. |
92 | 91 | ||
93 | config ACPI_SYSFS_POWER | ||
94 | bool "Future power /sys interface" | ||
95 | select POWER_SUPPLY | ||
96 | default y | ||
97 | help | ||
98 | Say N to disable power /sys interface | ||
99 | |||
100 | config ACPI_EC_DEBUGFS | 92 | config ACPI_EC_DEBUGFS |
101 | tristate "EC read/write access through /sys/kernel/debug/ec" | 93 | tristate "EC read/write access through /sys/kernel/debug/ec" |
102 | default n | 94 | default n |
@@ -105,7 +97,7 @@ config ACPI_EC_DEBUGFS | |||
105 | 97 | ||
106 | Be aware that using this interface can confuse your Embedded | 98 | Be aware that using this interface can confuse your Embedded |
107 | Controller in a way that a normal reboot is not enough. You then | 99 | Controller in a way that a normal reboot is not enough. You then |
108 | have to power of your system, and remove the laptop battery for | 100 | have to power off your system, and remove the laptop battery for |
109 | some seconds. | 101 | some seconds. |
110 | An Embedded Controller typically is available on laptops and reads | 102 | An Embedded Controller typically is available on laptops and reads |
111 | sensor values like battery state and temperature. | 103 | sensor values like battery state and temperature. |
@@ -136,6 +128,7 @@ config ACPI_PROC_EVENT | |||
136 | config ACPI_AC | 128 | config ACPI_AC |
137 | tristate "AC Adapter" | 129 | tristate "AC Adapter" |
138 | depends on X86 | 130 | depends on X86 |
131 | select POWER_SUPPLY | ||
139 | default y | 132 | default y |
140 | help | 133 | help |
141 | This driver supports the AC Adapter object, which indicates | 134 | This driver supports the AC Adapter object, which indicates |
@@ -148,6 +141,7 @@ config ACPI_AC | |||
148 | config ACPI_BATTERY | 141 | config ACPI_BATTERY |
149 | tristate "Battery" | 142 | tristate "Battery" |
150 | depends on X86 | 143 | depends on X86 |
144 | select POWER_SUPPLY | ||
151 | default y | 145 | default y |
152 | help | 146 | help |
153 | This driver adds support for battery information through | 147 | This driver adds support for battery information through |
@@ -364,6 +358,7 @@ config ACPI_HOTPLUG_MEMORY | |||
364 | config ACPI_SBS | 358 | config ACPI_SBS |
365 | tristate "Smart Battery System" | 359 | tristate "Smart Battery System" |
366 | depends on X86 | 360 | depends on X86 |
361 | select POWER_SUPPLY | ||
367 | help | 362 | help |
368 | This driver supports the Smart Battery System, another | 363 | This driver supports the Smart Battery System, another |
369 | type of access to battery information, found on some laptops. | 364 | type of access to battery information, found on some laptops. |
diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c index 56205a0b85d..ba9afeaa23a 100644 --- a/drivers/acpi/ac.c +++ b/drivers/acpi/ac.c | |||
@@ -32,9 +32,7 @@ | |||
32 | #include <linux/proc_fs.h> | 32 | #include <linux/proc_fs.h> |
33 | #include <linux/seq_file.h> | 33 | #include <linux/seq_file.h> |
34 | #endif | 34 | #endif |
35 | #ifdef CONFIG_ACPI_SYSFS_POWER | ||
36 | #include <linux/power_supply.h> | 35 | #include <linux/power_supply.h> |
37 | #endif | ||
38 | #include <acpi/acpi_bus.h> | 36 | #include <acpi/acpi_bus.h> |
39 | #include <acpi/acpi_drivers.h> | 37 | #include <acpi/acpi_drivers.h> |
40 | 38 | ||
@@ -86,9 +84,7 @@ static struct acpi_driver acpi_ac_driver = { | |||
86 | }; | 84 | }; |
87 | 85 | ||
88 | struct acpi_ac { | 86 | struct acpi_ac { |
89 | #ifdef CONFIG_ACPI_SYSFS_POWER | ||
90 | struct power_supply charger; | 87 | struct power_supply charger; |
91 | #endif | ||
92 | struct acpi_device * device; | 88 | struct acpi_device * device; |
93 | unsigned long long state; | 89 | unsigned long long state; |
94 | }; | 90 | }; |
@@ -104,7 +100,6 @@ static const struct file_operations acpi_ac_fops = { | |||
104 | .release = single_release, | 100 | .release = single_release, |
105 | }; | 101 | }; |
106 | #endif | 102 | #endif |
107 | #ifdef CONFIG_ACPI_SYSFS_POWER | ||
108 | static int get_ac_property(struct power_supply *psy, | 103 | static int get_ac_property(struct power_supply *psy, |
109 | enum power_supply_property psp, | 104 | enum power_supply_property psp, |
110 | union power_supply_propval *val) | 105 | union power_supply_propval *val) |
@@ -123,7 +118,6 @@ static int get_ac_property(struct power_supply *psy, | |||
123 | static enum power_supply_property ac_props[] = { | 118 | static enum power_supply_property ac_props[] = { |
124 | POWER_SUPPLY_PROP_ONLINE, | 119 | POWER_SUPPLY_PROP_ONLINE, |
125 | }; | 120 | }; |
126 | #endif | ||
127 | /* -------------------------------------------------------------------------- | 121 | /* -------------------------------------------------------------------------- |
128 | AC Adapter Management | 122 | AC Adapter Management |
129 | -------------------------------------------------------------------------- */ | 123 | -------------------------------------------------------------------------- */ |
@@ -247,9 +241,7 @@ static void acpi_ac_notify(struct acpi_device *device, u32 event) | |||
247 | dev_name(&device->dev), event, | 241 | dev_name(&device->dev), event, |
248 | (u32) ac->state); | 242 | (u32) ac->state); |
249 | acpi_notifier_call_chain(device, event, (u32) ac->state); | 243 | acpi_notifier_call_chain(device, event, (u32) ac->state); |
250 | #ifdef CONFIG_ACPI_SYSFS_POWER | ||
251 | kobject_uevent(&ac->charger.dev->kobj, KOBJ_CHANGE); | 244 | kobject_uevent(&ac->charger.dev->kobj, KOBJ_CHANGE); |
252 | #endif | ||
253 | } | 245 | } |
254 | 246 | ||
255 | return; | 247 | return; |
@@ -282,14 +274,12 @@ static int acpi_ac_add(struct acpi_device *device) | |||
282 | #endif | 274 | #endif |
283 | if (result) | 275 | if (result) |
284 | goto end; | 276 | goto end; |
285 | #ifdef CONFIG_ACPI_SYSFS_POWER | ||
286 | ac->charger.name = acpi_device_bid(device); | 277 | ac->charger.name = acpi_device_bid(device); |
287 | ac->charger.type = POWER_SUPPLY_TYPE_MAINS; | 278 | ac->charger.type = POWER_SUPPLY_TYPE_MAINS; |
288 | ac->charger.properties = ac_props; | 279 | ac->charger.properties = ac_props; |
289 | ac->charger.num_properties = ARRAY_SIZE(ac_props); | 280 | ac->charger.num_properties = ARRAY_SIZE(ac_props); |
290 | ac->charger.get_property = get_ac_property; | 281 | ac->charger.get_property = get_ac_property; |
291 | power_supply_register(&ac->device->dev, &ac->charger); | 282 | power_supply_register(&ac->device->dev, &ac->charger); |
292 | #endif | ||
293 | 283 | ||
294 | printk(KERN_INFO PREFIX "%s [%s] (%s)\n", | 284 | printk(KERN_INFO PREFIX "%s [%s] (%s)\n", |
295 | acpi_device_name(device), acpi_device_bid(device), | 285 | acpi_device_name(device), acpi_device_bid(device), |
@@ -316,10 +306,8 @@ static int acpi_ac_resume(struct acpi_device *device) | |||
316 | old_state = ac->state; | 306 | old_state = ac->state; |
317 | if (acpi_ac_get_state(ac)) | 307 | if (acpi_ac_get_state(ac)) |
318 | return 0; | 308 | return 0; |
319 | #ifdef CONFIG_ACPI_SYSFS_POWER | ||
320 | if (old_state != ac->state) | 309 | if (old_state != ac->state) |
321 | kobject_uevent(&ac->charger.dev->kobj, KOBJ_CHANGE); | 310 | kobject_uevent(&ac->charger.dev->kobj, KOBJ_CHANGE); |
322 | #endif | ||
323 | return 0; | 311 | return 0; |
324 | } | 312 | } |
325 | 313 | ||
@@ -333,10 +321,8 @@ static int acpi_ac_remove(struct acpi_device *device, int type) | |||
333 | 321 | ||
334 | ac = acpi_driver_data(device); | 322 | ac = acpi_driver_data(device); |
335 | 323 | ||
336 | #ifdef CONFIG_ACPI_SYSFS_POWER | ||
337 | if (ac->charger.dev) | 324 | if (ac->charger.dev) |
338 | power_supply_unregister(&ac->charger); | 325 | power_supply_unregister(&ac->charger); |
339 | #endif | ||
340 | #ifdef CONFIG_ACPI_PROCFS_POWER | 326 | #ifdef CONFIG_ACPI_PROCFS_POWER |
341 | acpi_ac_remove_fs(device); | 327 | acpi_ac_remove_fs(device); |
342 | #endif | 328 | #endif |
diff --git a/drivers/acpi/acpi_pad.c b/drivers/acpi/acpi_pad.c index b76848c80be..6b115f6c431 100644 --- a/drivers/acpi/acpi_pad.c +++ b/drivers/acpi/acpi_pad.c | |||
@@ -382,31 +382,32 @@ static void acpi_pad_remove_sysfs(struct acpi_device *device) | |||
382 | device_remove_file(&device->dev, &dev_attr_rrtime); | 382 | device_remove_file(&device->dev, &dev_attr_rrtime); |
383 | } | 383 | } |
384 | 384 | ||
385 | /* Query firmware how many CPUs should be idle */ | 385 | /* |
386 | static int acpi_pad_pur(acpi_handle handle, int *num_cpus) | 386 | * Query firmware how many CPUs should be idle |
387 | * return -1 on failure | ||
388 | */ | ||
389 | static int acpi_pad_pur(acpi_handle handle) | ||
387 | { | 390 | { |
388 | struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; | 391 | struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; |
389 | union acpi_object *package; | 392 | union acpi_object *package; |
390 | int rev, num, ret = -EINVAL; | 393 | int num = -1; |
391 | 394 | ||
392 | if (ACPI_FAILURE(acpi_evaluate_object(handle, "_PUR", NULL, &buffer))) | 395 | if (ACPI_FAILURE(acpi_evaluate_object(handle, "_PUR", NULL, &buffer))) |
393 | return -EINVAL; | 396 | return num; |
394 | 397 | ||
395 | if (!buffer.length || !buffer.pointer) | 398 | if (!buffer.length || !buffer.pointer) |
396 | return -EINVAL; | 399 | return num; |
397 | 400 | ||
398 | package = buffer.pointer; | 401 | package = buffer.pointer; |
399 | if (package->type != ACPI_TYPE_PACKAGE || package->package.count != 2) | 402 | |
400 | goto out; | 403 | if (package->type == ACPI_TYPE_PACKAGE && |
401 | rev = package->package.elements[0].integer.value; | 404 | package->package.count == 2 && |
402 | num = package->package.elements[1].integer.value; | 405 | package->package.elements[0].integer.value == 1) /* rev 1 */ |
403 | if (rev != 1 || num < 0) | 406 | |
404 | goto out; | 407 | num = package->package.elements[1].integer.value; |
405 | *num_cpus = num; | 408 | |
406 | ret = 0; | ||
407 | out: | ||
408 | kfree(buffer.pointer); | 409 | kfree(buffer.pointer); |
409 | return ret; | 410 | return num; |
410 | } | 411 | } |
411 | 412 | ||
412 | /* Notify firmware how many CPUs are idle */ | 413 | /* Notify firmware how many CPUs are idle */ |
@@ -433,7 +434,8 @@ static void acpi_pad_handle_notify(acpi_handle handle) | |||
433 | uint32_t idle_cpus; | 434 | uint32_t idle_cpus; |
434 | 435 | ||
435 | mutex_lock(&isolated_cpus_lock); | 436 | mutex_lock(&isolated_cpus_lock); |
436 | if (acpi_pad_pur(handle, &num_cpus)) { | 437 | num_cpus = acpi_pad_pur(handle); |
438 | if (num_cpus < 0) { | ||
437 | mutex_unlock(&isolated_cpus_lock); | 439 | mutex_unlock(&isolated_cpus_lock); |
438 | return; | 440 | return; |
439 | } | 441 | } |
diff --git a/drivers/acpi/acpica/Makefile b/drivers/acpi/acpica/Makefile index d93cc06f4bf..a7e1d1aa410 100644 --- a/drivers/acpi/acpica/Makefile +++ b/drivers/acpi/acpica/Makefile | |||
@@ -21,7 +21,7 @@ acpi-y += exconfig.o exfield.o exnames.o exoparg6.o exresolv.o exstorob.o\ | |||
21 | excreate.o exmisc.o exoparg2.o exregion.o exstore.o exutils.o \ | 21 | excreate.o exmisc.o exoparg2.o exregion.o exstore.o exutils.o \ |
22 | exdump.o exmutex.o exoparg3.o exresnte.o exstoren.o exdebug.o | 22 | exdump.o exmutex.o exoparg3.o exresnte.o exstoren.o exdebug.o |
23 | 23 | ||
24 | acpi-y += hwacpi.o hwgpe.o hwregs.o hwsleep.o hwxface.o hwvalid.o | 24 | acpi-y += hwacpi.o hwgpe.o hwregs.o hwsleep.o hwxface.o hwvalid.o hwpci.o |
25 | 25 | ||
26 | acpi-$(ACPI_FUTURE_USAGE) += hwtimer.o | 26 | acpi-$(ACPI_FUTURE_USAGE) += hwtimer.o |
27 | 27 | ||
@@ -44,4 +44,5 @@ acpi-y += tbxface.o tbinstal.o tbutils.o tbfind.o tbfadt.o tbxfroot.o | |||
44 | 44 | ||
45 | acpi-y += utalloc.o utdebug.o uteval.o utinit.o utmisc.o utxface.o \ | 45 | acpi-y += utalloc.o utdebug.o uteval.o utinit.o utmisc.o utxface.o \ |
46 | utcopy.o utdelete.o utglobal.o utmath.o utobject.o \ | 46 | utcopy.o utdelete.o utglobal.o utmath.o utobject.o \ |
47 | utstate.o utmutex.o utobject.o utresrc.o utlock.o utids.o | 47 | utstate.o utmutex.o utobject.o utresrc.o utlock.o utids.o \ |
48 | utosi.o utxferror.o | ||
diff --git a/drivers/acpi/acpica/acdebug.h b/drivers/acpi/acpica/acdebug.h index 48faf3eba9f..72e9d5eb083 100644 --- a/drivers/acpi/acpica/acdebug.h +++ b/drivers/acpi/acpica/acdebug.h | |||
@@ -105,6 +105,8 @@ void acpi_db_set_method_data(char *type_arg, char *index_arg, char *value_arg); | |||
105 | acpi_status | 105 | acpi_status |
106 | acpi_db_display_objects(char *obj_type_arg, char *display_count_arg); | 106 | acpi_db_display_objects(char *obj_type_arg, char *display_count_arg); |
107 | 107 | ||
108 | void acpi_db_display_interfaces(char *action_arg, char *interface_name_arg); | ||
109 | |||
108 | acpi_status acpi_db_find_name_in_namespace(char *name_arg); | 110 | acpi_status acpi_db_find_name_in_namespace(char *name_arg); |
109 | 111 | ||
110 | void acpi_db_set_scope(char *name); | 112 | void acpi_db_set_scope(char *name); |
diff --git a/drivers/acpi/acpica/acevents.h b/drivers/acpi/acpica/acevents.h index 36867cd70ea..a6f99cc37a1 100644 --- a/drivers/acpi/acpica/acevents.h +++ b/drivers/acpi/acpica/acevents.h | |||
@@ -105,8 +105,9 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device, | |||
105 | struct acpi_gpe_block_info **return_gpe_block); | 105 | struct acpi_gpe_block_info **return_gpe_block); |
106 | 106 | ||
107 | acpi_status | 107 | acpi_status |
108 | acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device, | 108 | acpi_ev_initialize_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, |
109 | struct acpi_gpe_block_info *gpe_block); | 109 | struct acpi_gpe_block_info *gpe_block, |
110 | void *ignored); | ||
110 | 111 | ||
111 | acpi_status acpi_ev_delete_gpe_block(struct acpi_gpe_block_info *gpe_block); | 112 | acpi_status acpi_ev_delete_gpe_block(struct acpi_gpe_block_info *gpe_block); |
112 | 113 | ||
diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index 1d192142c69..ad88fcae4eb 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h | |||
@@ -132,6 +132,7 @@ struct acpi_table_fadt acpi_gbl_FADT; | |||
132 | u32 acpi_current_gpe_count; | 132 | u32 acpi_current_gpe_count; |
133 | u32 acpi_gbl_trace_flags; | 133 | u32 acpi_gbl_trace_flags; |
134 | acpi_name acpi_gbl_trace_method_name; | 134 | acpi_name acpi_gbl_trace_method_name; |
135 | u8 acpi_gbl_system_awake_and_running; | ||
135 | 136 | ||
136 | #endif | 137 | #endif |
137 | 138 | ||
@@ -187,6 +188,10 @@ ACPI_EXTERN u8 acpi_gbl_integer_bit_width; | |||
187 | ACPI_EXTERN u8 acpi_gbl_integer_byte_width; | 188 | ACPI_EXTERN u8 acpi_gbl_integer_byte_width; |
188 | ACPI_EXTERN u8 acpi_gbl_integer_nybble_width; | 189 | ACPI_EXTERN u8 acpi_gbl_integer_nybble_width; |
189 | 190 | ||
191 | /* Mutex for _OSI support */ | ||
192 | |||
193 | ACPI_EXTERN acpi_mutex acpi_gbl_osi_mutex; | ||
194 | |||
190 | /* Reader/Writer lock is used for namespace walk and dynamic table unload */ | 195 | /* Reader/Writer lock is used for namespace walk and dynamic table unload */ |
191 | 196 | ||
192 | ACPI_EXTERN struct acpi_rw_lock acpi_gbl_namespace_rw_lock; | 197 | ACPI_EXTERN struct acpi_rw_lock acpi_gbl_namespace_rw_lock; |
@@ -255,6 +260,7 @@ ACPI_EXTERN acpi_init_handler acpi_gbl_init_handler; | |||
255 | ACPI_EXTERN acpi_tbl_handler acpi_gbl_table_handler; | 260 | ACPI_EXTERN acpi_tbl_handler acpi_gbl_table_handler; |
256 | ACPI_EXTERN void *acpi_gbl_table_handler_context; | 261 | ACPI_EXTERN void *acpi_gbl_table_handler_context; |
257 | ACPI_EXTERN struct acpi_walk_state *acpi_gbl_breakpoint_walk; | 262 | ACPI_EXTERN struct acpi_walk_state *acpi_gbl_breakpoint_walk; |
263 | ACPI_EXTERN acpi_interface_handler acpi_gbl_interface_handler; | ||
258 | 264 | ||
259 | /* Owner ID support */ | 265 | /* Owner ID support */ |
260 | 266 | ||
@@ -273,8 +279,8 @@ ACPI_EXTERN u8 acpi_gbl_debugger_configuration; | |||
273 | ACPI_EXTERN u8 acpi_gbl_step_to_next_call; | 279 | ACPI_EXTERN u8 acpi_gbl_step_to_next_call; |
274 | ACPI_EXTERN u8 acpi_gbl_acpi_hardware_present; | 280 | ACPI_EXTERN u8 acpi_gbl_acpi_hardware_present; |
275 | ACPI_EXTERN u8 acpi_gbl_events_initialized; | 281 | ACPI_EXTERN u8 acpi_gbl_events_initialized; |
276 | ACPI_EXTERN u8 acpi_gbl_system_awake_and_running; | ||
277 | ACPI_EXTERN u8 acpi_gbl_osi_data; | 282 | ACPI_EXTERN u8 acpi_gbl_osi_data; |
283 | ACPI_EXTERN struct acpi_interface_info *acpi_gbl_supported_interfaces; | ||
278 | 284 | ||
279 | #ifndef DEFINE_ACPI_GLOBALS | 285 | #ifndef DEFINE_ACPI_GLOBALS |
280 | 286 | ||
@@ -364,6 +370,7 @@ ACPI_EXTERN struct acpi_fixed_event_handler | |||
364 | ACPI_EXTERN struct acpi_gpe_xrupt_info *acpi_gbl_gpe_xrupt_list_head; | 370 | ACPI_EXTERN struct acpi_gpe_xrupt_info *acpi_gbl_gpe_xrupt_list_head; |
365 | ACPI_EXTERN struct acpi_gpe_block_info | 371 | ACPI_EXTERN struct acpi_gpe_block_info |
366 | *acpi_gbl_gpe_fadt_blocks[ACPI_MAX_GPE_BLOCKS]; | 372 | *acpi_gbl_gpe_fadt_blocks[ACPI_MAX_GPE_BLOCKS]; |
373 | ACPI_EXTERN u8 acpi_all_gpes_initialized; | ||
367 | 374 | ||
368 | /***************************************************************************** | 375 | /***************************************************************************** |
369 | * | 376 | * |
diff --git a/drivers/acpi/acpica/achware.h b/drivers/acpi/acpica/achware.h index 120b3af5659..167470ad2d2 100644 --- a/drivers/acpi/acpica/achware.h +++ b/drivers/acpi/acpica/achware.h | |||
@@ -121,6 +121,13 @@ acpi_hw_enable_runtime_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, | |||
121 | struct acpi_gpe_block_info *gpe_block, | 121 | struct acpi_gpe_block_info *gpe_block, |
122 | void *context); | 122 | void *context); |
123 | 123 | ||
124 | /* | ||
125 | * hwpci - PCI configuration support | ||
126 | */ | ||
127 | acpi_status | ||
128 | acpi_hw_derive_pci_id(struct acpi_pci_id *pci_id, | ||
129 | acpi_handle root_pci_device, acpi_handle pci_region); | ||
130 | |||
124 | #ifdef ACPI_FUTURE_USAGE | 131 | #ifdef ACPI_FUTURE_USAGE |
125 | /* | 132 | /* |
126 | * hwtimer - ACPI Timer prototypes | 133 | * hwtimer - ACPI Timer prototypes |
diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index df85b53a674..2ceb0c05b2d 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h | |||
@@ -413,6 +413,7 @@ struct acpi_handler_info { | |||
413 | void *context; /* Context to be passed to handler */ | 413 | void *context; /* Context to be passed to handler */ |
414 | struct acpi_namespace_node *method_node; /* Method node for this GPE level (saved) */ | 414 | struct acpi_namespace_node *method_node; /* Method node for this GPE level (saved) */ |
415 | u8 orig_flags; /* Original misc info about this GPE */ | 415 | u8 orig_flags; /* Original misc info about this GPE */ |
416 | u8 orig_enabled; /* Set if the GPE was originally enabled */ | ||
416 | }; | 417 | }; |
417 | 418 | ||
418 | union acpi_gpe_dispatch_info { | 419 | union acpi_gpe_dispatch_info { |
@@ -457,6 +458,7 @@ struct acpi_gpe_block_info { | |||
457 | u32 register_count; /* Number of register pairs in block */ | 458 | u32 register_count; /* Number of register pairs in block */ |
458 | u16 gpe_count; /* Number of individual GPEs in block */ | 459 | u16 gpe_count; /* Number of individual GPEs in block */ |
459 | u8 block_base_number; /* Base GPE number for this block */ | 460 | u8 block_base_number; /* Base GPE number for this block */ |
461 | u8 initialized; /* If set, the GPE block has been initialized */ | ||
460 | }; | 462 | }; |
461 | 463 | ||
462 | /* Information about GPE interrupt handlers, one per each interrupt level used for GPEs */ | 464 | /* Information about GPE interrupt handlers, one per each interrupt level used for GPEs */ |
@@ -473,7 +475,6 @@ struct acpi_gpe_walk_info { | |||
473 | struct acpi_gpe_block_info *gpe_block; | 475 | struct acpi_gpe_block_info *gpe_block; |
474 | u16 count; | 476 | u16 count; |
475 | acpi_owner_id owner_id; | 477 | acpi_owner_id owner_id; |
476 | u8 enable_this_gpe; | ||
477 | u8 execute_by_owner_id; | 478 | u8 execute_by_owner_id; |
478 | }; | 479 | }; |
479 | 480 | ||
@@ -854,6 +855,7 @@ struct acpi_bit_register_info { | |||
854 | ACPI_BITMASK_POWER_BUTTON_STATUS | \ | 855 | ACPI_BITMASK_POWER_BUTTON_STATUS | \ |
855 | ACPI_BITMASK_SLEEP_BUTTON_STATUS | \ | 856 | ACPI_BITMASK_SLEEP_BUTTON_STATUS | \ |
856 | ACPI_BITMASK_RT_CLOCK_STATUS | \ | 857 | ACPI_BITMASK_RT_CLOCK_STATUS | \ |
858 | ACPI_BITMASK_PCIEXP_WAKE_STATUS | \ | ||
857 | ACPI_BITMASK_WAKE_STATUS) | 859 | ACPI_BITMASK_WAKE_STATUS) |
858 | 860 | ||
859 | #define ACPI_BITMASK_TIMER_ENABLE 0x0001 | 861 | #define ACPI_BITMASK_TIMER_ENABLE 0x0001 |
@@ -908,15 +910,21 @@ struct acpi_bit_register_info { | |||
908 | #define ACPI_OSI_WIN_VISTA 0x07 | 910 | #define ACPI_OSI_WIN_VISTA 0x07 |
909 | #define ACPI_OSI_WINSRV_2008 0x08 | 911 | #define ACPI_OSI_WINSRV_2008 0x08 |
910 | #define ACPI_OSI_WIN_VISTA_SP1 0x09 | 912 | #define ACPI_OSI_WIN_VISTA_SP1 0x09 |
911 | #define ACPI_OSI_WIN_7 0x0A | 913 | #define ACPI_OSI_WIN_VISTA_SP2 0x0A |
914 | #define ACPI_OSI_WIN_7 0x0B | ||
912 | 915 | ||
913 | #define ACPI_ALWAYS_ILLEGAL 0x00 | 916 | #define ACPI_ALWAYS_ILLEGAL 0x00 |
914 | 917 | ||
915 | struct acpi_interface_info { | 918 | struct acpi_interface_info { |
916 | char *name; | 919 | char *name; |
920 | struct acpi_interface_info *next; | ||
921 | u8 flags; | ||
917 | u8 value; | 922 | u8 value; |
918 | }; | 923 | }; |
919 | 924 | ||
925 | #define ACPI_OSI_INVALID 0x01 | ||
926 | #define ACPI_OSI_DYNAMIC 0x02 | ||
927 | |||
920 | struct acpi_port_info { | 928 | struct acpi_port_info { |
921 | char *name; | 929 | char *name; |
922 | u16 start; | 930 | u16 start; |
@@ -996,7 +1004,7 @@ struct acpi_port_info { | |||
996 | struct acpi_db_method_info { | 1004 | struct acpi_db_method_info { |
997 | acpi_handle main_thread_gate; | 1005 | acpi_handle main_thread_gate; |
998 | acpi_handle thread_complete_gate; | 1006 | acpi_handle thread_complete_gate; |
999 | u32 *threads; | 1007 | acpi_thread_id *threads; |
1000 | u32 num_threads; | 1008 | u32 num_threads; |
1001 | u32 num_created; | 1009 | u32 num_created; |
1002 | u32 num_completed; | 1010 | u32 num_completed; |
diff --git a/drivers/acpi/acpica/acmacros.h b/drivers/acpi/acpica/acmacros.h index 9894929a2ab..8d5c9e0a495 100644 --- a/drivers/acpi/acpica/acmacros.h +++ b/drivers/acpi/acpica/acmacros.h | |||
@@ -338,8 +338,8 @@ | |||
338 | * the plist contains a set of parens to allow variable-length lists. | 338 | * the plist contains a set of parens to allow variable-length lists. |
339 | * These macros are used for both the debug and non-debug versions of the code. | 339 | * These macros are used for both the debug and non-debug versions of the code. |
340 | */ | 340 | */ |
341 | #define ACPI_ERROR_NAMESPACE(s, e) acpi_ns_report_error (AE_INFO, s, e); | 341 | #define ACPI_ERROR_NAMESPACE(s, e) acpi_ut_namespace_error (AE_INFO, s, e); |
342 | #define ACPI_ERROR_METHOD(s, n, p, e) acpi_ns_report_method_error (AE_INFO, s, n, p, e); | 342 | #define ACPI_ERROR_METHOD(s, n, p, e) acpi_ut_method_error (AE_INFO, s, n, p, e); |
343 | #define ACPI_WARN_PREDEFINED(plist) acpi_ut_predefined_warning plist | 343 | #define ACPI_WARN_PREDEFINED(plist) acpi_ut_predefined_warning plist |
344 | #define ACPI_INFO_PREDEFINED(plist) acpi_ut_predefined_info plist | 344 | #define ACPI_INFO_PREDEFINED(plist) acpi_ut_predefined_info plist |
345 | 345 | ||
diff --git a/drivers/acpi/acpica/acnamesp.h b/drivers/acpi/acpica/acnamesp.h index 9f60ff00220..d44d3bc5b84 100644 --- a/drivers/acpi/acpica/acnamesp.h +++ b/drivers/acpi/acpica/acnamesp.h | |||
@@ -339,18 +339,6 @@ acpi_object_type acpi_ns_get_type(struct acpi_namespace_node *node); | |||
339 | u32 acpi_ns_local(acpi_object_type type); | 339 | u32 acpi_ns_local(acpi_object_type type); |
340 | 340 | ||
341 | void | 341 | void |
342 | acpi_ns_report_error(const char *module_name, | ||
343 | u32 line_number, | ||
344 | const char *internal_name, acpi_status lookup_status); | ||
345 | |||
346 | void | ||
347 | acpi_ns_report_method_error(const char *module_name, | ||
348 | u32 line_number, | ||
349 | const char *message, | ||
350 | struct acpi_namespace_node *node, | ||
351 | const char *path, acpi_status lookup_status); | ||
352 | |||
353 | void | ||
354 | acpi_ns_print_node_pathname(struct acpi_namespace_node *node, const char *msg); | 342 | acpi_ns_print_node_pathname(struct acpi_namespace_node *node, const char *msg); |
355 | 343 | ||
356 | acpi_status acpi_ns_build_internal_name(struct acpi_namestring_info *info); | 344 | acpi_status acpi_ns_build_internal_name(struct acpi_namestring_info *info); |
diff --git a/drivers/acpi/acpica/acobject.h b/drivers/acpi/acpica/acobject.h index 54857fa87aa..bdbfaf22bd1 100644 --- a/drivers/acpi/acpica/acobject.h +++ b/drivers/acpi/acpica/acobject.h | |||
@@ -248,7 +248,7 @@ ACPI_OBJECT_COMMON_HEADER ACPI_COMMON_NOTIFY_INFO}; | |||
248 | u32 base_byte_offset; /* Byte offset within containing object */\ | 248 | u32 base_byte_offset; /* Byte offset within containing object */\ |
249 | u32 value; /* Value to store into the Bank or Index register */\ | 249 | u32 value; /* Value to store into the Bank or Index register */\ |
250 | u8 start_field_bit_offset;/* Bit offset within first field datum (0-63) */\ | 250 | u8 start_field_bit_offset;/* Bit offset within first field datum (0-63) */\ |
251 | u8 access_bit_width; /* Read/Write size in bits (8-64) */ | 251 | |
252 | 252 | ||
253 | struct acpi_object_field_common { /* COMMON FIELD (for BUFFER, REGION, BANK, and INDEX fields) */ | 253 | struct acpi_object_field_common { /* COMMON FIELD (for BUFFER, REGION, BANK, and INDEX fields) */ |
254 | ACPI_OBJECT_COMMON_HEADER ACPI_COMMON_FIELD_INFO union acpi_operand_object *region_obj; /* Parent Operation Region object (REGION/BANK fields only) */ | 254 | ACPI_OBJECT_COMMON_HEADER ACPI_COMMON_FIELD_INFO union acpi_operand_object *region_obj; /* Parent Operation Region object (REGION/BANK fields only) */ |
diff --git a/drivers/acpi/acpica/acutils.h b/drivers/acpi/acpica/acutils.h index 35df755251c..72e4183c193 100644 --- a/drivers/acpi/acpica/acutils.h +++ b/drivers/acpi/acpica/acutils.h | |||
@@ -312,8 +312,6 @@ void acpi_ut_delete_internal_object_list(union acpi_operand_object **obj_list); | |||
312 | /* | 312 | /* |
313 | * uteval - object evaluation | 313 | * uteval - object evaluation |
314 | */ | 314 | */ |
315 | acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state); | ||
316 | |||
317 | acpi_status | 315 | acpi_status |
318 | acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node, | 316 | acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node, |
319 | char *path, | 317 | char *path, |
@@ -395,6 +393,21 @@ acpi_status | |||
395 | acpi_ut_get_object_size(union acpi_operand_object *obj, acpi_size * obj_length); | 393 | acpi_ut_get_object_size(union acpi_operand_object *obj, acpi_size * obj_length); |
396 | 394 | ||
397 | /* | 395 | /* |
396 | * utosi - Support for the _OSI predefined control method | ||
397 | */ | ||
398 | acpi_status acpi_ut_initialize_interfaces(void); | ||
399 | |||
400 | void acpi_ut_interface_terminate(void); | ||
401 | |||
402 | acpi_status acpi_ut_install_interface(acpi_string interface_name); | ||
403 | |||
404 | acpi_status acpi_ut_remove_interface(acpi_string interface_name); | ||
405 | |||
406 | struct acpi_interface_info *acpi_ut_get_interface(acpi_string interface_name); | ||
407 | |||
408 | acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state); | ||
409 | |||
410 | /* | ||
398 | * utstate - Generic state creation/cache routines | 411 | * utstate - Generic state creation/cache routines |
399 | */ | 412 | */ |
400 | void | 413 | void |
@@ -473,17 +486,6 @@ u8 acpi_ut_valid_acpi_char(char character, u32 position); | |||
473 | 486 | ||
474 | acpi_status acpi_ut_strtoul64(char *string, u32 base, u64 * ret_integer); | 487 | acpi_status acpi_ut_strtoul64(char *string, u32 base, u64 * ret_integer); |
475 | 488 | ||
476 | void ACPI_INTERNAL_VAR_XFACE | ||
477 | acpi_ut_predefined_warning(const char *module_name, | ||
478 | u32 line_number, | ||
479 | char *pathname, | ||
480 | u8 node_flags, const char *format, ...); | ||
481 | |||
482 | void ACPI_INTERNAL_VAR_XFACE | ||
483 | acpi_ut_predefined_info(const char *module_name, | ||
484 | u32 line_number, | ||
485 | char *pathname, u8 node_flags, const char *format, ...); | ||
486 | |||
487 | /* Values for Base above (16=Hex, 10=Decimal) */ | 489 | /* Values for Base above (16=Hex, 10=Decimal) */ |
488 | 490 | ||
489 | #define ACPI_ANY_BASE 0 | 491 | #define ACPI_ANY_BASE 0 |
@@ -574,6 +576,32 @@ acpi_status | |||
574 | acpi_ut_create_list(char *list_name, | 576 | acpi_ut_create_list(char *list_name, |
575 | u16 object_size, struct acpi_memory_list **return_cache); | 577 | u16 object_size, struct acpi_memory_list **return_cache); |
576 | 578 | ||
577 | #endif | 579 | #endif /* ACPI_DBG_TRACK_ALLOCATIONS */ |
580 | |||
581 | /* | ||
582 | * utxferror - various error/warning output functions | ||
583 | */ | ||
584 | void ACPI_INTERNAL_VAR_XFACE | ||
585 | acpi_ut_predefined_warning(const char *module_name, | ||
586 | u32 line_number, | ||
587 | char *pathname, | ||
588 | u8 node_flags, const char *format, ...); | ||
589 | |||
590 | void ACPI_INTERNAL_VAR_XFACE | ||
591 | acpi_ut_predefined_info(const char *module_name, | ||
592 | u32 line_number, | ||
593 | char *pathname, u8 node_flags, const char *format, ...); | ||
594 | |||
595 | void | ||
596 | acpi_ut_namespace_error(const char *module_name, | ||
597 | u32 line_number, | ||
598 | const char *internal_name, acpi_status lookup_status); | ||
599 | |||
600 | void | ||
601 | acpi_ut_method_error(const char *module_name, | ||
602 | u32 line_number, | ||
603 | const char *message, | ||
604 | struct acpi_namespace_node *node, | ||
605 | const char *path, acpi_status lookup_status); | ||
578 | 606 | ||
579 | #endif /* _ACUTILS_H */ | 607 | #endif /* _ACUTILS_H */ |
diff --git a/drivers/acpi/acpica/dsmethod.c b/drivers/acpi/acpica/dsmethod.c index 64750ee96e2..d94dd8974b5 100644 --- a/drivers/acpi/acpica/dsmethod.c +++ b/drivers/acpi/acpica/dsmethod.c | |||
@@ -573,7 +573,7 @@ acpi_ds_terminate_control_method(union acpi_operand_object *method_desc, | |||
573 | 573 | ||
574 | acpi_os_release_mutex(method_desc->method. | 574 | acpi_os_release_mutex(method_desc->method. |
575 | mutex->mutex.os_mutex); | 575 | mutex->mutex.os_mutex); |
576 | method_desc->method.mutex->mutex.thread_id = NULL; | 576 | method_desc->method.mutex->mutex.thread_id = 0; |
577 | } | 577 | } |
578 | } | 578 | } |
579 | 579 | ||
diff --git a/drivers/acpi/acpica/dswexec.c b/drivers/acpi/acpica/dswexec.c index d555b374e31..6b0b5d08d97 100644 --- a/drivers/acpi/acpica/dswexec.c +++ b/drivers/acpi/acpica/dswexec.c | |||
@@ -300,10 +300,25 @@ acpi_ds_exec_begin_op(struct acpi_walk_state *walk_state, | |||
300 | * we must enter this object into the namespace. The created | 300 | * we must enter this object into the namespace. The created |
301 | * object is temporary and will be deleted upon completion of | 301 | * object is temporary and will be deleted upon completion of |
302 | * the execution of this method. | 302 | * the execution of this method. |
303 | * | ||
304 | * Note 10/2010: Except for the Scope() op. This opcode does | ||
305 | * not actually create a new object, it refers to an existing | ||
306 | * object. However, for Scope(), we want to indeed open a | ||
307 | * new scope. | ||
303 | */ | 308 | */ |
304 | status = acpi_ds_load2_begin_op(walk_state, NULL); | 309 | if (op->common.aml_opcode != AML_SCOPE_OP) { |
310 | status = | ||
311 | acpi_ds_load2_begin_op(walk_state, NULL); | ||
312 | } else { | ||
313 | status = | ||
314 | acpi_ds_scope_stack_push(op->named.node, | ||
315 | op->named.node-> | ||
316 | type, walk_state); | ||
317 | if (ACPI_FAILURE(status)) { | ||
318 | return_ACPI_STATUS(status); | ||
319 | } | ||
320 | } | ||
305 | } | 321 | } |
306 | |||
307 | break; | 322 | break; |
308 | 323 | ||
309 | case AML_CLASS_EXECUTE: | 324 | case AML_CLASS_EXECUTE: |
diff --git a/drivers/acpi/acpica/evevent.c b/drivers/acpi/acpica/evevent.c index 303618889da..c61c3039c31 100644 --- a/drivers/acpi/acpica/evevent.c +++ b/drivers/acpi/acpica/evevent.c | |||
@@ -95,47 +95,6 @@ acpi_status acpi_ev_initialize_events(void) | |||
95 | 95 | ||
96 | /******************************************************************************* | 96 | /******************************************************************************* |
97 | * | 97 | * |
98 | * FUNCTION: acpi_ev_install_fadt_gpes | ||
99 | * | ||
100 | * PARAMETERS: None | ||
101 | * | ||
102 | * RETURN: Status | ||
103 | * | ||
104 | * DESCRIPTION: Completes initialization of the FADT-defined GPE blocks | ||
105 | * (0 and 1). The HW must be fully initialized at this point, | ||
106 | * including global lock support. | ||
107 | * | ||
108 | ******************************************************************************/ | ||
109 | |||
110 | acpi_status acpi_ev_install_fadt_gpes(void) | ||
111 | { | ||
112 | acpi_status status; | ||
113 | |||
114 | ACPI_FUNCTION_TRACE(ev_install_fadt_gpes); | ||
115 | |||
116 | /* Namespace must be locked */ | ||
117 | |||
118 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | ||
119 | if (ACPI_FAILURE(status)) { | ||
120 | return (status); | ||
121 | } | ||
122 | |||
123 | /* FADT GPE Block 0 */ | ||
124 | |||
125 | (void)acpi_ev_initialize_gpe_block(acpi_gbl_fadt_gpe_device, | ||
126 | acpi_gbl_gpe_fadt_blocks[0]); | ||
127 | |||
128 | /* FADT GPE Block 1 */ | ||
129 | |||
130 | (void)acpi_ev_initialize_gpe_block(acpi_gbl_fadt_gpe_device, | ||
131 | acpi_gbl_gpe_fadt_blocks[1]); | ||
132 | |||
133 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | ||
134 | return_ACPI_STATUS(AE_OK); | ||
135 | } | ||
136 | |||
137 | /******************************************************************************* | ||
138 | * | ||
139 | * FUNCTION: acpi_ev_install_xrupt_handlers | 98 | * FUNCTION: acpi_ev_install_xrupt_handlers |
140 | * | 99 | * |
141 | * PARAMETERS: None | 100 | * PARAMETERS: None |
diff --git a/drivers/acpi/acpica/evgpeblk.c b/drivers/acpi/acpica/evgpeblk.c index 85445fb5844..020add3eee1 100644 --- a/drivers/acpi/acpica/evgpeblk.c +++ b/drivers/acpi/acpica/evgpeblk.c | |||
@@ -363,6 +363,7 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device, | |||
363 | gpe_block->gpe_count = (u16)(register_count * ACPI_GPE_REGISTER_WIDTH); | 363 | gpe_block->gpe_count = (u16)(register_count * ACPI_GPE_REGISTER_WIDTH); |
364 | gpe_block->register_count = register_count; | 364 | gpe_block->register_count = register_count; |
365 | gpe_block->block_base_number = gpe_block_base_number; | 365 | gpe_block->block_base_number = gpe_block_base_number; |
366 | gpe_block->initialized = FALSE; | ||
366 | 367 | ||
367 | ACPI_MEMCPY(&gpe_block->block_address, gpe_block_address, | 368 | ACPI_MEMCPY(&gpe_block->block_address, gpe_block_address, |
368 | sizeof(struct acpi_generic_address)); | 369 | sizeof(struct acpi_generic_address)); |
@@ -385,11 +386,12 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device, | |||
385 | return_ACPI_STATUS(status); | 386 | return_ACPI_STATUS(status); |
386 | } | 387 | } |
387 | 388 | ||
389 | acpi_all_gpes_initialized = FALSE; | ||
390 | |||
388 | /* Find all GPE methods (_Lxx or_Exx) for this block */ | 391 | /* Find all GPE methods (_Lxx or_Exx) for this block */ |
389 | 392 | ||
390 | walk_info.gpe_block = gpe_block; | 393 | walk_info.gpe_block = gpe_block; |
391 | walk_info.gpe_device = gpe_device; | 394 | walk_info.gpe_device = gpe_device; |
392 | walk_info.enable_this_gpe = FALSE; | ||
393 | walk_info.execute_by_owner_id = FALSE; | 395 | walk_info.execute_by_owner_id = FALSE; |
394 | 396 | ||
395 | status = acpi_ns_walk_namespace(ACPI_TYPE_METHOD, gpe_device, | 397 | 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, | |||
434 | ******************************************************************************/ | 436 | ******************************************************************************/ |
435 | 437 | ||
436 | acpi_status | 438 | acpi_status |
437 | acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device, | 439 | acpi_ev_initialize_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, |
438 | struct acpi_gpe_block_info *gpe_block) | 440 | struct acpi_gpe_block_info *gpe_block, |
441 | void *ignored) | ||
439 | { | 442 | { |
440 | acpi_status status; | 443 | acpi_status status; |
441 | struct acpi_gpe_event_info *gpe_event_info; | 444 | struct acpi_gpe_event_info *gpe_event_info; |
442 | u32 gpe_enabled_count; | 445 | u32 gpe_enabled_count; |
443 | u32 gpe_index; | 446 | u32 gpe_index; |
444 | u32 gpe_number; | ||
445 | u32 i; | 447 | u32 i; |
446 | u32 j; | 448 | u32 j; |
447 | 449 | ||
448 | ACPI_FUNCTION_TRACE(ev_initialize_gpe_block); | 450 | ACPI_FUNCTION_TRACE(ev_initialize_gpe_block); |
449 | 451 | ||
450 | /* Ignore a null GPE block (e.g., if no GPE block 1 exists) */ | 452 | /* |
451 | 453 | * Ignore a null GPE block (e.g., if no GPE block 1 exists) and | |
452 | if (!gpe_block) { | 454 | * GPE blocks that have been initialized already. |
455 | */ | ||
456 | if (!gpe_block || gpe_block->initialized) { | ||
453 | return_ACPI_STATUS(AE_OK); | 457 | return_ACPI_STATUS(AE_OK); |
454 | } | 458 | } |
455 | 459 | ||
456 | /* | 460 | /* |
457 | * Enable all GPEs that have a corresponding method. Any other GPEs | 461 | * Enable all GPEs that have a corresponding method and have the |
458 | * within this block must be enabled via the acpi_enable_gpe interface. | 462 | * ACPI_GPE_CAN_WAKE flag unset. Any other GPEs within this block must |
463 | * be enabled via the acpi_enable_gpe() interface. | ||
459 | */ | 464 | */ |
460 | gpe_enabled_count = 0; | 465 | gpe_enabled_count = 0; |
461 | 466 | ||
462 | if (gpe_device == acpi_gbl_fadt_gpe_device) { | ||
463 | gpe_device = NULL; | ||
464 | } | ||
465 | |||
466 | for (i = 0; i < gpe_block->register_count; i++) { | 467 | for (i = 0; i < gpe_block->register_count; i++) { |
467 | for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) { | 468 | for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) { |
468 | 469 | ||
@@ -470,27 +471,19 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device, | |||
470 | 471 | ||
471 | gpe_index = (i * ACPI_GPE_REGISTER_WIDTH) + j; | 472 | gpe_index = (i * ACPI_GPE_REGISTER_WIDTH) + j; |
472 | gpe_event_info = &gpe_block->event_info[gpe_index]; | 473 | gpe_event_info = &gpe_block->event_info[gpe_index]; |
473 | gpe_number = gpe_index + gpe_block->block_base_number; | ||
474 | 474 | ||
475 | /* Ignore GPEs that have no corresponding _Lxx/_Exx method */ | 475 | /* Ignore GPEs that have no corresponding _Lxx/_Exx method */ |
476 | 476 | ||
477 | if (!(gpe_event_info->flags & ACPI_GPE_DISPATCH_METHOD)) { | 477 | if (!(gpe_event_info->flags & ACPI_GPE_DISPATCH_METHOD) |
478 | || (gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) { | ||
478 | continue; | 479 | continue; |
479 | } | 480 | } |
480 | 481 | ||
481 | /* | 482 | status = acpi_raw_enable_gpe(gpe_event_info); |
482 | * If the GPE has already been enabled for runtime | ||
483 | * signaling, make sure it remains enabled, but do not | ||
484 | * increment its reference counter. | ||
485 | */ | ||
486 | status = gpe_event_info->runtime_count ? | ||
487 | acpi_ev_enable_gpe(gpe_event_info) : | ||
488 | acpi_enable_gpe(gpe_device, gpe_number); | ||
489 | |||
490 | if (ACPI_FAILURE(status)) { | 483 | if (ACPI_FAILURE(status)) { |
491 | ACPI_EXCEPTION((AE_INFO, status, | 484 | ACPI_EXCEPTION((AE_INFO, status, |
492 | "Could not enable GPE 0x%02X", | 485 | "Could not enable GPE 0x%02X", |
493 | gpe_number)); | 486 | gpe_index + gpe_block->block_base_number)); |
494 | continue; | 487 | continue; |
495 | } | 488 | } |
496 | 489 | ||
@@ -504,5 +497,7 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device, | |||
504 | gpe_enabled_count)); | 497 | gpe_enabled_count)); |
505 | } | 498 | } |
506 | 499 | ||
500 | gpe_block->initialized = TRUE; | ||
501 | |||
507 | return_ACPI_STATUS(AE_OK); | 502 | return_ACPI_STATUS(AE_OK); |
508 | } | 503 | } |
diff --git a/drivers/acpi/acpica/evgpeinit.c b/drivers/acpi/acpica/evgpeinit.c index 3084c5de1bb..2c7def95f72 100644 --- a/drivers/acpi/acpica/evgpeinit.c +++ b/drivers/acpi/acpica/evgpeinit.c | |||
@@ -210,8 +210,7 @@ acpi_status acpi_ev_gpe_initialize(void) | |||
210 | * | 210 | * |
211 | * DESCRIPTION: Check for new GPE methods (_Lxx/_Exx) made available as a | 211 | * DESCRIPTION: Check for new GPE methods (_Lxx/_Exx) made available as a |
212 | * result of a Load() or load_table() operation. If new GPE | 212 | * result of a Load() or load_table() operation. If new GPE |
213 | * methods have been installed, register the new methods and | 213 | * methods have been installed, register the new methods. |
214 | * enable and runtime GPEs that are associated with them. | ||
215 | * | 214 | * |
216 | ******************************************************************************/ | 215 | ******************************************************************************/ |
217 | 216 | ||
@@ -239,7 +238,6 @@ void acpi_ev_update_gpes(acpi_owner_id table_owner_id) | |||
239 | walk_info.owner_id = table_owner_id; | 238 | walk_info.owner_id = table_owner_id; |
240 | walk_info.execute_by_owner_id = TRUE; | 239 | walk_info.execute_by_owner_id = TRUE; |
241 | walk_info.count = 0; | 240 | walk_info.count = 0; |
242 | walk_info.enable_this_gpe = TRUE; | ||
243 | 241 | ||
244 | /* Walk the interrupt level descriptor list */ | 242 | /* Walk the interrupt level descriptor list */ |
245 | 243 | ||
@@ -301,8 +299,6 @@ void acpi_ev_update_gpes(acpi_owner_id table_owner_id) | |||
301 | * | 299 | * |
302 | * If walk_info->execute_by_owner_id is TRUE, we only execute examine GPE methods | 300 | * If walk_info->execute_by_owner_id is TRUE, we only execute examine GPE methods |
303 | * with that owner. | 301 | * with that owner. |
304 | * If walk_info->enable_this_gpe is TRUE, the GPE that is referred to by a GPE | ||
305 | * method is immediately enabled (Used for Load/load_table operators) | ||
306 | * | 302 | * |
307 | ******************************************************************************/ | 303 | ******************************************************************************/ |
308 | 304 | ||
@@ -315,8 +311,6 @@ acpi_ev_match_gpe_method(acpi_handle obj_handle, | |||
315 | struct acpi_gpe_walk_info *walk_info = | 311 | struct acpi_gpe_walk_info *walk_info = |
316 | ACPI_CAST_PTR(struct acpi_gpe_walk_info, context); | 312 | ACPI_CAST_PTR(struct acpi_gpe_walk_info, context); |
317 | struct acpi_gpe_event_info *gpe_event_info; | 313 | struct acpi_gpe_event_info *gpe_event_info; |
318 | struct acpi_namespace_node *gpe_device; | ||
319 | acpi_status status; | ||
320 | u32 gpe_number; | 314 | u32 gpe_number; |
321 | char name[ACPI_NAME_SIZE + 1]; | 315 | char name[ACPI_NAME_SIZE + 1]; |
322 | u8 type; | 316 | u8 type; |
@@ -421,29 +415,6 @@ acpi_ev_match_gpe_method(acpi_handle obj_handle, | |||
421 | gpe_event_info->flags |= (u8)(type | ACPI_GPE_DISPATCH_METHOD); | 415 | gpe_event_info->flags |= (u8)(type | ACPI_GPE_DISPATCH_METHOD); |
422 | gpe_event_info->dispatch.method_node = method_node; | 416 | gpe_event_info->dispatch.method_node = method_node; |
423 | 417 | ||
424 | /* | ||
425 | * Enable this GPE if requested. This only happens when during the | ||
426 | * execution of a Load or load_table operator. We have found a new | ||
427 | * GPE method and want to immediately enable the GPE if it is a | ||
428 | * runtime GPE. | ||
429 | */ | ||
430 | if (walk_info->enable_this_gpe) { | ||
431 | |||
432 | walk_info->count++; | ||
433 | gpe_device = walk_info->gpe_device; | ||
434 | |||
435 | if (gpe_device == acpi_gbl_fadt_gpe_device) { | ||
436 | gpe_device = NULL; | ||
437 | } | ||
438 | |||
439 | status = acpi_enable_gpe(gpe_device, gpe_number); | ||
440 | if (ACPI_FAILURE(status)) { | ||
441 | ACPI_EXCEPTION((AE_INFO, status, | ||
442 | "Could not enable GPE 0x%02X", | ||
443 | gpe_number)); | ||
444 | } | ||
445 | } | ||
446 | |||
447 | ACPI_DEBUG_PRINT((ACPI_DB_LOAD, | 418 | ACPI_DEBUG_PRINT((ACPI_DB_LOAD, |
448 | "Registered GPE method %s as GPE number 0x%.2X\n", | 419 | "Registered GPE method %s as GPE number 0x%.2X\n", |
449 | name, gpe_number)); | 420 | name, gpe_number)); |
diff --git a/drivers/acpi/acpica/evmisc.c b/drivers/acpi/acpica/evmisc.c index df0aea9a8cf..fcaed9fb44f 100644 --- a/drivers/acpi/acpica/evmisc.c +++ b/drivers/acpi/acpica/evmisc.c | |||
@@ -553,7 +553,7 @@ acpi_status acpi_ev_release_global_lock(void) | |||
553 | acpi_gbl_global_lock_acquired = FALSE; | 553 | acpi_gbl_global_lock_acquired = FALSE; |
554 | 554 | ||
555 | /* Release the local GL mutex */ | 555 | /* Release the local GL mutex */ |
556 | acpi_ev_global_lock_thread_id = NULL; | 556 | acpi_ev_global_lock_thread_id = 0; |
557 | acpi_ev_global_lock_acquired = 0; | 557 | acpi_ev_global_lock_acquired = 0; |
558 | acpi_os_release_mutex(acpi_gbl_global_lock_mutex->mutex.os_mutex); | 558 | acpi_os_release_mutex(acpi_gbl_global_lock_mutex->mutex.os_mutex); |
559 | return_ACPI_STATUS(status); | 559 | return_ACPI_STATUS(status); |
diff --git a/drivers/acpi/acpica/evrgnini.c b/drivers/acpi/acpica/evrgnini.c index f40d271bf56..0b47a6dc929 100644 --- a/drivers/acpi/acpica/evrgnini.c +++ b/drivers/acpi/acpica/evrgnini.c | |||
@@ -289,8 +289,8 @@ acpi_ev_pci_config_region_setup(acpi_handle handle, | |||
289 | } | 289 | } |
290 | 290 | ||
291 | /* | 291 | /* |
292 | * Get the PCI device and function numbers from the _ADR object contained | 292 | * Get the PCI device and function numbers from the _ADR object |
293 | * in the parent's scope. | 293 | * contained in the parent's scope. |
294 | */ | 294 | */ |
295 | status = acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR, | 295 | status = acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR, |
296 | pci_device_node, &pci_value); | 296 | pci_device_node, &pci_value); |
@@ -320,9 +320,15 @@ acpi_ev_pci_config_region_setup(acpi_handle handle, | |||
320 | pci_id->bus = ACPI_LOWORD(pci_value); | 320 | pci_id->bus = ACPI_LOWORD(pci_value); |
321 | } | 321 | } |
322 | 322 | ||
323 | /* Complete this device's pci_id */ | 323 | /* Complete/update the PCI ID for this device */ |
324 | 324 | ||
325 | acpi_os_derive_pci_id(pci_root_node, region_obj->region.node, &pci_id); | 325 | status = |
326 | acpi_hw_derive_pci_id(pci_id, pci_root_node, | ||
327 | region_obj->region.node); | ||
328 | if (ACPI_FAILURE(status)) { | ||
329 | ACPI_FREE(pci_id); | ||
330 | return_ACPI_STATUS(status); | ||
331 | } | ||
326 | 332 | ||
327 | *region_context = pci_id; | 333 | *region_context = pci_id; |
328 | return_ACPI_STATUS(AE_OK); | 334 | return_ACPI_STATUS(AE_OK); |
diff --git a/drivers/acpi/acpica/evxface.c b/drivers/acpi/acpica/evxface.c index 14e48add32f..36af222cac6 100644 --- a/drivers/acpi/acpica/evxface.c +++ b/drivers/acpi/acpica/evxface.c | |||
@@ -726,15 +726,16 @@ acpi_install_gpe_handler(acpi_handle gpe_device, | |||
726 | (ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK); | 726 | (ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK); |
727 | 727 | ||
728 | /* | 728 | /* |
729 | * If the GPE is associated with a method and it cannot wake up the | 729 | * If the GPE is associated with a method, it might have been enabled |
730 | * system from sleep states, it was enabled automatically during | 730 | * automatically during initialization, in which case it has to be |
731 | * initialization, so it has to be disabled now to avoid spurious | 731 | * disabled now to avoid spurious execution of the handler. |
732 | * execution of the handler. | ||
733 | */ | 732 | */ |
734 | 733 | ||
735 | if ((handler->orig_flags & ACPI_GPE_DISPATCH_METHOD) | 734 | if ((handler->orig_flags & ACPI_GPE_DISPATCH_METHOD) |
736 | && !(gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) | 735 | && gpe_event_info->runtime_count) { |
736 | handler->orig_enabled = 1; | ||
737 | (void)acpi_raw_disable_gpe(gpe_event_info); | 737 | (void)acpi_raw_disable_gpe(gpe_event_info); |
738 | } | ||
738 | 739 | ||
739 | /* Install the handler */ | 740 | /* Install the handler */ |
740 | 741 | ||
@@ -837,13 +838,13 @@ acpi_remove_gpe_handler(acpi_handle gpe_device, | |||
837 | gpe_event_info->flags |= handler->orig_flags; | 838 | gpe_event_info->flags |= handler->orig_flags; |
838 | 839 | ||
839 | /* | 840 | /* |
840 | * If the GPE was previously associated with a method and it cannot wake | 841 | * If the GPE was previously associated with a method and it was |
841 | * up the system from sleep states, it should be enabled at this point | 842 | * enabled, it should be enabled at this point to restore the |
842 | * to restore the post-initialization configuration. | 843 | * post-initialization configuration. |
843 | */ | 844 | */ |
844 | 845 | ||
845 | if ((handler->orig_flags & ACPI_GPE_DISPATCH_METHOD) | 846 | if ((handler->orig_flags & ACPI_GPE_DISPATCH_METHOD) |
846 | && !(gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) | 847 | && handler->orig_enabled) |
847 | (void)acpi_raw_enable_gpe(gpe_event_info); | 848 | (void)acpi_raw_enable_gpe(gpe_event_info); |
848 | 849 | ||
849 | /* Now we can free the handler object */ | 850 | /* Now we can free the handler object */ |
diff --git a/drivers/acpi/acpica/evxfevnt.c b/drivers/acpi/acpica/evxfevnt.c index 304825528d4..a1dabe3fd8a 100644 --- a/drivers/acpi/acpica/evxfevnt.c +++ b/drivers/acpi/acpica/evxfevnt.c | |||
@@ -379,21 +379,12 @@ acpi_status acpi_gpe_can_wake(acpi_handle gpe_device, u32 gpe_number) | |||
379 | /* Ensure that we have a valid GPE number */ | 379 | /* Ensure that we have a valid GPE number */ |
380 | 380 | ||
381 | gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); | 381 | gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); |
382 | if (!gpe_event_info) { | 382 | if (gpe_event_info) { |
383 | gpe_event_info->flags |= ACPI_GPE_CAN_WAKE; | ||
384 | } else { | ||
383 | status = AE_BAD_PARAMETER; | 385 | status = AE_BAD_PARAMETER; |
384 | goto unlock_and_exit; | ||
385 | } | ||
386 | |||
387 | if (gpe_event_info->flags & ACPI_GPE_CAN_WAKE) { | ||
388 | goto unlock_and_exit; | ||
389 | } | 386 | } |
390 | 387 | ||
391 | gpe_event_info->flags |= ACPI_GPE_CAN_WAKE; | ||
392 | if (gpe_event_info->flags & ACPI_GPE_DISPATCH_METHOD) { | ||
393 | (void)acpi_raw_disable_gpe(gpe_event_info); | ||
394 | } | ||
395 | |||
396 | unlock_and_exit: | ||
397 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); | 388 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); |
398 | return_ACPI_STATUS(status); | 389 | return_ACPI_STATUS(status); |
399 | } | 390 | } |
@@ -651,7 +642,7 @@ acpi_install_gpe_block(acpi_handle gpe_device, | |||
651 | struct acpi_generic_address *gpe_block_address, | 642 | struct acpi_generic_address *gpe_block_address, |
652 | u32 register_count, u32 interrupt_number) | 643 | u32 register_count, u32 interrupt_number) |
653 | { | 644 | { |
654 | acpi_status status; | 645 | acpi_status status = AE_OK; |
655 | union acpi_operand_object *obj_desc; | 646 | union acpi_operand_object *obj_desc; |
656 | struct acpi_namespace_node *node; | 647 | struct acpi_namespace_node *node; |
657 | struct acpi_gpe_block_info *gpe_block; | 648 | struct acpi_gpe_block_info *gpe_block; |
@@ -715,10 +706,6 @@ acpi_install_gpe_block(acpi_handle gpe_device, | |||
715 | 706 | ||
716 | obj_desc->device.gpe_block = gpe_block; | 707 | obj_desc->device.gpe_block = gpe_block; |
717 | 708 | ||
718 | /* Enable the runtime GPEs in the new block */ | ||
719 | |||
720 | status = acpi_ev_initialize_gpe_block(node, gpe_block); | ||
721 | |||
722 | unlock_and_exit: | 709 | unlock_and_exit: |
723 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | 710 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); |
724 | return_ACPI_STATUS(status); | 711 | return_ACPI_STATUS(status); |
@@ -924,3 +911,43 @@ acpi_status acpi_enable_all_runtime_gpes(void) | |||
924 | 911 | ||
925 | return_ACPI_STATUS(status); | 912 | return_ACPI_STATUS(status); |
926 | } | 913 | } |
914 | |||
915 | /****************************************************************************** | ||
916 | * | ||
917 | * FUNCTION: acpi_update_gpes | ||
918 | * | ||
919 | * PARAMETERS: None | ||
920 | * | ||
921 | * RETURN: None | ||
922 | * | ||
923 | * DESCRIPTION: Enable all GPEs that have associated _Lxx or _Exx methods and | ||
924 | * are not pointed to by any device _PRW methods indicating that | ||
925 | * these GPEs are generally intended for system or device wakeup | ||
926 | * (such GPEs have to be enabled directly when the devices whose | ||
927 | * _PRW methods point to them are set up for wakeup signaling). | ||
928 | * | ||
929 | ******************************************************************************/ | ||
930 | |||
931 | acpi_status acpi_update_gpes(void) | ||
932 | { | ||
933 | acpi_status status; | ||
934 | |||
935 | ACPI_FUNCTION_TRACE(acpi_update_gpes); | ||
936 | |||
937 | status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); | ||
938 | if (ACPI_FAILURE(status)) { | ||
939 | return_ACPI_STATUS(status); | ||
940 | } else if (acpi_all_gpes_initialized) { | ||
941 | goto unlock; | ||
942 | } | ||
943 | |||
944 | status = acpi_ev_walk_gpe_list(acpi_ev_initialize_gpe_block, NULL); | ||
945 | if (ACPI_SUCCESS(status)) { | ||
946 | acpi_all_gpes_initialized = TRUE; | ||
947 | } | ||
948 | |||
949 | unlock: | ||
950 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); | ||
951 | |||
952 | return_ACPI_STATUS(status); | ||
953 | } | ||
diff --git a/drivers/acpi/acpica/evxfregn.c b/drivers/acpi/acpica/evxfregn.c index 541cbc1544d..ce9314f7945 100644 --- a/drivers/acpi/acpica/evxfregn.c +++ b/drivers/acpi/acpica/evxfregn.c | |||
@@ -64,6 +64,12 @@ ACPI_MODULE_NAME("evxfregn") | |||
64 | * | 64 | * |
65 | * DESCRIPTION: Install a handler for all op_regions of a given space_id. | 65 | * DESCRIPTION: Install a handler for all op_regions of a given space_id. |
66 | * | 66 | * |
67 | * NOTE: This function should only be called after acpi_enable_subsystem has | ||
68 | * been called. This is because any _REG methods associated with the Space ID | ||
69 | * are executed here, and these methods can only be safely executed after | ||
70 | * the default handlers have been installed and the hardware has been | ||
71 | * initialized (via acpi_enable_subsystem.) | ||
72 | * | ||
67 | ******************************************************************************/ | 73 | ******************************************************************************/ |
68 | acpi_status | 74 | acpi_status |
69 | acpi_install_address_space_handler(acpi_handle device, | 75 | acpi_install_address_space_handler(acpi_handle device, |
diff --git a/drivers/acpi/acpica/exfldio.c b/drivers/acpi/acpica/exfldio.c index 047217303a4..38293fd3e08 100644 --- a/drivers/acpi/acpica/exfldio.c +++ b/drivers/acpi/acpica/exfldio.c | |||
@@ -119,8 +119,8 @@ acpi_ex_setup_region(union acpi_operand_object *obj_desc, | |||
119 | } | 119 | } |
120 | 120 | ||
121 | /* | 121 | /* |
122 | * Exit now for SMBus or IPMI address space, it has a non-linear address space | 122 | * Exit now for SMBus or IPMI address space, it has a non-linear |
123 | * and the request cannot be directly validated | 123 | * address space and the request cannot be directly validated |
124 | */ | 124 | */ |
125 | if (rgn_desc->region.space_id == ACPI_ADR_SPACE_SMBUS || | 125 | if (rgn_desc->region.space_id == ACPI_ADR_SPACE_SMBUS || |
126 | rgn_desc->region.space_id == ACPI_ADR_SPACE_IPMI) { | 126 | rgn_desc->region.space_id == ACPI_ADR_SPACE_IPMI) { |
@@ -147,8 +147,7 @@ acpi_ex_setup_region(union acpi_operand_object *obj_desc, | |||
147 | * (Region length is specified in bytes) | 147 | * (Region length is specified in bytes) |
148 | */ | 148 | */ |
149 | if (rgn_desc->region.length < | 149 | if (rgn_desc->region.length < |
150 | (obj_desc->common_field.base_byte_offset + | 150 | (obj_desc->common_field.base_byte_offset + field_datum_byte_offset + |
151 | field_datum_byte_offset + | ||
152 | obj_desc->common_field.access_byte_width)) { | 151 | obj_desc->common_field.access_byte_width)) { |
153 | if (acpi_gbl_enable_interpreter_slack) { | 152 | if (acpi_gbl_enable_interpreter_slack) { |
154 | /* | 153 | /* |
@@ -680,6 +679,7 @@ acpi_ex_extract_from_field(union acpi_operand_object *obj_desc, | |||
680 | u32 buffer_tail_bits; | 679 | u32 buffer_tail_bits; |
681 | u32 datum_count; | 680 | u32 datum_count; |
682 | u32 field_datum_count; | 681 | u32 field_datum_count; |
682 | u32 access_bit_width; | ||
683 | u32 i; | 683 | u32 i; |
684 | 684 | ||
685 | ACPI_FUNCTION_TRACE(ex_extract_from_field); | 685 | ACPI_FUNCTION_TRACE(ex_extract_from_field); |
@@ -694,16 +694,36 @@ acpi_ex_extract_from_field(union acpi_operand_object *obj_desc, | |||
694 | 694 | ||
695 | return_ACPI_STATUS(AE_BUFFER_OVERFLOW); | 695 | return_ACPI_STATUS(AE_BUFFER_OVERFLOW); |
696 | } | 696 | } |
697 | |||
697 | ACPI_MEMSET(buffer, 0, buffer_length); | 698 | ACPI_MEMSET(buffer, 0, buffer_length); |
699 | access_bit_width = ACPI_MUL_8(obj_desc->common_field.access_byte_width); | ||
700 | |||
701 | /* Handle the simple case here */ | ||
702 | |||
703 | if ((obj_desc->common_field.start_field_bit_offset == 0) && | ||
704 | (obj_desc->common_field.bit_length == access_bit_width)) { | ||
705 | status = acpi_ex_field_datum_io(obj_desc, 0, buffer, ACPI_READ); | ||
706 | return_ACPI_STATUS(status); | ||
707 | } | ||
708 | |||
709 | /* TBD: Move to common setup code */ | ||
710 | |||
711 | /* Field algorithm is limited to sizeof(u64), truncate if needed */ | ||
712 | |||
713 | if (obj_desc->common_field.access_byte_width > sizeof(u64)) { | ||
714 | obj_desc->common_field.access_byte_width = sizeof(u64); | ||
715 | access_bit_width = sizeof(u64) * 8; | ||
716 | } | ||
698 | 717 | ||
699 | /* Compute the number of datums (access width data items) */ | 718 | /* Compute the number of datums (access width data items) */ |
700 | 719 | ||
701 | datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length, | 720 | datum_count = |
702 | obj_desc->common_field.access_bit_width); | 721 | ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length, |
722 | access_bit_width); | ||
723 | |||
703 | field_datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length + | 724 | field_datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length + |
704 | obj_desc->common_field. | 725 | obj_desc->common_field. |
705 | start_field_bit_offset, | 726 | start_field_bit_offset, |
706 | obj_desc->common_field. | ||
707 | access_bit_width); | 727 | access_bit_width); |
708 | 728 | ||
709 | /* Priming read from the field */ | 729 | /* Priming read from the field */ |
@@ -738,12 +758,11 @@ acpi_ex_extract_from_field(union acpi_operand_object *obj_desc, | |||
738 | * This avoids the differences in behavior between different compilers | 758 | * This avoids the differences in behavior between different compilers |
739 | * concerning shift values larger than the target data width. | 759 | * concerning shift values larger than the target data width. |
740 | */ | 760 | */ |
741 | if ((obj_desc->common_field.access_bit_width - | 761 | if (access_bit_width - |
742 | obj_desc->common_field.start_field_bit_offset) < | 762 | obj_desc->common_field.start_field_bit_offset < |
743 | ACPI_INTEGER_BIT_SIZE) { | 763 | ACPI_INTEGER_BIT_SIZE) { |
744 | merged_datum |= | 764 | merged_datum |= |
745 | raw_datum << (obj_desc->common_field. | 765 | raw_datum << (access_bit_width - |
746 | access_bit_width - | ||
747 | obj_desc->common_field. | 766 | obj_desc->common_field. |
748 | start_field_bit_offset); | 767 | start_field_bit_offset); |
749 | } | 768 | } |
@@ -765,8 +784,7 @@ acpi_ex_extract_from_field(union acpi_operand_object *obj_desc, | |||
765 | 784 | ||
766 | /* Mask off any extra bits in the last datum */ | 785 | /* Mask off any extra bits in the last datum */ |
767 | 786 | ||
768 | buffer_tail_bits = obj_desc->common_field.bit_length % | 787 | buffer_tail_bits = obj_desc->common_field.bit_length % access_bit_width; |
769 | obj_desc->common_field.access_bit_width; | ||
770 | if (buffer_tail_bits) { | 788 | if (buffer_tail_bits) { |
771 | merged_datum &= ACPI_MASK_BITS_ABOVE(buffer_tail_bits); | 789 | merged_datum &= ACPI_MASK_BITS_ABOVE(buffer_tail_bits); |
772 | } | 790 | } |
@@ -798,6 +816,7 @@ acpi_status | |||
798 | acpi_ex_insert_into_field(union acpi_operand_object *obj_desc, | 816 | acpi_ex_insert_into_field(union acpi_operand_object *obj_desc, |
799 | void *buffer, u32 buffer_length) | 817 | void *buffer, u32 buffer_length) |
800 | { | 818 | { |
819 | void *new_buffer; | ||
801 | acpi_status status; | 820 | acpi_status status; |
802 | u64 mask; | 821 | u64 mask; |
803 | u64 width_mask; | 822 | u64 width_mask; |
@@ -808,9 +827,9 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc, | |||
808 | u32 buffer_tail_bits; | 827 | u32 buffer_tail_bits; |
809 | u32 datum_count; | 828 | u32 datum_count; |
810 | u32 field_datum_count; | 829 | u32 field_datum_count; |
811 | u32 i; | 830 | u32 access_bit_width; |
812 | u32 required_length; | 831 | u32 required_length; |
813 | void *new_buffer; | 832 | u32 i; |
814 | 833 | ||
815 | ACPI_FUNCTION_TRACE(ex_insert_into_field); | 834 | ACPI_FUNCTION_TRACE(ex_insert_into_field); |
816 | 835 | ||
@@ -844,17 +863,24 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc, | |||
844 | buffer_length = required_length; | 863 | buffer_length = required_length; |
845 | } | 864 | } |
846 | 865 | ||
866 | /* TBD: Move to common setup code */ | ||
867 | |||
868 | /* Algo is limited to sizeof(u64), so cut the access_byte_width */ | ||
869 | if (obj_desc->common_field.access_byte_width > sizeof(u64)) { | ||
870 | obj_desc->common_field.access_byte_width = sizeof(u64); | ||
871 | } | ||
872 | |||
873 | access_bit_width = ACPI_MUL_8(obj_desc->common_field.access_byte_width); | ||
874 | |||
847 | /* | 875 | /* |
848 | * Create the bitmasks used for bit insertion. | 876 | * Create the bitmasks used for bit insertion. |
849 | * Note: This if/else is used to bypass compiler differences with the | 877 | * Note: This if/else is used to bypass compiler differences with the |
850 | * shift operator | 878 | * shift operator |
851 | */ | 879 | */ |
852 | if (obj_desc->common_field.access_bit_width == ACPI_INTEGER_BIT_SIZE) { | 880 | if (access_bit_width == ACPI_INTEGER_BIT_SIZE) { |
853 | width_mask = ACPI_UINT64_MAX; | 881 | width_mask = ACPI_UINT64_MAX; |
854 | } else { | 882 | } else { |
855 | width_mask = | 883 | width_mask = ACPI_MASK_BITS_ABOVE(access_bit_width); |
856 | ACPI_MASK_BITS_ABOVE(obj_desc->common_field. | ||
857 | access_bit_width); | ||
858 | } | 884 | } |
859 | 885 | ||
860 | mask = width_mask & | 886 | mask = width_mask & |
@@ -863,12 +889,11 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc, | |||
863 | /* Compute the number of datums (access width data items) */ | 889 | /* Compute the number of datums (access width data items) */ |
864 | 890 | ||
865 | datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length, | 891 | datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length, |
866 | obj_desc->common_field.access_bit_width); | 892 | access_bit_width); |
867 | 893 | ||
868 | field_datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length + | 894 | field_datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length + |
869 | obj_desc->common_field. | 895 | obj_desc->common_field. |
870 | start_field_bit_offset, | 896 | start_field_bit_offset, |
871 | obj_desc->common_field. | ||
872 | access_bit_width); | 897 | access_bit_width); |
873 | 898 | ||
874 | /* Get initial Datum from the input buffer */ | 899 | /* Get initial Datum from the input buffer */ |
@@ -905,12 +930,11 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc, | |||
905 | * This avoids the differences in behavior between different compilers | 930 | * This avoids the differences in behavior between different compilers |
906 | * concerning shift values larger than the target data width. | 931 | * concerning shift values larger than the target data width. |
907 | */ | 932 | */ |
908 | if ((obj_desc->common_field.access_bit_width - | 933 | if ((access_bit_width - |
909 | obj_desc->common_field.start_field_bit_offset) < | 934 | obj_desc->common_field.start_field_bit_offset) < |
910 | ACPI_INTEGER_BIT_SIZE) { | 935 | ACPI_INTEGER_BIT_SIZE) { |
911 | merged_datum = | 936 | merged_datum = |
912 | raw_datum >> (obj_desc->common_field. | 937 | raw_datum >> (access_bit_width - |
913 | access_bit_width - | ||
914 | obj_desc->common_field. | 938 | obj_desc->common_field. |
915 | start_field_bit_offset); | 939 | start_field_bit_offset); |
916 | } else { | 940 | } else { |
@@ -929,6 +953,7 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc, | |||
929 | ACPI_MEMCPY(&raw_datum, ((char *)buffer) + buffer_offset, | 953 | ACPI_MEMCPY(&raw_datum, ((char *)buffer) + buffer_offset, |
930 | ACPI_MIN(obj_desc->common_field.access_byte_width, | 954 | ACPI_MIN(obj_desc->common_field.access_byte_width, |
931 | buffer_length - buffer_offset)); | 955 | buffer_length - buffer_offset)); |
956 | |||
932 | merged_datum |= | 957 | merged_datum |= |
933 | raw_datum << obj_desc->common_field.start_field_bit_offset; | 958 | raw_datum << obj_desc->common_field.start_field_bit_offset; |
934 | } | 959 | } |
@@ -937,7 +962,7 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc, | |||
937 | 962 | ||
938 | buffer_tail_bits = (obj_desc->common_field.bit_length + | 963 | buffer_tail_bits = (obj_desc->common_field.bit_length + |
939 | obj_desc->common_field.start_field_bit_offset) % | 964 | obj_desc->common_field.start_field_bit_offset) % |
940 | obj_desc->common_field.access_bit_width; | 965 | access_bit_width; |
941 | if (buffer_tail_bits) { | 966 | if (buffer_tail_bits) { |
942 | mask &= ACPI_MASK_BITS_ABOVE(buffer_tail_bits); | 967 | mask &= ACPI_MASK_BITS_ABOVE(buffer_tail_bits); |
943 | } | 968 | } |
diff --git a/drivers/acpi/acpica/exmutex.c b/drivers/acpi/acpica/exmutex.c index f73be97043c..6af14e43f83 100644 --- a/drivers/acpi/acpica/exmutex.c +++ b/drivers/acpi/acpica/exmutex.c | |||
@@ -336,7 +336,7 @@ acpi_status acpi_ex_release_mutex_object(union acpi_operand_object *obj_desc) | |||
336 | 336 | ||
337 | /* Clear mutex info */ | 337 | /* Clear mutex info */ |
338 | 338 | ||
339 | obj_desc->mutex.thread_id = NULL; | 339 | obj_desc->mutex.thread_id = 0; |
340 | return_ACPI_STATUS(status); | 340 | return_ACPI_STATUS(status); |
341 | } | 341 | } |
342 | 342 | ||
@@ -393,10 +393,10 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc, | |||
393 | if ((owner_thread->thread_id != walk_state->thread->thread_id) && | 393 | if ((owner_thread->thread_id != walk_state->thread->thread_id) && |
394 | (obj_desc != acpi_gbl_global_lock_mutex)) { | 394 | (obj_desc != acpi_gbl_global_lock_mutex)) { |
395 | ACPI_ERROR((AE_INFO, | 395 | ACPI_ERROR((AE_INFO, |
396 | "Thread %p cannot release Mutex [%4.4s] acquired by thread %p", | 396 | "Thread %u cannot release Mutex [%4.4s] acquired by thread %u", |
397 | ACPI_CAST_PTR(void, walk_state->thread->thread_id), | 397 | (u32)walk_state->thread->thread_id, |
398 | acpi_ut_get_node_name(obj_desc->mutex.node), | 398 | acpi_ut_get_node_name(obj_desc->mutex.node), |
399 | ACPI_CAST_PTR(void, owner_thread->thread_id))); | 399 | (u32)owner_thread->thread_id)); |
400 | return_ACPI_STATUS(AE_AML_NOT_OWNER); | 400 | return_ACPI_STATUS(AE_AML_NOT_OWNER); |
401 | } | 401 | } |
402 | 402 | ||
@@ -488,7 +488,7 @@ void acpi_ex_release_all_mutexes(struct acpi_thread_state *thread) | |||
488 | /* Mark mutex unowned */ | 488 | /* Mark mutex unowned */ |
489 | 489 | ||
490 | obj_desc->mutex.owner_thread = NULL; | 490 | obj_desc->mutex.owner_thread = NULL; |
491 | obj_desc->mutex.thread_id = NULL; | 491 | obj_desc->mutex.thread_id = 0; |
492 | 492 | ||
493 | /* Update Thread sync_level (Last mutex is the important one) */ | 493 | /* Update Thread sync_level (Last mutex is the important one) */ |
494 | 494 | ||
diff --git a/drivers/acpi/acpica/exprep.c b/drivers/acpi/acpica/exprep.c index 98a331d2249..7aae29f73d3 100644 --- a/drivers/acpi/acpica/exprep.c +++ b/drivers/acpi/acpica/exprep.c | |||
@@ -355,12 +355,10 @@ acpi_ex_prep_common_field_object(union acpi_operand_object *obj_desc, | |||
355 | return_ACPI_STATUS(AE_AML_OPERAND_VALUE); | 355 | return_ACPI_STATUS(AE_AML_OPERAND_VALUE); |
356 | } | 356 | } |
357 | 357 | ||
358 | /* Setup width (access granularity) fields */ | 358 | /* Setup width (access granularity) fields (values are: 1, 2, 4, 8) */ |
359 | 359 | ||
360 | obj_desc->common_field.access_byte_width = (u8) | 360 | obj_desc->common_field.access_byte_width = (u8) |
361 | ACPI_DIV_8(access_bit_width); /* 1, 2, 4, 8 */ | 361 | ACPI_DIV_8(access_bit_width); |
362 | |||
363 | obj_desc->common_field.access_bit_width = (u8) access_bit_width; | ||
364 | 362 | ||
365 | /* | 363 | /* |
366 | * base_byte_offset is the address of the start of the field within the | 364 | * 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) | |||
405 | { | 403 | { |
406 | union acpi_operand_object *obj_desc; | 404 | union acpi_operand_object *obj_desc; |
407 | union acpi_operand_object *second_desc = NULL; | 405 | union acpi_operand_object *second_desc = NULL; |
408 | u32 type; | ||
409 | acpi_status status; | 406 | acpi_status status; |
407 | u32 access_byte_width; | ||
408 | u32 type; | ||
410 | 409 | ||
411 | ACPI_FUNCTION_TRACE(ex_prep_field_value); | 410 | ACPI_FUNCTION_TRACE(ex_prep_field_value); |
412 | 411 | ||
@@ -421,8 +420,8 @@ acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info) | |||
421 | type = acpi_ns_get_type(info->region_node); | 420 | type = acpi_ns_get_type(info->region_node); |
422 | if (type != ACPI_TYPE_REGION) { | 421 | if (type != ACPI_TYPE_REGION) { |
423 | ACPI_ERROR((AE_INFO, | 422 | ACPI_ERROR((AE_INFO, |
424 | "Needed Region, found type 0x%X (%s)", | 423 | "Needed Region, found type 0x%X (%s)", type, |
425 | type, acpi_ut_get_type_name(type))); | 424 | acpi_ut_get_type_name(type))); |
426 | 425 | ||
427 | return_ACPI_STATUS(AE_AML_OPERAND_TYPE); | 426 | return_ACPI_STATUS(AE_AML_OPERAND_TYPE); |
428 | } | 427 | } |
@@ -438,7 +437,8 @@ acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info) | |||
438 | /* Initialize areas of the object that are common to all fields */ | 437 | /* Initialize areas of the object that are common to all fields */ |
439 | 438 | ||
440 | obj_desc->common_field.node = info->field_node; | 439 | obj_desc->common_field.node = info->field_node; |
441 | status = acpi_ex_prep_common_field_object(obj_desc, info->field_flags, | 440 | status = acpi_ex_prep_common_field_object(obj_desc, |
441 | info->field_flags, | ||
442 | info->attribute, | 442 | info->attribute, |
443 | info->field_bit_position, | 443 | info->field_bit_position, |
444 | info->field_bit_length); | 444 | info->field_bit_length); |
@@ -455,26 +455,25 @@ acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info) | |||
455 | obj_desc->field.region_obj = | 455 | obj_desc->field.region_obj = |
456 | acpi_ns_get_attached_object(info->region_node); | 456 | acpi_ns_get_attached_object(info->region_node); |
457 | 457 | ||
458 | /* An additional reference for the container */ | 458 | /* Allow full data read from EC address space */ |
459 | 459 | ||
460 | acpi_ut_add_reference(obj_desc->field.region_obj); | 460 | if ((obj_desc->field.region_obj->region.space_id == |
461 | ACPI_ADR_SPACE_EC) | ||
462 | && (obj_desc->common_field.bit_length > 8)) { | ||
463 | access_byte_width = | ||
464 | ACPI_ROUND_BITS_UP_TO_BYTES(obj_desc->common_field. | ||
465 | bit_length); | ||
466 | |||
467 | /* Maximum byte width supported is 255 */ | ||
461 | 468 | ||
462 | /* allow full data read from EC address space */ | 469 | if (access_byte_width < 256) { |
463 | if (obj_desc->field.region_obj->region.space_id == | ||
464 | ACPI_ADR_SPACE_EC) { | ||
465 | if (obj_desc->common_field.bit_length > 8) { | ||
466 | unsigned width = | ||
467 | ACPI_ROUND_BITS_UP_TO_BYTES( | ||
468 | obj_desc->common_field.bit_length); | ||
469 | // access_bit_width is u8, don't overflow it | ||
470 | if (width > 8) | ||
471 | width = 8; | ||
472 | obj_desc->common_field.access_byte_width = | 470 | obj_desc->common_field.access_byte_width = |
473 | width; | 471 | (u8)access_byte_width; |
474 | obj_desc->common_field.access_bit_width = | ||
475 | 8 * width; | ||
476 | } | 472 | } |
477 | } | 473 | } |
474 | /* An additional reference for the container */ | ||
475 | |||
476 | acpi_ut_add_reference(obj_desc->field.region_obj); | ||
478 | 477 | ||
479 | ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, | 478 | ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, |
480 | "RegionField: BitOff %X, Off %X, Gran %X, Region %p\n", | 479 | "RegionField: BitOff %X, Off %X, Gran %X, Region %p\n", |
diff --git a/drivers/acpi/acpica/exregion.c b/drivers/acpi/acpica/exregion.c index 8819d2ac5ae..de17e10da0e 100644 --- a/drivers/acpi/acpica/exregion.c +++ b/drivers/acpi/acpica/exregion.c | |||
@@ -353,7 +353,6 @@ acpi_ex_pci_config_space_handler(u32 function, | |||
353 | acpi_status status = AE_OK; | 353 | acpi_status status = AE_OK; |
354 | struct acpi_pci_id *pci_id; | 354 | struct acpi_pci_id *pci_id; |
355 | u16 pci_register; | 355 | u16 pci_register; |
356 | u32 value32; | ||
357 | 356 | ||
358 | ACPI_FUNCTION_TRACE(ex_pci_config_space_handler); | 357 | ACPI_FUNCTION_TRACE(ex_pci_config_space_handler); |
359 | 358 | ||
@@ -381,8 +380,7 @@ acpi_ex_pci_config_space_handler(u32 function, | |||
381 | case ACPI_READ: | 380 | case ACPI_READ: |
382 | 381 | ||
383 | status = acpi_os_read_pci_configuration(pci_id, pci_register, | 382 | status = acpi_os_read_pci_configuration(pci_id, pci_register, |
384 | &value32, bit_width); | 383 | value, bit_width); |
385 | *value = value32; | ||
386 | break; | 384 | break; |
387 | 385 | ||
388 | case ACPI_WRITE: | 386 | case ACPI_WRITE: |
diff --git a/drivers/acpi/acpica/exutils.c b/drivers/acpi/acpica/exutils.c index 74c24d517f8..4093522eed4 100644 --- a/drivers/acpi/acpica/exutils.c +++ b/drivers/acpi/acpica/exutils.c | |||
@@ -109,7 +109,7 @@ void acpi_ex_enter_interpreter(void) | |||
109 | * | 109 | * |
110 | * DESCRIPTION: Reacquire the interpreter execution region from within the | 110 | * DESCRIPTION: Reacquire the interpreter execution region from within the |
111 | * interpreter code. Failure to enter the interpreter region is a | 111 | * interpreter code. Failure to enter the interpreter region is a |
112 | * fatal system error. Used in conjuction with | 112 | * fatal system error. Used in conjunction with |
113 | * relinquish_interpreter | 113 | * relinquish_interpreter |
114 | * | 114 | * |
115 | ******************************************************************************/ | 115 | ******************************************************************************/ |
diff --git a/drivers/acpi/acpica/hwpci.c b/drivers/acpi/acpica/hwpci.c new file mode 100644 index 00000000000..ad21c7d8bf4 --- /dev/null +++ b/drivers/acpi/acpica/hwpci.c | |||
@@ -0,0 +1,412 @@ | |||
1 | /******************************************************************************* | ||
2 | * | ||
3 | * Module Name: hwpci - Obtain PCI bus, device, and function numbers | ||
4 | * | ||
5 | ******************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2010, Intel Corp. | ||
9 | * All rights reserved. | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * 1. Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions, and the following disclaimer, | ||
16 | * without modification. | ||
17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
18 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
19 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
20 | * including a substantially similar Disclaimer requirement for further | ||
21 | * binary redistribution. | ||
22 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
23 | * of any contributors may be used to endorse or promote products derived | ||
24 | * from this software without specific prior written permission. | ||
25 | * | ||
26 | * Alternatively, this software may be distributed under the terms of the | ||
27 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
28 | * Software Foundation. | ||
29 | * | ||
30 | * NO WARRANTY | ||
31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
41 | * POSSIBILITY OF SUCH DAMAGES. | ||
42 | */ | ||
43 | |||
44 | #include <acpi/acpi.h> | ||
45 | #include "accommon.h" | ||
46 | |||
47 | #define _COMPONENT ACPI_NAMESPACE | ||
48 | ACPI_MODULE_NAME("hwpci") | ||
49 | |||
50 | /* PCI configuration space values */ | ||
51 | #define PCI_CFG_HEADER_TYPE_REG 0x0E | ||
52 | #define PCI_CFG_PRIMARY_BUS_NUMBER_REG 0x18 | ||
53 | #define PCI_CFG_SECONDARY_BUS_NUMBER_REG 0x19 | ||
54 | /* PCI header values */ | ||
55 | #define PCI_HEADER_TYPE_MASK 0x7F | ||
56 | #define PCI_TYPE_BRIDGE 0x01 | ||
57 | #define PCI_TYPE_CARDBUS_BRIDGE 0x02 | ||
58 | typedef struct acpi_pci_device { | ||
59 | acpi_handle device; | ||
60 | struct acpi_pci_device *next; | ||
61 | |||
62 | } acpi_pci_device; | ||
63 | |||
64 | /* Local prototypes */ | ||
65 | |||
66 | static acpi_status | ||
67 | acpi_hw_build_pci_list(acpi_handle root_pci_device, | ||
68 | acpi_handle pci_region, | ||
69 | struct acpi_pci_device **return_list_head); | ||
70 | |||
71 | static acpi_status | ||
72 | acpi_hw_process_pci_list(struct acpi_pci_id *pci_id, | ||
73 | struct acpi_pci_device *list_head); | ||
74 | |||
75 | static void acpi_hw_delete_pci_list(struct acpi_pci_device *list_head); | ||
76 | |||
77 | static acpi_status | ||
78 | acpi_hw_get_pci_device_info(struct acpi_pci_id *pci_id, | ||
79 | acpi_handle pci_device, | ||
80 | u16 *bus_number, u8 *is_bridge); | ||
81 | |||
82 | /******************************************************************************* | ||
83 | * | ||
84 | * FUNCTION: acpi_hw_derive_pci_id | ||
85 | * | ||
86 | * PARAMETERS: pci_id - Initial values for the PCI ID. May be | ||
87 | * modified by this function. | ||
88 | * root_pci_device - A handle to a PCI device object. This | ||
89 | * object must be a PCI Root Bridge having a | ||
90 | * _HID value of either PNP0A03 or PNP0A08 | ||
91 | * pci_region - A handle to a PCI configuration space | ||
92 | * Operation Region being initialized | ||
93 | * | ||
94 | * RETURN: Status | ||
95 | * | ||
96 | * DESCRIPTION: This function derives a full PCI ID for a PCI device, | ||
97 | * consisting of a Segment number, Bus number, Device number, | ||
98 | * and function code. | ||
99 | * | ||
100 | * The PCI hardware dynamically configures PCI bus numbers | ||
101 | * depending on the bus topology discovered during system | ||
102 | * initialization. This function is invoked during configuration | ||
103 | * of a PCI_Config Operation Region in order to (possibly) update | ||
104 | * the Bus/Device/Function numbers in the pci_id with the actual | ||
105 | * values as determined by the hardware and operating system | ||
106 | * configuration. | ||
107 | * | ||
108 | * The pci_id parameter is initially populated during the Operation | ||
109 | * Region initialization. This function is then called, and is | ||
110 | * will make any necessary modifications to the Bus, Device, or | ||
111 | * Function number PCI ID subfields as appropriate for the | ||
112 | * current hardware and OS configuration. | ||
113 | * | ||
114 | * NOTE: Created 08/2010. Replaces the previous OSL acpi_os_derive_pci_id | ||
115 | * interface since this feature is OS-independent. This module | ||
116 | * specifically avoids any use of recursion by building a local | ||
117 | * temporary device list. | ||
118 | * | ||
119 | ******************************************************************************/ | ||
120 | |||
121 | acpi_status | ||
122 | acpi_hw_derive_pci_id(struct acpi_pci_id *pci_id, | ||
123 | acpi_handle root_pci_device, acpi_handle pci_region) | ||
124 | { | ||
125 | acpi_status status; | ||
126 | struct acpi_pci_device *list_head = NULL; | ||
127 | |||
128 | ACPI_FUNCTION_TRACE(hw_derive_pci_id); | ||
129 | |||
130 | if (!pci_id) { | ||
131 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
132 | } | ||
133 | |||
134 | /* Build a list of PCI devices, from pci_region up to root_pci_device */ | ||
135 | |||
136 | status = | ||
137 | acpi_hw_build_pci_list(root_pci_device, pci_region, &list_head); | ||
138 | if (ACPI_SUCCESS(status)) { | ||
139 | |||
140 | /* Walk the list, updating the PCI device/function/bus numbers */ | ||
141 | |||
142 | status = acpi_hw_process_pci_list(pci_id, list_head); | ||
143 | } | ||
144 | |||
145 | /* Always delete the list */ | ||
146 | |||
147 | acpi_hw_delete_pci_list(list_head); | ||
148 | return_ACPI_STATUS(status); | ||
149 | } | ||
150 | |||
151 | /******************************************************************************* | ||
152 | * | ||
153 | * FUNCTION: acpi_hw_build_pci_list | ||
154 | * | ||
155 | * PARAMETERS: root_pci_device - A handle to a PCI device object. This | ||
156 | * object is guaranteed to be a PCI Root | ||
157 | * Bridge having a _HID value of either | ||
158 | * PNP0A03 or PNP0A08 | ||
159 | * pci_region - A handle to the PCI configuration space | ||
160 | * Operation Region | ||
161 | * return_list_head - Where the PCI device list is returned | ||
162 | * | ||
163 | * RETURN: Status | ||
164 | * | ||
165 | * DESCRIPTION: Builds a list of devices from the input PCI region up to the | ||
166 | * Root PCI device for this namespace subtree. | ||
167 | * | ||
168 | ******************************************************************************/ | ||
169 | |||
170 | static acpi_status | ||
171 | acpi_hw_build_pci_list(acpi_handle root_pci_device, | ||
172 | acpi_handle pci_region, | ||
173 | struct acpi_pci_device **return_list_head) | ||
174 | { | ||
175 | acpi_handle current_device; | ||
176 | acpi_handle parent_device; | ||
177 | acpi_status status; | ||
178 | struct acpi_pci_device *list_element; | ||
179 | struct acpi_pci_device *list_head = NULL; | ||
180 | |||
181 | /* | ||
182 | * Ascend namespace branch until the root_pci_device is reached, building | ||
183 | * a list of device nodes. Loop will exit when either the PCI device is | ||
184 | * found, or the root of the namespace is reached. | ||
185 | */ | ||
186 | current_device = pci_region; | ||
187 | while (1) { | ||
188 | status = acpi_get_parent(current_device, &parent_device); | ||
189 | if (ACPI_FAILURE(status)) { | ||
190 | return (status); | ||
191 | } | ||
192 | |||
193 | /* Finished when we reach the PCI root device (PNP0A03 or PNP0A08) */ | ||
194 | |||
195 | if (parent_device == root_pci_device) { | ||
196 | *return_list_head = list_head; | ||
197 | return (AE_OK); | ||
198 | } | ||
199 | |||
200 | list_element = ACPI_ALLOCATE(sizeof(struct acpi_pci_device)); | ||
201 | if (!list_element) { | ||
202 | return (AE_NO_MEMORY); | ||
203 | } | ||
204 | |||
205 | /* Put new element at the head of the list */ | ||
206 | |||
207 | list_element->next = list_head; | ||
208 | list_element->device = parent_device; | ||
209 | list_head = list_element; | ||
210 | |||
211 | current_device = parent_device; | ||
212 | } | ||
213 | } | ||
214 | |||
215 | /******************************************************************************* | ||
216 | * | ||
217 | * FUNCTION: acpi_hw_process_pci_list | ||
218 | * | ||
219 | * PARAMETERS: pci_id - Initial values for the PCI ID. May be | ||
220 | * modified by this function. | ||
221 | * list_head - Device list created by | ||
222 | * acpi_hw_build_pci_list | ||
223 | * | ||
224 | * RETURN: Status | ||
225 | * | ||
226 | * DESCRIPTION: Walk downward through the PCI device list, getting the device | ||
227 | * info for each, via the PCI configuration space and updating | ||
228 | * the PCI ID as necessary. Deletes the list during traversal. | ||
229 | * | ||
230 | ******************************************************************************/ | ||
231 | |||
232 | static acpi_status | ||
233 | acpi_hw_process_pci_list(struct acpi_pci_id *pci_id, | ||
234 | struct acpi_pci_device *list_head) | ||
235 | { | ||
236 | acpi_status status = AE_OK; | ||
237 | struct acpi_pci_device *info; | ||
238 | u16 bus_number; | ||
239 | u8 is_bridge = TRUE; | ||
240 | |||
241 | ACPI_FUNCTION_NAME(hw_process_pci_list); | ||
242 | |||
243 | ACPI_DEBUG_PRINT((ACPI_DB_OPREGION, | ||
244 | "Input PciId: Seg %4.4X Bus %4.4X Dev %4.4X Func %4.4X\n", | ||
245 | pci_id->segment, pci_id->bus, pci_id->device, | ||
246 | pci_id->function)); | ||
247 | |||
248 | bus_number = pci_id->bus; | ||
249 | |||
250 | /* | ||
251 | * Descend down the namespace tree, collecting PCI device, function, | ||
252 | * and bus numbers. bus_number is only important for PCI bridges. | ||
253 | * Algorithm: As we descend the tree, use the last valid PCI device, | ||
254 | * function, and bus numbers that are discovered, and assign them | ||
255 | * to the PCI ID for the target device. | ||
256 | */ | ||
257 | info = list_head; | ||
258 | while (info) { | ||
259 | status = acpi_hw_get_pci_device_info(pci_id, info->device, | ||
260 | &bus_number, &is_bridge); | ||
261 | if (ACPI_FAILURE(status)) { | ||
262 | return_ACPI_STATUS(status); | ||
263 | } | ||
264 | |||
265 | info = info->next; | ||
266 | } | ||
267 | |||
268 | ACPI_DEBUG_PRINT((ACPI_DB_OPREGION, | ||
269 | "Output PciId: Seg %4.4X Bus %4.4X Dev %4.4X Func %4.4X " | ||
270 | "Status %X BusNumber %X IsBridge %X\n", | ||
271 | pci_id->segment, pci_id->bus, pci_id->device, | ||
272 | pci_id->function, status, bus_number, is_bridge)); | ||
273 | |||
274 | return_ACPI_STATUS(AE_OK); | ||
275 | } | ||
276 | |||
277 | /******************************************************************************* | ||
278 | * | ||
279 | * FUNCTION: acpi_hw_delete_pci_list | ||
280 | * | ||
281 | * PARAMETERS: list_head - Device list created by | ||
282 | * acpi_hw_build_pci_list | ||
283 | * | ||
284 | * RETURN: None | ||
285 | * | ||
286 | * DESCRIPTION: Free the entire PCI list. | ||
287 | * | ||
288 | ******************************************************************************/ | ||
289 | |||
290 | static void acpi_hw_delete_pci_list(struct acpi_pci_device *list_head) | ||
291 | { | ||
292 | struct acpi_pci_device *next; | ||
293 | struct acpi_pci_device *previous; | ||
294 | |||
295 | next = list_head; | ||
296 | while (next) { | ||
297 | previous = next; | ||
298 | next = previous->next; | ||
299 | ACPI_FREE(previous); | ||
300 | } | ||
301 | } | ||
302 | |||
303 | /******************************************************************************* | ||
304 | * | ||
305 | * FUNCTION: acpi_hw_get_pci_device_info | ||
306 | * | ||
307 | * PARAMETERS: pci_id - Initial values for the PCI ID. May be | ||
308 | * modified by this function. | ||
309 | * pci_device - Handle for the PCI device object | ||
310 | * bus_number - Where a PCI bridge bus number is returned | ||
311 | * is_bridge - Return value, indicates if this PCI | ||
312 | * device is a PCI bridge | ||
313 | * | ||
314 | * RETURN: Status | ||
315 | * | ||
316 | * DESCRIPTION: Get the device info for a single PCI device object. Get the | ||
317 | * _ADR (contains PCI device and function numbers), and for PCI | ||
318 | * bridge devices, get the bus number from PCI configuration | ||
319 | * space. | ||
320 | * | ||
321 | ******************************************************************************/ | ||
322 | |||
323 | static acpi_status | ||
324 | acpi_hw_get_pci_device_info(struct acpi_pci_id *pci_id, | ||
325 | acpi_handle pci_device, | ||
326 | u16 *bus_number, u8 *is_bridge) | ||
327 | { | ||
328 | acpi_status status; | ||
329 | acpi_object_type object_type; | ||
330 | u64 return_value; | ||
331 | u64 pci_value; | ||
332 | |||
333 | /* We only care about objects of type Device */ | ||
334 | |||
335 | status = acpi_get_type(pci_device, &object_type); | ||
336 | if (ACPI_FAILURE(status)) { | ||
337 | return (status); | ||
338 | } | ||
339 | |||
340 | if (object_type != ACPI_TYPE_DEVICE) { | ||
341 | return (AE_OK); | ||
342 | } | ||
343 | |||
344 | /* We need an _ADR. Ignore device if not present */ | ||
345 | |||
346 | status = acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR, | ||
347 | pci_device, &return_value); | ||
348 | if (ACPI_FAILURE(status)) { | ||
349 | return (AE_OK); | ||
350 | } | ||
351 | |||
352 | /* | ||
353 | * From _ADR, get the PCI Device and Function and | ||
354 | * update the PCI ID. | ||
355 | */ | ||
356 | pci_id->device = ACPI_HIWORD(ACPI_LODWORD(return_value)); | ||
357 | pci_id->function = ACPI_LOWORD(ACPI_LODWORD(return_value)); | ||
358 | |||
359 | /* | ||
360 | * If the previous device was a bridge, use the previous | ||
361 | * device bus number | ||
362 | */ | ||
363 | if (*is_bridge) { | ||
364 | pci_id->bus = *bus_number; | ||
365 | } | ||
366 | |||
367 | /* | ||
368 | * Get the bus numbers from PCI Config space: | ||
369 | * | ||
370 | * First, get the PCI header_type | ||
371 | */ | ||
372 | *is_bridge = FALSE; | ||
373 | status = acpi_os_read_pci_configuration(pci_id, | ||
374 | PCI_CFG_HEADER_TYPE_REG, | ||
375 | &pci_value, 8); | ||
376 | if (ACPI_FAILURE(status)) { | ||
377 | return (status); | ||
378 | } | ||
379 | |||
380 | /* We only care about bridges (1=pci_bridge, 2=card_bus_bridge) */ | ||
381 | |||
382 | pci_value &= PCI_HEADER_TYPE_MASK; | ||
383 | |||
384 | if ((pci_value != PCI_TYPE_BRIDGE) && | ||
385 | (pci_value != PCI_TYPE_CARDBUS_BRIDGE)) { | ||
386 | return (AE_OK); | ||
387 | } | ||
388 | |||
389 | /* Bridge: Get the Primary bus_number */ | ||
390 | |||
391 | status = acpi_os_read_pci_configuration(pci_id, | ||
392 | PCI_CFG_PRIMARY_BUS_NUMBER_REG, | ||
393 | &pci_value, 8); | ||
394 | if (ACPI_FAILURE(status)) { | ||
395 | return (status); | ||
396 | } | ||
397 | |||
398 | *is_bridge = TRUE; | ||
399 | pci_id->bus = (u16)pci_value; | ||
400 | |||
401 | /* Bridge: Get the Secondary bus_number */ | ||
402 | |||
403 | status = acpi_os_read_pci_configuration(pci_id, | ||
404 | PCI_CFG_SECONDARY_BUS_NUMBER_REG, | ||
405 | &pci_value, 8); | ||
406 | if (ACPI_FAILURE(status)) { | ||
407 | return (status); | ||
408 | } | ||
409 | |||
410 | *bus_number = (u16)pci_value; | ||
411 | return (AE_OK); | ||
412 | } | ||
diff --git a/drivers/acpi/acpica/nsrepair2.c b/drivers/acpi/acpica/nsrepair2.c index 4009498fbab..4ef9f43ea92 100644 --- a/drivers/acpi/acpica/nsrepair2.c +++ b/drivers/acpi/acpica/nsrepair2.c | |||
@@ -74,10 +74,18 @@ acpi_ns_repair_ALR(struct acpi_predefined_data *data, | |||
74 | union acpi_operand_object **return_object_ptr); | 74 | union acpi_operand_object **return_object_ptr); |
75 | 75 | ||
76 | static acpi_status | 76 | static acpi_status |
77 | acpi_ns_repair_CID(struct acpi_predefined_data *data, | ||
78 | union acpi_operand_object **return_object_ptr); | ||
79 | |||
80 | static acpi_status | ||
77 | acpi_ns_repair_FDE(struct acpi_predefined_data *data, | 81 | acpi_ns_repair_FDE(struct acpi_predefined_data *data, |
78 | union acpi_operand_object **return_object_ptr); | 82 | union acpi_operand_object **return_object_ptr); |
79 | 83 | ||
80 | static acpi_status | 84 | static acpi_status |
85 | acpi_ns_repair_HID(struct acpi_predefined_data *data, | ||
86 | union acpi_operand_object **return_object_ptr); | ||
87 | |||
88 | static acpi_status | ||
81 | acpi_ns_repair_PSS(struct acpi_predefined_data *data, | 89 | acpi_ns_repair_PSS(struct acpi_predefined_data *data, |
82 | union acpi_operand_object **return_object_ptr); | 90 | union acpi_operand_object **return_object_ptr); |
83 | 91 | ||
@@ -108,8 +116,10 @@ acpi_ns_sort_list(union acpi_operand_object **elements, | |||
108 | * As necessary: | 116 | * As necessary: |
109 | * | 117 | * |
110 | * _ALR: Sort the list ascending by ambient_illuminance | 118 | * _ALR: Sort the list ascending by ambient_illuminance |
119 | * _CID: Strings: uppercase all, remove any leading asterisk | ||
111 | * _FDE: Convert Buffer of BYTEs to a Buffer of DWORDs | 120 | * _FDE: Convert Buffer of BYTEs to a Buffer of DWORDs |
112 | * _GTM: Convert Buffer of BYTEs to a Buffer of DWORDs | 121 | * _GTM: Convert Buffer of BYTEs to a Buffer of DWORDs |
122 | * _HID: Strings: uppercase all, remove any leading asterisk | ||
113 | * _PSS: Sort the list descending by Power | 123 | * _PSS: Sort the list descending by Power |
114 | * _TSS: Sort the list descending by Power | 124 | * _TSS: Sort the list descending by Power |
115 | * | 125 | * |
@@ -122,8 +132,10 @@ acpi_ns_sort_list(union acpi_operand_object **elements, | |||
122 | */ | 132 | */ |
123 | static const struct acpi_repair_info acpi_ns_repairable_names[] = { | 133 | static const struct acpi_repair_info acpi_ns_repairable_names[] = { |
124 | {"_ALR", acpi_ns_repair_ALR}, | 134 | {"_ALR", acpi_ns_repair_ALR}, |
135 | {"_CID", acpi_ns_repair_CID}, | ||
125 | {"_FDE", acpi_ns_repair_FDE}, | 136 | {"_FDE", acpi_ns_repair_FDE}, |
126 | {"_GTM", acpi_ns_repair_FDE}, /* _GTM has same repair as _FDE */ | 137 | {"_GTM", acpi_ns_repair_FDE}, /* _GTM has same repair as _FDE */ |
138 | {"_HID", acpi_ns_repair_HID}, | ||
127 | {"_PSS", acpi_ns_repair_PSS}, | 139 | {"_PSS", acpi_ns_repair_PSS}, |
128 | {"_TSS", acpi_ns_repair_TSS}, | 140 | {"_TSS", acpi_ns_repair_TSS}, |
129 | {{0, 0, 0, 0}, NULL} /* Table terminator */ | 141 | {{0, 0, 0, 0}, NULL} /* Table terminator */ |
@@ -321,6 +333,157 @@ acpi_ns_repair_FDE(struct acpi_predefined_data *data, | |||
321 | 333 | ||
322 | /****************************************************************************** | 334 | /****************************************************************************** |
323 | * | 335 | * |
336 | * FUNCTION: acpi_ns_repair_CID | ||
337 | * | ||
338 | * PARAMETERS: Data - Pointer to validation data structure | ||
339 | * return_object_ptr - Pointer to the object returned from the | ||
340 | * evaluation of a method or object | ||
341 | * | ||
342 | * RETURN: Status. AE_OK if object is OK or was repaired successfully | ||
343 | * | ||
344 | * DESCRIPTION: Repair for the _CID object. If a string, ensure that all | ||
345 | * letters are uppercase and that there is no leading asterisk. | ||
346 | * If a Package, ensure same for all string elements. | ||
347 | * | ||
348 | *****************************************************************************/ | ||
349 | |||
350 | static acpi_status | ||
351 | acpi_ns_repair_CID(struct acpi_predefined_data *data, | ||
352 | union acpi_operand_object **return_object_ptr) | ||
353 | { | ||
354 | acpi_status status; | ||
355 | union acpi_operand_object *return_object = *return_object_ptr; | ||
356 | union acpi_operand_object **element_ptr; | ||
357 | union acpi_operand_object *original_element; | ||
358 | u16 original_ref_count; | ||
359 | u32 i; | ||
360 | |||
361 | /* Check for _CID as a simple string */ | ||
362 | |||
363 | if (return_object->common.type == ACPI_TYPE_STRING) { | ||
364 | status = acpi_ns_repair_HID(data, return_object_ptr); | ||
365 | return (status); | ||
366 | } | ||
367 | |||
368 | /* Exit if not a Package */ | ||
369 | |||
370 | if (return_object->common.type != ACPI_TYPE_PACKAGE) { | ||
371 | return (AE_OK); | ||
372 | } | ||
373 | |||
374 | /* Examine each element of the _CID package */ | ||
375 | |||
376 | element_ptr = return_object->package.elements; | ||
377 | for (i = 0; i < return_object->package.count; i++) { | ||
378 | original_element = *element_ptr; | ||
379 | original_ref_count = original_element->common.reference_count; | ||
380 | |||
381 | status = acpi_ns_repair_HID(data, element_ptr); | ||
382 | if (ACPI_FAILURE(status)) { | ||
383 | return (status); | ||
384 | } | ||
385 | |||
386 | /* Take care with reference counts */ | ||
387 | |||
388 | if (original_element != *element_ptr) { | ||
389 | |||
390 | /* Element was replaced */ | ||
391 | |||
392 | (*element_ptr)->common.reference_count = | ||
393 | original_ref_count; | ||
394 | |||
395 | acpi_ut_remove_reference(original_element); | ||
396 | } | ||
397 | |||
398 | element_ptr++; | ||
399 | } | ||
400 | |||
401 | return (AE_OK); | ||
402 | } | ||
403 | |||
404 | /****************************************************************************** | ||
405 | * | ||
406 | * FUNCTION: acpi_ns_repair_HID | ||
407 | * | ||
408 | * PARAMETERS: Data - Pointer to validation data structure | ||
409 | * return_object_ptr - Pointer to the object returned from the | ||
410 | * evaluation of a method or object | ||
411 | * | ||
412 | * RETURN: Status. AE_OK if object is OK or was repaired successfully | ||
413 | * | ||
414 | * DESCRIPTION: Repair for the _HID object. If a string, ensure that all | ||
415 | * letters are uppercase and that there is no leading asterisk. | ||
416 | * | ||
417 | *****************************************************************************/ | ||
418 | |||
419 | static acpi_status | ||
420 | acpi_ns_repair_HID(struct acpi_predefined_data *data, | ||
421 | union acpi_operand_object **return_object_ptr) | ||
422 | { | ||
423 | union acpi_operand_object *return_object = *return_object_ptr; | ||
424 | union acpi_operand_object *new_string; | ||
425 | char *source; | ||
426 | char *dest; | ||
427 | |||
428 | ACPI_FUNCTION_NAME(ns_repair_HID); | ||
429 | |||
430 | /* We only care about string _HID objects (not integers) */ | ||
431 | |||
432 | if (return_object->common.type != ACPI_TYPE_STRING) { | ||
433 | return (AE_OK); | ||
434 | } | ||
435 | |||
436 | if (return_object->string.length == 0) { | ||
437 | ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags, | ||
438 | "Invalid zero-length _HID or _CID string")); | ||
439 | |||
440 | /* Return AE_OK anyway, let driver handle it */ | ||
441 | |||
442 | data->flags |= ACPI_OBJECT_REPAIRED; | ||
443 | return (AE_OK); | ||
444 | } | ||
445 | |||
446 | /* It is simplest to always create a new string object */ | ||
447 | |||
448 | new_string = acpi_ut_create_string_object(return_object->string.length); | ||
449 | if (!new_string) { | ||
450 | return (AE_NO_MEMORY); | ||
451 | } | ||
452 | |||
453 | /* | ||
454 | * Remove a leading asterisk if present. For some unknown reason, there | ||
455 | * are many machines in the field that contains IDs like this. | ||
456 | * | ||
457 | * Examples: "*PNP0C03", "*ACPI0003" | ||
458 | */ | ||
459 | source = return_object->string.pointer; | ||
460 | if (*source == '*') { | ||
461 | source++; | ||
462 | new_string->string.length--; | ||
463 | |||
464 | ACPI_DEBUG_PRINT((ACPI_DB_REPAIR, | ||
465 | "%s: Removed invalid leading asterisk\n", | ||
466 | data->pathname)); | ||
467 | } | ||
468 | |||
469 | /* | ||
470 | * Copy and uppercase the string. From the ACPI specification: | ||
471 | * | ||
472 | * A valid PNP ID must be of the form "AAA####" where A is an uppercase | ||
473 | * letter and # is a hex digit. A valid ACPI ID must be of the form | ||
474 | * "ACPI####" where # is a hex digit. | ||
475 | */ | ||
476 | for (dest = new_string->string.pointer; *source; dest++, source++) { | ||
477 | *dest = (char)ACPI_TOUPPER(*source); | ||
478 | } | ||
479 | |||
480 | acpi_ut_remove_reference(return_object); | ||
481 | *return_object_ptr = new_string; | ||
482 | return (AE_OK); | ||
483 | } | ||
484 | |||
485 | /****************************************************************************** | ||
486 | * | ||
324 | * FUNCTION: acpi_ns_repair_TSS | 487 | * FUNCTION: acpi_ns_repair_TSS |
325 | * | 488 | * |
326 | * PARAMETERS: Data - Pointer to validation data structure | 489 | * PARAMETERS: Data - Pointer to validation data structure |
diff --git a/drivers/acpi/acpica/nsutils.c b/drivers/acpi/acpica/nsutils.c index e1add3491b0..a7d6ad9c111 100644 --- a/drivers/acpi/acpica/nsutils.c +++ b/drivers/acpi/acpica/nsutils.c | |||
@@ -60,104 +60,6 @@ acpi_name acpi_ns_find_parent_name(struct acpi_namespace_node *node_to_search); | |||
60 | 60 | ||
61 | /******************************************************************************* | 61 | /******************************************************************************* |
62 | * | 62 | * |
63 | * FUNCTION: acpi_ns_report_error | ||
64 | * | ||
65 | * PARAMETERS: module_name - Caller's module name (for error output) | ||
66 | * line_number - Caller's line number (for error output) | ||
67 | * internal_name - Name or path of the namespace node | ||
68 | * lookup_status - Exception code from NS lookup | ||
69 | * | ||
70 | * RETURN: None | ||
71 | * | ||
72 | * DESCRIPTION: Print warning message with full pathname | ||
73 | * | ||
74 | ******************************************************************************/ | ||
75 | |||
76 | void | ||
77 | acpi_ns_report_error(const char *module_name, | ||
78 | u32 line_number, | ||
79 | const char *internal_name, acpi_status lookup_status) | ||
80 | { | ||
81 | acpi_status status; | ||
82 | u32 bad_name; | ||
83 | char *name = NULL; | ||
84 | |||
85 | acpi_os_printf("ACPI Error (%s-%04d): ", module_name, line_number); | ||
86 | |||
87 | if (lookup_status == AE_BAD_CHARACTER) { | ||
88 | |||
89 | /* There is a non-ascii character in the name */ | ||
90 | |||
91 | ACPI_MOVE_32_TO_32(&bad_name, | ||
92 | ACPI_CAST_PTR(u32, internal_name)); | ||
93 | acpi_os_printf("[0x%4.4X] (NON-ASCII)", bad_name); | ||
94 | } else { | ||
95 | /* Convert path to external format */ | ||
96 | |||
97 | status = acpi_ns_externalize_name(ACPI_UINT32_MAX, | ||
98 | internal_name, NULL, &name); | ||
99 | |||
100 | /* Print target name */ | ||
101 | |||
102 | if (ACPI_SUCCESS(status)) { | ||
103 | acpi_os_printf("[%s]", name); | ||
104 | } else { | ||
105 | acpi_os_printf("[COULD NOT EXTERNALIZE NAME]"); | ||
106 | } | ||
107 | |||
108 | if (name) { | ||
109 | ACPI_FREE(name); | ||
110 | } | ||
111 | } | ||
112 | |||
113 | acpi_os_printf(" Namespace lookup failure, %s\n", | ||
114 | acpi_format_exception(lookup_status)); | ||
115 | } | ||
116 | |||
117 | /******************************************************************************* | ||
118 | * | ||
119 | * FUNCTION: acpi_ns_report_method_error | ||
120 | * | ||
121 | * PARAMETERS: module_name - Caller's module name (for error output) | ||
122 | * line_number - Caller's line number (for error output) | ||
123 | * Message - Error message to use on failure | ||
124 | * prefix_node - Prefix relative to the path | ||
125 | * Path - Path to the node (optional) | ||
126 | * method_status - Execution status | ||
127 | * | ||
128 | * RETURN: None | ||
129 | * | ||
130 | * DESCRIPTION: Print warning message with full pathname | ||
131 | * | ||
132 | ******************************************************************************/ | ||
133 | |||
134 | void | ||
135 | acpi_ns_report_method_error(const char *module_name, | ||
136 | u32 line_number, | ||
137 | const char *message, | ||
138 | struct acpi_namespace_node *prefix_node, | ||
139 | const char *path, acpi_status method_status) | ||
140 | { | ||
141 | acpi_status status; | ||
142 | struct acpi_namespace_node *node = prefix_node; | ||
143 | |||
144 | acpi_os_printf("ACPI Error (%s-%04d): ", module_name, line_number); | ||
145 | |||
146 | if (path) { | ||
147 | status = | ||
148 | acpi_ns_get_node(prefix_node, path, ACPI_NS_NO_UPSEARCH, | ||
149 | &node); | ||
150 | if (ACPI_FAILURE(status)) { | ||
151 | acpi_os_printf("[Could not get node by pathname]"); | ||
152 | } | ||
153 | } | ||
154 | |||
155 | acpi_ns_print_node_pathname(node, message); | ||
156 | acpi_os_printf(", %s\n", acpi_format_exception(method_status)); | ||
157 | } | ||
158 | |||
159 | /******************************************************************************* | ||
160 | * | ||
161 | * FUNCTION: acpi_ns_print_node_pathname | 63 | * FUNCTION: acpi_ns_print_node_pathname |
162 | * | 64 | * |
163 | * PARAMETERS: Node - Object | 65 | * PARAMETERS: Node - Object |
diff --git a/drivers/acpi/acpica/rsutils.c b/drivers/acpi/acpica/rsutils.c index 22cfcfbd9ff..491191e6cf6 100644 --- a/drivers/acpi/acpica/rsutils.c +++ b/drivers/acpi/acpica/rsutils.c | |||
@@ -149,7 +149,7 @@ acpi_rs_move_data(void *destination, void *source, u16 item_count, u8 move_type) | |||
149 | 149 | ||
150 | /* | 150 | /* |
151 | * 16-, 32-, and 64-bit cases must use the move macros that perform | 151 | * 16-, 32-, and 64-bit cases must use the move macros that perform |
152 | * endian conversion and/or accomodate hardware that cannot perform | 152 | * endian conversion and/or accommodate hardware that cannot perform |
153 | * misaligned memory transfers | 153 | * misaligned memory transfers |
154 | */ | 154 | */ |
155 | case ACPI_RSC_MOVE16: | 155 | case ACPI_RSC_MOVE16: |
diff --git a/drivers/acpi/acpica/tbfadt.c b/drivers/acpi/acpica/tbfadt.c index 1728cb9bf60..d2ff4325c42 100644 --- a/drivers/acpi/acpica/tbfadt.c +++ b/drivers/acpi/acpica/tbfadt.c | |||
@@ -49,7 +49,7 @@ | |||
49 | ACPI_MODULE_NAME("tbfadt") | 49 | ACPI_MODULE_NAME("tbfadt") |
50 | 50 | ||
51 | /* Local prototypes */ | 51 | /* Local prototypes */ |
52 | static inline void | 52 | static ACPI_INLINE void |
53 | acpi_tb_init_generic_address(struct acpi_generic_address *generic_address, | 53 | acpi_tb_init_generic_address(struct acpi_generic_address *generic_address, |
54 | u8 space_id, u8 byte_width, u64 address); | 54 | u8 space_id, u8 byte_width, u64 address); |
55 | 55 | ||
@@ -181,7 +181,7 @@ static struct acpi_fadt_pm_info fadt_pm_info_table[] = { | |||
181 | * | 181 | * |
182 | ******************************************************************************/ | 182 | ******************************************************************************/ |
183 | 183 | ||
184 | static inline void | 184 | static ACPI_INLINE void |
185 | acpi_tb_init_generic_address(struct acpi_generic_address *generic_address, | 185 | acpi_tb_init_generic_address(struct acpi_generic_address *generic_address, |
186 | u8 space_id, u8 byte_width, u64 address) | 186 | u8 space_id, u8 byte_width, u64 address) |
187 | { | 187 | { |
diff --git a/drivers/acpi/acpica/utdebug.c b/drivers/acpi/acpica/utdebug.c index 98351064005..f21c486929a 100644 --- a/drivers/acpi/acpica/utdebug.c +++ b/drivers/acpi/acpica/utdebug.c | |||
@@ -179,9 +179,8 @@ acpi_debug_print(u32 requested_debug_level, | |||
179 | if (thread_id != acpi_gbl_prev_thread_id) { | 179 | if (thread_id != acpi_gbl_prev_thread_id) { |
180 | if (ACPI_LV_THREADS & acpi_dbg_level) { | 180 | if (ACPI_LV_THREADS & acpi_dbg_level) { |
181 | acpi_os_printf | 181 | acpi_os_printf |
182 | ("\n**** Context Switch from TID %p to TID %p ****\n\n", | 182 | ("\n**** Context Switch from TID %u to TID %u ****\n\n", |
183 | ACPI_CAST_PTR(void, acpi_gbl_prev_thread_id), | 183 | (u32)acpi_gbl_prev_thread_id, (u32)thread_id); |
184 | ACPI_CAST_PTR(void, thread_id)); | ||
185 | } | 184 | } |
186 | 185 | ||
187 | acpi_gbl_prev_thread_id = thread_id; | 186 | acpi_gbl_prev_thread_id = thread_id; |
@@ -194,7 +193,7 @@ acpi_debug_print(u32 requested_debug_level, | |||
194 | acpi_os_printf("%8s-%04ld ", module_name, line_number); | 193 | acpi_os_printf("%8s-%04ld ", module_name, line_number); |
195 | 194 | ||
196 | if (ACPI_LV_THREADS & acpi_dbg_level) { | 195 | if (ACPI_LV_THREADS & acpi_dbg_level) { |
197 | acpi_os_printf("[%p] ", ACPI_CAST_PTR(void, thread_id)); | 196 | acpi_os_printf("[%u] ", (u32)thread_id); |
198 | } | 197 | } |
199 | 198 | ||
200 | acpi_os_printf("[%02ld] %-22.22s: ", | 199 | acpi_os_printf("[%02ld] %-22.22s: ", |
diff --git a/drivers/acpi/acpica/uteval.c b/drivers/acpi/acpica/uteval.c index 6dfdeb65349..22f59ef604e 100644 --- a/drivers/acpi/acpica/uteval.c +++ b/drivers/acpi/acpica/uteval.c | |||
@@ -48,153 +48,6 @@ | |||
48 | #define _COMPONENT ACPI_UTILITIES | 48 | #define _COMPONENT ACPI_UTILITIES |
49 | ACPI_MODULE_NAME("uteval") | 49 | ACPI_MODULE_NAME("uteval") |
50 | 50 | ||
51 | /* | ||
52 | * Strings supported by the _OSI predefined (internal) method. | ||
53 | * | ||
54 | * March 2009: Removed "Linux" as this host no longer wants to respond true | ||
55 | * for this string. Basically, the only safe OS strings are windows-related | ||
56 | * and in many or most cases represent the only test path within the | ||
57 | * BIOS-provided ASL code. | ||
58 | * | ||
59 | * The second element of each entry is used to track the newest version of | ||
60 | * Windows that the BIOS has requested. | ||
61 | */ | ||
62 | static struct acpi_interface_info acpi_interfaces_supported[] = { | ||
63 | /* Operating System Vendor Strings */ | ||
64 | |||
65 | {"Windows 2000", ACPI_OSI_WIN_2000}, /* Windows 2000 */ | ||
66 | {"Windows 2001", ACPI_OSI_WIN_XP}, /* Windows XP */ | ||
67 | {"Windows 2001 SP1", ACPI_OSI_WIN_XP_SP1}, /* Windows XP SP1 */ | ||
68 | {"Windows 2001.1", ACPI_OSI_WINSRV_2003}, /* Windows Server 2003 */ | ||
69 | {"Windows 2001 SP2", ACPI_OSI_WIN_XP_SP2}, /* Windows XP SP2 */ | ||
70 | {"Windows 2001.1 SP1", ACPI_OSI_WINSRV_2003_SP1}, /* Windows Server 2003 SP1 - Added 03/2006 */ | ||
71 | {"Windows 2006", ACPI_OSI_WIN_VISTA}, /* Windows Vista - Added 03/2006 */ | ||
72 | {"Windows 2006.1", ACPI_OSI_WINSRV_2008}, /* Windows Server 2008 - Added 09/2009 */ | ||
73 | {"Windows 2006 SP1", ACPI_OSI_WIN_VISTA_SP1}, /* Windows Vista SP1 - Added 09/2009 */ | ||
74 | {"Windows 2009", ACPI_OSI_WIN_7}, /* Windows 7 and Server 2008 R2 - Added 09/2009 */ | ||
75 | |||
76 | /* Feature Group Strings */ | ||
77 | |||
78 | {"Extended Address Space Descriptor", 0} | ||
79 | |||
80 | /* | ||
81 | * All "optional" feature group strings (features that are implemented | ||
82 | * by the host) should be implemented in the host version of | ||
83 | * acpi_os_validate_interface and should not be added here. | ||
84 | */ | ||
85 | }; | ||
86 | |||
87 | /******************************************************************************* | ||
88 | * | ||
89 | * FUNCTION: acpi_ut_osi_implementation | ||
90 | * | ||
91 | * PARAMETERS: walk_state - Current walk state | ||
92 | * | ||
93 | * RETURN: Status | ||
94 | * | ||
95 | * DESCRIPTION: Implementation of the _OSI predefined control method | ||
96 | * | ||
97 | ******************************************************************************/ | ||
98 | |||
99 | acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state) | ||
100 | { | ||
101 | acpi_status status; | ||
102 | union acpi_operand_object *string_desc; | ||
103 | union acpi_operand_object *return_desc; | ||
104 | u32 return_value; | ||
105 | u32 i; | ||
106 | |||
107 | ACPI_FUNCTION_TRACE(ut_osi_implementation); | ||
108 | |||
109 | /* Validate the string input argument */ | ||
110 | |||
111 | string_desc = walk_state->arguments[0].object; | ||
112 | if (!string_desc || (string_desc->common.type != ACPI_TYPE_STRING)) { | ||
113 | return_ACPI_STATUS(AE_TYPE); | ||
114 | } | ||
115 | |||
116 | /* Create a return object */ | ||
117 | |||
118 | return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER); | ||
119 | if (!return_desc) { | ||
120 | return_ACPI_STATUS(AE_NO_MEMORY); | ||
121 | } | ||
122 | |||
123 | /* Default return value is 0, NOT SUPPORTED */ | ||
124 | |||
125 | return_value = 0; | ||
126 | |||
127 | /* Compare input string to static table of supported interfaces */ | ||
128 | |||
129 | for (i = 0; i < ACPI_ARRAY_LENGTH(acpi_interfaces_supported); i++) { | ||
130 | if (!ACPI_STRCMP(string_desc->string.pointer, | ||
131 | acpi_interfaces_supported[i].name)) { | ||
132 | /* | ||
133 | * The interface is supported. | ||
134 | * Update the osi_data if necessary. We keep track of the latest | ||
135 | * version of Windows that has been requested by the BIOS. | ||
136 | */ | ||
137 | if (acpi_interfaces_supported[i].value > | ||
138 | acpi_gbl_osi_data) { | ||
139 | acpi_gbl_osi_data = | ||
140 | acpi_interfaces_supported[i].value; | ||
141 | } | ||
142 | |||
143 | return_value = ACPI_UINT32_MAX; | ||
144 | goto exit; | ||
145 | } | ||
146 | } | ||
147 | |||
148 | /* | ||
149 | * Did not match the string in the static table, call the host OSL to | ||
150 | * check for a match with one of the optional strings (such as | ||
151 | * "Module Device", "3.0 Thermal Model", etc.) | ||
152 | */ | ||
153 | status = acpi_os_validate_interface(string_desc->string.pointer); | ||
154 | if (ACPI_SUCCESS(status)) { | ||
155 | |||
156 | /* The interface is supported */ | ||
157 | |||
158 | return_value = ACPI_UINT32_MAX; | ||
159 | } | ||
160 | |||
161 | exit: | ||
162 | ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, | ||
163 | "ACPI: BIOS _OSI(%s) is %ssupported\n", | ||
164 | string_desc->string.pointer, return_value == 0 ? "not " : "")); | ||
165 | |||
166 | /* Complete the return value */ | ||
167 | |||
168 | return_desc->integer.value = return_value; | ||
169 | walk_state->return_desc = return_desc; | ||
170 | return_ACPI_STATUS (AE_OK); | ||
171 | } | ||
172 | |||
173 | /******************************************************************************* | ||
174 | * | ||
175 | * FUNCTION: acpi_osi_invalidate | ||
176 | * | ||
177 | * PARAMETERS: interface_string | ||
178 | * | ||
179 | * RETURN: Status | ||
180 | * | ||
181 | * DESCRIPTION: invalidate string in pre-defiend _OSI string list | ||
182 | * | ||
183 | ******************************************************************************/ | ||
184 | |||
185 | acpi_status acpi_osi_invalidate(char *interface) | ||
186 | { | ||
187 | int i; | ||
188 | |||
189 | for (i = 0; i < ACPI_ARRAY_LENGTH(acpi_interfaces_supported); i++) { | ||
190 | if (!ACPI_STRCMP(interface, acpi_interfaces_supported[i].name)) { | ||
191 | *acpi_interfaces_supported[i].name = '\0'; | ||
192 | return AE_OK; | ||
193 | } | ||
194 | } | ||
195 | return AE_NOT_FOUND; | ||
196 | } | ||
197 | |||
198 | /******************************************************************************* | 51 | /******************************************************************************* |
199 | * | 52 | * |
200 | * FUNCTION: acpi_ut_evaluate_object | 53 | * FUNCTION: acpi_ut_evaluate_object |
diff --git a/drivers/acpi/acpica/utglobal.c b/drivers/acpi/acpica/utglobal.c index 0558747579e..e87bc6760be 100644 --- a/drivers/acpi/acpica/utglobal.c +++ b/drivers/acpi/acpica/utglobal.c | |||
@@ -154,14 +154,16 @@ ACPI_EXPORT_SYMBOL(acpi_format_exception) | |||
154 | * 1) _SB_ is defined to be a device to allow \_SB_._INI to be run | 154 | * 1) _SB_ is defined to be a device to allow \_SB_._INI to be run |
155 | * during the initialization sequence. | 155 | * during the initialization sequence. |
156 | * 2) _TZ_ is defined to be a thermal zone in order to allow ASL code to | 156 | * 2) _TZ_ is defined to be a thermal zone in order to allow ASL code to |
157 | * perform a Notify() operation on it. | 157 | * perform a Notify() operation on it. 09/2010: Changed to type Device. |
158 | * This still allows notifies, but does not confuse host code that | ||
159 | * searches for valid thermal_zone objects. | ||
158 | */ | 160 | */ |
159 | const struct acpi_predefined_names acpi_gbl_pre_defined_names[] = { | 161 | const struct acpi_predefined_names acpi_gbl_pre_defined_names[] = { |
160 | {"_GPE", ACPI_TYPE_LOCAL_SCOPE, NULL}, | 162 | {"_GPE", ACPI_TYPE_LOCAL_SCOPE, NULL}, |
161 | {"_PR_", ACPI_TYPE_LOCAL_SCOPE, NULL}, | 163 | {"_PR_", ACPI_TYPE_LOCAL_SCOPE, NULL}, |
162 | {"_SB_", ACPI_TYPE_DEVICE, NULL}, | 164 | {"_SB_", ACPI_TYPE_DEVICE, NULL}, |
163 | {"_SI_", ACPI_TYPE_LOCAL_SCOPE, NULL}, | 165 | {"_SI_", ACPI_TYPE_LOCAL_SCOPE, NULL}, |
164 | {"_TZ_", ACPI_TYPE_THERMAL, NULL}, | 166 | {"_TZ_", ACPI_TYPE_DEVICE, NULL}, |
165 | {"_REV", ACPI_TYPE_INTEGER, (char *)ACPI_CA_SUPPORT_LEVEL}, | 167 | {"_REV", ACPI_TYPE_INTEGER, (char *)ACPI_CA_SUPPORT_LEVEL}, |
166 | {"_OS_", ACPI_TYPE_STRING, ACPI_OS_NAME}, | 168 | {"_OS_", ACPI_TYPE_STRING, ACPI_OS_NAME}, |
167 | {"_GL_", ACPI_TYPE_MUTEX, (char *)1}, | 169 | {"_GL_", ACPI_TYPE_MUTEX, (char *)1}, |
@@ -766,6 +768,7 @@ acpi_status acpi_ut_init_globals(void) | |||
766 | acpi_gbl_gpe_fadt_blocks[0] = NULL; | 768 | acpi_gbl_gpe_fadt_blocks[0] = NULL; |
767 | acpi_gbl_gpe_fadt_blocks[1] = NULL; | 769 | acpi_gbl_gpe_fadt_blocks[1] = NULL; |
768 | acpi_current_gpe_count = 0; | 770 | acpi_current_gpe_count = 0; |
771 | acpi_all_gpes_initialized = FALSE; | ||
769 | 772 | ||
770 | /* Global handlers */ | 773 | /* Global handlers */ |
771 | 774 | ||
@@ -774,6 +777,7 @@ acpi_status acpi_ut_init_globals(void) | |||
774 | acpi_gbl_exception_handler = NULL; | 777 | acpi_gbl_exception_handler = NULL; |
775 | acpi_gbl_init_handler = NULL; | 778 | acpi_gbl_init_handler = NULL; |
776 | acpi_gbl_table_handler = NULL; | 779 | acpi_gbl_table_handler = NULL; |
780 | acpi_gbl_interface_handler = NULL; | ||
777 | 781 | ||
778 | /* Global Lock support */ | 782 | /* Global Lock support */ |
779 | 783 | ||
@@ -800,6 +804,7 @@ acpi_status acpi_ut_init_globals(void) | |||
800 | acpi_gbl_debugger_configuration = DEBUGGER_THREADING; | 804 | acpi_gbl_debugger_configuration = DEBUGGER_THREADING; |
801 | acpi_gbl_db_output_flags = ACPI_DB_CONSOLE_OUTPUT; | 805 | acpi_gbl_db_output_flags = ACPI_DB_CONSOLE_OUTPUT; |
802 | acpi_gbl_osi_data = 0; | 806 | acpi_gbl_osi_data = 0; |
807 | acpi_gbl_osi_mutex = NULL; | ||
803 | 808 | ||
804 | /* Hardware oriented */ | 809 | /* Hardware oriented */ |
805 | 810 | ||
diff --git a/drivers/acpi/acpica/utids.c b/drivers/acpi/acpica/utids.c index 1397fadd0d4..d2906328535 100644 --- a/drivers/acpi/acpica/utids.c +++ b/drivers/acpi/acpica/utids.c | |||
@@ -48,42 +48,6 @@ | |||
48 | #define _COMPONENT ACPI_UTILITIES | 48 | #define _COMPONENT ACPI_UTILITIES |
49 | ACPI_MODULE_NAME("utids") | 49 | ACPI_MODULE_NAME("utids") |
50 | 50 | ||
51 | /* Local prototypes */ | ||
52 | static void acpi_ut_copy_id_string(char *destination, char *source); | ||
53 | |||
54 | /******************************************************************************* | ||
55 | * | ||
56 | * FUNCTION: acpi_ut_copy_id_string | ||
57 | * | ||
58 | * PARAMETERS: Destination - Where to copy the string | ||
59 | * Source - Source string | ||
60 | * | ||
61 | * RETURN: None | ||
62 | * | ||
63 | * DESCRIPTION: Copies an ID string for the _HID, _CID, and _UID methods. | ||
64 | * Performs removal of a leading asterisk if present -- workaround | ||
65 | * for a known issue on a bunch of machines. | ||
66 | * | ||
67 | ******************************************************************************/ | ||
68 | |||
69 | static void acpi_ut_copy_id_string(char *destination, char *source) | ||
70 | { | ||
71 | |||
72 | /* | ||
73 | * Workaround for ID strings that have a leading asterisk. This construct | ||
74 | * is not allowed by the ACPI specification (ID strings must be | ||
75 | * alphanumeric), but enough existing machines have this embedded in their | ||
76 | * ID strings that the following code is useful. | ||
77 | */ | ||
78 | if (*source == '*') { | ||
79 | source++; | ||
80 | } | ||
81 | |||
82 | /* Do the actual copy */ | ||
83 | |||
84 | ACPI_STRCPY(destination, source); | ||
85 | } | ||
86 | |||
87 | /******************************************************************************* | 51 | /******************************************************************************* |
88 | * | 52 | * |
89 | * FUNCTION: acpi_ut_execute_HID | 53 | * FUNCTION: acpi_ut_execute_HID |
@@ -101,7 +65,6 @@ static void acpi_ut_copy_id_string(char *destination, char *source) | |||
101 | * NOTE: Internal function, no parameter validation | 65 | * NOTE: Internal function, no parameter validation |
102 | * | 66 | * |
103 | ******************************************************************************/ | 67 | ******************************************************************************/ |
104 | |||
105 | acpi_status | 68 | acpi_status |
106 | acpi_ut_execute_HID(struct acpi_namespace_node *device_node, | 69 | acpi_ut_execute_HID(struct acpi_namespace_node *device_node, |
107 | struct acpica_device_id **return_id) | 70 | struct acpica_device_id **return_id) |
@@ -147,7 +110,7 @@ acpi_ut_execute_HID(struct acpi_namespace_node *device_node, | |||
147 | if (obj_desc->common.type == ACPI_TYPE_INTEGER) { | 110 | if (obj_desc->common.type == ACPI_TYPE_INTEGER) { |
148 | acpi_ex_eisa_id_to_string(hid->string, obj_desc->integer.value); | 111 | acpi_ex_eisa_id_to_string(hid->string, obj_desc->integer.value); |
149 | } else { | 112 | } else { |
150 | acpi_ut_copy_id_string(hid->string, obj_desc->string.pointer); | 113 | ACPI_STRCPY(hid->string, obj_desc->string.pointer); |
151 | } | 114 | } |
152 | 115 | ||
153 | hid->length = length; | 116 | hid->length = length; |
@@ -224,7 +187,7 @@ acpi_ut_execute_UID(struct acpi_namespace_node *device_node, | |||
224 | if (obj_desc->common.type == ACPI_TYPE_INTEGER) { | 187 | if (obj_desc->common.type == ACPI_TYPE_INTEGER) { |
225 | acpi_ex_integer_to_string(uid->string, obj_desc->integer.value); | 188 | acpi_ex_integer_to_string(uid->string, obj_desc->integer.value); |
226 | } else { | 189 | } else { |
227 | acpi_ut_copy_id_string(uid->string, obj_desc->string.pointer); | 190 | ACPI_STRCPY(uid->string, obj_desc->string.pointer); |
228 | } | 191 | } |
229 | 192 | ||
230 | uid->length = length; | 193 | uid->length = length; |
@@ -357,8 +320,8 @@ acpi_ut_execute_CID(struct acpi_namespace_node *device_node, | |||
357 | 320 | ||
358 | /* Copy the String CID from the returned object */ | 321 | /* Copy the String CID from the returned object */ |
359 | 322 | ||
360 | acpi_ut_copy_id_string(next_id_string, | 323 | ACPI_STRCPY(next_id_string, |
361 | cid_objects[i]->string.pointer); | 324 | cid_objects[i]->string.pointer); |
362 | length = cid_objects[i]->string.length + 1; | 325 | length = cid_objects[i]->string.length + 1; |
363 | } | 326 | } |
364 | 327 | ||
diff --git a/drivers/acpi/acpica/utinit.c b/drivers/acpi/acpica/utinit.c index a39c93dac71..c1b1c803ea9 100644 --- a/drivers/acpi/acpica/utinit.c +++ b/drivers/acpi/acpica/utinit.c | |||
@@ -117,6 +117,10 @@ void acpi_ut_subsystem_shutdown(void) | |||
117 | /* Close the acpi_event Handling */ | 117 | /* Close the acpi_event Handling */ |
118 | 118 | ||
119 | acpi_ev_terminate(); | 119 | acpi_ev_terminate(); |
120 | |||
121 | /* Delete any dynamic _OSI interfaces */ | ||
122 | |||
123 | acpi_ut_interface_terminate(); | ||
120 | #endif | 124 | #endif |
121 | 125 | ||
122 | /* Close the Namespace */ | 126 | /* Close the Namespace */ |
diff --git a/drivers/acpi/acpica/utmath.c b/drivers/acpi/acpica/utmath.c index 35059a14eb7..49cf7b7fd81 100644 --- a/drivers/acpi/acpica/utmath.c +++ b/drivers/acpi/acpica/utmath.c | |||
@@ -48,11 +48,27 @@ | |||
48 | ACPI_MODULE_NAME("utmath") | 48 | ACPI_MODULE_NAME("utmath") |
49 | 49 | ||
50 | /* | 50 | /* |
51 | * Support for double-precision integer divide. This code is included here | 51 | * Optional support for 64-bit double-precision integer divide. This code |
52 | * in order to support kernel environments where the double-precision math | 52 | * is configurable and is implemented in order to support 32-bit kernel |
53 | * library is not available. | 53 | * environments where a 64-bit double-precision math library is not available. |
54 | * | ||
55 | * Support for a more normal 64-bit divide/modulo (with check for a divide- | ||
56 | * by-zero) appears after this optional section of code. | ||
54 | */ | 57 | */ |
55 | #ifndef ACPI_USE_NATIVE_DIVIDE | 58 | #ifndef ACPI_USE_NATIVE_DIVIDE |
59 | /* Structures used only for 64-bit divide */ | ||
60 | typedef struct uint64_struct { | ||
61 | u32 lo; | ||
62 | u32 hi; | ||
63 | |||
64 | } uint64_struct; | ||
65 | |||
66 | typedef union uint64_overlay { | ||
67 | u64 full; | ||
68 | struct uint64_struct part; | ||
69 | |||
70 | } uint64_overlay; | ||
71 | |||
56 | /******************************************************************************* | 72 | /******************************************************************************* |
57 | * | 73 | * |
58 | * FUNCTION: acpi_ut_short_divide | 74 | * FUNCTION: acpi_ut_short_divide |
@@ -69,6 +85,7 @@ ACPI_MODULE_NAME("utmath") | |||
69 | * 32-bit remainder. | 85 | * 32-bit remainder. |
70 | * | 86 | * |
71 | ******************************************************************************/ | 87 | ******************************************************************************/ |
88 | |||
72 | acpi_status | 89 | acpi_status |
73 | acpi_ut_short_divide(u64 dividend, | 90 | acpi_ut_short_divide(u64 dividend, |
74 | u32 divisor, u64 *out_quotient, u32 *out_remainder) | 91 | u32 divisor, u64 *out_quotient, u32 *out_remainder) |
diff --git a/drivers/acpi/acpica/utmisc.c b/drivers/acpi/acpica/utmisc.c index e8d0724ee40..c7d0e05ef5a 100644 --- a/drivers/acpi/acpica/utmisc.c +++ b/drivers/acpi/acpica/utmisc.c | |||
@@ -50,11 +50,6 @@ | |||
50 | #define _COMPONENT ACPI_UTILITIES | 50 | #define _COMPONENT ACPI_UTILITIES |
51 | ACPI_MODULE_NAME("utmisc") | 51 | ACPI_MODULE_NAME("utmisc") |
52 | 52 | ||
53 | /* | ||
54 | * Common suffix for messages | ||
55 | */ | ||
56 | #define ACPI_COMMON_MSG_SUFFIX \ | ||
57 | acpi_os_printf(" (%8.8X/%s-%u)\n", ACPI_CA_VERSION, module_name, line_number) | ||
58 | /******************************************************************************* | 53 | /******************************************************************************* |
59 | * | 54 | * |
60 | * FUNCTION: acpi_ut_validate_exception | 55 | * FUNCTION: acpi_ut_validate_exception |
@@ -1044,160 +1039,3 @@ acpi_ut_walk_package_tree(union acpi_operand_object * source_object, | |||
1044 | 1039 | ||
1045 | return_ACPI_STATUS(AE_AML_INTERNAL); | 1040 | return_ACPI_STATUS(AE_AML_INTERNAL); |
1046 | } | 1041 | } |
1047 | |||
1048 | /******************************************************************************* | ||
1049 | * | ||
1050 | * FUNCTION: acpi_error, acpi_exception, acpi_warning, acpi_info | ||
1051 | * | ||
1052 | * PARAMETERS: module_name - Caller's module name (for error output) | ||
1053 | * line_number - Caller's line number (for error output) | ||
1054 | * Format - Printf format string + additional args | ||
1055 | * | ||
1056 | * RETURN: None | ||
1057 | * | ||
1058 | * DESCRIPTION: Print message with module/line/version info | ||
1059 | * | ||
1060 | ******************************************************************************/ | ||
1061 | |||
1062 | void ACPI_INTERNAL_VAR_XFACE | ||
1063 | acpi_error(const char *module_name, u32 line_number, const char *format, ...) | ||
1064 | { | ||
1065 | va_list args; | ||
1066 | |||
1067 | acpi_os_printf("ACPI Error: "); | ||
1068 | |||
1069 | va_start(args, format); | ||
1070 | acpi_os_vprintf(format, args); | ||
1071 | ACPI_COMMON_MSG_SUFFIX; | ||
1072 | va_end(args); | ||
1073 | } | ||
1074 | |||
1075 | void ACPI_INTERNAL_VAR_XFACE | ||
1076 | acpi_exception(const char *module_name, | ||
1077 | u32 line_number, acpi_status status, const char *format, ...) | ||
1078 | { | ||
1079 | va_list args; | ||
1080 | |||
1081 | acpi_os_printf("ACPI Exception: %s, ", acpi_format_exception(status)); | ||
1082 | |||
1083 | va_start(args, format); | ||
1084 | acpi_os_vprintf(format, args); | ||
1085 | ACPI_COMMON_MSG_SUFFIX; | ||
1086 | va_end(args); | ||
1087 | } | ||
1088 | |||
1089 | void ACPI_INTERNAL_VAR_XFACE | ||
1090 | acpi_warning(const char *module_name, u32 line_number, const char *format, ...) | ||
1091 | { | ||
1092 | va_list args; | ||
1093 | |||
1094 | acpi_os_printf("ACPI Warning: "); | ||
1095 | |||
1096 | va_start(args, format); | ||
1097 | acpi_os_vprintf(format, args); | ||
1098 | ACPI_COMMON_MSG_SUFFIX; | ||
1099 | va_end(args); | ||
1100 | } | ||
1101 | |||
1102 | void ACPI_INTERNAL_VAR_XFACE | ||
1103 | acpi_info(const char *module_name, u32 line_number, const char *format, ...) | ||
1104 | { | ||
1105 | va_list args; | ||
1106 | |||
1107 | acpi_os_printf("ACPI: "); | ||
1108 | |||
1109 | va_start(args, format); | ||
1110 | acpi_os_vprintf(format, args); | ||
1111 | acpi_os_printf("\n"); | ||
1112 | va_end(args); | ||
1113 | } | ||
1114 | |||
1115 | ACPI_EXPORT_SYMBOL(acpi_error) | ||
1116 | ACPI_EXPORT_SYMBOL(acpi_exception) | ||
1117 | ACPI_EXPORT_SYMBOL(acpi_warning) | ||
1118 | ACPI_EXPORT_SYMBOL(acpi_info) | ||
1119 | |||
1120 | /******************************************************************************* | ||
1121 | * | ||
1122 | * FUNCTION: acpi_ut_predefined_warning | ||
1123 | * | ||
1124 | * PARAMETERS: module_name - Caller's module name (for error output) | ||
1125 | * line_number - Caller's line number (for error output) | ||
1126 | * Pathname - Full pathname to the node | ||
1127 | * node_flags - From Namespace node for the method/object | ||
1128 | * Format - Printf format string + additional args | ||
1129 | * | ||
1130 | * RETURN: None | ||
1131 | * | ||
1132 | * DESCRIPTION: Warnings for the predefined validation module. Messages are | ||
1133 | * only emitted the first time a problem with a particular | ||
1134 | * method/object is detected. This prevents a flood of error | ||
1135 | * messages for methods that are repeatedly evaluated. | ||
1136 | * | ||
1137 | ******************************************************************************/ | ||
1138 | |||
1139 | void ACPI_INTERNAL_VAR_XFACE | ||
1140 | acpi_ut_predefined_warning(const char *module_name, | ||
1141 | u32 line_number, | ||
1142 | char *pathname, | ||
1143 | u8 node_flags, const char *format, ...) | ||
1144 | { | ||
1145 | va_list args; | ||
1146 | |||
1147 | /* | ||
1148 | * Warning messages for this method/object will be disabled after the | ||
1149 | * first time a validation fails or an object is successfully repaired. | ||
1150 | */ | ||
1151 | if (node_flags & ANOBJ_EVALUATED) { | ||
1152 | return; | ||
1153 | } | ||
1154 | |||
1155 | acpi_os_printf("ACPI Warning for %s: ", pathname); | ||
1156 | |||
1157 | va_start(args, format); | ||
1158 | acpi_os_vprintf(format, args); | ||
1159 | ACPI_COMMON_MSG_SUFFIX; | ||
1160 | va_end(args); | ||
1161 | } | ||
1162 | |||
1163 | /******************************************************************************* | ||
1164 | * | ||
1165 | * FUNCTION: acpi_ut_predefined_info | ||
1166 | * | ||
1167 | * PARAMETERS: module_name - Caller's module name (for error output) | ||
1168 | * line_number - Caller's line number (for error output) | ||
1169 | * Pathname - Full pathname to the node | ||
1170 | * node_flags - From Namespace node for the method/object | ||
1171 | * Format - Printf format string + additional args | ||
1172 | * | ||
1173 | * RETURN: None | ||
1174 | * | ||
1175 | * DESCRIPTION: Info messages for the predefined validation module. Messages | ||
1176 | * are only emitted the first time a problem with a particular | ||
1177 | * method/object is detected. This prevents a flood of | ||
1178 | * messages for methods that are repeatedly evaluated. | ||
1179 | * | ||
1180 | ******************************************************************************/ | ||
1181 | |||
1182 | void ACPI_INTERNAL_VAR_XFACE | ||
1183 | acpi_ut_predefined_info(const char *module_name, | ||
1184 | u32 line_number, | ||
1185 | char *pathname, u8 node_flags, const char *format, ...) | ||
1186 | { | ||
1187 | va_list args; | ||
1188 | |||
1189 | /* | ||
1190 | * Warning messages for this method/object will be disabled after the | ||
1191 | * first time a validation fails or an object is successfully repaired. | ||
1192 | */ | ||
1193 | if (node_flags & ANOBJ_EVALUATED) { | ||
1194 | return; | ||
1195 | } | ||
1196 | |||
1197 | acpi_os_printf("ACPI Info for %s: ", pathname); | ||
1198 | |||
1199 | va_start(args, format); | ||
1200 | acpi_os_vprintf(format, args); | ||
1201 | ACPI_COMMON_MSG_SUFFIX; | ||
1202 | va_end(args); | ||
1203 | } | ||
diff --git a/drivers/acpi/acpica/utmutex.c b/drivers/acpi/acpica/utmutex.c index f5cca3a1300..d9efa495b43 100644 --- a/drivers/acpi/acpica/utmutex.c +++ b/drivers/acpi/acpica/utmutex.c | |||
@@ -86,6 +86,12 @@ acpi_status acpi_ut_mutex_initialize(void) | |||
86 | spin_lock_init(acpi_gbl_gpe_lock); | 86 | spin_lock_init(acpi_gbl_gpe_lock); |
87 | spin_lock_init(acpi_gbl_hardware_lock); | 87 | spin_lock_init(acpi_gbl_hardware_lock); |
88 | 88 | ||
89 | /* Mutex for _OSI support */ | ||
90 | status = acpi_os_create_mutex(&acpi_gbl_osi_mutex); | ||
91 | if (ACPI_FAILURE(status)) { | ||
92 | return_ACPI_STATUS(status); | ||
93 | } | ||
94 | |||
89 | /* Create the reader/writer lock for namespace access */ | 95 | /* Create the reader/writer lock for namespace access */ |
90 | 96 | ||
91 | status = acpi_ut_create_rw_lock(&acpi_gbl_namespace_rw_lock); | 97 | status = acpi_ut_create_rw_lock(&acpi_gbl_namespace_rw_lock); |
@@ -117,6 +123,8 @@ void acpi_ut_mutex_terminate(void) | |||
117 | acpi_ut_delete_mutex(i); | 123 | acpi_ut_delete_mutex(i); |
118 | } | 124 | } |
119 | 125 | ||
126 | acpi_os_delete_mutex(acpi_gbl_osi_mutex); | ||
127 | |||
120 | /* Delete the spinlocks */ | 128 | /* Delete the spinlocks */ |
121 | 129 | ||
122 | acpi_os_delete_lock(acpi_gbl_gpe_lock); | 130 | acpi_os_delete_lock(acpi_gbl_gpe_lock); |
@@ -220,18 +228,17 @@ acpi_status acpi_ut_acquire_mutex(acpi_mutex_handle mutex_id) | |||
220 | if (acpi_gbl_mutex_info[i].thread_id == this_thread_id) { | 228 | if (acpi_gbl_mutex_info[i].thread_id == this_thread_id) { |
221 | if (i == mutex_id) { | 229 | if (i == mutex_id) { |
222 | ACPI_ERROR((AE_INFO, | 230 | ACPI_ERROR((AE_INFO, |
223 | "Mutex [%s] already acquired by this thread [%p]", | 231 | "Mutex [%s] already acquired by this thread [%u]", |
224 | acpi_ut_get_mutex_name | 232 | acpi_ut_get_mutex_name |
225 | (mutex_id), | 233 | (mutex_id), |
226 | ACPI_CAST_PTR(void, | 234 | (u32)this_thread_id)); |
227 | this_thread_id))); | ||
228 | 235 | ||
229 | return (AE_ALREADY_ACQUIRED); | 236 | return (AE_ALREADY_ACQUIRED); |
230 | } | 237 | } |
231 | 238 | ||
232 | ACPI_ERROR((AE_INFO, | 239 | ACPI_ERROR((AE_INFO, |
233 | "Invalid acquire order: Thread %p owns [%s], wants [%s]", | 240 | "Invalid acquire order: Thread %u owns [%s], wants [%s]", |
234 | ACPI_CAST_PTR(void, this_thread_id), | 241 | (u32)this_thread_id, |
235 | acpi_ut_get_mutex_name(i), | 242 | acpi_ut_get_mutex_name(i), |
236 | acpi_ut_get_mutex_name(mutex_id))); | 243 | acpi_ut_get_mutex_name(mutex_id))); |
237 | 244 | ||
@@ -242,24 +249,24 @@ acpi_status acpi_ut_acquire_mutex(acpi_mutex_handle mutex_id) | |||
242 | #endif | 249 | #endif |
243 | 250 | ||
244 | ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, | 251 | ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, |
245 | "Thread %p attempting to acquire Mutex [%s]\n", | 252 | "Thread %u attempting to acquire Mutex [%s]\n", |
246 | ACPI_CAST_PTR(void, this_thread_id), | 253 | (u32)this_thread_id, |
247 | acpi_ut_get_mutex_name(mutex_id))); | 254 | acpi_ut_get_mutex_name(mutex_id))); |
248 | 255 | ||
249 | status = acpi_os_acquire_mutex(acpi_gbl_mutex_info[mutex_id].mutex, | 256 | status = acpi_os_acquire_mutex(acpi_gbl_mutex_info[mutex_id].mutex, |
250 | ACPI_WAIT_FOREVER); | 257 | ACPI_WAIT_FOREVER); |
251 | if (ACPI_SUCCESS(status)) { | 258 | if (ACPI_SUCCESS(status)) { |
252 | ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, | 259 | ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, |
253 | "Thread %p acquired Mutex [%s]\n", | 260 | "Thread %u acquired Mutex [%s]\n", |
254 | ACPI_CAST_PTR(void, this_thread_id), | 261 | (u32)this_thread_id, |
255 | acpi_ut_get_mutex_name(mutex_id))); | 262 | acpi_ut_get_mutex_name(mutex_id))); |
256 | 263 | ||
257 | acpi_gbl_mutex_info[mutex_id].use_count++; | 264 | acpi_gbl_mutex_info[mutex_id].use_count++; |
258 | acpi_gbl_mutex_info[mutex_id].thread_id = this_thread_id; | 265 | acpi_gbl_mutex_info[mutex_id].thread_id = this_thread_id; |
259 | } else { | 266 | } else { |
260 | ACPI_EXCEPTION((AE_INFO, status, | 267 | ACPI_EXCEPTION((AE_INFO, status, |
261 | "Thread %p could not acquire Mutex [0x%X]", | 268 | "Thread %u could not acquire Mutex [0x%X]", |
262 | ACPI_CAST_PTR(void, this_thread_id), mutex_id)); | 269 | (u32)this_thread_id, mutex_id)); |
263 | } | 270 | } |
264 | 271 | ||
265 | return (status); | 272 | return (status); |
@@ -279,10 +286,14 @@ acpi_status acpi_ut_acquire_mutex(acpi_mutex_handle mutex_id) | |||
279 | 286 | ||
280 | acpi_status acpi_ut_release_mutex(acpi_mutex_handle mutex_id) | 287 | acpi_status acpi_ut_release_mutex(acpi_mutex_handle mutex_id) |
281 | { | 288 | { |
289 | acpi_thread_id this_thread_id; | ||
290 | |||
282 | ACPI_FUNCTION_NAME(ut_release_mutex); | 291 | ACPI_FUNCTION_NAME(ut_release_mutex); |
283 | 292 | ||
284 | ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Thread %p releasing Mutex [%s]\n", | 293 | this_thread_id = acpi_os_get_thread_id(); |
285 | ACPI_CAST_PTR(void, acpi_os_get_thread_id()), | 294 | |
295 | ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Thread %u releasing Mutex [%s]\n", | ||
296 | (u32)this_thread_id, | ||
286 | acpi_ut_get_mutex_name(mutex_id))); | 297 | acpi_ut_get_mutex_name(mutex_id))); |
287 | 298 | ||
288 | if (mutex_id > ACPI_MAX_MUTEX) { | 299 | if (mutex_id > ACPI_MAX_MUTEX) { |
diff --git a/drivers/acpi/acpica/utosi.c b/drivers/acpi/acpica/utosi.c new file mode 100644 index 00000000000..18c59a85fdc --- /dev/null +++ b/drivers/acpi/acpica/utosi.c | |||
@@ -0,0 +1,380 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Module Name: utosi - Support for the _OSI predefined control method | ||
4 | * | ||
5 | *****************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2010, Intel Corp. | ||
9 | * All rights reserved. | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * 1. Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions, and the following disclaimer, | ||
16 | * without modification. | ||
17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
18 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
19 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
20 | * including a substantially similar Disclaimer requirement for further | ||
21 | * binary redistribution. | ||
22 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
23 | * of any contributors may be used to endorse or promote products derived | ||
24 | * from this software without specific prior written permission. | ||
25 | * | ||
26 | * Alternatively, this software may be distributed under the terms of the | ||
27 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
28 | * Software Foundation. | ||
29 | * | ||
30 | * NO WARRANTY | ||
31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
41 | * POSSIBILITY OF SUCH DAMAGES. | ||
42 | */ | ||
43 | |||
44 | #include <acpi/acpi.h> | ||
45 | #include "accommon.h" | ||
46 | |||
47 | #define _COMPONENT ACPI_UTILITIES | ||
48 | ACPI_MODULE_NAME("utosi") | ||
49 | |||
50 | /* | ||
51 | * Strings supported by the _OSI predefined control method (which is | ||
52 | * implemented internally within this module.) | ||
53 | * | ||
54 | * March 2009: Removed "Linux" as this host no longer wants to respond true | ||
55 | * for this string. Basically, the only safe OS strings are windows-related | ||
56 | * and in many or most cases represent the only test path within the | ||
57 | * BIOS-provided ASL code. | ||
58 | * | ||
59 | * The last element of each entry is used to track the newest version of | ||
60 | * Windows that the BIOS has requested. | ||
61 | */ | ||
62 | static struct acpi_interface_info acpi_default_supported_interfaces[] = { | ||
63 | /* Operating System Vendor Strings */ | ||
64 | |||
65 | {"Windows 2000", NULL, 0, ACPI_OSI_WIN_2000}, /* Windows 2000 */ | ||
66 | {"Windows 2001", NULL, 0, ACPI_OSI_WIN_XP}, /* Windows XP */ | ||
67 | {"Windows 2001 SP1", NULL, 0, ACPI_OSI_WIN_XP_SP1}, /* Windows XP SP1 */ | ||
68 | {"Windows 2001.1", NULL, 0, ACPI_OSI_WINSRV_2003}, /* Windows Server 2003 */ | ||
69 | {"Windows 2001 SP2", NULL, 0, ACPI_OSI_WIN_XP_SP2}, /* Windows XP SP2 */ | ||
70 | {"Windows 2001.1 SP1", NULL, 0, ACPI_OSI_WINSRV_2003_SP1}, /* Windows Server 2003 SP1 - Added 03/2006 */ | ||
71 | {"Windows 2006", NULL, 0, ACPI_OSI_WIN_VISTA}, /* Windows Vista - Added 03/2006 */ | ||
72 | {"Windows 2006.1", NULL, 0, ACPI_OSI_WINSRV_2008}, /* Windows Server 2008 - Added 09/2009 */ | ||
73 | {"Windows 2006 SP1", NULL, 0, ACPI_OSI_WIN_VISTA_SP1}, /* Windows Vista SP1 - Added 09/2009 */ | ||
74 | {"Windows 2006 SP2", NULL, 0, ACPI_OSI_WIN_VISTA_SP2}, /* Windows Vista SP2 - Added 09/2010 */ | ||
75 | {"Windows 2009", NULL, 0, ACPI_OSI_WIN_7}, /* Windows 7 and Server 2008 R2 - Added 09/2009 */ | ||
76 | |||
77 | /* Feature Group Strings */ | ||
78 | |||
79 | {"Extended Address Space Descriptor", NULL, 0, 0} | ||
80 | |||
81 | /* | ||
82 | * All "optional" feature group strings (features that are implemented | ||
83 | * by the host) should be dynamically added by the host via | ||
84 | * acpi_install_interface and should not be manually added here. | ||
85 | * | ||
86 | * Examples of optional feature group strings: | ||
87 | * | ||
88 | * "Module Device" | ||
89 | * "Processor Device" | ||
90 | * "3.0 Thermal Model" | ||
91 | * "3.0 _SCP Extensions" | ||
92 | * "Processor Aggregator Device" | ||
93 | */ | ||
94 | }; | ||
95 | |||
96 | /******************************************************************************* | ||
97 | * | ||
98 | * FUNCTION: acpi_ut_initialize_interfaces | ||
99 | * | ||
100 | * PARAMETERS: None | ||
101 | * | ||
102 | * RETURN: Status | ||
103 | * | ||
104 | * DESCRIPTION: Initialize the global _OSI supported interfaces list | ||
105 | * | ||
106 | ******************************************************************************/ | ||
107 | |||
108 | acpi_status acpi_ut_initialize_interfaces(void) | ||
109 | { | ||
110 | u32 i; | ||
111 | |||
112 | (void)acpi_os_acquire_mutex(acpi_gbl_osi_mutex, ACPI_WAIT_FOREVER); | ||
113 | acpi_gbl_supported_interfaces = acpi_default_supported_interfaces; | ||
114 | |||
115 | /* Link the static list of supported interfaces */ | ||
116 | |||
117 | for (i = 0; | ||
118 | i < (ACPI_ARRAY_LENGTH(acpi_default_supported_interfaces) - 1); | ||
119 | i++) { | ||
120 | acpi_default_supported_interfaces[i].next = | ||
121 | &acpi_default_supported_interfaces[(acpi_size) i + 1]; | ||
122 | } | ||
123 | |||
124 | acpi_os_release_mutex(acpi_gbl_osi_mutex); | ||
125 | return (AE_OK); | ||
126 | } | ||
127 | |||
128 | /******************************************************************************* | ||
129 | * | ||
130 | * FUNCTION: acpi_ut_interface_terminate | ||
131 | * | ||
132 | * PARAMETERS: None | ||
133 | * | ||
134 | * RETURN: None | ||
135 | * | ||
136 | * DESCRIPTION: Delete all interfaces in the global list. Sets | ||
137 | * acpi_gbl_supported_interfaces to NULL. | ||
138 | * | ||
139 | ******************************************************************************/ | ||
140 | |||
141 | void acpi_ut_interface_terminate(void) | ||
142 | { | ||
143 | struct acpi_interface_info *next_interface; | ||
144 | |||
145 | (void)acpi_os_acquire_mutex(acpi_gbl_osi_mutex, ACPI_WAIT_FOREVER); | ||
146 | next_interface = acpi_gbl_supported_interfaces; | ||
147 | |||
148 | while (next_interface) { | ||
149 | acpi_gbl_supported_interfaces = next_interface->next; | ||
150 | |||
151 | /* Only interfaces added at runtime can be freed */ | ||
152 | |||
153 | if (next_interface->flags & ACPI_OSI_DYNAMIC) { | ||
154 | ACPI_FREE(next_interface->name); | ||
155 | ACPI_FREE(next_interface); | ||
156 | } | ||
157 | |||
158 | next_interface = acpi_gbl_supported_interfaces; | ||
159 | } | ||
160 | |||
161 | acpi_os_release_mutex(acpi_gbl_osi_mutex); | ||
162 | } | ||
163 | |||
164 | /******************************************************************************* | ||
165 | * | ||
166 | * FUNCTION: acpi_ut_install_interface | ||
167 | * | ||
168 | * PARAMETERS: interface_name - The interface to install | ||
169 | * | ||
170 | * RETURN: Status | ||
171 | * | ||
172 | * DESCRIPTION: Install the interface into the global interface list. | ||
173 | * Caller MUST hold acpi_gbl_osi_mutex | ||
174 | * | ||
175 | ******************************************************************************/ | ||
176 | |||
177 | acpi_status acpi_ut_install_interface(acpi_string interface_name) | ||
178 | { | ||
179 | struct acpi_interface_info *interface_info; | ||
180 | |||
181 | /* Allocate info block and space for the name string */ | ||
182 | |||
183 | interface_info = | ||
184 | ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_interface_info)); | ||
185 | if (!interface_info) { | ||
186 | return (AE_NO_MEMORY); | ||
187 | } | ||
188 | |||
189 | interface_info->name = | ||
190 | ACPI_ALLOCATE_ZEROED(ACPI_STRLEN(interface_name) + 1); | ||
191 | if (!interface_info->name) { | ||
192 | ACPI_FREE(interface_info); | ||
193 | return (AE_NO_MEMORY); | ||
194 | } | ||
195 | |||
196 | /* Initialize new info and insert at the head of the global list */ | ||
197 | |||
198 | ACPI_STRCPY(interface_info->name, interface_name); | ||
199 | interface_info->flags = ACPI_OSI_DYNAMIC; | ||
200 | interface_info->next = acpi_gbl_supported_interfaces; | ||
201 | |||
202 | acpi_gbl_supported_interfaces = interface_info; | ||
203 | return (AE_OK); | ||
204 | } | ||
205 | |||
206 | /******************************************************************************* | ||
207 | * | ||
208 | * FUNCTION: acpi_ut_remove_interface | ||
209 | * | ||
210 | * PARAMETERS: interface_name - The interface to remove | ||
211 | * | ||
212 | * RETURN: Status | ||
213 | * | ||
214 | * DESCRIPTION: Remove the interface from the global interface list. | ||
215 | * Caller MUST hold acpi_gbl_osi_mutex | ||
216 | * | ||
217 | ******************************************************************************/ | ||
218 | |||
219 | acpi_status acpi_ut_remove_interface(acpi_string interface_name) | ||
220 | { | ||
221 | struct acpi_interface_info *previous_interface; | ||
222 | struct acpi_interface_info *next_interface; | ||
223 | |||
224 | previous_interface = next_interface = acpi_gbl_supported_interfaces; | ||
225 | while (next_interface) { | ||
226 | if (!ACPI_STRCMP(interface_name, next_interface->name)) { | ||
227 | |||
228 | /* Found: name is in either the static list or was added at runtime */ | ||
229 | |||
230 | if (next_interface->flags & ACPI_OSI_DYNAMIC) { | ||
231 | |||
232 | /* Interface was added dynamically, remove and free it */ | ||
233 | |||
234 | if (previous_interface == next_interface) { | ||
235 | acpi_gbl_supported_interfaces = | ||
236 | next_interface->next; | ||
237 | } else { | ||
238 | previous_interface->next = | ||
239 | next_interface->next; | ||
240 | } | ||
241 | |||
242 | ACPI_FREE(next_interface->name); | ||
243 | ACPI_FREE(next_interface); | ||
244 | } else { | ||
245 | /* | ||
246 | * Interface is in static list. If marked invalid, then it | ||
247 | * does not actually exist. Else, mark it invalid. | ||
248 | */ | ||
249 | if (next_interface->flags & ACPI_OSI_INVALID) { | ||
250 | return (AE_NOT_EXIST); | ||
251 | } | ||
252 | |||
253 | next_interface->flags |= ACPI_OSI_INVALID; | ||
254 | } | ||
255 | |||
256 | return (AE_OK); | ||
257 | } | ||
258 | |||
259 | previous_interface = next_interface; | ||
260 | next_interface = next_interface->next; | ||
261 | } | ||
262 | |||
263 | /* Interface was not found */ | ||
264 | |||
265 | return (AE_NOT_EXIST); | ||
266 | } | ||
267 | |||
268 | /******************************************************************************* | ||
269 | * | ||
270 | * FUNCTION: acpi_ut_get_interface | ||
271 | * | ||
272 | * PARAMETERS: interface_name - The interface to find | ||
273 | * | ||
274 | * RETURN: struct acpi_interface_info if found. NULL if not found. | ||
275 | * | ||
276 | * DESCRIPTION: Search for the specified interface name in the global list. | ||
277 | * Caller MUST hold acpi_gbl_osi_mutex | ||
278 | * | ||
279 | ******************************************************************************/ | ||
280 | |||
281 | struct acpi_interface_info *acpi_ut_get_interface(acpi_string interface_name) | ||
282 | { | ||
283 | struct acpi_interface_info *next_interface; | ||
284 | |||
285 | next_interface = acpi_gbl_supported_interfaces; | ||
286 | while (next_interface) { | ||
287 | if (!ACPI_STRCMP(interface_name, next_interface->name)) { | ||
288 | return (next_interface); | ||
289 | } | ||
290 | |||
291 | next_interface = next_interface->next; | ||
292 | } | ||
293 | |||
294 | return (NULL); | ||
295 | } | ||
296 | |||
297 | /******************************************************************************* | ||
298 | * | ||
299 | * FUNCTION: acpi_ut_osi_implementation | ||
300 | * | ||
301 | * PARAMETERS: walk_state - Current walk state | ||
302 | * | ||
303 | * RETURN: Status | ||
304 | * | ||
305 | * DESCRIPTION: Implementation of the _OSI predefined control method. When | ||
306 | * an invocation of _OSI is encountered in the system AML, | ||
307 | * control is transferred to this function. | ||
308 | * | ||
309 | ******************************************************************************/ | ||
310 | |||
311 | acpi_status acpi_ut_osi_implementation(struct acpi_walk_state * walk_state) | ||
312 | { | ||
313 | union acpi_operand_object *string_desc; | ||
314 | union acpi_operand_object *return_desc; | ||
315 | struct acpi_interface_info *interface_info; | ||
316 | acpi_interface_handler interface_handler; | ||
317 | u32 return_value; | ||
318 | |||
319 | ACPI_FUNCTION_TRACE(ut_osi_implementation); | ||
320 | |||
321 | /* Validate the string input argument (from the AML caller) */ | ||
322 | |||
323 | string_desc = walk_state->arguments[0].object; | ||
324 | if (!string_desc || (string_desc->common.type != ACPI_TYPE_STRING)) { | ||
325 | return_ACPI_STATUS(AE_TYPE); | ||
326 | } | ||
327 | |||
328 | /* Create a return object */ | ||
329 | |||
330 | return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER); | ||
331 | if (!return_desc) { | ||
332 | return_ACPI_STATUS(AE_NO_MEMORY); | ||
333 | } | ||
334 | |||
335 | /* Default return value is 0, NOT SUPPORTED */ | ||
336 | |||
337 | return_value = 0; | ||
338 | (void)acpi_os_acquire_mutex(acpi_gbl_osi_mutex, ACPI_WAIT_FOREVER); | ||
339 | |||
340 | /* Lookup the interface in the global _OSI list */ | ||
341 | |||
342 | interface_info = acpi_ut_get_interface(string_desc->string.pointer); | ||
343 | if (interface_info && !(interface_info->flags & ACPI_OSI_INVALID)) { | ||
344 | /* | ||
345 | * The interface is supported. | ||
346 | * Update the osi_data if necessary. We keep track of the latest | ||
347 | * version of Windows that has been requested by the BIOS. | ||
348 | */ | ||
349 | if (interface_info->value > acpi_gbl_osi_data) { | ||
350 | acpi_gbl_osi_data = interface_info->value; | ||
351 | } | ||
352 | |||
353 | return_value = ACPI_UINT32_MAX; | ||
354 | } | ||
355 | |||
356 | acpi_os_release_mutex(acpi_gbl_osi_mutex); | ||
357 | |||
358 | /* | ||
359 | * Invoke an optional _OSI interface handler. The host OS may wish | ||
360 | * to do some interface-specific handling. For example, warn about | ||
361 | * certain interfaces or override the true/false support value. | ||
362 | */ | ||
363 | interface_handler = acpi_gbl_interface_handler; | ||
364 | if (interface_handler) { | ||
365 | return_value = | ||
366 | interface_handler(string_desc->string.pointer, | ||
367 | return_value); | ||
368 | } | ||
369 | |||
370 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_INFO, | ||
371 | "ACPI: BIOS _OSI(\"%s\") is %ssupported\n", | ||
372 | string_desc->string.pointer, | ||
373 | return_value == 0 ? "not " : "")); | ||
374 | |||
375 | /* Complete the return object */ | ||
376 | |||
377 | return_desc->integer.value = return_value; | ||
378 | walk_state->return_desc = return_desc; | ||
379 | return_ACPI_STATUS(AE_OK); | ||
380 | } | ||
diff --git a/drivers/acpi/acpica/utxface.c b/drivers/acpi/acpica/utxface.c index 7f8cefcb2b3..1f484c9a688 100644 --- a/drivers/acpi/acpica/utxface.c +++ b/drivers/acpi/acpica/utxface.c | |||
@@ -110,6 +110,15 @@ acpi_status __init acpi_initialize_subsystem(void) | |||
110 | return_ACPI_STATUS(status); | 110 | return_ACPI_STATUS(status); |
111 | } | 111 | } |
112 | 112 | ||
113 | /* Initialize the global OSI interfaces list with the static names */ | ||
114 | |||
115 | status = acpi_ut_initialize_interfaces(); | ||
116 | if (ACPI_FAILURE(status)) { | ||
117 | ACPI_EXCEPTION((AE_INFO, status, | ||
118 | "During OSI interfaces initialization")); | ||
119 | return_ACPI_STATUS(status); | ||
120 | } | ||
121 | |||
113 | /* If configured, initialize the AML debugger */ | 122 | /* If configured, initialize the AML debugger */ |
114 | 123 | ||
115 | ACPI_DEBUGGER_EXEC(status = acpi_db_initialize()); | 124 | ACPI_DEBUGGER_EXEC(status = acpi_db_initialize()); |
@@ -290,19 +299,6 @@ acpi_status acpi_initialize_objects(u32 flags) | |||
290 | } | 299 | } |
291 | 300 | ||
292 | /* | 301 | /* |
293 | * Complete the GPE initialization for the GPE blocks defined in the FADT | ||
294 | * (GPE block 0 and 1). | ||
295 | * | ||
296 | * NOTE: Currently, there seems to be no need to run the _REG methods | ||
297 | * before enabling the GPEs. | ||
298 | */ | ||
299 | if (!(flags & ACPI_NO_EVENT_INIT)) { | ||
300 | status = acpi_ev_install_fadt_gpes(); | ||
301 | if (ACPI_FAILURE(status)) | ||
302 | return (status); | ||
303 | } | ||
304 | |||
305 | /* | ||
306 | * Empty the caches (delete the cached objects) on the assumption that | 302 | * Empty the caches (delete the cached objects) on the assumption that |
307 | * the table load filled them up more than they will be at runtime -- | 303 | * the table load filled them up more than they will be at runtime -- |
308 | * thus wasting non-paged memory. | 304 | * thus wasting non-paged memory. |
@@ -506,6 +502,7 @@ acpi_install_initialization_handler(acpi_init_handler handler, u32 function) | |||
506 | 502 | ||
507 | ACPI_EXPORT_SYMBOL(acpi_install_initialization_handler) | 503 | ACPI_EXPORT_SYMBOL(acpi_install_initialization_handler) |
508 | #endif /* ACPI_FUTURE_USAGE */ | 504 | #endif /* ACPI_FUTURE_USAGE */ |
505 | |||
509 | /***************************************************************************** | 506 | /***************************************************************************** |
510 | * | 507 | * |
511 | * FUNCTION: acpi_purge_cached_objects | 508 | * FUNCTION: acpi_purge_cached_objects |
@@ -529,4 +526,117 @@ acpi_status acpi_purge_cached_objects(void) | |||
529 | } | 526 | } |
530 | 527 | ||
531 | ACPI_EXPORT_SYMBOL(acpi_purge_cached_objects) | 528 | ACPI_EXPORT_SYMBOL(acpi_purge_cached_objects) |
532 | #endif | 529 | |
530 | /***************************************************************************** | ||
531 | * | ||
532 | * FUNCTION: acpi_install_interface | ||
533 | * | ||
534 | * PARAMETERS: interface_name - The interface to install | ||
535 | * | ||
536 | * RETURN: Status | ||
537 | * | ||
538 | * DESCRIPTION: Install an _OSI interface to the global list | ||
539 | * | ||
540 | ****************************************************************************/ | ||
541 | acpi_status acpi_install_interface(acpi_string interface_name) | ||
542 | { | ||
543 | acpi_status status; | ||
544 | struct acpi_interface_info *interface_info; | ||
545 | |||
546 | /* Parameter validation */ | ||
547 | |||
548 | if (!interface_name || (ACPI_STRLEN(interface_name) == 0)) { | ||
549 | return (AE_BAD_PARAMETER); | ||
550 | } | ||
551 | |||
552 | (void)acpi_os_acquire_mutex(acpi_gbl_osi_mutex, ACPI_WAIT_FOREVER); | ||
553 | |||
554 | /* Check if the interface name is already in the global list */ | ||
555 | |||
556 | interface_info = acpi_ut_get_interface(interface_name); | ||
557 | if (interface_info) { | ||
558 | /* | ||
559 | * The interface already exists in the list. This is OK if the | ||
560 | * interface has been marked invalid -- just clear the bit. | ||
561 | */ | ||
562 | if (interface_info->flags & ACPI_OSI_INVALID) { | ||
563 | interface_info->flags &= ~ACPI_OSI_INVALID; | ||
564 | status = AE_OK; | ||
565 | } else { | ||
566 | status = AE_ALREADY_EXISTS; | ||
567 | } | ||
568 | } else { | ||
569 | /* New interface name, install into the global list */ | ||
570 | |||
571 | status = acpi_ut_install_interface(interface_name); | ||
572 | } | ||
573 | |||
574 | acpi_os_release_mutex(acpi_gbl_osi_mutex); | ||
575 | return (status); | ||
576 | } | ||
577 | |||
578 | ACPI_EXPORT_SYMBOL(acpi_install_interface) | ||
579 | |||
580 | /***************************************************************************** | ||
581 | * | ||
582 | * FUNCTION: acpi_remove_interface | ||
583 | * | ||
584 | * PARAMETERS: interface_name - The interface to remove | ||
585 | * | ||
586 | * RETURN: Status | ||
587 | * | ||
588 | * DESCRIPTION: Remove an _OSI interface from the global list | ||
589 | * | ||
590 | ****************************************************************************/ | ||
591 | acpi_status acpi_remove_interface(acpi_string interface_name) | ||
592 | { | ||
593 | acpi_status status; | ||
594 | |||
595 | /* Parameter validation */ | ||
596 | |||
597 | if (!interface_name || (ACPI_STRLEN(interface_name) == 0)) { | ||
598 | return (AE_BAD_PARAMETER); | ||
599 | } | ||
600 | |||
601 | (void)acpi_os_acquire_mutex(acpi_gbl_osi_mutex, ACPI_WAIT_FOREVER); | ||
602 | |||
603 | status = acpi_ut_remove_interface(interface_name); | ||
604 | |||
605 | acpi_os_release_mutex(acpi_gbl_osi_mutex); | ||
606 | return (status); | ||
607 | } | ||
608 | |||
609 | ACPI_EXPORT_SYMBOL(acpi_remove_interface) | ||
610 | |||
611 | /***************************************************************************** | ||
612 | * | ||
613 | * FUNCTION: acpi_install_interface_handler | ||
614 | * | ||
615 | * PARAMETERS: Handler - The _OSI interface handler to install | ||
616 | * NULL means "remove existing handler" | ||
617 | * | ||
618 | * RETURN: Status | ||
619 | * | ||
620 | * DESCRIPTION: Install a handler for the predefined _OSI ACPI method. | ||
621 | * invoked during execution of the internal implementation of | ||
622 | * _OSI. A NULL handler simply removes any existing handler. | ||
623 | * | ||
624 | ****************************************************************************/ | ||
625 | acpi_status acpi_install_interface_handler(acpi_interface_handler handler) | ||
626 | { | ||
627 | acpi_status status = AE_OK; | ||
628 | |||
629 | (void)acpi_os_acquire_mutex(acpi_gbl_osi_mutex, ACPI_WAIT_FOREVER); | ||
630 | |||
631 | if (handler && acpi_gbl_interface_handler) { | ||
632 | status = AE_ALREADY_EXISTS; | ||
633 | } else { | ||
634 | acpi_gbl_interface_handler = handler; | ||
635 | } | ||
636 | |||
637 | acpi_os_release_mutex(acpi_gbl_osi_mutex); | ||
638 | return (status); | ||
639 | } | ||
640 | |||
641 | ACPI_EXPORT_SYMBOL(acpi_install_interface_handler) | ||
642 | #endif /* !ACPI_ASL_COMPILER */ | ||
diff --git a/drivers/acpi/acpica/utxferror.c b/drivers/acpi/acpica/utxferror.c new file mode 100644 index 00000000000..6f12e314fba --- /dev/null +++ b/drivers/acpi/acpica/utxferror.c | |||
@@ -0,0 +1,415 @@ | |||
1 | /******************************************************************************* | ||
2 | * | ||
3 | * Module Name: utxferror - Various error/warning output functions | ||
4 | * | ||
5 | ******************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2010, Intel Corp. | ||
9 | * All rights reserved. | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * 1. Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions, and the following disclaimer, | ||
16 | * without modification. | ||
17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
18 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
19 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
20 | * including a substantially similar Disclaimer requirement for further | ||
21 | * binary redistribution. | ||
22 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
23 | * of any contributors may be used to endorse or promote products derived | ||
24 | * from this software without specific prior written permission. | ||
25 | * | ||
26 | * Alternatively, this software may be distributed under the terms of the | ||
27 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
28 | * Software Foundation. | ||
29 | * | ||
30 | * NO WARRANTY | ||
31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
41 | * POSSIBILITY OF SUCH DAMAGES. | ||
42 | */ | ||
43 | |||
44 | #include <acpi/acpi.h> | ||
45 | #include "accommon.h" | ||
46 | #include "acnamesp.h" | ||
47 | |||
48 | #define _COMPONENT ACPI_UTILITIES | ||
49 | ACPI_MODULE_NAME("utxferror") | ||
50 | |||
51 | /* | ||
52 | * This module is used for the in-kernel ACPICA as well as the ACPICA | ||
53 | * tools/applications. | ||
54 | * | ||
55 | * For the i_aSL compiler case, the output is redirected to stderr so that | ||
56 | * any of the various ACPI errors and warnings do not appear in the output | ||
57 | * files, for either the compiler or disassembler portions of the tool. | ||
58 | */ | ||
59 | #ifdef ACPI_ASL_COMPILER | ||
60 | #include <stdio.h> | ||
61 | extern FILE *acpi_gbl_output_file; | ||
62 | |||
63 | #define ACPI_MSG_REDIRECT_BEGIN \ | ||
64 | FILE *output_file = acpi_gbl_output_file; \ | ||
65 | acpi_os_redirect_output (stderr); | ||
66 | |||
67 | #define ACPI_MSG_REDIRECT_END \ | ||
68 | acpi_os_redirect_output (output_file); | ||
69 | |||
70 | #else | ||
71 | /* | ||
72 | * non-i_aSL case - no redirection, nothing to do | ||
73 | */ | ||
74 | #define ACPI_MSG_REDIRECT_BEGIN | ||
75 | #define ACPI_MSG_REDIRECT_END | ||
76 | #endif | ||
77 | /* | ||
78 | * Common message prefixes | ||
79 | */ | ||
80 | #define ACPI_MSG_ERROR "ACPI Error: " | ||
81 | #define ACPI_MSG_EXCEPTION "ACPI Exception: " | ||
82 | #define ACPI_MSG_WARNING "ACPI Warning: " | ||
83 | #define ACPI_MSG_INFO "ACPI: " | ||
84 | /* | ||
85 | * Common message suffix | ||
86 | */ | ||
87 | #define ACPI_MSG_SUFFIX \ | ||
88 | acpi_os_printf (" (%8.8X/%s-%u)\n", ACPI_CA_VERSION, module_name, line_number) | ||
89 | /******************************************************************************* | ||
90 | * | ||
91 | * FUNCTION: acpi_error | ||
92 | * | ||
93 | * PARAMETERS: module_name - Caller's module name (for error output) | ||
94 | * line_number - Caller's line number (for error output) | ||
95 | * Format - Printf format string + additional args | ||
96 | * | ||
97 | * RETURN: None | ||
98 | * | ||
99 | * DESCRIPTION: Print "ACPI Error" message with module/line/version info | ||
100 | * | ||
101 | ******************************************************************************/ | ||
102 | void ACPI_INTERNAL_VAR_XFACE | ||
103 | acpi_error(const char *module_name, u32 line_number, const char *format, ...) | ||
104 | { | ||
105 | va_list arg_list; | ||
106 | |||
107 | ACPI_MSG_REDIRECT_BEGIN; | ||
108 | acpi_os_printf(ACPI_MSG_ERROR); | ||
109 | |||
110 | va_start(arg_list, format); | ||
111 | acpi_os_vprintf(format, arg_list); | ||
112 | ACPI_MSG_SUFFIX; | ||
113 | va_end(arg_list); | ||
114 | |||
115 | ACPI_MSG_REDIRECT_END; | ||
116 | } | ||
117 | |||
118 | ACPI_EXPORT_SYMBOL(acpi_error) | ||
119 | |||
120 | /******************************************************************************* | ||
121 | * | ||
122 | * FUNCTION: acpi_exception | ||
123 | * | ||
124 | * PARAMETERS: module_name - Caller's module name (for error output) | ||
125 | * line_number - Caller's line number (for error output) | ||
126 | * Status - Status to be formatted | ||
127 | * Format - Printf format string + additional args | ||
128 | * | ||
129 | * RETURN: None | ||
130 | * | ||
131 | * DESCRIPTION: Print "ACPI Exception" message with module/line/version info | ||
132 | * and decoded acpi_status. | ||
133 | * | ||
134 | ******************************************************************************/ | ||
135 | void ACPI_INTERNAL_VAR_XFACE | ||
136 | acpi_exception(const char *module_name, | ||
137 | u32 line_number, acpi_status status, const char *format, ...) | ||
138 | { | ||
139 | va_list arg_list; | ||
140 | |||
141 | ACPI_MSG_REDIRECT_BEGIN; | ||
142 | acpi_os_printf(ACPI_MSG_EXCEPTION "%s, ", | ||
143 | acpi_format_exception(status)); | ||
144 | |||
145 | va_start(arg_list, format); | ||
146 | acpi_os_vprintf(format, arg_list); | ||
147 | ACPI_MSG_SUFFIX; | ||
148 | va_end(arg_list); | ||
149 | |||
150 | ACPI_MSG_REDIRECT_END; | ||
151 | } | ||
152 | |||
153 | ACPI_EXPORT_SYMBOL(acpi_exception) | ||
154 | |||
155 | /******************************************************************************* | ||
156 | * | ||
157 | * FUNCTION: acpi_warning | ||
158 | * | ||
159 | * PARAMETERS: module_name - Caller's module name (for error output) | ||
160 | * line_number - Caller's line number (for error output) | ||
161 | * Format - Printf format string + additional args | ||
162 | * | ||
163 | * RETURN: None | ||
164 | * | ||
165 | * DESCRIPTION: Print "ACPI Warning" message with module/line/version info | ||
166 | * | ||
167 | ******************************************************************************/ | ||
168 | void ACPI_INTERNAL_VAR_XFACE | ||
169 | acpi_warning(const char *module_name, u32 line_number, const char *format, ...) | ||
170 | { | ||
171 | va_list arg_list; | ||
172 | |||
173 | ACPI_MSG_REDIRECT_BEGIN; | ||
174 | acpi_os_printf(ACPI_MSG_WARNING); | ||
175 | |||
176 | va_start(arg_list, format); | ||
177 | acpi_os_vprintf(format, arg_list); | ||
178 | ACPI_MSG_SUFFIX; | ||
179 | va_end(arg_list); | ||
180 | |||
181 | ACPI_MSG_REDIRECT_END; | ||
182 | } | ||
183 | |||
184 | ACPI_EXPORT_SYMBOL(acpi_warning) | ||
185 | |||
186 | /******************************************************************************* | ||
187 | * | ||
188 | * FUNCTION: acpi_info | ||
189 | * | ||
190 | * PARAMETERS: module_name - Caller's module name (for error output) | ||
191 | * line_number - Caller's line number (for error output) | ||
192 | * Format - Printf format string + additional args | ||
193 | * | ||
194 | * RETURN: None | ||
195 | * | ||
196 | * DESCRIPTION: Print generic "ACPI:" information message. There is no | ||
197 | * module/line/version info in order to keep the message simple. | ||
198 | * | ||
199 | * TBD: module_name and line_number args are not needed, should be removed. | ||
200 | * | ||
201 | ******************************************************************************/ | ||
202 | void ACPI_INTERNAL_VAR_XFACE | ||
203 | acpi_info(const char *module_name, u32 line_number, const char *format, ...) | ||
204 | { | ||
205 | va_list arg_list; | ||
206 | |||
207 | ACPI_MSG_REDIRECT_BEGIN; | ||
208 | acpi_os_printf(ACPI_MSG_INFO); | ||
209 | |||
210 | va_start(arg_list, format); | ||
211 | acpi_os_vprintf(format, arg_list); | ||
212 | acpi_os_printf("\n"); | ||
213 | va_end(arg_list); | ||
214 | |||
215 | ACPI_MSG_REDIRECT_END; | ||
216 | } | ||
217 | |||
218 | ACPI_EXPORT_SYMBOL(acpi_info) | ||
219 | |||
220 | /* | ||
221 | * The remainder of this module contains internal error functions that may | ||
222 | * be configured out. | ||
223 | */ | ||
224 | #if !defined (ACPI_NO_ERROR_MESSAGES) && !defined (ACPI_BIN_APP) | ||
225 | /******************************************************************************* | ||
226 | * | ||
227 | * FUNCTION: acpi_ut_predefined_warning | ||
228 | * | ||
229 | * PARAMETERS: module_name - Caller's module name (for error output) | ||
230 | * line_number - Caller's line number (for error output) | ||
231 | * Pathname - Full pathname to the node | ||
232 | * node_flags - From Namespace node for the method/object | ||
233 | * Format - Printf format string + additional args | ||
234 | * | ||
235 | * RETURN: None | ||
236 | * | ||
237 | * DESCRIPTION: Warnings for the predefined validation module. Messages are | ||
238 | * only emitted the first time a problem with a particular | ||
239 | * method/object is detected. This prevents a flood of error | ||
240 | * messages for methods that are repeatedly evaluated. | ||
241 | * | ||
242 | ******************************************************************************/ | ||
243 | void ACPI_INTERNAL_VAR_XFACE | ||
244 | acpi_ut_predefined_warning(const char *module_name, | ||
245 | u32 line_number, | ||
246 | char *pathname, | ||
247 | u8 node_flags, const char *format, ...) | ||
248 | { | ||
249 | va_list arg_list; | ||
250 | |||
251 | /* | ||
252 | * Warning messages for this method/object will be disabled after the | ||
253 | * first time a validation fails or an object is successfully repaired. | ||
254 | */ | ||
255 | if (node_flags & ANOBJ_EVALUATED) { | ||
256 | return; | ||
257 | } | ||
258 | |||
259 | acpi_os_printf(ACPI_MSG_WARNING "For %s: ", pathname); | ||
260 | |||
261 | va_start(arg_list, format); | ||
262 | acpi_os_vprintf(format, arg_list); | ||
263 | ACPI_MSG_SUFFIX; | ||
264 | va_end(arg_list); | ||
265 | } | ||
266 | |||
267 | /******************************************************************************* | ||
268 | * | ||
269 | * FUNCTION: acpi_ut_predefined_info | ||
270 | * | ||
271 | * PARAMETERS: module_name - Caller's module name (for error output) | ||
272 | * line_number - Caller's line number (for error output) | ||
273 | * Pathname - Full pathname to the node | ||
274 | * node_flags - From Namespace node for the method/object | ||
275 | * Format - Printf format string + additional args | ||
276 | * | ||
277 | * RETURN: None | ||
278 | * | ||
279 | * DESCRIPTION: Info messages for the predefined validation module. Messages | ||
280 | * are only emitted the first time a problem with a particular | ||
281 | * method/object is detected. This prevents a flood of | ||
282 | * messages for methods that are repeatedly evaluated. | ||
283 | * | ||
284 | ******************************************************************************/ | ||
285 | |||
286 | void ACPI_INTERNAL_VAR_XFACE | ||
287 | acpi_ut_predefined_info(const char *module_name, | ||
288 | u32 line_number, | ||
289 | char *pathname, u8 node_flags, const char *format, ...) | ||
290 | { | ||
291 | va_list arg_list; | ||
292 | |||
293 | /* | ||
294 | * Warning messages for this method/object will be disabled after the | ||
295 | * first time a validation fails or an object is successfully repaired. | ||
296 | */ | ||
297 | if (node_flags & ANOBJ_EVALUATED) { | ||
298 | return; | ||
299 | } | ||
300 | |||
301 | acpi_os_printf(ACPI_MSG_INFO "For %s: ", pathname); | ||
302 | |||
303 | va_start(arg_list, format); | ||
304 | acpi_os_vprintf(format, arg_list); | ||
305 | ACPI_MSG_SUFFIX; | ||
306 | va_end(arg_list); | ||
307 | } | ||
308 | |||
309 | /******************************************************************************* | ||
310 | * | ||
311 | * FUNCTION: acpi_ut_namespace_error | ||
312 | * | ||
313 | * PARAMETERS: module_name - Caller's module name (for error output) | ||
314 | * line_number - Caller's line number (for error output) | ||
315 | * internal_name - Name or path of the namespace node | ||
316 | * lookup_status - Exception code from NS lookup | ||
317 | * | ||
318 | * RETURN: None | ||
319 | * | ||
320 | * DESCRIPTION: Print error message with the full pathname for the NS node. | ||
321 | * | ||
322 | ******************************************************************************/ | ||
323 | |||
324 | void | ||
325 | acpi_ut_namespace_error(const char *module_name, | ||
326 | u32 line_number, | ||
327 | const char *internal_name, acpi_status lookup_status) | ||
328 | { | ||
329 | acpi_status status; | ||
330 | u32 bad_name; | ||
331 | char *name = NULL; | ||
332 | |||
333 | ACPI_MSG_REDIRECT_BEGIN; | ||
334 | acpi_os_printf(ACPI_MSG_ERROR); | ||
335 | |||
336 | if (lookup_status == AE_BAD_CHARACTER) { | ||
337 | |||
338 | /* There is a non-ascii character in the name */ | ||
339 | |||
340 | ACPI_MOVE_32_TO_32(&bad_name, | ||
341 | ACPI_CAST_PTR(u32, internal_name)); | ||
342 | acpi_os_printf("[0x%4.4X] (NON-ASCII)", bad_name); | ||
343 | } else { | ||
344 | /* Convert path to external format */ | ||
345 | |||
346 | status = acpi_ns_externalize_name(ACPI_UINT32_MAX, | ||
347 | internal_name, NULL, &name); | ||
348 | |||
349 | /* Print target name */ | ||
350 | |||
351 | if (ACPI_SUCCESS(status)) { | ||
352 | acpi_os_printf("[%s]", name); | ||
353 | } else { | ||
354 | acpi_os_printf("[COULD NOT EXTERNALIZE NAME]"); | ||
355 | } | ||
356 | |||
357 | if (name) { | ||
358 | ACPI_FREE(name); | ||
359 | } | ||
360 | } | ||
361 | |||
362 | acpi_os_printf(" Namespace lookup failure, %s", | ||
363 | acpi_format_exception(lookup_status)); | ||
364 | |||
365 | ACPI_MSG_SUFFIX; | ||
366 | ACPI_MSG_REDIRECT_END; | ||
367 | } | ||
368 | |||
369 | /******************************************************************************* | ||
370 | * | ||
371 | * FUNCTION: acpi_ut_method_error | ||
372 | * | ||
373 | * PARAMETERS: module_name - Caller's module name (for error output) | ||
374 | * line_number - Caller's line number (for error output) | ||
375 | * Message - Error message to use on failure | ||
376 | * prefix_node - Prefix relative to the path | ||
377 | * Path - Path to the node (optional) | ||
378 | * method_status - Execution status | ||
379 | * | ||
380 | * RETURN: None | ||
381 | * | ||
382 | * DESCRIPTION: Print error message with the full pathname for the method. | ||
383 | * | ||
384 | ******************************************************************************/ | ||
385 | |||
386 | void | ||
387 | acpi_ut_method_error(const char *module_name, | ||
388 | u32 line_number, | ||
389 | const char *message, | ||
390 | struct acpi_namespace_node *prefix_node, | ||
391 | const char *path, acpi_status method_status) | ||
392 | { | ||
393 | acpi_status status; | ||
394 | struct acpi_namespace_node *node = prefix_node; | ||
395 | |||
396 | ACPI_MSG_REDIRECT_BEGIN; | ||
397 | acpi_os_printf(ACPI_MSG_ERROR); | ||
398 | |||
399 | if (path) { | ||
400 | status = | ||
401 | acpi_ns_get_node(prefix_node, path, ACPI_NS_NO_UPSEARCH, | ||
402 | &node); | ||
403 | if (ACPI_FAILURE(status)) { | ||
404 | acpi_os_printf("[Could not get node by pathname]"); | ||
405 | } | ||
406 | } | ||
407 | |||
408 | acpi_ns_print_node_pathname(node, message); | ||
409 | acpi_os_printf(", %s", acpi_format_exception(method_status)); | ||
410 | |||
411 | ACPI_MSG_SUFFIX; | ||
412 | ACPI_MSG_REDIRECT_END; | ||
413 | } | ||
414 | |||
415 | #endif /* ACPI_NO_ERROR_MESSAGES */ | ||
diff --git a/drivers/acpi/apei/Kconfig b/drivers/acpi/apei/Kconfig index 907e350f1c7..fca34ccfd29 100644 --- a/drivers/acpi/apei/Kconfig +++ b/drivers/acpi/apei/Kconfig | |||
@@ -34,6 +34,6 @@ config ACPI_APEI_ERST_DEBUG | |||
34 | depends on ACPI_APEI | 34 | depends on ACPI_APEI |
35 | help | 35 | help |
36 | ERST is a way provided by APEI to save and retrieve hardware | 36 | ERST is a way provided by APEI to save and retrieve hardware |
37 | error infomation to and from a persistent store. Enable this | 37 | error information to and from a persistent store. Enable this |
38 | if you want to debugging and testing the ERST kernel support | 38 | if you want to debugging and testing the ERST kernel support |
39 | and firmware implementation. | 39 | and firmware implementation. |
diff --git a/drivers/acpi/apei/apei-base.c b/drivers/acpi/apei/apei-base.c index 73fd0c7487c..4a904a4bf05 100644 --- a/drivers/acpi/apei/apei-base.c +++ b/drivers/acpi/apei/apei-base.c | |||
@@ -445,11 +445,15 @@ EXPORT_SYMBOL_GPL(apei_resources_sub); | |||
445 | int apei_resources_request(struct apei_resources *resources, | 445 | int apei_resources_request(struct apei_resources *resources, |
446 | const char *desc) | 446 | const char *desc) |
447 | { | 447 | { |
448 | struct apei_res *res, *res_bak; | 448 | struct apei_res *res, *res_bak = NULL; |
449 | struct resource *r; | 449 | struct resource *r; |
450 | int rc; | ||
450 | 451 | ||
451 | apei_resources_sub(resources, &apei_resources_all); | 452 | rc = apei_resources_sub(resources, &apei_resources_all); |
453 | if (rc) | ||
454 | return rc; | ||
452 | 455 | ||
456 | rc = -EINVAL; | ||
453 | list_for_each_entry(res, &resources->iomem, list) { | 457 | list_for_each_entry(res, &resources->iomem, list) { |
454 | r = request_mem_region(res->start, res->end - res->start, | 458 | r = request_mem_region(res->start, res->end - res->start, |
455 | desc); | 459 | desc); |
@@ -475,7 +479,11 @@ int apei_resources_request(struct apei_resources *resources, | |||
475 | } | 479 | } |
476 | } | 480 | } |
477 | 481 | ||
478 | apei_resources_merge(&apei_resources_all, resources); | 482 | rc = apei_resources_merge(&apei_resources_all, resources); |
483 | if (rc) { | ||
484 | pr_err(APEI_PFX "Fail to merge resources!\n"); | ||
485 | goto err_unmap_ioport; | ||
486 | } | ||
479 | 487 | ||
480 | return 0; | 488 | return 0; |
481 | err_unmap_ioport: | 489 | err_unmap_ioport: |
@@ -491,12 +499,13 @@ err_unmap_iomem: | |||
491 | break; | 499 | break; |
492 | release_mem_region(res->start, res->end - res->start); | 500 | release_mem_region(res->start, res->end - res->start); |
493 | } | 501 | } |
494 | return -EINVAL; | 502 | return rc; |
495 | } | 503 | } |
496 | EXPORT_SYMBOL_GPL(apei_resources_request); | 504 | EXPORT_SYMBOL_GPL(apei_resources_request); |
497 | 505 | ||
498 | void apei_resources_release(struct apei_resources *resources) | 506 | void apei_resources_release(struct apei_resources *resources) |
499 | { | 507 | { |
508 | int rc; | ||
500 | struct apei_res *res; | 509 | struct apei_res *res; |
501 | 510 | ||
502 | list_for_each_entry(res, &resources->iomem, list) | 511 | list_for_each_entry(res, &resources->iomem, list) |
@@ -504,7 +513,9 @@ void apei_resources_release(struct apei_resources *resources) | |||
504 | list_for_each_entry(res, &resources->ioport, list) | 513 | list_for_each_entry(res, &resources->ioport, list) |
505 | release_region(res->start, res->end - res->start); | 514 | release_region(res->start, res->end - res->start); |
506 | 515 | ||
507 | apei_resources_sub(&apei_resources_all, resources); | 516 | rc = apei_resources_sub(&apei_resources_all, resources); |
517 | if (rc) | ||
518 | pr_err(APEI_PFX "Fail to sub resources!\n"); | ||
508 | } | 519 | } |
509 | EXPORT_SYMBOL_GPL(apei_resources_release); | 520 | EXPORT_SYMBOL_GPL(apei_resources_release); |
510 | 521 | ||
diff --git a/drivers/acpi/apei/einj.c b/drivers/acpi/apei/einj.c index 465c885938e..cf29df69380 100644 --- a/drivers/acpi/apei/einj.c +++ b/drivers/acpi/apei/einj.c | |||
@@ -426,7 +426,9 @@ DEFINE_SIMPLE_ATTRIBUTE(error_inject_fops, NULL, | |||
426 | 426 | ||
427 | static int einj_check_table(struct acpi_table_einj *einj_tab) | 427 | static int einj_check_table(struct acpi_table_einj *einj_tab) |
428 | { | 428 | { |
429 | if (einj_tab->header_length != sizeof(struct acpi_table_einj)) | 429 | if ((einj_tab->header_length != |
430 | (sizeof(struct acpi_table_einj) - sizeof(einj_tab->header))) | ||
431 | && (einj_tab->header_length != sizeof(struct acpi_table_einj))) | ||
430 | return -EINVAL; | 432 | return -EINVAL; |
431 | if (einj_tab->header.length < sizeof(struct acpi_table_einj)) | 433 | if (einj_tab->header.length < sizeof(struct acpi_table_einj)) |
432 | return -EINVAL; | 434 | return -EINVAL; |
diff --git a/drivers/acpi/apei/erst-dbg.c b/drivers/acpi/apei/erst-dbg.c index 5281ddda277..da1228a9a54 100644 --- a/drivers/acpi/apei/erst-dbg.c +++ b/drivers/acpi/apei/erst-dbg.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * APEI Error Record Serialization Table debug support | 2 | * APEI Error Record Serialization Table debug support |
3 | * | 3 | * |
4 | * ERST is a way provided by APEI to save and retrieve hardware error | 4 | * ERST is a way provided by APEI to save and retrieve hardware error |
5 | * infomation to and from a persistent store. This file provide the | 5 | * information to and from a persistent store. This file provide the |
6 | * debugging/testing support for ERST kernel support and firmware | 6 | * debugging/testing support for ERST kernel support and firmware |
7 | * implementation. | 7 | * implementation. |
8 | * | 8 | * |
@@ -111,11 +111,13 @@ retry: | |||
111 | goto out; | 111 | goto out; |
112 | } | 112 | } |
113 | if (len > erst_dbg_buf_len) { | 113 | if (len > erst_dbg_buf_len) { |
114 | kfree(erst_dbg_buf); | 114 | void *p; |
115 | rc = -ENOMEM; | 115 | rc = -ENOMEM; |
116 | erst_dbg_buf = kmalloc(len, GFP_KERNEL); | 116 | p = kmalloc(len, GFP_KERNEL); |
117 | if (!erst_dbg_buf) | 117 | if (!p) |
118 | goto out; | 118 | goto out; |
119 | kfree(erst_dbg_buf); | ||
120 | erst_dbg_buf = p; | ||
119 | erst_dbg_buf_len = len; | 121 | erst_dbg_buf_len = len; |
120 | goto retry; | 122 | goto retry; |
121 | } | 123 | } |
@@ -150,11 +152,13 @@ static ssize_t erst_dbg_write(struct file *filp, const char __user *ubuf, | |||
150 | if (mutex_lock_interruptible(&erst_dbg_mutex)) | 152 | if (mutex_lock_interruptible(&erst_dbg_mutex)) |
151 | return -EINTR; | 153 | return -EINTR; |
152 | if (usize > erst_dbg_buf_len) { | 154 | if (usize > erst_dbg_buf_len) { |
153 | kfree(erst_dbg_buf); | 155 | void *p; |
154 | rc = -ENOMEM; | 156 | rc = -ENOMEM; |
155 | erst_dbg_buf = kmalloc(usize, GFP_KERNEL); | 157 | p = kmalloc(usize, GFP_KERNEL); |
156 | if (!erst_dbg_buf) | 158 | if (!p) |
157 | goto out; | 159 | goto out; |
160 | kfree(erst_dbg_buf); | ||
161 | erst_dbg_buf = p; | ||
158 | erst_dbg_buf_len = usize; | 162 | erst_dbg_buf_len = usize; |
159 | } | 163 | } |
160 | rc = copy_from_user(erst_dbg_buf, ubuf, usize); | 164 | rc = copy_from_user(erst_dbg_buf, ubuf, usize); |
diff --git a/drivers/acpi/apei/erst.c b/drivers/acpi/apei/erst.c index 18645f4e83c..1211c03149e 100644 --- a/drivers/acpi/apei/erst.c +++ b/drivers/acpi/apei/erst.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * APEI Error Record Serialization Table support | 2 | * APEI Error Record Serialization Table support |
3 | * | 3 | * |
4 | * ERST is a way provided by APEI to save and retrieve hardware error | 4 | * ERST is a way provided by APEI to save and retrieve hardware error |
5 | * infomation to and from a persistent store. | 5 | * information to and from a persistent store. |
6 | * | 6 | * |
7 | * For more information about ERST, please refer to ACPI Specification | 7 | * For more information about ERST, please refer to ACPI Specification |
8 | * version 4.0, section 17.4. | 8 | * version 4.0, section 17.4. |
@@ -266,13 +266,30 @@ static int erst_exec_move_data(struct apei_exec_context *ctx, | |||
266 | { | 266 | { |
267 | int rc; | 267 | int rc; |
268 | u64 offset; | 268 | u64 offset; |
269 | void *src, *dst; | ||
270 | |||
271 | /* ioremap does not work in interrupt context */ | ||
272 | if (in_interrupt()) { | ||
273 | pr_warning(ERST_PFX | ||
274 | "MOVE_DATA can not be used in interrupt context"); | ||
275 | return -EBUSY; | ||
276 | } | ||
269 | 277 | ||
270 | rc = __apei_exec_read_register(entry, &offset); | 278 | rc = __apei_exec_read_register(entry, &offset); |
271 | if (rc) | 279 | if (rc) |
272 | return rc; | 280 | return rc; |
273 | memmove((void *)ctx->dst_base + offset, | 281 | |
274 | (void *)ctx->src_base + offset, | 282 | src = ioremap(ctx->src_base + offset, ctx->var2); |
275 | ctx->var2); | 283 | if (!src) |
284 | return -ENOMEM; | ||
285 | dst = ioremap(ctx->dst_base + offset, ctx->var2); | ||
286 | if (!dst) | ||
287 | return -ENOMEM; | ||
288 | |||
289 | memmove(dst, src, ctx->var2); | ||
290 | |||
291 | iounmap(src); | ||
292 | iounmap(dst); | ||
276 | 293 | ||
277 | return 0; | 294 | return 0; |
278 | } | 295 | } |
@@ -750,7 +767,9 @@ __setup("erst_disable", setup_erst_disable); | |||
750 | 767 | ||
751 | static int erst_check_table(struct acpi_table_erst *erst_tab) | 768 | static int erst_check_table(struct acpi_table_erst *erst_tab) |
752 | { | 769 | { |
753 | if (erst_tab->header_length != sizeof(struct acpi_table_erst)) | 770 | if ((erst_tab->header_length != |
771 | (sizeof(struct acpi_table_erst) - sizeof(erst_tab->header))) | ||
772 | && (erst_tab->header_length != sizeof(struct acpi_table_einj))) | ||
754 | return -EINVAL; | 773 | return -EINVAL; |
755 | if (erst_tab->header.length < sizeof(struct acpi_table_erst)) | 774 | if (erst_tab->header.length < sizeof(struct acpi_table_erst)) |
756 | return -EINVAL; | 775 | return -EINVAL; |
diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index 385a6059714..0d505e59214 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c | |||
@@ -302,7 +302,7 @@ static int __devinit ghes_probe(struct platform_device *ghes_dev) | |||
302 | struct ghes *ghes = NULL; | 302 | struct ghes *ghes = NULL; |
303 | int rc = -EINVAL; | 303 | int rc = -EINVAL; |
304 | 304 | ||
305 | generic = ghes_dev->dev.platform_data; | 305 | generic = *(struct acpi_hest_generic **)ghes_dev->dev.platform_data; |
306 | if (!generic->enabled) | 306 | if (!generic->enabled) |
307 | return -ENODEV; | 307 | return -ENODEV; |
308 | 308 | ||
diff --git a/drivers/acpi/apei/hest.c b/drivers/acpi/apei/hest.c index 343168d1826..1a3508a7fe0 100644 --- a/drivers/acpi/apei/hest.c +++ b/drivers/acpi/apei/hest.c | |||
@@ -137,20 +137,23 @@ static int hest_parse_ghes_count(struct acpi_hest_header *hest_hdr, void *data) | |||
137 | 137 | ||
138 | static int hest_parse_ghes(struct acpi_hest_header *hest_hdr, void *data) | 138 | static int hest_parse_ghes(struct acpi_hest_header *hest_hdr, void *data) |
139 | { | 139 | { |
140 | struct acpi_hest_generic *generic; | ||
141 | struct platform_device *ghes_dev; | 140 | struct platform_device *ghes_dev; |
142 | struct ghes_arr *ghes_arr = data; | 141 | struct ghes_arr *ghes_arr = data; |
143 | int rc; | 142 | int rc; |
144 | 143 | ||
145 | if (hest_hdr->type != ACPI_HEST_TYPE_GENERIC_ERROR) | 144 | if (hest_hdr->type != ACPI_HEST_TYPE_GENERIC_ERROR) |
146 | return 0; | 145 | return 0; |
147 | generic = (struct acpi_hest_generic *)hest_hdr; | 146 | |
148 | if (!generic->enabled) | 147 | if (!((struct acpi_hest_generic *)hest_hdr)->enabled) |
149 | return 0; | 148 | return 0; |
150 | ghes_dev = platform_device_alloc("GHES", hest_hdr->source_id); | 149 | ghes_dev = platform_device_alloc("GHES", hest_hdr->source_id); |
151 | if (!ghes_dev) | 150 | if (!ghes_dev) |
152 | return -ENOMEM; | 151 | return -ENOMEM; |
153 | ghes_dev->dev.platform_data = generic; | 152 | |
153 | rc = platform_device_add_data(ghes_dev, &hest_hdr, sizeof(void *)); | ||
154 | if (rc) | ||
155 | goto err; | ||
156 | |||
154 | rc = platform_device_add(ghes_dev); | 157 | rc = platform_device_add(ghes_dev); |
155 | if (rc) | 158 | if (rc) |
156 | goto err; | 159 | goto err; |
diff --git a/drivers/acpi/atomicio.c b/drivers/acpi/atomicio.c index 8f8bd736d4f..542e5390389 100644 --- a/drivers/acpi/atomicio.c +++ b/drivers/acpi/atomicio.c | |||
@@ -142,7 +142,7 @@ static void __iomem *acpi_pre_map(phys_addr_t paddr, | |||
142 | list_add_tail_rcu(&map->list, &acpi_iomaps); | 142 | list_add_tail_rcu(&map->list, &acpi_iomaps); |
143 | spin_unlock_irqrestore(&acpi_iomaps_lock, flags); | 143 | spin_unlock_irqrestore(&acpi_iomaps_lock, flags); |
144 | 144 | ||
145 | return vaddr + (paddr - pg_off); | 145 | return map->vaddr + (paddr - map->paddr); |
146 | err_unmap: | 146 | err_unmap: |
147 | iounmap(vaddr); | 147 | iounmap(vaddr); |
148 | return NULL; | 148 | return NULL; |
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index dc58402b0a1..95649d37307 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c | |||
@@ -42,10 +42,7 @@ | |||
42 | 42 | ||
43 | #include <acpi/acpi_bus.h> | 43 | #include <acpi/acpi_bus.h> |
44 | #include <acpi/acpi_drivers.h> | 44 | #include <acpi/acpi_drivers.h> |
45 | |||
46 | #ifdef CONFIG_ACPI_SYSFS_POWER | ||
47 | #include <linux/power_supply.h> | 45 | #include <linux/power_supply.h> |
48 | #endif | ||
49 | 46 | ||
50 | #define PREFIX "ACPI: " | 47 | #define PREFIX "ACPI: " |
51 | 48 | ||
@@ -98,13 +95,12 @@ enum { | |||
98 | * due to bad math. | 95 | * due to bad math. |
99 | */ | 96 | */ |
100 | ACPI_BATTERY_QUIRK_SIGNED16_CURRENT, | 97 | ACPI_BATTERY_QUIRK_SIGNED16_CURRENT, |
98 | ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, | ||
101 | }; | 99 | }; |
102 | 100 | ||
103 | struct acpi_battery { | 101 | struct acpi_battery { |
104 | struct mutex lock; | 102 | struct mutex lock; |
105 | #ifdef CONFIG_ACPI_SYSFS_POWER | ||
106 | struct power_supply bat; | 103 | struct power_supply bat; |
107 | #endif | ||
108 | struct acpi_device *device; | 104 | struct acpi_device *device; |
109 | unsigned long update_time; | 105 | unsigned long update_time; |
110 | int rate_now; | 106 | int rate_now; |
@@ -141,7 +137,6 @@ inline int acpi_battery_present(struct acpi_battery *battery) | |||
141 | return battery->device->status.battery_present; | 137 | return battery->device->status.battery_present; |
142 | } | 138 | } |
143 | 139 | ||
144 | #ifdef CONFIG_ACPI_SYSFS_POWER | ||
145 | static int acpi_battery_technology(struct acpi_battery *battery) | 140 | static int acpi_battery_technology(struct acpi_battery *battery) |
146 | { | 141 | { |
147 | if (!strcasecmp("NiCd", battery->type)) | 142 | if (!strcasecmp("NiCd", battery->type)) |
@@ -186,6 +181,7 @@ static int acpi_battery_get_property(struct power_supply *psy, | |||
186 | enum power_supply_property psp, | 181 | enum power_supply_property psp, |
187 | union power_supply_propval *val) | 182 | union power_supply_propval *val) |
188 | { | 183 | { |
184 | int ret = 0; | ||
189 | struct acpi_battery *battery = to_acpi_battery(psy); | 185 | struct acpi_battery *battery = to_acpi_battery(psy); |
190 | 186 | ||
191 | if (acpi_battery_present(battery)) { | 187 | if (acpi_battery_present(battery)) { |
@@ -214,26 +210,44 @@ static int acpi_battery_get_property(struct power_supply *psy, | |||
214 | val->intval = battery->cycle_count; | 210 | val->intval = battery->cycle_count; |
215 | break; | 211 | break; |
216 | case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: | 212 | case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: |
217 | val->intval = battery->design_voltage * 1000; | 213 | if (battery->design_voltage == ACPI_BATTERY_VALUE_UNKNOWN) |
214 | ret = -ENODEV; | ||
215 | else | ||
216 | val->intval = battery->design_voltage * 1000; | ||
218 | break; | 217 | break; |
219 | case POWER_SUPPLY_PROP_VOLTAGE_NOW: | 218 | case POWER_SUPPLY_PROP_VOLTAGE_NOW: |
220 | val->intval = battery->voltage_now * 1000; | 219 | if (battery->voltage_now == ACPI_BATTERY_VALUE_UNKNOWN) |
220 | ret = -ENODEV; | ||
221 | else | ||
222 | val->intval = battery->voltage_now * 1000; | ||
221 | break; | 223 | break; |
222 | case POWER_SUPPLY_PROP_CURRENT_NOW: | 224 | case POWER_SUPPLY_PROP_CURRENT_NOW: |
223 | case POWER_SUPPLY_PROP_POWER_NOW: | 225 | case POWER_SUPPLY_PROP_POWER_NOW: |
224 | val->intval = battery->rate_now * 1000; | 226 | if (battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN) |
227 | ret = -ENODEV; | ||
228 | else | ||
229 | val->intval = battery->rate_now * 1000; | ||
225 | break; | 230 | break; |
226 | case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: | 231 | case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: |
227 | case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN: | 232 | case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN: |
228 | val->intval = battery->design_capacity * 1000; | 233 | if (battery->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN) |
234 | ret = -ENODEV; | ||
235 | else | ||
236 | val->intval = battery->design_capacity * 1000; | ||
229 | break; | 237 | break; |
230 | case POWER_SUPPLY_PROP_CHARGE_FULL: | 238 | case POWER_SUPPLY_PROP_CHARGE_FULL: |
231 | case POWER_SUPPLY_PROP_ENERGY_FULL: | 239 | case POWER_SUPPLY_PROP_ENERGY_FULL: |
232 | val->intval = battery->full_charge_capacity * 1000; | 240 | if (battery->full_charge_capacity == ACPI_BATTERY_VALUE_UNKNOWN) |
241 | ret = -ENODEV; | ||
242 | else | ||
243 | val->intval = battery->full_charge_capacity * 1000; | ||
233 | break; | 244 | break; |
234 | case POWER_SUPPLY_PROP_CHARGE_NOW: | 245 | case POWER_SUPPLY_PROP_CHARGE_NOW: |
235 | case POWER_SUPPLY_PROP_ENERGY_NOW: | 246 | case POWER_SUPPLY_PROP_ENERGY_NOW: |
236 | val->intval = battery->capacity_now * 1000; | 247 | if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN) |
248 | ret = -ENODEV; | ||
249 | else | ||
250 | val->intval = battery->capacity_now * 1000; | ||
237 | break; | 251 | break; |
238 | case POWER_SUPPLY_PROP_MODEL_NAME: | 252 | case POWER_SUPPLY_PROP_MODEL_NAME: |
239 | val->strval = battery->model_number; | 253 | val->strval = battery->model_number; |
@@ -245,9 +259,9 @@ static int acpi_battery_get_property(struct power_supply *psy, | |||
245 | val->strval = battery->serial_number; | 259 | val->strval = battery->serial_number; |
246 | break; | 260 | break; |
247 | default: | 261 | default: |
248 | return -EINVAL; | 262 | ret = -EINVAL; |
249 | } | 263 | } |
250 | return 0; | 264 | return ret; |
251 | } | 265 | } |
252 | 266 | ||
253 | static enum power_supply_property charge_battery_props[] = { | 267 | static enum power_supply_property charge_battery_props[] = { |
@@ -273,7 +287,6 @@ static enum power_supply_property energy_battery_props[] = { | |||
273 | POWER_SUPPLY_PROP_CYCLE_COUNT, | 287 | POWER_SUPPLY_PROP_CYCLE_COUNT, |
274 | POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, | 288 | POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, |
275 | POWER_SUPPLY_PROP_VOLTAGE_NOW, | 289 | POWER_SUPPLY_PROP_VOLTAGE_NOW, |
276 | POWER_SUPPLY_PROP_CURRENT_NOW, | ||
277 | POWER_SUPPLY_PROP_POWER_NOW, | 290 | POWER_SUPPLY_PROP_POWER_NOW, |
278 | POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN, | 291 | POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN, |
279 | POWER_SUPPLY_PROP_ENERGY_FULL, | 292 | POWER_SUPPLY_PROP_ENERGY_FULL, |
@@ -282,7 +295,6 @@ static enum power_supply_property energy_battery_props[] = { | |||
282 | POWER_SUPPLY_PROP_MANUFACTURER, | 295 | POWER_SUPPLY_PROP_MANUFACTURER, |
283 | POWER_SUPPLY_PROP_SERIAL_NUMBER, | 296 | POWER_SUPPLY_PROP_SERIAL_NUMBER, |
284 | }; | 297 | }; |
285 | #endif | ||
286 | 298 | ||
287 | #ifdef CONFIG_ACPI_PROCFS_POWER | 299 | #ifdef CONFIG_ACPI_PROCFS_POWER |
288 | inline char *acpi_battery_units(struct acpi_battery *battery) | 300 | inline char *acpi_battery_units(struct acpi_battery *battery) |
@@ -413,6 +425,8 @@ static int acpi_battery_get_info(struct acpi_battery *battery) | |||
413 | result = extract_package(battery, buffer.pointer, | 425 | result = extract_package(battery, buffer.pointer, |
414 | info_offsets, ARRAY_SIZE(info_offsets)); | 426 | info_offsets, ARRAY_SIZE(info_offsets)); |
415 | kfree(buffer.pointer); | 427 | kfree(buffer.pointer); |
428 | if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags)) | ||
429 | battery->full_charge_capacity = battery->design_capacity; | ||
416 | return result; | 430 | return result; |
417 | } | 431 | } |
418 | 432 | ||
@@ -449,6 +463,10 @@ static int acpi_battery_get_state(struct acpi_battery *battery) | |||
449 | battery->rate_now != -1) | 463 | battery->rate_now != -1) |
450 | battery->rate_now = abs((s16)battery->rate_now); | 464 | battery->rate_now = abs((s16)battery->rate_now); |
451 | 465 | ||
466 | if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags) | ||
467 | && battery->capacity_now >= 0 && battery->capacity_now <= 100) | ||
468 | battery->capacity_now = (battery->capacity_now * | ||
469 | battery->full_charge_capacity) / 100; | ||
452 | return result; | 470 | return result; |
453 | } | 471 | } |
454 | 472 | ||
@@ -493,7 +511,6 @@ static int acpi_battery_init_alarm(struct acpi_battery *battery) | |||
493 | return acpi_battery_set_alarm(battery); | 511 | return acpi_battery_set_alarm(battery); |
494 | } | 512 | } |
495 | 513 | ||
496 | #ifdef CONFIG_ACPI_SYSFS_POWER | ||
497 | static ssize_t acpi_battery_alarm_show(struct device *dev, | 514 | static ssize_t acpi_battery_alarm_show(struct device *dev, |
498 | struct device_attribute *attr, | 515 | struct device_attribute *attr, |
499 | char *buf) | 516 | char *buf) |
@@ -553,7 +570,6 @@ static void sysfs_remove_battery(struct acpi_battery *battery) | |||
553 | power_supply_unregister(&battery->bat); | 570 | power_supply_unregister(&battery->bat); |
554 | battery->bat.dev = NULL; | 571 | battery->bat.dev = NULL; |
555 | } | 572 | } |
556 | #endif | ||
557 | 573 | ||
558 | static void acpi_battery_quirks(struct acpi_battery *battery) | 574 | static void acpi_battery_quirks(struct acpi_battery *battery) |
559 | { | 575 | { |
@@ -562,6 +578,33 @@ static void acpi_battery_quirks(struct acpi_battery *battery) | |||
562 | } | 578 | } |
563 | } | 579 | } |
564 | 580 | ||
581 | /* | ||
582 | * According to the ACPI spec, some kinds of primary batteries can | ||
583 | * report percentage battery remaining capacity directly to OS. | ||
584 | * In this case, it reports the Last Full Charged Capacity == 100 | ||
585 | * and BatteryPresentRate == 0xFFFFFFFF. | ||
586 | * | ||
587 | * Now we found some battery reports percentage remaining capacity | ||
588 | * even if it's rechargeable. | ||
589 | * https://bugzilla.kernel.org/show_bug.cgi?id=15979 | ||
590 | * | ||
591 | * Handle this correctly so that they won't break userspace. | ||
592 | */ | ||
593 | static void acpi_battery_quirks2(struct acpi_battery *battery) | ||
594 | { | ||
595 | if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags)) | ||
596 | return ; | ||
597 | |||
598 | if (battery->full_charge_capacity == 100 && | ||
599 | battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN && | ||
600 | battery->capacity_now >=0 && battery->capacity_now <= 100) { | ||
601 | set_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags); | ||
602 | battery->full_charge_capacity = battery->design_capacity; | ||
603 | battery->capacity_now = (battery->capacity_now * | ||
604 | battery->full_charge_capacity) / 100; | ||
605 | } | ||
606 | } | ||
607 | |||
565 | static int acpi_battery_update(struct acpi_battery *battery) | 608 | static int acpi_battery_update(struct acpi_battery *battery) |
566 | { | 609 | { |
567 | int result, old_present = acpi_battery_present(battery); | 610 | int result, old_present = acpi_battery_present(battery); |
@@ -569,9 +612,7 @@ static int acpi_battery_update(struct acpi_battery *battery) | |||
569 | if (result) | 612 | if (result) |
570 | return result; | 613 | return result; |
571 | if (!acpi_battery_present(battery)) { | 614 | if (!acpi_battery_present(battery)) { |
572 | #ifdef CONFIG_ACPI_SYSFS_POWER | ||
573 | sysfs_remove_battery(battery); | 615 | sysfs_remove_battery(battery); |
574 | #endif | ||
575 | battery->update_time = 0; | 616 | battery->update_time = 0; |
576 | return 0; | 617 | return 0; |
577 | } | 618 | } |
@@ -583,11 +624,11 @@ static int acpi_battery_update(struct acpi_battery *battery) | |||
583 | acpi_battery_quirks(battery); | 624 | acpi_battery_quirks(battery); |
584 | acpi_battery_init_alarm(battery); | 625 | acpi_battery_init_alarm(battery); |
585 | } | 626 | } |
586 | #ifdef CONFIG_ACPI_SYSFS_POWER | ||
587 | if (!battery->bat.dev) | 627 | if (!battery->bat.dev) |
588 | sysfs_add_battery(battery); | 628 | sysfs_add_battery(battery); |
589 | #endif | 629 | result = acpi_battery_get_state(battery); |
590 | return acpi_battery_get_state(battery); | 630 | acpi_battery_quirks2(battery); |
631 | return result; | ||
591 | } | 632 | } |
592 | 633 | ||
593 | /* -------------------------------------------------------------------------- | 634 | /* -------------------------------------------------------------------------- |
@@ -868,26 +909,20 @@ static void acpi_battery_remove_fs(struct acpi_device *device) | |||
868 | static void acpi_battery_notify(struct acpi_device *device, u32 event) | 909 | static void acpi_battery_notify(struct acpi_device *device, u32 event) |
869 | { | 910 | { |
870 | struct acpi_battery *battery = acpi_driver_data(device); | 911 | struct acpi_battery *battery = acpi_driver_data(device); |
871 | #ifdef CONFIG_ACPI_SYSFS_POWER | ||
872 | struct device *old; | 912 | struct device *old; |
873 | #endif | ||
874 | 913 | ||
875 | if (!battery) | 914 | if (!battery) |
876 | return; | 915 | return; |
877 | #ifdef CONFIG_ACPI_SYSFS_POWER | ||
878 | old = battery->bat.dev; | 916 | old = battery->bat.dev; |
879 | #endif | ||
880 | acpi_battery_update(battery); | 917 | acpi_battery_update(battery); |
881 | acpi_bus_generate_proc_event(device, event, | 918 | acpi_bus_generate_proc_event(device, event, |
882 | acpi_battery_present(battery)); | 919 | acpi_battery_present(battery)); |
883 | acpi_bus_generate_netlink_event(device->pnp.device_class, | 920 | acpi_bus_generate_netlink_event(device->pnp.device_class, |
884 | dev_name(&device->dev), event, | 921 | dev_name(&device->dev), event, |
885 | acpi_battery_present(battery)); | 922 | acpi_battery_present(battery)); |
886 | #ifdef CONFIG_ACPI_SYSFS_POWER | ||
887 | /* acpi_battery_update could remove power_supply object */ | 923 | /* acpi_battery_update could remove power_supply object */ |
888 | if (old && battery->bat.dev) | 924 | if (old && battery->bat.dev) |
889 | power_supply_changed(&battery->bat); | 925 | power_supply_changed(&battery->bat); |
890 | #endif | ||
891 | } | 926 | } |
892 | 927 | ||
893 | static int acpi_battery_add(struct acpi_device *device) | 928 | static int acpi_battery_add(struct acpi_device *device) |
@@ -935,9 +970,7 @@ static int acpi_battery_remove(struct acpi_device *device, int type) | |||
935 | #ifdef CONFIG_ACPI_PROCFS_POWER | 970 | #ifdef CONFIG_ACPI_PROCFS_POWER |
936 | acpi_battery_remove_fs(device); | 971 | acpi_battery_remove_fs(device); |
937 | #endif | 972 | #endif |
938 | #ifdef CONFIG_ACPI_SYSFS_POWER | ||
939 | sysfs_remove_battery(battery); | 973 | sysfs_remove_battery(battery); |
940 | #endif | ||
941 | mutex_destroy(&battery->lock); | 974 | mutex_destroy(&battery->lock); |
942 | kfree(battery); | 975 | kfree(battery); |
943 | return 0; | 976 | return 0; |
diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c index 2bb28b9d91c..af308d03f49 100644 --- a/drivers/acpi/blacklist.c +++ b/drivers/acpi/blacklist.c | |||
@@ -183,6 +183,8 @@ static int __init dmi_disable_osi_vista(const struct dmi_system_id *d) | |||
183 | { | 183 | { |
184 | printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident); | 184 | printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident); |
185 | acpi_osi_setup("!Windows 2006"); | 185 | acpi_osi_setup("!Windows 2006"); |
186 | acpi_osi_setup("!Windows 2006 SP1"); | ||
187 | acpi_osi_setup("!Windows 2006 SP2"); | ||
186 | return 0; | 188 | return 0; |
187 | } | 189 | } |
188 | static int __init dmi_disable_osi_win7(const struct dmi_system_id *d) | 190 | static int __init dmi_disable_osi_win7(const struct dmi_system_id *d) |
@@ -202,6 +204,23 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { | |||
202 | }, | 204 | }, |
203 | }, | 205 | }, |
204 | { | 206 | { |
207 | /* | ||
208 | * There have a NVIF method in MSI GX723 DSDT need call by Nvidia | ||
209 | * driver (e.g. nouveau) when user press brightness hotkey. | ||
210 | * Currently, nouveau driver didn't do the job and it causes there | ||
211 | * have a infinite while loop in DSDT when user press hotkey. | ||
212 | * We add MSI GX723's dmi information to this table for workaround | ||
213 | * this issue. | ||
214 | * Will remove MSI GX723 from the table after nouveau grows support. | ||
215 | */ | ||
216 | .callback = dmi_disable_osi_vista, | ||
217 | .ident = "MSI GX723", | ||
218 | .matches = { | ||
219 | DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"), | ||
220 | DMI_MATCH(DMI_PRODUCT_NAME, "GX723"), | ||
221 | }, | ||
222 | }, | ||
223 | { | ||
205 | .callback = dmi_disable_osi_vista, | 224 | .callback = dmi_disable_osi_vista, |
206 | .ident = "Sony VGN-NS10J_S", | 225 | .ident = "Sony VGN-NS10J_S", |
207 | .matches = { | 226 | .matches = { |
@@ -226,6 +245,14 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { | |||
226 | }, | 245 | }, |
227 | }, | 246 | }, |
228 | { | 247 | { |
248 | .callback = dmi_disable_osi_vista, | ||
249 | .ident = "Toshiba Satellite L355", | ||
250 | .matches = { | ||
251 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | ||
252 | DMI_MATCH(DMI_PRODUCT_VERSION, "Satellite L355"), | ||
253 | }, | ||
254 | }, | ||
255 | { | ||
229 | .callback = dmi_disable_osi_win7, | 256 | .callback = dmi_disable_osi_win7, |
230 | .ident = "ASUS K50IJ", | 257 | .ident = "ASUS K50IJ", |
231 | .matches = { | 258 | .matches = { |
@@ -233,6 +260,14 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { | |||
233 | DMI_MATCH(DMI_PRODUCT_NAME, "K50IJ"), | 260 | DMI_MATCH(DMI_PRODUCT_NAME, "K50IJ"), |
234 | }, | 261 | }, |
235 | }, | 262 | }, |
263 | { | ||
264 | .callback = dmi_disable_osi_vista, | ||
265 | .ident = "Toshiba P305D", | ||
266 | .matches = { | ||
267 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | ||
268 | DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P305D"), | ||
269 | }, | ||
270 | }, | ||
236 | 271 | ||
237 | /* | 272 | /* |
238 | * BIOS invocation of _OSI(Linux) is almost always a BIOS bug. | 273 | * BIOS invocation of _OSI(Linux) is almost always a BIOS bug. |
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index 5c221ab535d..310e3b9749c 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c | |||
@@ -55,7 +55,7 @@ EXPORT_SYMBOL(acpi_root_dir); | |||
55 | static int set_power_nocheck(const struct dmi_system_id *id) | 55 | static int set_power_nocheck(const struct dmi_system_id *id) |
56 | { | 56 | { |
57 | printk(KERN_NOTICE PREFIX "%s detected - " | 57 | printk(KERN_NOTICE PREFIX "%s detected - " |
58 | "disable power check in power transistion\n", id->ident); | 58 | "disable power check in power transition\n", id->ident); |
59 | acpi_power_nocheck = 1; | 59 | acpi_power_nocheck = 1; |
60 | return 0; | 60 | return 0; |
61 | } | 61 | } |
@@ -80,23 +80,15 @@ static int set_copy_dsdt(const struct dmi_system_id *id) | |||
80 | 80 | ||
81 | static struct dmi_system_id dsdt_dmi_table[] __initdata = { | 81 | static struct dmi_system_id dsdt_dmi_table[] __initdata = { |
82 | /* | 82 | /* |
83 | * Insyde BIOS on some TOSHIBA machines corrupt the DSDT. | 83 | * Invoke DSDT corruption work-around on all Toshiba Satellite. |
84 | * https://bugzilla.kernel.org/show_bug.cgi?id=14679 | 84 | * https://bugzilla.kernel.org/show_bug.cgi?id=14679 |
85 | */ | 85 | */ |
86 | { | 86 | { |
87 | .callback = set_copy_dsdt, | 87 | .callback = set_copy_dsdt, |
88 | .ident = "TOSHIBA Satellite A505", | 88 | .ident = "TOSHIBA Satellite", |
89 | .matches = { | 89 | .matches = { |
90 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | 90 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), |
91 | DMI_MATCH(DMI_PRODUCT_NAME, "Satellite A505"), | 91 | DMI_MATCH(DMI_PRODUCT_NAME, "Satellite"), |
92 | }, | ||
93 | }, | ||
94 | { | ||
95 | .callback = set_copy_dsdt, | ||
96 | .ident = "TOSHIBA Satellite L505D", | ||
97 | .matches = { | ||
98 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | ||
99 | DMI_MATCH(DMI_PRODUCT_NAME, "Satellite L505D"), | ||
100 | }, | 92 | }, |
101 | }, | 93 | }, |
102 | {} | 94 | {} |
@@ -1027,7 +1019,7 @@ static int __init acpi_init(void) | |||
1027 | 1019 | ||
1028 | /* | 1020 | /* |
1029 | * If the laptop falls into the DMI check table, the power state check | 1021 | * If the laptop falls into the DMI check table, the power state check |
1030 | * will be disabled in the course of device power transistion. | 1022 | * will be disabled in the course of device power transition. |
1031 | */ | 1023 | */ |
1032 | dmi_check_system(power_nocheck_dmi_table); | 1024 | dmi_check_system(power_nocheck_dmi_table); |
1033 | 1025 | ||
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c index 1575a9b51f1..71ef9cd0735 100644 --- a/drivers/acpi/button.c +++ b/drivers/acpi/button.c | |||
@@ -338,7 +338,8 @@ static int acpi_button_add(struct acpi_device *device) | |||
338 | { | 338 | { |
339 | struct acpi_button *button; | 339 | struct acpi_button *button; |
340 | struct input_dev *input; | 340 | struct input_dev *input; |
341 | char *hid, *name, *class; | 341 | const char *hid = acpi_device_hid(device); |
342 | char *name, *class; | ||
342 | int error; | 343 | int error; |
343 | 344 | ||
344 | button = kzalloc(sizeof(struct acpi_button), GFP_KERNEL); | 345 | button = kzalloc(sizeof(struct acpi_button), GFP_KERNEL); |
@@ -353,7 +354,6 @@ static int acpi_button_add(struct acpi_device *device) | |||
353 | goto err_free_button; | 354 | goto err_free_button; |
354 | } | 355 | } |
355 | 356 | ||
356 | hid = acpi_device_hid(device); | ||
357 | name = acpi_device_name(device); | 357 | name = acpi_device_name(device); |
358 | class = acpi_device_class(device); | 358 | class = acpi_device_class(device); |
359 | 359 | ||
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index 3fe29e992be..44f99bd8374 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c | |||
@@ -725,6 +725,7 @@ static void dock_notify(acpi_handle handle, u32 event, void *data) | |||
725 | complete_dock(ds); | 725 | complete_dock(ds); |
726 | dock_event(ds, event, DOCK_EVENT); | 726 | dock_event(ds, event, DOCK_EVENT); |
727 | dock_lock(ds, 1); | 727 | dock_lock(ds, 1); |
728 | acpi_update_gpes(); | ||
728 | break; | 729 | break; |
729 | } | 730 | } |
730 | if (dock_present(ds) || dock_in_progress(ds)) | 731 | if (dock_present(ds) || dock_in_progress(ds)) |
diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c index 8a3b840c0bb..60049080c86 100644 --- a/drivers/acpi/fan.c +++ b/drivers/acpi/fan.c | |||
@@ -27,8 +27,6 @@ | |||
27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
28 | #include <linux/init.h> | 28 | #include <linux/init.h> |
29 | #include <linux/types.h> | 29 | #include <linux/types.h> |
30 | #include <linux/proc_fs.h> | ||
31 | #include <linux/seq_file.h> | ||
32 | #include <asm/uaccess.h> | 30 | #include <asm/uaccess.h> |
33 | #include <linux/thermal.h> | 31 | #include <linux/thermal.h> |
34 | #include <acpi/acpi_bus.h> | 32 | #include <acpi/acpi_bus.h> |
@@ -119,122 +117,6 @@ static struct thermal_cooling_device_ops fan_cooling_ops = { | |||
119 | }; | 117 | }; |
120 | 118 | ||
121 | /* -------------------------------------------------------------------------- | 119 | /* -------------------------------------------------------------------------- |
122 | FS Interface (/proc) | ||
123 | -------------------------------------------------------------------------- */ | ||
124 | #ifdef CONFIG_ACPI_PROCFS | ||
125 | |||
126 | static struct proc_dir_entry *acpi_fan_dir; | ||
127 | |||
128 | static int acpi_fan_read_state(struct seq_file *seq, void *offset) | ||
129 | { | ||
130 | struct acpi_device *device = seq->private; | ||
131 | int state = 0; | ||
132 | |||
133 | |||
134 | if (device) { | ||
135 | if (acpi_bus_get_power(device->handle, &state)) | ||
136 | seq_printf(seq, "status: ERROR\n"); | ||
137 | else | ||
138 | seq_printf(seq, "status: %s\n", | ||
139 | !state ? "on" : "off"); | ||
140 | } | ||
141 | return 0; | ||
142 | } | ||
143 | |||
144 | static int acpi_fan_state_open_fs(struct inode *inode, struct file *file) | ||
145 | { | ||
146 | return single_open(file, acpi_fan_read_state, PDE(inode)->data); | ||
147 | } | ||
148 | |||
149 | static ssize_t | ||
150 | acpi_fan_write_state(struct file *file, const char __user * buffer, | ||
151 | size_t count, loff_t * ppos) | ||
152 | { | ||
153 | int result = 0; | ||
154 | struct seq_file *m = file->private_data; | ||
155 | struct acpi_device *device = m->private; | ||
156 | char state_string[3] = { '\0' }; | ||
157 | |||
158 | if (count > sizeof(state_string) - 1) | ||
159 | return -EINVAL; | ||
160 | |||
161 | if (copy_from_user(state_string, buffer, count)) | ||
162 | return -EFAULT; | ||
163 | |||
164 | state_string[count] = '\0'; | ||
165 | if ((state_string[0] < '0') || (state_string[0] > '3')) | ||
166 | return -EINVAL; | ||
167 | if (state_string[1] == '\n') | ||
168 | state_string[1] = '\0'; | ||
169 | if (state_string[1] != '\0') | ||
170 | return -EINVAL; | ||
171 | |||
172 | result = acpi_bus_set_power(device->handle, | ||
173 | simple_strtoul(state_string, NULL, 0)); | ||
174 | if (result) | ||
175 | return result; | ||
176 | |||
177 | return count; | ||
178 | } | ||
179 | |||
180 | static const struct file_operations acpi_fan_state_ops = { | ||
181 | .open = acpi_fan_state_open_fs, | ||
182 | .read = seq_read, | ||
183 | .write = acpi_fan_write_state, | ||
184 | .llseek = seq_lseek, | ||
185 | .release = single_release, | ||
186 | .owner = THIS_MODULE, | ||
187 | }; | ||
188 | |||
189 | static int acpi_fan_add_fs(struct acpi_device *device) | ||
190 | { | ||
191 | struct proc_dir_entry *entry = NULL; | ||
192 | |||
193 | |||
194 | if (!device) | ||
195 | return -EINVAL; | ||
196 | |||
197 | if (!acpi_device_dir(device)) { | ||
198 | acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), | ||
199 | acpi_fan_dir); | ||
200 | if (!acpi_device_dir(device)) | ||
201 | return -ENODEV; | ||
202 | } | ||
203 | |||
204 | /* 'status' [R/W] */ | ||
205 | entry = proc_create_data(ACPI_FAN_FILE_STATE, | ||
206 | S_IFREG | S_IRUGO | S_IWUSR, | ||
207 | acpi_device_dir(device), | ||
208 | &acpi_fan_state_ops, | ||
209 | device); | ||
210 | if (!entry) | ||
211 | return -ENODEV; | ||
212 | return 0; | ||
213 | } | ||
214 | |||
215 | static int acpi_fan_remove_fs(struct acpi_device *device) | ||
216 | { | ||
217 | |||
218 | if (acpi_device_dir(device)) { | ||
219 | remove_proc_entry(ACPI_FAN_FILE_STATE, acpi_device_dir(device)); | ||
220 | remove_proc_entry(acpi_device_bid(device), acpi_fan_dir); | ||
221 | acpi_device_dir(device) = NULL; | ||
222 | } | ||
223 | |||
224 | return 0; | ||
225 | } | ||
226 | #else | ||
227 | static int acpi_fan_add_fs(struct acpi_device *device) | ||
228 | { | ||
229 | return 0; | ||
230 | } | ||
231 | |||
232 | static int acpi_fan_remove_fs(struct acpi_device *device) | ||
233 | { | ||
234 | return 0; | ||
235 | } | ||
236 | #endif | ||
237 | /* -------------------------------------------------------------------------- | ||
238 | Driver Interface | 120 | Driver Interface |
239 | -------------------------------------------------------------------------- */ | 121 | -------------------------------------------------------------------------- */ |
240 | 122 | ||
@@ -284,10 +166,6 @@ static int acpi_fan_add(struct acpi_device *device) | |||
284 | dev_err(&device->dev, "Failed to create sysfs link " | 166 | dev_err(&device->dev, "Failed to create sysfs link " |
285 | "'device'\n"); | 167 | "'device'\n"); |
286 | 168 | ||
287 | result = acpi_fan_add_fs(device); | ||
288 | if (result) | ||
289 | goto end; | ||
290 | |||
291 | printk(KERN_INFO PREFIX "%s [%s] (%s)\n", | 169 | printk(KERN_INFO PREFIX "%s [%s] (%s)\n", |
292 | acpi_device_name(device), acpi_device_bid(device), | 170 | acpi_device_name(device), acpi_device_bid(device), |
293 | !device->power.state ? "on" : "off"); | 171 | !device->power.state ? "on" : "off"); |
@@ -303,7 +181,6 @@ static int acpi_fan_remove(struct acpi_device *device, int type) | |||
303 | if (!device || !cdev) | 181 | if (!device || !cdev) |
304 | return -EINVAL; | 182 | return -EINVAL; |
305 | 183 | ||
306 | acpi_fan_remove_fs(device); | ||
307 | sysfs_remove_link(&device->dev.kobj, "thermal_cooling"); | 184 | sysfs_remove_link(&device->dev.kobj, "thermal_cooling"); |
308 | sysfs_remove_link(&cdev->device.kobj, "device"); | 185 | sysfs_remove_link(&cdev->device.kobj, "device"); |
309 | thermal_cooling_device_unregister(cdev); | 186 | thermal_cooling_device_unregister(cdev); |
@@ -347,19 +224,9 @@ static int __init acpi_fan_init(void) | |||
347 | { | 224 | { |
348 | int result = 0; | 225 | int result = 0; |
349 | 226 | ||
350 | #ifdef CONFIG_ACPI_PROCFS | ||
351 | acpi_fan_dir = proc_mkdir(ACPI_FAN_CLASS, acpi_root_dir); | ||
352 | if (!acpi_fan_dir) | ||
353 | return -ENODEV; | ||
354 | #endif | ||
355 | |||
356 | result = acpi_bus_register_driver(&acpi_fan_driver); | 227 | result = acpi_bus_register_driver(&acpi_fan_driver); |
357 | if (result < 0) { | 228 | if (result < 0) |
358 | #ifdef CONFIG_ACPI_PROCFS | ||
359 | remove_proc_entry(ACPI_FAN_CLASS, acpi_root_dir); | ||
360 | #endif | ||
361 | return -ENODEV; | 229 | return -ENODEV; |
362 | } | ||
363 | 230 | ||
364 | return 0; | 231 | return 0; |
365 | } | 232 | } |
@@ -369,8 +236,6 @@ static void __exit acpi_fan_exit(void) | |||
369 | 236 | ||
370 | acpi_bus_unregister_driver(&acpi_fan_driver); | 237 | acpi_bus_unregister_driver(&acpi_fan_driver); |
371 | 238 | ||
372 | remove_proc_entry(ACPI_FAN_CLASS, acpi_root_dir); | ||
373 | |||
374 | return; | 239 | return; |
375 | } | 240 | } |
376 | 241 | ||
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 65b25a303b8..d3bed219c44 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c | |||
@@ -96,7 +96,9 @@ static LIST_HEAD(resource_list_head); | |||
96 | static DEFINE_SPINLOCK(acpi_res_lock); | 96 | static DEFINE_SPINLOCK(acpi_res_lock); |
97 | 97 | ||
98 | #define OSI_STRING_LENGTH_MAX 64 /* arbitrary */ | 98 | #define OSI_STRING_LENGTH_MAX 64 /* arbitrary */ |
99 | static char osi_additional_string[OSI_STRING_LENGTH_MAX]; | 99 | static char osi_setup_string[OSI_STRING_LENGTH_MAX]; |
100 | |||
101 | static void __init acpi_osi_setup_late(void); | ||
100 | 102 | ||
101 | /* | 103 | /* |
102 | * The story of _OSI(Linux) | 104 | * The story of _OSI(Linux) |
@@ -138,6 +140,20 @@ static struct osi_linux { | |||
138 | unsigned int known:1; | 140 | unsigned int known:1; |
139 | } osi_linux = { 0, 0, 0, 0}; | 141 | } osi_linux = { 0, 0, 0, 0}; |
140 | 142 | ||
143 | static u32 acpi_osi_handler(acpi_string interface, u32 supported) | ||
144 | { | ||
145 | if (!strcmp("Linux", interface)) { | ||
146 | |||
147 | printk(KERN_NOTICE FW_BUG PREFIX | ||
148 | "BIOS _OSI(Linux) query %s%s\n", | ||
149 | osi_linux.enable ? "honored" : "ignored", | ||
150 | osi_linux.cmdline ? " via cmdline" : | ||
151 | osi_linux.dmi ? " via DMI" : ""); | ||
152 | } | ||
153 | |||
154 | return supported; | ||
155 | } | ||
156 | |||
141 | static void __init acpi_request_region (struct acpi_generic_address *addr, | 157 | static void __init acpi_request_region (struct acpi_generic_address *addr, |
142 | unsigned int length, char *desc) | 158 | unsigned int length, char *desc) |
143 | { | 159 | { |
@@ -198,6 +214,8 @@ acpi_status acpi_os_initialize1(void) | |||
198 | BUG_ON(!kacpid_wq); | 214 | BUG_ON(!kacpid_wq); |
199 | BUG_ON(!kacpi_notify_wq); | 215 | BUG_ON(!kacpi_notify_wq); |
200 | BUG_ON(!kacpi_hotplug_wq); | 216 | BUG_ON(!kacpi_hotplug_wq); |
217 | acpi_install_interface_handler(acpi_osi_handler); | ||
218 | acpi_osi_setup_late(); | ||
201 | return AE_OK; | 219 | return AE_OK; |
202 | } | 220 | } |
203 | 221 | ||
@@ -547,9 +565,10 @@ acpi_os_write_memory(acpi_physical_address phys_addr, u32 value, u32 width) | |||
547 | 565 | ||
548 | acpi_status | 566 | acpi_status |
549 | acpi_os_read_pci_configuration(struct acpi_pci_id * pci_id, u32 reg, | 567 | acpi_os_read_pci_configuration(struct acpi_pci_id * pci_id, u32 reg, |
550 | u32 *value, u32 width) | 568 | u64 *value, u32 width) |
551 | { | 569 | { |
552 | int result, size; | 570 | int result, size; |
571 | u32 value32; | ||
553 | 572 | ||
554 | if (!value) | 573 | if (!value) |
555 | return AE_BAD_PARAMETER; | 574 | return AE_BAD_PARAMETER; |
@@ -570,7 +589,8 @@ acpi_os_read_pci_configuration(struct acpi_pci_id * pci_id, u32 reg, | |||
570 | 589 | ||
571 | result = raw_pci_read(pci_id->segment, pci_id->bus, | 590 | result = raw_pci_read(pci_id->segment, pci_id->bus, |
572 | PCI_DEVFN(pci_id->device, pci_id->function), | 591 | PCI_DEVFN(pci_id->device, pci_id->function), |
573 | reg, size, value); | 592 | reg, size, &value32); |
593 | *value = value32; | ||
574 | 594 | ||
575 | return (result ? AE_ERROR : AE_OK); | 595 | return (result ? AE_ERROR : AE_OK); |
576 | } | 596 | } |
@@ -602,74 +622,6 @@ acpi_os_write_pci_configuration(struct acpi_pci_id * pci_id, u32 reg, | |||
602 | return (result ? AE_ERROR : AE_OK); | 622 | return (result ? AE_ERROR : AE_OK); |
603 | } | 623 | } |
604 | 624 | ||
605 | /* TODO: Change code to take advantage of driver model more */ | ||
606 | static void acpi_os_derive_pci_id_2(acpi_handle rhandle, /* upper bound */ | ||
607 | acpi_handle chandle, /* current node */ | ||
608 | struct acpi_pci_id **id, | ||
609 | int *is_bridge, u8 * bus_number) | ||
610 | { | ||
611 | acpi_handle handle; | ||
612 | struct acpi_pci_id *pci_id = *id; | ||
613 | acpi_status status; | ||
614 | unsigned long long temp; | ||
615 | acpi_object_type type; | ||
616 | |||
617 | acpi_get_parent(chandle, &handle); | ||
618 | if (handle != rhandle) { | ||
619 | acpi_os_derive_pci_id_2(rhandle, handle, &pci_id, is_bridge, | ||
620 | bus_number); | ||
621 | |||
622 | status = acpi_get_type(handle, &type); | ||
623 | if ((ACPI_FAILURE(status)) || (type != ACPI_TYPE_DEVICE)) | ||
624 | return; | ||
625 | |||
626 | status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, | ||
627 | &temp); | ||
628 | if (ACPI_SUCCESS(status)) { | ||
629 | u32 val; | ||
630 | pci_id->device = ACPI_HIWORD(ACPI_LODWORD(temp)); | ||
631 | pci_id->function = ACPI_LOWORD(ACPI_LODWORD(temp)); | ||
632 | |||
633 | if (*is_bridge) | ||
634 | pci_id->bus = *bus_number; | ||
635 | |||
636 | /* any nicer way to get bus number of bridge ? */ | ||
637 | status = | ||
638 | acpi_os_read_pci_configuration(pci_id, 0x0e, &val, | ||
639 | 8); | ||
640 | if (ACPI_SUCCESS(status) | ||
641 | && ((val & 0x7f) == 1 || (val & 0x7f) == 2)) { | ||
642 | status = | ||
643 | acpi_os_read_pci_configuration(pci_id, 0x18, | ||
644 | &val, 8); | ||
645 | if (!ACPI_SUCCESS(status)) { | ||
646 | /* Certainly broken... FIX ME */ | ||
647 | return; | ||
648 | } | ||
649 | *is_bridge = 1; | ||
650 | pci_id->bus = val; | ||
651 | status = | ||
652 | acpi_os_read_pci_configuration(pci_id, 0x19, | ||
653 | &val, 8); | ||
654 | if (ACPI_SUCCESS(status)) { | ||
655 | *bus_number = val; | ||
656 | } | ||
657 | } else | ||
658 | *is_bridge = 0; | ||
659 | } | ||
660 | } | ||
661 | } | ||
662 | |||
663 | void acpi_os_derive_pci_id(acpi_handle rhandle, /* upper bound */ | ||
664 | acpi_handle chandle, /* current node */ | ||
665 | struct acpi_pci_id **id) | ||
666 | { | ||
667 | int is_bridge = 1; | ||
668 | u8 bus_number = (*id)->bus; | ||
669 | |||
670 | acpi_os_derive_pci_id_2(rhandle, chandle, id, &is_bridge, &bus_number); | ||
671 | } | ||
672 | |||
673 | static void acpi_os_execute_deferred(struct work_struct *work) | 625 | static void acpi_os_execute_deferred(struct work_struct *work) |
674 | { | 626 | { |
675 | struct acpi_os_dpc *dpc = container_of(work, struct acpi_os_dpc, work); | 627 | struct acpi_os_dpc *dpc = container_of(work, struct acpi_os_dpc, work); |
@@ -977,6 +929,12 @@ static void __init set_osi_linux(unsigned int enable) | |||
977 | printk(KERN_NOTICE PREFIX "%sed _OSI(Linux)\n", | 929 | printk(KERN_NOTICE PREFIX "%sed _OSI(Linux)\n", |
978 | enable ? "Add": "Delet"); | 930 | enable ? "Add": "Delet"); |
979 | } | 931 | } |
932 | |||
933 | if (osi_linux.enable) | ||
934 | acpi_osi_setup("Linux"); | ||
935 | else | ||
936 | acpi_osi_setup("!Linux"); | ||
937 | |||
980 | return; | 938 | return; |
981 | } | 939 | } |
982 | 940 | ||
@@ -1011,21 +969,33 @@ void __init acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d) | |||
1011 | * string starting with '!' disables that string | 969 | * string starting with '!' disables that string |
1012 | * otherwise string is added to list, augmenting built-in strings | 970 | * otherwise string is added to list, augmenting built-in strings |
1013 | */ | 971 | */ |
1014 | int __init acpi_osi_setup(char *str) | 972 | static void __init acpi_osi_setup_late(void) |
1015 | { | 973 | { |
1016 | if (str == NULL || *str == '\0') { | 974 | char *str = osi_setup_string; |
1017 | printk(KERN_INFO PREFIX "_OSI method disabled\n"); | 975 | |
1018 | acpi_gbl_create_osi_method = FALSE; | 976 | if (*str == '\0') |
1019 | } else if (!strcmp("!Linux", str)) { | 977 | return; |
978 | |||
979 | if (!strcmp("!Linux", str)) { | ||
1020 | acpi_cmdline_osi_linux(0); /* !enable */ | 980 | acpi_cmdline_osi_linux(0); /* !enable */ |
1021 | } else if (*str == '!') { | 981 | } else if (*str == '!') { |
1022 | if (acpi_osi_invalidate(++str) == AE_OK) | 982 | if (acpi_remove_interface(++str) == AE_OK) |
1023 | printk(KERN_INFO PREFIX "Deleted _OSI(%s)\n", str); | 983 | printk(KERN_INFO PREFIX "Deleted _OSI(%s)\n", str); |
1024 | } else if (!strcmp("Linux", str)) { | 984 | } else if (!strcmp("Linux", str)) { |
1025 | acpi_cmdline_osi_linux(1); /* enable */ | 985 | acpi_cmdline_osi_linux(1); /* enable */ |
1026 | } else if (*osi_additional_string == '\0') { | 986 | } else { |
1027 | strncpy(osi_additional_string, str, OSI_STRING_LENGTH_MAX); | 987 | if (acpi_install_interface(str) == AE_OK) |
1028 | printk(KERN_INFO PREFIX "Added _OSI(%s)\n", str); | 988 | printk(KERN_INFO PREFIX "Added _OSI(%s)\n", str); |
989 | } | ||
990 | } | ||
991 | |||
992 | int __init acpi_osi_setup(char *str) | ||
993 | { | ||
994 | if (str == NULL || *str == '\0') { | ||
995 | printk(KERN_INFO PREFIX "_OSI method disabled\n"); | ||
996 | acpi_gbl_create_osi_method = FALSE; | ||
997 | } else { | ||
998 | strncpy(osi_setup_string, str, OSI_STRING_LENGTH_MAX); | ||
1029 | } | 999 | } |
1030 | 1000 | ||
1031 | return 1; | 1001 | return 1; |
@@ -1282,38 +1252,6 @@ acpi_status acpi_os_release_object(acpi_cache_t * cache, void *object) | |||
1282 | return (AE_OK); | 1252 | return (AE_OK); |
1283 | } | 1253 | } |
1284 | 1254 | ||
1285 | /****************************************************************************** | ||
1286 | * | ||
1287 | * FUNCTION: acpi_os_validate_interface | ||
1288 | * | ||
1289 | * PARAMETERS: interface - Requested interface to be validated | ||
1290 | * | ||
1291 | * RETURN: AE_OK if interface is supported, AE_SUPPORT otherwise | ||
1292 | * | ||
1293 | * DESCRIPTION: Match an interface string to the interfaces supported by the | ||
1294 | * host. Strings originate from an AML call to the _OSI method. | ||
1295 | * | ||
1296 | *****************************************************************************/ | ||
1297 | |||
1298 | acpi_status | ||
1299 | acpi_os_validate_interface (char *interface) | ||
1300 | { | ||
1301 | if (!strncmp(osi_additional_string, interface, OSI_STRING_LENGTH_MAX)) | ||
1302 | return AE_OK; | ||
1303 | if (!strcmp("Linux", interface)) { | ||
1304 | |||
1305 | printk(KERN_NOTICE PREFIX | ||
1306 | "BIOS _OSI(Linux) query %s%s\n", | ||
1307 | osi_linux.enable ? "honored" : "ignored", | ||
1308 | osi_linux.cmdline ? " via cmdline" : | ||
1309 | osi_linux.dmi ? " via DMI" : ""); | ||
1310 | |||
1311 | if (osi_linux.enable) | ||
1312 | return AE_OK; | ||
1313 | } | ||
1314 | return AE_SUPPORT; | ||
1315 | } | ||
1316 | |||
1317 | static inline int acpi_res_list_add(struct acpi_res_list *res) | 1255 | static inline int acpi_res_list_add(struct acpi_res_list *res) |
1318 | { | 1256 | { |
1319 | struct acpi_res_list *res_list_elem; | 1257 | struct acpi_res_list *res_list_elem; |
diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c index e4804fb05e2..f907cfbfa13 100644 --- a/drivers/acpi/pci_irq.c +++ b/drivers/acpi/pci_irq.c | |||
@@ -32,7 +32,6 @@ | |||
32 | #include <linux/module.h> | 32 | #include <linux/module.h> |
33 | #include <linux/init.h> | 33 | #include <linux/init.h> |
34 | #include <linux/types.h> | 34 | #include <linux/types.h> |
35 | #include <linux/proc_fs.h> | ||
36 | #include <linux/spinlock.h> | 35 | #include <linux/spinlock.h> |
37 | #include <linux/pm.h> | 36 | #include <linux/pm.h> |
38 | #include <linux/pci.h> | 37 | #include <linux/pci.h> |
diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c index 8d47a5846ae..9ff80a7e9f6 100644 --- a/drivers/acpi/pci_link.c +++ b/drivers/acpi/pci_link.c | |||
@@ -34,7 +34,6 @@ | |||
34 | #include <linux/module.h> | 34 | #include <linux/module.h> |
35 | #include <linux/init.h> | 35 | #include <linux/init.h> |
36 | #include <linux/types.h> | 36 | #include <linux/types.h> |
37 | #include <linux/proc_fs.h> | ||
38 | #include <linux/spinlock.h> | 37 | #include <linux/spinlock.h> |
39 | #include <linux/pm.h> | 38 | #include <linux/pm.h> |
40 | #include <linux/pci.h> | 39 | #include <linux/pci.h> |
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index 3ba8d1f44a7..96668ad0962 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c | |||
@@ -27,7 +27,6 @@ | |||
27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
28 | #include <linux/init.h> | 28 | #include <linux/init.h> |
29 | #include <linux/types.h> | 29 | #include <linux/types.h> |
30 | #include <linux/proc_fs.h> | ||
31 | #include <linux/spinlock.h> | 30 | #include <linux/spinlock.h> |
32 | #include <linux/pm.h> | 31 | #include <linux/pm.h> |
33 | #include <linux/pm_runtime.h> | 32 | #include <linux/pm_runtime.h> |
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index e9699aaed10..bec561c14be 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c | |||
@@ -29,12 +29,6 @@ static int set_no_mwait(const struct dmi_system_id *id) | |||
29 | 29 | ||
30 | static struct dmi_system_id __cpuinitdata processor_idle_dmi_table[] = { | 30 | static struct dmi_system_id __cpuinitdata processor_idle_dmi_table[] = { |
31 | { | 31 | { |
32 | set_no_mwait, "IFL91 board", { | ||
33 | DMI_MATCH(DMI_BIOS_VENDOR, "COMPAL"), | ||
34 | DMI_MATCH(DMI_SYS_VENDOR, "ZEPTO"), | ||
35 | DMI_MATCH(DMI_PRODUCT_VERSION, "3215W"), | ||
36 | DMI_MATCH(DMI_BOARD_NAME, "IFL91") }, NULL}, | ||
37 | { | ||
38 | set_no_mwait, "Extensa 5220", { | 32 | set_no_mwait, "Extensa 5220", { |
39 | DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"), | 33 | DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"), |
40 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 34 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
@@ -352,4 +346,5 @@ void __init acpi_early_processor_set_pdc(void) | |||
352 | acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT, | 346 | acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT, |
353 | ACPI_UINT32_MAX, | 347 | ACPI_UINT32_MAX, |
354 | early_init_pdc, NULL, NULL, NULL); | 348 | early_init_pdc, NULL, NULL, NULL); |
349 | acpi_get_devices("ACPI0007", early_init_pdc, NULL, NULL); | ||
355 | } | 350 | } |
diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c index 15602189238..356c320bdd0 100644 --- a/drivers/acpi/processor_driver.c +++ b/drivers/acpi/processor_driver.c | |||
@@ -40,8 +40,10 @@ | |||
40 | #include <linux/pm.h> | 40 | #include <linux/pm.h> |
41 | #include <linux/cpufreq.h> | 41 | #include <linux/cpufreq.h> |
42 | #include <linux/cpu.h> | 42 | #include <linux/cpu.h> |
43 | #ifdef CONFIG_ACPI_PROCFS | ||
43 | #include <linux/proc_fs.h> | 44 | #include <linux/proc_fs.h> |
44 | #include <linux/seq_file.h> | 45 | #include <linux/seq_file.h> |
46 | #endif | ||
45 | #include <linux/dmi.h> | 47 | #include <linux/dmi.h> |
46 | #include <linux/moduleparam.h> | 48 | #include <linux/moduleparam.h> |
47 | #include <linux/cpuidle.h> | 49 | #include <linux/cpuidle.h> |
@@ -244,6 +246,7 @@ static int acpi_processor_errata(struct acpi_processor *pr) | |||
244 | return result; | 246 | return result; |
245 | } | 247 | } |
246 | 248 | ||
249 | #ifdef CONFIG_ACPI_PROCFS | ||
247 | static struct proc_dir_entry *acpi_processor_dir = NULL; | 250 | static struct proc_dir_entry *acpi_processor_dir = NULL; |
248 | 251 | ||
249 | static int __cpuinit acpi_processor_add_fs(struct acpi_device *device) | 252 | 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) | |||
280 | 283 | ||
281 | return 0; | 284 | return 0; |
282 | } | 285 | } |
283 | 286 | #else | |
287 | static inline int acpi_processor_add_fs(struct acpi_device *device) | ||
288 | { | ||
289 | return 0; | ||
290 | } | ||
291 | static inline int acpi_processor_remove_fs(struct acpi_device *device) | ||
292 | { | ||
293 | return 0; | ||
294 | } | ||
295 | #endif | ||
284 | /* -------------------------------------------------------------------------- | 296 | /* -------------------------------------------------------------------------- |
285 | Driver Interface | 297 | Driver Interface |
286 | -------------------------------------------------------------------------- */ | 298 | -------------------------------------------------------------------------- */ |
@@ -842,15 +854,17 @@ static int __init acpi_processor_init(void) | |||
842 | 854 | ||
843 | memset(&errata, 0, sizeof(errata)); | 855 | memset(&errata, 0, sizeof(errata)); |
844 | 856 | ||
857 | #ifdef CONFIG_ACPI_PROCFS | ||
845 | acpi_processor_dir = proc_mkdir(ACPI_PROCESSOR_CLASS, acpi_root_dir); | 858 | acpi_processor_dir = proc_mkdir(ACPI_PROCESSOR_CLASS, acpi_root_dir); |
846 | if (!acpi_processor_dir) | 859 | if (!acpi_processor_dir) |
847 | return -ENOMEM; | 860 | return -ENOMEM; |
861 | #endif | ||
848 | 862 | ||
849 | if (!cpuidle_register_driver(&acpi_idle_driver)) { | 863 | if (!cpuidle_register_driver(&acpi_idle_driver)) { |
850 | printk(KERN_DEBUG "ACPI: %s registered with cpuidle\n", | 864 | printk(KERN_DEBUG "ACPI: %s registered with cpuidle\n", |
851 | acpi_idle_driver.name); | 865 | acpi_idle_driver.name); |
852 | } else { | 866 | } else { |
853 | printk(KERN_DEBUG "ACPI: acpi_idle yielding to %s", | 867 | printk(KERN_DEBUG "ACPI: acpi_idle yielding to %s\n", |
854 | cpuidle_get_driver()->name); | 868 | cpuidle_get_driver()->name); |
855 | } | 869 | } |
856 | 870 | ||
@@ -871,7 +885,9 @@ static int __init acpi_processor_init(void) | |||
871 | out_cpuidle: | 885 | out_cpuidle: |
872 | cpuidle_unregister_driver(&acpi_idle_driver); | 886 | cpuidle_unregister_driver(&acpi_idle_driver); |
873 | 887 | ||
888 | #ifdef CONFIG_ACPI_PROCFS | ||
874 | remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir); | 889 | remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir); |
890 | #endif | ||
875 | 891 | ||
876 | return result; | 892 | return result; |
877 | } | 893 | } |
@@ -891,7 +907,9 @@ static void __exit acpi_processor_exit(void) | |||
891 | 907 | ||
892 | cpuidle_unregister_driver(&acpi_idle_driver); | 908 | cpuidle_unregister_driver(&acpi_idle_driver); |
893 | 909 | ||
910 | #ifdef CONFIG_ACPI_PROCFS | ||
894 | remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir); | 911 | remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir); |
912 | #endif | ||
895 | 913 | ||
896 | return; | 914 | return; |
897 | } | 915 | } |
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index ba1bd263d90..3a73a93596e 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c | |||
@@ -447,8 +447,8 @@ int acpi_processor_notify_smm(struct module *calling_module) | |||
447 | if (!try_module_get(calling_module)) | 447 | if (!try_module_get(calling_module)) |
448 | return -EINVAL; | 448 | return -EINVAL; |
449 | 449 | ||
450 | /* is_done is set to negative if an error occured, | 450 | /* is_done is set to negative if an error occurred, |
451 | * and to postitive if _no_ error occured, but SMM | 451 | * and to postitive if _no_ error occurred, but SMM |
452 | * was already notified. This avoids double notification | 452 | * was already notified. This avoids double notification |
453 | * which might lead to unexpected results... | 453 | * which might lead to unexpected results... |
454 | */ | 454 | */ |
diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c index 730863855ed..ff3632717c5 100644 --- a/drivers/acpi/processor_throttling.c +++ b/drivers/acpi/processor_throttling.c | |||
@@ -32,8 +32,10 @@ | |||
32 | #include <linux/init.h> | 32 | #include <linux/init.h> |
33 | #include <linux/sched.h> | 33 | #include <linux/sched.h> |
34 | #include <linux/cpufreq.h> | 34 | #include <linux/cpufreq.h> |
35 | #ifdef CONFIG_ACPI_PROCFS | ||
35 | #include <linux/proc_fs.h> | 36 | #include <linux/proc_fs.h> |
36 | #include <linux/seq_file.h> | 37 | #include <linux/seq_file.h> |
38 | #endif | ||
37 | 39 | ||
38 | #include <asm/io.h> | 40 | #include <asm/io.h> |
39 | #include <asm/uaccess.h> | 41 | #include <asm/uaccess.h> |
@@ -1214,6 +1216,7 @@ int acpi_processor_get_throttling_info(struct acpi_processor *pr) | |||
1214 | return result; | 1216 | return result; |
1215 | } | 1217 | } |
1216 | 1218 | ||
1219 | #ifdef CONFIG_ACPI_PROCFS | ||
1217 | /* proc interface */ | 1220 | /* proc interface */ |
1218 | static int acpi_processor_throttling_seq_show(struct seq_file *seq, | 1221 | static int acpi_processor_throttling_seq_show(struct seq_file *seq, |
1219 | void *offset) | 1222 | void *offset) |
@@ -1322,3 +1325,4 @@ const struct file_operations acpi_processor_throttling_fops = { | |||
1322 | .llseek = seq_lseek, | 1325 | .llseek = seq_lseek, |
1323 | .release = single_release, | 1326 | .release = single_release, |
1324 | }; | 1327 | }; |
1328 | #endif | ||
diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c index 4ff76e8174e..e5dbedb16bb 100644 --- a/drivers/acpi/sbs.c +++ b/drivers/acpi/sbs.c | |||
@@ -40,10 +40,7 @@ | |||
40 | #include <linux/timer.h> | 40 | #include <linux/timer.h> |
41 | #include <linux/jiffies.h> | 41 | #include <linux/jiffies.h> |
42 | #include <linux/delay.h> | 42 | #include <linux/delay.h> |
43 | |||
44 | #ifdef CONFIG_ACPI_SYSFS_POWER | ||
45 | #include <linux/power_supply.h> | 43 | #include <linux/power_supply.h> |
46 | #endif | ||
47 | 44 | ||
48 | #include "sbshc.h" | 45 | #include "sbshc.h" |
49 | 46 | ||
@@ -85,9 +82,7 @@ static const struct acpi_device_id sbs_device_ids[] = { | |||
85 | MODULE_DEVICE_TABLE(acpi, sbs_device_ids); | 82 | MODULE_DEVICE_TABLE(acpi, sbs_device_ids); |
86 | 83 | ||
87 | struct acpi_battery { | 84 | struct acpi_battery { |
88 | #ifdef CONFIG_ACPI_SYSFS_POWER | ||
89 | struct power_supply bat; | 85 | struct power_supply bat; |
90 | #endif | ||
91 | struct acpi_sbs *sbs; | 86 | struct acpi_sbs *sbs; |
92 | #ifdef CONFIG_ACPI_PROCFS_POWER | 87 | #ifdef CONFIG_ACPI_PROCFS_POWER |
93 | struct proc_dir_entry *proc_entry; | 88 | struct proc_dir_entry *proc_entry; |
@@ -120,9 +115,7 @@ struct acpi_battery { | |||
120 | #define to_acpi_battery(x) container_of(x, struct acpi_battery, bat); | 115 | #define to_acpi_battery(x) container_of(x, struct acpi_battery, bat); |
121 | 116 | ||
122 | struct acpi_sbs { | 117 | struct acpi_sbs { |
123 | #ifdef CONFIG_ACPI_SYSFS_POWER | ||
124 | struct power_supply charger; | 118 | struct power_supply charger; |
125 | #endif | ||
126 | struct acpi_device *device; | 119 | struct acpi_device *device; |
127 | struct acpi_smb_hc *hc; | 120 | struct acpi_smb_hc *hc; |
128 | struct mutex lock; | 121 | struct mutex lock; |
@@ -166,7 +159,6 @@ static inline int acpi_battery_scale(struct acpi_battery *battery) | |||
166 | acpi_battery_ipscale(battery); | 159 | acpi_battery_ipscale(battery); |
167 | } | 160 | } |
168 | 161 | ||
169 | #ifdef CONFIG_ACPI_SYSFS_POWER | ||
170 | static int sbs_get_ac_property(struct power_supply *psy, | 162 | static int sbs_get_ac_property(struct power_supply *psy, |
171 | enum power_supply_property psp, | 163 | enum power_supply_property psp, |
172 | union power_supply_propval *val) | 164 | union power_supply_propval *val) |
@@ -313,7 +305,6 @@ static enum power_supply_property sbs_energy_battery_props[] = { | |||
313 | POWER_SUPPLY_PROP_MANUFACTURER, | 305 | POWER_SUPPLY_PROP_MANUFACTURER, |
314 | }; | 306 | }; |
315 | 307 | ||
316 | #endif | ||
317 | 308 | ||
318 | /* -------------------------------------------------------------------------- | 309 | /* -------------------------------------------------------------------------- |
319 | Smart Battery System Management | 310 | Smart Battery System Management |
@@ -449,7 +440,6 @@ static int acpi_ac_get_present(struct acpi_sbs *sbs) | |||
449 | return result; | 440 | return result; |
450 | } | 441 | } |
451 | 442 | ||
452 | #ifdef CONFIG_ACPI_SYSFS_POWER | ||
453 | static ssize_t acpi_battery_alarm_show(struct device *dev, | 443 | static ssize_t acpi_battery_alarm_show(struct device *dev, |
454 | struct device_attribute *attr, | 444 | struct device_attribute *attr, |
455 | char *buf) | 445 | char *buf) |
@@ -479,7 +469,6 @@ static struct device_attribute alarm_attr = { | |||
479 | .show = acpi_battery_alarm_show, | 469 | .show = acpi_battery_alarm_show, |
480 | .store = acpi_battery_alarm_store, | 470 | .store = acpi_battery_alarm_store, |
481 | }; | 471 | }; |
482 | #endif | ||
483 | 472 | ||
484 | /* -------------------------------------------------------------------------- | 473 | /* -------------------------------------------------------------------------- |
485 | FS Interface (/proc/acpi) | 474 | FS Interface (/proc/acpi) |
@@ -798,7 +787,6 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id) | |||
798 | &acpi_battery_state_fops, &acpi_battery_alarm_fops, | 787 | &acpi_battery_state_fops, &acpi_battery_alarm_fops, |
799 | battery); | 788 | battery); |
800 | #endif | 789 | #endif |
801 | #ifdef CONFIG_ACPI_SYSFS_POWER | ||
802 | battery->bat.name = battery->name; | 790 | battery->bat.name = battery->name; |
803 | battery->bat.type = POWER_SUPPLY_TYPE_BATTERY; | 791 | battery->bat.type = POWER_SUPPLY_TYPE_BATTERY; |
804 | if (!acpi_battery_mode(battery)) { | 792 | if (!acpi_battery_mode(battery)) { |
@@ -819,7 +807,6 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id) | |||
819 | goto end; | 807 | goto end; |
820 | battery->have_sysfs_alarm = 1; | 808 | battery->have_sysfs_alarm = 1; |
821 | end: | 809 | end: |
822 | #endif | ||
823 | printk(KERN_INFO PREFIX "%s [%s]: Battery Slot [%s] (battery %s)\n", | 810 | printk(KERN_INFO PREFIX "%s [%s]: Battery Slot [%s] (battery %s)\n", |
824 | ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device), | 811 | ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device), |
825 | battery->name, battery->present ? "present" : "absent"); | 812 | battery->name, battery->present ? "present" : "absent"); |
@@ -828,17 +815,13 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id) | |||
828 | 815 | ||
829 | static void acpi_battery_remove(struct acpi_sbs *sbs, int id) | 816 | static void acpi_battery_remove(struct acpi_sbs *sbs, int id) |
830 | { | 817 | { |
831 | #if defined(CONFIG_ACPI_SYSFS_POWER) || defined(CONFIG_ACPI_PROCFS_POWER) | ||
832 | struct acpi_battery *battery = &sbs->battery[id]; | 818 | struct acpi_battery *battery = &sbs->battery[id]; |
833 | #endif | ||
834 | 819 | ||
835 | #ifdef CONFIG_ACPI_SYSFS_POWER | ||
836 | if (battery->bat.dev) { | 820 | if (battery->bat.dev) { |
837 | if (battery->have_sysfs_alarm) | 821 | if (battery->have_sysfs_alarm) |
838 | device_remove_file(battery->bat.dev, &alarm_attr); | 822 | device_remove_file(battery->bat.dev, &alarm_attr); |
839 | power_supply_unregister(&battery->bat); | 823 | power_supply_unregister(&battery->bat); |
840 | } | 824 | } |
841 | #endif | ||
842 | #ifdef CONFIG_ACPI_PROCFS_POWER | 825 | #ifdef CONFIG_ACPI_PROCFS_POWER |
843 | if (battery->proc_entry) | 826 | if (battery->proc_entry) |
844 | acpi_sbs_remove_fs(&battery->proc_entry, acpi_battery_dir); | 827 | acpi_sbs_remove_fs(&battery->proc_entry, acpi_battery_dir); |
@@ -859,14 +842,12 @@ static int acpi_charger_add(struct acpi_sbs *sbs) | |||
859 | if (result) | 842 | if (result) |
860 | goto end; | 843 | goto end; |
861 | #endif | 844 | #endif |
862 | #ifdef CONFIG_ACPI_SYSFS_POWER | ||
863 | sbs->charger.name = "sbs-charger"; | 845 | sbs->charger.name = "sbs-charger"; |
864 | sbs->charger.type = POWER_SUPPLY_TYPE_MAINS; | 846 | sbs->charger.type = POWER_SUPPLY_TYPE_MAINS; |
865 | sbs->charger.properties = sbs_ac_props; | 847 | sbs->charger.properties = sbs_ac_props; |
866 | sbs->charger.num_properties = ARRAY_SIZE(sbs_ac_props); | 848 | sbs->charger.num_properties = ARRAY_SIZE(sbs_ac_props); |
867 | sbs->charger.get_property = sbs_get_ac_property; | 849 | sbs->charger.get_property = sbs_get_ac_property; |
868 | power_supply_register(&sbs->device->dev, &sbs->charger); | 850 | power_supply_register(&sbs->device->dev, &sbs->charger); |
869 | #endif | ||
870 | printk(KERN_INFO PREFIX "%s [%s]: AC Adapter [%s] (%s)\n", | 851 | printk(KERN_INFO PREFIX "%s [%s]: AC Adapter [%s] (%s)\n", |
871 | ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device), | 852 | ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device), |
872 | ACPI_AC_DIR_NAME, sbs->charger_present ? "on-line" : "off-line"); | 853 | ACPI_AC_DIR_NAME, sbs->charger_present ? "on-line" : "off-line"); |
@@ -876,10 +857,8 @@ static int acpi_charger_add(struct acpi_sbs *sbs) | |||
876 | 857 | ||
877 | static void acpi_charger_remove(struct acpi_sbs *sbs) | 858 | static void acpi_charger_remove(struct acpi_sbs *sbs) |
878 | { | 859 | { |
879 | #ifdef CONFIG_ACPI_SYSFS_POWER | ||
880 | if (sbs->charger.dev) | 860 | if (sbs->charger.dev) |
881 | power_supply_unregister(&sbs->charger); | 861 | power_supply_unregister(&sbs->charger); |
882 | #endif | ||
883 | #ifdef CONFIG_ACPI_PROCFS_POWER | 862 | #ifdef CONFIG_ACPI_PROCFS_POWER |
884 | if (sbs->charger_entry) | 863 | if (sbs->charger_entry) |
885 | acpi_sbs_remove_fs(&sbs->charger_entry, acpi_ac_dir); | 864 | acpi_sbs_remove_fs(&sbs->charger_entry, acpi_ac_dir); |
@@ -900,9 +879,7 @@ static void acpi_sbs_callback(void *context) | |||
900 | ACPI_SBS_NOTIFY_STATUS, | 879 | ACPI_SBS_NOTIFY_STATUS, |
901 | sbs->charger_present); | 880 | sbs->charger_present); |
902 | #endif | 881 | #endif |
903 | #ifdef CONFIG_ACPI_SYSFS_POWER | ||
904 | kobject_uevent(&sbs->charger.dev->kobj, KOBJ_CHANGE); | 882 | kobject_uevent(&sbs->charger.dev->kobj, KOBJ_CHANGE); |
905 | #endif | ||
906 | } | 883 | } |
907 | if (sbs->manager_present) { | 884 | if (sbs->manager_present) { |
908 | for (id = 0; id < MAX_SBS_BAT; ++id) { | 885 | for (id = 0; id < MAX_SBS_BAT; ++id) { |
@@ -919,9 +896,7 @@ static void acpi_sbs_callback(void *context) | |||
919 | ACPI_SBS_NOTIFY_STATUS, | 896 | ACPI_SBS_NOTIFY_STATUS, |
920 | bat->present); | 897 | bat->present); |
921 | #endif | 898 | #endif |
922 | #ifdef CONFIG_ACPI_SYSFS_POWER | ||
923 | kobject_uevent(&bat->bat.dev->kobj, KOBJ_CHANGE); | 899 | kobject_uevent(&bat->bat.dev->kobj, KOBJ_CHANGE); |
924 | #endif | ||
925 | } | 900 | } |
926 | } | 901 | } |
927 | } | 902 | } |
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index b23825ecfa3..2b6c21d86b9 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
@@ -26,6 +26,8 @@ extern struct acpi_device *acpi_root; | |||
26 | 26 | ||
27 | #define ACPI_IS_ROOT_DEVICE(device) (!(device)->parent) | 27 | #define ACPI_IS_ROOT_DEVICE(device) (!(device)->parent) |
28 | 28 | ||
29 | static const char *dummy_hid = "device"; | ||
30 | |||
29 | static LIST_HEAD(acpi_device_list); | 31 | static LIST_HEAD(acpi_device_list); |
30 | static LIST_HEAD(acpi_bus_id_list); | 32 | static LIST_HEAD(acpi_bus_id_list); |
31 | DEFINE_MUTEX(acpi_device_lock); | 33 | DEFINE_MUTEX(acpi_device_lock); |
@@ -49,6 +51,9 @@ static int create_modalias(struct acpi_device *acpi_dev, char *modalias, | |||
49 | int count; | 51 | int count; |
50 | struct acpi_hardware_id *id; | 52 | struct acpi_hardware_id *id; |
51 | 53 | ||
54 | if (list_empty(&acpi_dev->pnp.ids)) | ||
55 | return 0; | ||
56 | |||
52 | len = snprintf(modalias, size, "acpi:"); | 57 | len = snprintf(modalias, size, "acpi:"); |
53 | size -= len; | 58 | size -= len; |
54 | 59 | ||
@@ -202,13 +207,15 @@ static int acpi_device_setup_files(struct acpi_device *dev) | |||
202 | goto end; | 207 | goto end; |
203 | } | 208 | } |
204 | 209 | ||
205 | result = device_create_file(&dev->dev, &dev_attr_hid); | 210 | if (!list_empty(&dev->pnp.ids)) { |
206 | if (result) | 211 | result = device_create_file(&dev->dev, &dev_attr_hid); |
207 | goto end; | 212 | if (result) |
213 | goto end; | ||
208 | 214 | ||
209 | result = device_create_file(&dev->dev, &dev_attr_modalias); | 215 | result = device_create_file(&dev->dev, &dev_attr_modalias); |
210 | if (result) | 216 | if (result) |
211 | goto end; | 217 | goto end; |
218 | } | ||
212 | 219 | ||
213 | /* | 220 | /* |
214 | * If device has _EJ0, 'eject' file is created that is used to trigger | 221 | * 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) | |||
316 | struct acpi_device *acpi_dev = to_acpi_device(dev); | 323 | struct acpi_device *acpi_dev = to_acpi_device(dev); |
317 | int len; | 324 | int len; |
318 | 325 | ||
326 | if (list_empty(&acpi_dev->pnp.ids)) | ||
327 | return 0; | ||
328 | |||
319 | if (add_uevent_var(env, "MODALIAS=")) | 329 | if (add_uevent_var(env, "MODALIAS=")) |
320 | return -ENOMEM; | 330 | return -ENOMEM; |
321 | len = create_modalias(acpi_dev, &env->buf[env->buflen - 1], | 331 | len = create_modalias(acpi_dev, &env->buf[env->buflen - 1], |
@@ -1010,10 +1020,13 @@ static int acpi_dock_match(struct acpi_device *device) | |||
1010 | return acpi_get_handle(device->handle, "_DCK", &tmp); | 1020 | return acpi_get_handle(device->handle, "_DCK", &tmp); |
1011 | } | 1021 | } |
1012 | 1022 | ||
1013 | char *acpi_device_hid(struct acpi_device *device) | 1023 | const char *acpi_device_hid(struct acpi_device *device) |
1014 | { | 1024 | { |
1015 | struct acpi_hardware_id *hid; | 1025 | struct acpi_hardware_id *hid; |
1016 | 1026 | ||
1027 | if (list_empty(&device->pnp.ids)) | ||
1028 | return dummy_hid; | ||
1029 | |||
1017 | hid = list_first_entry(&device->pnp.ids, struct acpi_hardware_id, list); | 1030 | hid = list_first_entry(&device->pnp.ids, struct acpi_hardware_id, list); |
1018 | return hid->id; | 1031 | return hid->id; |
1019 | } | 1032 | } |
@@ -1142,16 +1155,6 @@ static void acpi_device_set_id(struct acpi_device *device) | |||
1142 | acpi_add_id(device, ACPI_BUTTON_HID_SLEEPF); | 1155 | acpi_add_id(device, ACPI_BUTTON_HID_SLEEPF); |
1143 | break; | 1156 | break; |
1144 | } | 1157 | } |
1145 | |||
1146 | /* | ||
1147 | * We build acpi_devices for some objects that don't have _HID or _CID, | ||
1148 | * e.g., PCI bridges and slots. Drivers can't bind to these objects, | ||
1149 | * but we do use them indirectly by traversing the acpi_device tree. | ||
1150 | * This generic ID isn't useful for driver binding, but it provides | ||
1151 | * the useful property that "every acpi_device has an ID." | ||
1152 | */ | ||
1153 | if (list_empty(&device->pnp.ids)) | ||
1154 | acpi_add_id(device, "device"); | ||
1155 | } | 1158 | } |
1156 | 1159 | ||
1157 | static int acpi_device_set_context(struct acpi_device *device) | 1160 | static int acpi_device_set_context(struct acpi_device *device) |
@@ -1431,6 +1434,7 @@ EXPORT_SYMBOL(acpi_bus_add); | |||
1431 | int acpi_bus_start(struct acpi_device *device) | 1434 | int acpi_bus_start(struct acpi_device *device) |
1432 | { | 1435 | { |
1433 | struct acpi_bus_ops ops; | 1436 | struct acpi_bus_ops ops; |
1437 | int result; | ||
1434 | 1438 | ||
1435 | if (!device) | 1439 | if (!device) |
1436 | return -EINVAL; | 1440 | return -EINVAL; |
@@ -1438,7 +1442,11 @@ int acpi_bus_start(struct acpi_device *device) | |||
1438 | memset(&ops, 0, sizeof(ops)); | 1442 | memset(&ops, 0, sizeof(ops)); |
1439 | ops.acpi_op_start = 1; | 1443 | ops.acpi_op_start = 1; |
1440 | 1444 | ||
1441 | return acpi_bus_scan(device->handle, &ops, NULL); | 1445 | result = acpi_bus_scan(device->handle, &ops, NULL); |
1446 | |||
1447 | acpi_update_gpes(); | ||
1448 | |||
1449 | return result; | ||
1442 | } | 1450 | } |
1443 | EXPORT_SYMBOL(acpi_bus_start); | 1451 | EXPORT_SYMBOL(acpi_bus_start); |
1444 | 1452 | ||
@@ -1552,6 +1560,8 @@ int __init acpi_scan_init(void) | |||
1552 | 1560 | ||
1553 | if (result) | 1561 | if (result) |
1554 | acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL); | 1562 | acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL); |
1563 | else | ||
1564 | acpi_update_gpes(); | ||
1555 | 1565 | ||
1556 | return result; | 1566 | return result; |
1557 | } | 1567 | } |
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index cf82989ae75..e807f4196f8 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c | |||
@@ -27,6 +27,8 @@ | |||
27 | 27 | ||
28 | u8 sleep_states[ACPI_S_STATE_COUNT]; | 28 | u8 sleep_states[ACPI_S_STATE_COUNT]; |
29 | 29 | ||
30 | static u32 acpi_target_sleep_state = ACPI_STATE_S0; | ||
31 | |||
30 | static void acpi_sleep_tts_switch(u32 acpi_state) | 32 | static void acpi_sleep_tts_switch(u32 acpi_state) |
31 | { | 33 | { |
32 | union acpi_object in_arg = { ACPI_TYPE_INTEGER }; | 34 | union acpi_object in_arg = { ACPI_TYPE_INTEGER }; |
@@ -79,8 +81,6 @@ static int acpi_sleep_prepare(u32 acpi_state) | |||
79 | } | 81 | } |
80 | 82 | ||
81 | #ifdef CONFIG_ACPI_SLEEP | 83 | #ifdef CONFIG_ACPI_SLEEP |
82 | static u32 acpi_target_sleep_state = ACPI_STATE_S0; | ||
83 | |||
84 | /* | 84 | /* |
85 | * The ACPI specification wants us to save NVS memory regions during hibernation | 85 | * The ACPI specification wants us to save NVS memory regions during hibernation |
86 | * and to restore them during the subsequent resume. Windows does that also for | 86 | * and to restore them during the subsequent resume. Windows does that also for |
@@ -363,6 +363,12 @@ static int __init init_old_suspend_ordering(const struct dmi_system_id *d) | |||
363 | return 0; | 363 | return 0; |
364 | } | 364 | } |
365 | 365 | ||
366 | static int __init init_nvs_nosave(const struct dmi_system_id *d) | ||
367 | { | ||
368 | acpi_nvs_nosave(); | ||
369 | return 0; | ||
370 | } | ||
371 | |||
366 | static struct dmi_system_id __initdata acpisleep_dmi_table[] = { | 372 | static struct dmi_system_id __initdata acpisleep_dmi_table[] = { |
367 | { | 373 | { |
368 | .callback = init_old_suspend_ordering, | 374 | .callback = init_old_suspend_ordering, |
@@ -397,6 +403,22 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = { | |||
397 | DMI_MATCH(DMI_BOARD_NAME, "CF51-2L"), | 403 | DMI_MATCH(DMI_BOARD_NAME, "CF51-2L"), |
398 | }, | 404 | }, |
399 | }, | 405 | }, |
406 | { | ||
407 | .callback = init_nvs_nosave, | ||
408 | .ident = "Sony Vaio VGN-SR11M", | ||
409 | .matches = { | ||
410 | DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), | ||
411 | DMI_MATCH(DMI_PRODUCT_NAME, "VGN-SR11M"), | ||
412 | }, | ||
413 | }, | ||
414 | { | ||
415 | .callback = init_nvs_nosave, | ||
416 | .ident = "Everex StepNote Series", | ||
417 | .matches = { | ||
418 | DMI_MATCH(DMI_SYS_VENDOR, "Everex Systems, Inc."), | ||
419 | DMI_MATCH(DMI_PRODUCT_NAME, "Everex StepNote Series"), | ||
420 | }, | ||
421 | }, | ||
400 | {}, | 422 | {}, |
401 | }; | 423 | }; |
402 | #endif /* CONFIG_SUSPEND */ | 424 | #endif /* CONFIG_SUSPEND */ |
@@ -540,7 +562,7 @@ int acpi_suspend(u32 acpi_state) | |||
540 | return -EINVAL; | 562 | return -EINVAL; |
541 | } | 563 | } |
542 | 564 | ||
543 | #ifdef CONFIG_PM_SLEEP | 565 | #ifdef CONFIG_PM_OPS |
544 | /** | 566 | /** |
545 | * acpi_pm_device_sleep_state - return preferred power state of ACPI device | 567 | * acpi_pm_device_sleep_state - return preferred power state of ACPI device |
546 | * in the system sleep state given by %acpi_target_sleep_state | 568 | * in the system sleep state given by %acpi_target_sleep_state |
@@ -602,7 +624,7 @@ int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p) | |||
602 | * can wake the system. _S0W may be valid, too. | 624 | * can wake the system. _S0W may be valid, too. |
603 | */ | 625 | */ |
604 | if (acpi_target_sleep_state == ACPI_STATE_S0 || | 626 | if (acpi_target_sleep_state == ACPI_STATE_S0 || |
605 | (device_may_wakeup(dev) && adev->wakeup.state.enabled && | 627 | (device_may_wakeup(dev) && |
606 | adev->wakeup.sleep_state <= acpi_target_sleep_state)) { | 628 | adev->wakeup.sleep_state <= acpi_target_sleep_state)) { |
607 | acpi_status status; | 629 | acpi_status status; |
608 | 630 | ||
@@ -610,7 +632,9 @@ int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p) | |||
610 | status = acpi_evaluate_integer(handle, acpi_method, NULL, | 632 | status = acpi_evaluate_integer(handle, acpi_method, NULL, |
611 | &d_max); | 633 | &d_max); |
612 | if (ACPI_FAILURE(status)) { | 634 | if (ACPI_FAILURE(status)) { |
613 | d_max = d_min; | 635 | if (acpi_target_sleep_state != ACPI_STATE_S0 || |
636 | status != AE_NOT_FOUND) | ||
637 | d_max = d_min; | ||
614 | } else if (d_max < d_min) { | 638 | } else if (d_max < d_min) { |
615 | /* Warn the user of the broken DSDT */ | 639 | /* Warn the user of the broken DSDT */ |
616 | printk(KERN_WARNING "ACPI: Wrong value from %s\n", | 640 | printk(KERN_WARNING "ACPI: Wrong value from %s\n", |
@@ -624,7 +648,9 @@ int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p) | |||
624 | *d_min_p = d_min; | 648 | *d_min_p = d_min; |
625 | return d_max; | 649 | return d_max; |
626 | } | 650 | } |
651 | #endif /* CONFIG_PM_OPS */ | ||
627 | 652 | ||
653 | #ifdef CONFIG_PM_SLEEP | ||
628 | /** | 654 | /** |
629 | * acpi_pm_device_sleep_wake - enable or disable the system wake-up | 655 | * acpi_pm_device_sleep_wake - enable or disable the system wake-up |
630 | * capability of given device | 656 | * capability of given device |
@@ -655,7 +681,7 @@ int acpi_pm_device_sleep_wake(struct device *dev, bool enable) | |||
655 | 681 | ||
656 | return error; | 682 | return error; |
657 | } | 683 | } |
658 | #endif | 684 | #endif /* CONFIG_PM_SLEEP */ |
659 | 685 | ||
660 | static void acpi_power_off_prepare(void) | 686 | static void acpi_power_off_prepare(void) |
661 | { | 687 | { |
diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c index 68e2e4582fa..f8588f81048 100644 --- a/drivers/acpi/sysfs.c +++ b/drivers/acpi/sysfs.c | |||
@@ -100,7 +100,7 @@ static const struct acpi_dlevel acpi_debug_levels[] = { | |||
100 | ACPI_DEBUG_INIT(ACPI_LV_EVENTS), | 100 | ACPI_DEBUG_INIT(ACPI_LV_EVENTS), |
101 | }; | 101 | }; |
102 | 102 | ||
103 | static int param_get_debug_layer(char *buffer, struct kernel_param *kp) | 103 | static int param_get_debug_layer(char *buffer, const struct kernel_param *kp) |
104 | { | 104 | { |
105 | int result = 0; | 105 | int result = 0; |
106 | int i; | 106 | int i; |
@@ -128,7 +128,7 @@ static int param_get_debug_layer(char *buffer, struct kernel_param *kp) | |||
128 | return result; | 128 | return result; |
129 | } | 129 | } |
130 | 130 | ||
131 | static int param_get_debug_level(char *buffer, struct kernel_param *kp) | 131 | static int param_get_debug_level(char *buffer, const struct kernel_param *kp) |
132 | { | 132 | { |
133 | int result = 0; | 133 | int result = 0; |
134 | int i; | 134 | int i; |
@@ -149,10 +149,18 @@ static int param_get_debug_level(char *buffer, struct kernel_param *kp) | |||
149 | return result; | 149 | return result; |
150 | } | 150 | } |
151 | 151 | ||
152 | module_param_call(debug_layer, param_set_uint, param_get_debug_layer, | 152 | static struct kernel_param_ops param_ops_debug_layer = { |
153 | &acpi_dbg_layer, 0644); | 153 | .set = param_set_uint, |
154 | module_param_call(debug_level, param_set_uint, param_get_debug_level, | 154 | .get = param_get_debug_layer, |
155 | &acpi_dbg_level, 0644); | 155 | }; |
156 | |||
157 | static struct kernel_param_ops param_ops_debug_level = { | ||
158 | .set = param_set_uint, | ||
159 | .get = param_get_debug_level, | ||
160 | }; | ||
161 | |||
162 | module_param_cb(debug_layer, ¶m_ops_debug_layer, &acpi_dbg_layer, 0644); | ||
163 | module_param_cb(debug_level, ¶m_ops_debug_level, &acpi_dbg_level, 0644); | ||
156 | 164 | ||
157 | static char trace_method_name[6]; | 165 | static char trace_method_name[6]; |
158 | module_param_string(trace_method_name, trace_method_name, 6, 0644); | 166 | module_param_string(trace_method_name, trace_method_name, 6, 0644); |
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 2f8f17131d9..5a27b0a3131 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c | |||
@@ -37,12 +37,6 @@ | |||
37 | #include <linux/init.h> | 37 | #include <linux/init.h> |
38 | #include <linux/slab.h> | 38 | #include <linux/slab.h> |
39 | #include <linux/types.h> | 39 | #include <linux/types.h> |
40 | |||
41 | #ifdef CONFIG_ACPI_PROCFS | ||
42 | #include <linux/proc_fs.h> | ||
43 | #include <linux/seq_file.h> | ||
44 | #endif | ||
45 | |||
46 | #include <linux/jiffies.h> | 40 | #include <linux/jiffies.h> |
47 | #include <linux/kmod.h> | 41 | #include <linux/kmod.h> |
48 | #include <linux/reboot.h> | 42 | #include <linux/reboot.h> |
@@ -195,61 +189,6 @@ struct acpi_thermal { | |||
195 | struct mutex lock; | 189 | struct mutex lock; |
196 | }; | 190 | }; |
197 | 191 | ||
198 | #ifdef CONFIG_ACPI_PROCFS | ||
199 | static int acpi_thermal_state_open_fs(struct inode *inode, struct file *file); | ||
200 | static int acpi_thermal_temp_open_fs(struct inode *inode, struct file *file); | ||
201 | static int acpi_thermal_trip_open_fs(struct inode *inode, struct file *file); | ||
202 | static int acpi_thermal_cooling_open_fs(struct inode *inode, struct file *file); | ||
203 | static ssize_t acpi_thermal_write_cooling_mode(struct file *, | ||
204 | const char __user *, size_t, | ||
205 | loff_t *); | ||
206 | static int acpi_thermal_polling_open_fs(struct inode *inode, struct file *file); | ||
207 | static ssize_t acpi_thermal_write_polling(struct file *, const char __user *, | ||
208 | size_t, loff_t *); | ||
209 | |||
210 | static const struct file_operations acpi_thermal_state_fops = { | ||
211 | .owner = THIS_MODULE, | ||
212 | .open = acpi_thermal_state_open_fs, | ||
213 | .read = seq_read, | ||
214 | .llseek = seq_lseek, | ||
215 | .release = single_release, | ||
216 | }; | ||
217 | |||
218 | static const struct file_operations acpi_thermal_temp_fops = { | ||
219 | .owner = THIS_MODULE, | ||
220 | .open = acpi_thermal_temp_open_fs, | ||
221 | .read = seq_read, | ||
222 | .llseek = seq_lseek, | ||
223 | .release = single_release, | ||
224 | }; | ||
225 | |||
226 | static const struct file_operations acpi_thermal_trip_fops = { | ||
227 | .owner = THIS_MODULE, | ||
228 | .open = acpi_thermal_trip_open_fs, | ||
229 | .read = seq_read, | ||
230 | .llseek = seq_lseek, | ||
231 | .release = single_release, | ||
232 | }; | ||
233 | |||
234 | static const struct file_operations acpi_thermal_cooling_fops = { | ||
235 | .owner = THIS_MODULE, | ||
236 | .open = acpi_thermal_cooling_open_fs, | ||
237 | .read = seq_read, | ||
238 | .write = acpi_thermal_write_cooling_mode, | ||
239 | .llseek = seq_lseek, | ||
240 | .release = single_release, | ||
241 | }; | ||
242 | |||
243 | static const struct file_operations acpi_thermal_polling_fops = { | ||
244 | .owner = THIS_MODULE, | ||
245 | .open = acpi_thermal_polling_open_fs, | ||
246 | .read = seq_read, | ||
247 | .write = acpi_thermal_write_polling, | ||
248 | .llseek = seq_lseek, | ||
249 | .release = single_release, | ||
250 | }; | ||
251 | #endif /* CONFIG_ACPI_PROCFS*/ | ||
252 | |||
253 | /* -------------------------------------------------------------------------- | 192 | /* -------------------------------------------------------------------------- |
254 | Thermal Zone Management | 193 | Thermal Zone Management |
255 | -------------------------------------------------------------------------- */ | 194 | -------------------------------------------------------------------------- */ |
@@ -958,358 +897,6 @@ static void acpi_thermal_unregister_thermal_zone(struct acpi_thermal *tz) | |||
958 | 897 | ||
959 | 898 | ||
960 | /* -------------------------------------------------------------------------- | 899 | /* -------------------------------------------------------------------------- |
961 | FS Interface (/proc) | ||
962 | -------------------------------------------------------------------------- */ | ||
963 | #ifdef CONFIG_ACPI_PROCFS | ||
964 | static struct proc_dir_entry *acpi_thermal_dir; | ||
965 | |||
966 | static int acpi_thermal_state_seq_show(struct seq_file *seq, void *offset) | ||
967 | { | ||
968 | struct acpi_thermal *tz = seq->private; | ||
969 | |||
970 | |||
971 | if (!tz) | ||
972 | goto end; | ||
973 | |||
974 | seq_puts(seq, "state: "); | ||
975 | |||
976 | if (!tz->state.critical && !tz->state.hot && !tz->state.passive | ||
977 | && !tz->state.active) | ||
978 | seq_puts(seq, "ok\n"); | ||
979 | else { | ||
980 | if (tz->state.critical) | ||
981 | seq_puts(seq, "critical "); | ||
982 | if (tz->state.hot) | ||
983 | seq_puts(seq, "hot "); | ||
984 | if (tz->state.passive) | ||
985 | seq_puts(seq, "passive "); | ||
986 | if (tz->state.active) | ||
987 | seq_printf(seq, "active[%d]", tz->state.active_index); | ||
988 | seq_puts(seq, "\n"); | ||
989 | } | ||
990 | |||
991 | end: | ||
992 | return 0; | ||
993 | } | ||
994 | |||
995 | static int acpi_thermal_state_open_fs(struct inode *inode, struct file *file) | ||
996 | { | ||
997 | return single_open(file, acpi_thermal_state_seq_show, PDE(inode)->data); | ||
998 | } | ||
999 | |||
1000 | static int acpi_thermal_temp_seq_show(struct seq_file *seq, void *offset) | ||
1001 | { | ||
1002 | int result = 0; | ||
1003 | struct acpi_thermal *tz = seq->private; | ||
1004 | |||
1005 | |||
1006 | if (!tz) | ||
1007 | goto end; | ||
1008 | |||
1009 | result = acpi_thermal_get_temperature(tz); | ||
1010 | if (result) | ||
1011 | goto end; | ||
1012 | |||
1013 | seq_printf(seq, "temperature: %ld C\n", | ||
1014 | KELVIN_TO_CELSIUS(tz->temperature)); | ||
1015 | |||
1016 | end: | ||
1017 | return 0; | ||
1018 | } | ||
1019 | |||
1020 | static int acpi_thermal_temp_open_fs(struct inode *inode, struct file *file) | ||
1021 | { | ||
1022 | return single_open(file, acpi_thermal_temp_seq_show, PDE(inode)->data); | ||
1023 | } | ||
1024 | |||
1025 | static int acpi_thermal_trip_seq_show(struct seq_file *seq, void *offset) | ||
1026 | { | ||
1027 | struct acpi_thermal *tz = seq->private; | ||
1028 | struct acpi_device *device; | ||
1029 | acpi_status status; | ||
1030 | |||
1031 | int i = 0; | ||
1032 | int j = 0; | ||
1033 | |||
1034 | |||
1035 | if (!tz) | ||
1036 | goto end; | ||
1037 | |||
1038 | if (tz->trips.critical.flags.valid) | ||
1039 | seq_printf(seq, "critical (S5): %ld C%s", | ||
1040 | KELVIN_TO_CELSIUS(tz->trips.critical.temperature), | ||
1041 | nocrt ? " <disabled>\n" : "\n"); | ||
1042 | |||
1043 | if (tz->trips.hot.flags.valid) | ||
1044 | seq_printf(seq, "hot (S4): %ld C%s", | ||
1045 | KELVIN_TO_CELSIUS(tz->trips.hot.temperature), | ||
1046 | nocrt ? " <disabled>\n" : "\n"); | ||
1047 | |||
1048 | if (tz->trips.passive.flags.valid) { | ||
1049 | seq_printf(seq, | ||
1050 | "passive: %ld C: tc1=%lu tc2=%lu tsp=%lu devices=", | ||
1051 | KELVIN_TO_CELSIUS(tz->trips.passive.temperature), | ||
1052 | tz->trips.passive.tc1, tz->trips.passive.tc2, | ||
1053 | tz->trips.passive.tsp); | ||
1054 | for (j = 0; j < tz->trips.passive.devices.count; j++) { | ||
1055 | status = acpi_bus_get_device(tz->trips.passive.devices. | ||
1056 | handles[j], &device); | ||
1057 | seq_printf(seq, "%4.4s ", status ? "" : | ||
1058 | acpi_device_bid(device)); | ||
1059 | } | ||
1060 | seq_puts(seq, "\n"); | ||
1061 | } else { | ||
1062 | seq_printf(seq, "passive (forced):"); | ||
1063 | if (tz->thermal_zone->forced_passive) | ||
1064 | seq_printf(seq, " %i C\n", | ||
1065 | tz->thermal_zone->forced_passive / 1000); | ||
1066 | else | ||
1067 | seq_printf(seq, "<not set>\n"); | ||
1068 | } | ||
1069 | |||
1070 | for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { | ||
1071 | if (!(tz->trips.active[i].flags.valid)) | ||
1072 | break; | ||
1073 | seq_printf(seq, "active[%d]: %ld C: devices=", | ||
1074 | i, | ||
1075 | KELVIN_TO_CELSIUS(tz->trips.active[i].temperature)); | ||
1076 | for (j = 0; j < tz->trips.active[i].devices.count; j++){ | ||
1077 | status = acpi_bus_get_device(tz->trips.active[i]. | ||
1078 | devices.handles[j], | ||
1079 | &device); | ||
1080 | seq_printf(seq, "%4.4s ", status ? "" : | ||
1081 | acpi_device_bid(device)); | ||
1082 | } | ||
1083 | seq_puts(seq, "\n"); | ||
1084 | } | ||
1085 | |||
1086 | end: | ||
1087 | return 0; | ||
1088 | } | ||
1089 | |||
1090 | static int acpi_thermal_trip_open_fs(struct inode *inode, struct file *file) | ||
1091 | { | ||
1092 | return single_open(file, acpi_thermal_trip_seq_show, PDE(inode)->data); | ||
1093 | } | ||
1094 | |||
1095 | static int acpi_thermal_cooling_seq_show(struct seq_file *seq, void *offset) | ||
1096 | { | ||
1097 | struct acpi_thermal *tz = seq->private; | ||
1098 | |||
1099 | |||
1100 | if (!tz) | ||
1101 | goto end; | ||
1102 | |||
1103 | if (!tz->flags.cooling_mode) | ||
1104 | seq_puts(seq, "<setting not supported>\n"); | ||
1105 | else | ||
1106 | seq_puts(seq, "0 - Active; 1 - Passive\n"); | ||
1107 | |||
1108 | end: | ||
1109 | return 0; | ||
1110 | } | ||
1111 | |||
1112 | static int acpi_thermal_cooling_open_fs(struct inode *inode, struct file *file) | ||
1113 | { | ||
1114 | return single_open(file, acpi_thermal_cooling_seq_show, | ||
1115 | PDE(inode)->data); | ||
1116 | } | ||
1117 | |||
1118 | static ssize_t | ||
1119 | acpi_thermal_write_cooling_mode(struct file *file, | ||
1120 | const char __user * buffer, | ||
1121 | size_t count, loff_t * ppos) | ||
1122 | { | ||
1123 | struct seq_file *m = file->private_data; | ||
1124 | struct acpi_thermal *tz = m->private; | ||
1125 | int result = 0; | ||
1126 | char mode_string[12] = { '\0' }; | ||
1127 | |||
1128 | |||
1129 | if (!tz || (count > sizeof(mode_string) - 1)) | ||
1130 | return -EINVAL; | ||
1131 | |||
1132 | if (!tz->flags.cooling_mode) | ||
1133 | return -ENODEV; | ||
1134 | |||
1135 | if (copy_from_user(mode_string, buffer, count)) | ||
1136 | return -EFAULT; | ||
1137 | |||
1138 | mode_string[count] = '\0'; | ||
1139 | |||
1140 | result = acpi_thermal_set_cooling_mode(tz, | ||
1141 | simple_strtoul(mode_string, NULL, | ||
1142 | 0)); | ||
1143 | if (result) | ||
1144 | return result; | ||
1145 | |||
1146 | acpi_thermal_check(tz); | ||
1147 | |||
1148 | return count; | ||
1149 | } | ||
1150 | |||
1151 | static int acpi_thermal_polling_seq_show(struct seq_file *seq, void *offset) | ||
1152 | { | ||
1153 | struct acpi_thermal *tz = seq->private; | ||
1154 | |||
1155 | |||
1156 | if (!tz) | ||
1157 | goto end; | ||
1158 | |||
1159 | if (!tz->thermal_zone->polling_delay) { | ||
1160 | seq_puts(seq, "<polling disabled>\n"); | ||
1161 | goto end; | ||
1162 | } | ||
1163 | |||
1164 | seq_printf(seq, "polling frequency: %d seconds\n", | ||
1165 | (tz->thermal_zone->polling_delay / 1000)); | ||
1166 | |||
1167 | end: | ||
1168 | return 0; | ||
1169 | } | ||
1170 | |||
1171 | static int acpi_thermal_polling_open_fs(struct inode *inode, struct file *file) | ||
1172 | { | ||
1173 | return single_open(file, acpi_thermal_polling_seq_show, | ||
1174 | PDE(inode)->data); | ||
1175 | } | ||
1176 | |||
1177 | static int acpi_thermal_set_polling(struct acpi_thermal *tz, int seconds) | ||
1178 | { | ||
1179 | if (!tz) | ||
1180 | return -EINVAL; | ||
1181 | |||
1182 | /* Convert value to deci-seconds */ | ||
1183 | tz->polling_frequency = seconds * 10; | ||
1184 | |||
1185 | tz->thermal_zone->polling_delay = seconds * 1000; | ||
1186 | |||
1187 | if (tz->tz_enabled) | ||
1188 | thermal_zone_device_update(tz->thermal_zone); | ||
1189 | |||
1190 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
1191 | "Polling frequency set to %lu seconds\n", | ||
1192 | tz->polling_frequency/10)); | ||
1193 | |||
1194 | return 0; | ||
1195 | } | ||
1196 | |||
1197 | static ssize_t | ||
1198 | acpi_thermal_write_polling(struct file *file, | ||
1199 | const char __user * buffer, | ||
1200 | size_t count, loff_t * ppos) | ||
1201 | { | ||
1202 | struct seq_file *m = file->private_data; | ||
1203 | struct acpi_thermal *tz = m->private; | ||
1204 | int result = 0; | ||
1205 | char polling_string[12] = { '\0' }; | ||
1206 | int seconds = 0; | ||
1207 | |||
1208 | |||
1209 | if (!tz || (count > sizeof(polling_string) - 1)) | ||
1210 | return -EINVAL; | ||
1211 | |||
1212 | if (copy_from_user(polling_string, buffer, count)) | ||
1213 | return -EFAULT; | ||
1214 | |||
1215 | polling_string[count] = '\0'; | ||
1216 | |||
1217 | seconds = simple_strtoul(polling_string, NULL, 0); | ||
1218 | |||
1219 | result = acpi_thermal_set_polling(tz, seconds); | ||
1220 | if (result) | ||
1221 | return result; | ||
1222 | |||
1223 | acpi_thermal_check(tz); | ||
1224 | |||
1225 | return count; | ||
1226 | } | ||
1227 | |||
1228 | static int acpi_thermal_add_fs(struct acpi_device *device) | ||
1229 | { | ||
1230 | struct proc_dir_entry *entry = NULL; | ||
1231 | |||
1232 | |||
1233 | if (!acpi_device_dir(device)) { | ||
1234 | acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), | ||
1235 | acpi_thermal_dir); | ||
1236 | if (!acpi_device_dir(device)) | ||
1237 | return -ENODEV; | ||
1238 | } | ||
1239 | |||
1240 | /* 'state' [R] */ | ||
1241 | entry = proc_create_data(ACPI_THERMAL_FILE_STATE, | ||
1242 | S_IRUGO, acpi_device_dir(device), | ||
1243 | &acpi_thermal_state_fops, | ||
1244 | acpi_driver_data(device)); | ||
1245 | if (!entry) | ||
1246 | return -ENODEV; | ||
1247 | |||
1248 | /* 'temperature' [R] */ | ||
1249 | entry = proc_create_data(ACPI_THERMAL_FILE_TEMPERATURE, | ||
1250 | S_IRUGO, acpi_device_dir(device), | ||
1251 | &acpi_thermal_temp_fops, | ||
1252 | acpi_driver_data(device)); | ||
1253 | if (!entry) | ||
1254 | return -ENODEV; | ||
1255 | |||
1256 | /* 'trip_points' [R] */ | ||
1257 | entry = proc_create_data(ACPI_THERMAL_FILE_TRIP_POINTS, | ||
1258 | S_IRUGO, | ||
1259 | acpi_device_dir(device), | ||
1260 | &acpi_thermal_trip_fops, | ||
1261 | acpi_driver_data(device)); | ||
1262 | if (!entry) | ||
1263 | return -ENODEV; | ||
1264 | |||
1265 | /* 'cooling_mode' [R/W] */ | ||
1266 | entry = proc_create_data(ACPI_THERMAL_FILE_COOLING_MODE, | ||
1267 | S_IFREG | S_IRUGO | S_IWUSR, | ||
1268 | acpi_device_dir(device), | ||
1269 | &acpi_thermal_cooling_fops, | ||
1270 | acpi_driver_data(device)); | ||
1271 | if (!entry) | ||
1272 | return -ENODEV; | ||
1273 | |||
1274 | /* 'polling_frequency' [R/W] */ | ||
1275 | entry = proc_create_data(ACPI_THERMAL_FILE_POLLING_FREQ, | ||
1276 | S_IFREG | S_IRUGO | S_IWUSR, | ||
1277 | acpi_device_dir(device), | ||
1278 | &acpi_thermal_polling_fops, | ||
1279 | acpi_driver_data(device)); | ||
1280 | if (!entry) | ||
1281 | return -ENODEV; | ||
1282 | return 0; | ||
1283 | } | ||
1284 | |||
1285 | static int acpi_thermal_remove_fs(struct acpi_device *device) | ||
1286 | { | ||
1287 | |||
1288 | if (acpi_device_dir(device)) { | ||
1289 | remove_proc_entry(ACPI_THERMAL_FILE_POLLING_FREQ, | ||
1290 | acpi_device_dir(device)); | ||
1291 | remove_proc_entry(ACPI_THERMAL_FILE_COOLING_MODE, | ||
1292 | acpi_device_dir(device)); | ||
1293 | remove_proc_entry(ACPI_THERMAL_FILE_TRIP_POINTS, | ||
1294 | acpi_device_dir(device)); | ||
1295 | remove_proc_entry(ACPI_THERMAL_FILE_TEMPERATURE, | ||
1296 | acpi_device_dir(device)); | ||
1297 | remove_proc_entry(ACPI_THERMAL_FILE_STATE, | ||
1298 | acpi_device_dir(device)); | ||
1299 | remove_proc_entry(acpi_device_bid(device), acpi_thermal_dir); | ||
1300 | acpi_device_dir(device) = NULL; | ||
1301 | } | ||
1302 | |||
1303 | return 0; | ||
1304 | } | ||
1305 | #else | ||
1306 | static inline int acpi_thermal_add_fs(struct acpi_device *device) { return 0; } | ||
1307 | static inline int acpi_thermal_remove_fs(struct acpi_device *device) | ||
1308 | { | ||
1309 | return 0; | ||
1310 | } | ||
1311 | #endif /* CONFIG_ACPI_PROCFS */ | ||
1312 | /* -------------------------------------------------------------------------- | ||
1313 | Driver Interface | 900 | Driver Interface |
1314 | -------------------------------------------------------------------------- */ | 901 | -------------------------------------------------------------------------- */ |
1315 | 902 | ||
@@ -1428,17 +1015,11 @@ static int acpi_thermal_add(struct acpi_device *device) | |||
1428 | if (result) | 1015 | if (result) |
1429 | goto free_memory; | 1016 | goto free_memory; |
1430 | 1017 | ||
1431 | result = acpi_thermal_add_fs(device); | ||
1432 | if (result) | ||
1433 | goto unregister_thermal_zone; | ||
1434 | |||
1435 | printk(KERN_INFO PREFIX "%s [%s] (%ld C)\n", | 1018 | printk(KERN_INFO PREFIX "%s [%s] (%ld C)\n", |
1436 | acpi_device_name(device), acpi_device_bid(device), | 1019 | acpi_device_name(device), acpi_device_bid(device), |
1437 | KELVIN_TO_CELSIUS(tz->temperature)); | 1020 | KELVIN_TO_CELSIUS(tz->temperature)); |
1438 | goto end; | 1021 | goto end; |
1439 | 1022 | ||
1440 | unregister_thermal_zone: | ||
1441 | thermal_zone_device_unregister(tz->thermal_zone); | ||
1442 | free_memory: | 1023 | free_memory: |
1443 | kfree(tz); | 1024 | kfree(tz); |
1444 | end: | 1025 | end: |
@@ -1454,7 +1035,6 @@ static int acpi_thermal_remove(struct acpi_device *device, int type) | |||
1454 | 1035 | ||
1455 | tz = acpi_driver_data(device); | 1036 | tz = acpi_driver_data(device); |
1456 | 1037 | ||
1457 | acpi_thermal_remove_fs(device); | ||
1458 | acpi_thermal_unregister_thermal_zone(tz); | 1038 | acpi_thermal_unregister_thermal_zone(tz); |
1459 | mutex_destroy(&tz->lock); | 1039 | mutex_destroy(&tz->lock); |
1460 | kfree(tz); | 1040 | kfree(tz); |
@@ -1580,19 +1160,9 @@ static int __init acpi_thermal_init(void) | |||
1580 | return -ENODEV; | 1160 | return -ENODEV; |
1581 | } | 1161 | } |
1582 | 1162 | ||
1583 | #ifdef CONFIG_ACPI_PROCFS | ||
1584 | acpi_thermal_dir = proc_mkdir(ACPI_THERMAL_CLASS, acpi_root_dir); | ||
1585 | if (!acpi_thermal_dir) | ||
1586 | return -ENODEV; | ||
1587 | #endif | ||
1588 | |||
1589 | result = acpi_bus_register_driver(&acpi_thermal_driver); | 1163 | result = acpi_bus_register_driver(&acpi_thermal_driver); |
1590 | if (result < 0) { | 1164 | if (result < 0) |
1591 | #ifdef CONFIG_ACPI_PROCFS | ||
1592 | remove_proc_entry(ACPI_THERMAL_CLASS, acpi_root_dir); | ||
1593 | #endif | ||
1594 | return -ENODEV; | 1165 | return -ENODEV; |
1595 | } | ||
1596 | 1166 | ||
1597 | return 0; | 1167 | return 0; |
1598 | } | 1168 | } |
@@ -1602,10 +1172,6 @@ static void __exit acpi_thermal_exit(void) | |||
1602 | 1172 | ||
1603 | acpi_bus_unregister_driver(&acpi_thermal_driver); | 1173 | acpi_bus_unregister_driver(&acpi_thermal_driver); |
1604 | 1174 | ||
1605 | #ifdef CONFIG_ACPI_PROCFS | ||
1606 | remove_proc_entry(ACPI_THERMAL_CLASS, acpi_root_dir); | ||
1607 | #endif | ||
1608 | |||
1609 | return; | 1175 | return; |
1610 | } | 1176 | } |
1611 | 1177 | ||
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 67dec0c675a..5cd0228d2da 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c | |||
@@ -30,8 +30,6 @@ | |||
30 | #include <linux/types.h> | 30 | #include <linux/types.h> |
31 | #include <linux/list.h> | 31 | #include <linux/list.h> |
32 | #include <linux/mutex.h> | 32 | #include <linux/mutex.h> |
33 | #include <linux/proc_fs.h> | ||
34 | #include <linux/seq_file.h> | ||
35 | #include <linux/input.h> | 33 | #include <linux/input.h> |
36 | #include <linux/backlight.h> | 34 | #include <linux/backlight.h> |
37 | #include <linux/thermal.h> | 35 | #include <linux/thermal.h> |
@@ -152,9 +150,6 @@ struct acpi_video_bus { | |||
152 | struct acpi_video_bus_flags flags; | 150 | struct acpi_video_bus_flags flags; |
153 | struct list_head video_device_list; | 151 | struct list_head video_device_list; |
154 | struct mutex device_list_lock; /* protects video_device_list */ | 152 | struct mutex device_list_lock; /* protects video_device_list */ |
155 | #ifdef CONFIG_ACPI_PROCFS | ||
156 | struct proc_dir_entry *dir; | ||
157 | #endif | ||
158 | struct input_dev *input; | 153 | struct input_dev *input; |
159 | char phys[32]; /* for input device */ | 154 | char phys[32]; /* for input device */ |
160 | struct notifier_block pm_nb; | 155 | struct notifier_block pm_nb; |
@@ -210,108 +205,6 @@ struct acpi_video_device { | |||
210 | struct output_device *output_dev; | 205 | struct output_device *output_dev; |
211 | }; | 206 | }; |
212 | 207 | ||
213 | #ifdef CONFIG_ACPI_PROCFS | ||
214 | /* bus */ | ||
215 | static int acpi_video_bus_info_open_fs(struct inode *inode, struct file *file); | ||
216 | static const struct file_operations acpi_video_bus_info_fops = { | ||
217 | .owner = THIS_MODULE, | ||
218 | .open = acpi_video_bus_info_open_fs, | ||
219 | .read = seq_read, | ||
220 | .llseek = seq_lseek, | ||
221 | .release = single_release, | ||
222 | }; | ||
223 | |||
224 | static int acpi_video_bus_ROM_open_fs(struct inode *inode, struct file *file); | ||
225 | static const struct file_operations acpi_video_bus_ROM_fops = { | ||
226 | .owner = THIS_MODULE, | ||
227 | .open = acpi_video_bus_ROM_open_fs, | ||
228 | .read = seq_read, | ||
229 | .llseek = seq_lseek, | ||
230 | .release = single_release, | ||
231 | }; | ||
232 | |||
233 | static int acpi_video_bus_POST_info_open_fs(struct inode *inode, | ||
234 | struct file *file); | ||
235 | static const struct file_operations acpi_video_bus_POST_info_fops = { | ||
236 | .owner = THIS_MODULE, | ||
237 | .open = acpi_video_bus_POST_info_open_fs, | ||
238 | .read = seq_read, | ||
239 | .llseek = seq_lseek, | ||
240 | .release = single_release, | ||
241 | }; | ||
242 | |||
243 | static int acpi_video_bus_POST_open_fs(struct inode *inode, struct file *file); | ||
244 | static ssize_t acpi_video_bus_write_POST(struct file *file, | ||
245 | const char __user *buffer, size_t count, loff_t *data); | ||
246 | static const struct file_operations acpi_video_bus_POST_fops = { | ||
247 | .owner = THIS_MODULE, | ||
248 | .open = acpi_video_bus_POST_open_fs, | ||
249 | .read = seq_read, | ||
250 | .write = acpi_video_bus_write_POST, | ||
251 | .llseek = seq_lseek, | ||
252 | .release = single_release, | ||
253 | }; | ||
254 | |||
255 | static int acpi_video_bus_DOS_open_fs(struct inode *inode, struct file *file); | ||
256 | static ssize_t acpi_video_bus_write_DOS(struct file *file, | ||
257 | const char __user *buffer, size_t count, loff_t *data); | ||
258 | static const struct file_operations acpi_video_bus_DOS_fops = { | ||
259 | .owner = THIS_MODULE, | ||
260 | .open = acpi_video_bus_DOS_open_fs, | ||
261 | .read = seq_read, | ||
262 | .write = acpi_video_bus_write_DOS, | ||
263 | .llseek = seq_lseek, | ||
264 | .release = single_release, | ||
265 | }; | ||
266 | |||
267 | /* device */ | ||
268 | static int acpi_video_device_info_open_fs(struct inode *inode, | ||
269 | struct file *file); | ||
270 | static const struct file_operations acpi_video_device_info_fops = { | ||
271 | .owner = THIS_MODULE, | ||
272 | .open = acpi_video_device_info_open_fs, | ||
273 | .read = seq_read, | ||
274 | .llseek = seq_lseek, | ||
275 | .release = single_release, | ||
276 | }; | ||
277 | |||
278 | static int acpi_video_device_state_open_fs(struct inode *inode, | ||
279 | struct file *file); | ||
280 | static ssize_t acpi_video_device_write_state(struct file *file, | ||
281 | const char __user *buffer, size_t count, loff_t *data); | ||
282 | static const struct file_operations acpi_video_device_state_fops = { | ||
283 | .owner = THIS_MODULE, | ||
284 | .open = acpi_video_device_state_open_fs, | ||
285 | .read = seq_read, | ||
286 | .write = acpi_video_device_write_state, | ||
287 | .llseek = seq_lseek, | ||
288 | .release = single_release, | ||
289 | }; | ||
290 | |||
291 | static int acpi_video_device_brightness_open_fs(struct inode *inode, | ||
292 | struct file *file); | ||
293 | static ssize_t acpi_video_device_write_brightness(struct file *file, | ||
294 | const char __user *buffer, size_t count, loff_t *data); | ||
295 | static const struct file_operations acpi_video_device_brightness_fops = { | ||
296 | .owner = THIS_MODULE, | ||
297 | .open = acpi_video_device_brightness_open_fs, | ||
298 | .read = seq_read, | ||
299 | .write = acpi_video_device_write_brightness, | ||
300 | .llseek = seq_lseek, | ||
301 | .release = single_release, | ||
302 | }; | ||
303 | |||
304 | static int acpi_video_device_EDID_open_fs(struct inode *inode, | ||
305 | struct file *file); | ||
306 | static const struct file_operations acpi_video_device_EDID_fops = { | ||
307 | .owner = THIS_MODULE, | ||
308 | .open = acpi_video_device_EDID_open_fs, | ||
309 | .read = seq_read, | ||
310 | .llseek = seq_lseek, | ||
311 | .release = single_release, | ||
312 | }; | ||
313 | #endif /* CONFIG_ACPI_PROCFS */ | ||
314 | |||
315 | static const char device_decode[][30] = { | 208 | static const char device_decode[][30] = { |
316 | "motherboard VGA device", | 209 | "motherboard VGA device", |
317 | "PCI VGA device", | 210 | "PCI VGA device", |
@@ -1111,646 +1004,6 @@ static int acpi_video_bus_check(struct acpi_video_bus *video) | |||
1111 | } | 1004 | } |
1112 | 1005 | ||
1113 | /* -------------------------------------------------------------------------- | 1006 | /* -------------------------------------------------------------------------- |
1114 | FS Interface (/proc) | ||
1115 | -------------------------------------------------------------------------- */ | ||
1116 | #ifdef CONFIG_ACPI_PROCFS | ||
1117 | |||
1118 | static struct proc_dir_entry *acpi_video_dir; | ||
1119 | |||
1120 | /* video devices */ | ||
1121 | |||
1122 | static int acpi_video_device_info_seq_show(struct seq_file *seq, void *offset) | ||
1123 | { | ||
1124 | struct acpi_video_device *dev = seq->private; | ||
1125 | |||
1126 | |||
1127 | if (!dev) | ||
1128 | goto end; | ||
1129 | |||
1130 | seq_printf(seq, "device_id: 0x%04x\n", (u32) dev->device_id); | ||
1131 | seq_printf(seq, "type: "); | ||
1132 | if (dev->flags.crt) | ||
1133 | seq_printf(seq, "CRT\n"); | ||
1134 | else if (dev->flags.lcd) | ||
1135 | seq_printf(seq, "LCD\n"); | ||
1136 | else if (dev->flags.tvout) | ||
1137 | seq_printf(seq, "TVOUT\n"); | ||
1138 | else if (dev->flags.dvi) | ||
1139 | seq_printf(seq, "DVI\n"); | ||
1140 | else | ||
1141 | seq_printf(seq, "UNKNOWN\n"); | ||
1142 | |||
1143 | seq_printf(seq, "known by bios: %s\n", dev->flags.bios ? "yes" : "no"); | ||
1144 | |||
1145 | end: | ||
1146 | return 0; | ||
1147 | } | ||
1148 | |||
1149 | static int | ||
1150 | acpi_video_device_info_open_fs(struct inode *inode, struct file *file) | ||
1151 | { | ||
1152 | return single_open(file, acpi_video_device_info_seq_show, | ||
1153 | PDE(inode)->data); | ||
1154 | } | ||
1155 | |||
1156 | static int | ||
1157 | acpi_video_device_query(struct acpi_video_device *device, | ||
1158 | unsigned long long *state) | ||
1159 | { | ||
1160 | int status; | ||
1161 | |||
1162 | status = acpi_evaluate_integer(device->dev->handle, "_DGS", | ||
1163 | NULL, state); | ||
1164 | |||
1165 | return status; | ||
1166 | } | ||
1167 | |||
1168 | static int acpi_video_device_state_seq_show(struct seq_file *seq, void *offset) | ||
1169 | { | ||
1170 | int status; | ||
1171 | struct acpi_video_device *dev = seq->private; | ||
1172 | unsigned long long state; | ||
1173 | |||
1174 | |||
1175 | if (!dev) | ||
1176 | goto end; | ||
1177 | |||
1178 | status = acpi_video_device_get_state(dev, &state); | ||
1179 | seq_printf(seq, "state: "); | ||
1180 | if (ACPI_SUCCESS(status)) | ||
1181 | seq_printf(seq, "0x%02llx\n", state); | ||
1182 | else | ||
1183 | seq_printf(seq, "<not supported>\n"); | ||
1184 | |||
1185 | status = acpi_video_device_query(dev, &state); | ||
1186 | seq_printf(seq, "query: "); | ||
1187 | if (ACPI_SUCCESS(status)) | ||
1188 | seq_printf(seq, "0x%02llx\n", state); | ||
1189 | else | ||
1190 | seq_printf(seq, "<not supported>\n"); | ||
1191 | |||
1192 | end: | ||
1193 | return 0; | ||
1194 | } | ||
1195 | |||
1196 | static int | ||
1197 | acpi_video_device_state_open_fs(struct inode *inode, struct file *file) | ||
1198 | { | ||
1199 | return single_open(file, acpi_video_device_state_seq_show, | ||
1200 | PDE(inode)->data); | ||
1201 | } | ||
1202 | |||
1203 | static ssize_t | ||
1204 | acpi_video_device_write_state(struct file *file, | ||
1205 | const char __user * buffer, | ||
1206 | size_t count, loff_t * data) | ||
1207 | { | ||
1208 | int status; | ||
1209 | struct seq_file *m = file->private_data; | ||
1210 | struct acpi_video_device *dev = m->private; | ||
1211 | char str[12] = { 0 }; | ||
1212 | u32 state = 0; | ||
1213 | |||
1214 | |||
1215 | if (!dev || count >= sizeof(str)) | ||
1216 | return -EINVAL; | ||
1217 | |||
1218 | if (copy_from_user(str, buffer, count)) | ||
1219 | return -EFAULT; | ||
1220 | |||
1221 | str[count] = 0; | ||
1222 | state = simple_strtoul(str, NULL, 0); | ||
1223 | state &= ((1ul << 31) | (1ul << 30) | (1ul << 0)); | ||
1224 | |||
1225 | status = acpi_video_device_set_state(dev, state); | ||
1226 | |||
1227 | if (status) | ||
1228 | return -EFAULT; | ||
1229 | |||
1230 | return count; | ||
1231 | } | ||
1232 | |||
1233 | static int | ||
1234 | acpi_video_device_brightness_seq_show(struct seq_file *seq, void *offset) | ||
1235 | { | ||
1236 | struct acpi_video_device *dev = seq->private; | ||
1237 | int i; | ||
1238 | |||
1239 | |||
1240 | if (!dev || !dev->brightness) { | ||
1241 | seq_printf(seq, "<not supported>\n"); | ||
1242 | return 0; | ||
1243 | } | ||
1244 | |||
1245 | seq_printf(seq, "levels: "); | ||
1246 | for (i = 2; i < dev->brightness->count; i++) | ||
1247 | seq_printf(seq, " %d", dev->brightness->levels[i]); | ||
1248 | seq_printf(seq, "\ncurrent: %d\n", dev->brightness->curr); | ||
1249 | |||
1250 | return 0; | ||
1251 | } | ||
1252 | |||
1253 | static int | ||
1254 | acpi_video_device_brightness_open_fs(struct inode *inode, struct file *file) | ||
1255 | { | ||
1256 | return single_open(file, acpi_video_device_brightness_seq_show, | ||
1257 | PDE(inode)->data); | ||
1258 | } | ||
1259 | |||
1260 | static ssize_t | ||
1261 | acpi_video_device_write_brightness(struct file *file, | ||
1262 | const char __user * buffer, | ||
1263 | size_t count, loff_t * data) | ||
1264 | { | ||
1265 | struct seq_file *m = file->private_data; | ||
1266 | struct acpi_video_device *dev = m->private; | ||
1267 | char str[5] = { 0 }; | ||
1268 | unsigned int level = 0; | ||
1269 | int i; | ||
1270 | |||
1271 | |||
1272 | if (!dev || !dev->brightness || count >= sizeof(str)) | ||
1273 | return -EINVAL; | ||
1274 | |||
1275 | if (copy_from_user(str, buffer, count)) | ||
1276 | return -EFAULT; | ||
1277 | |||
1278 | str[count] = 0; | ||
1279 | level = simple_strtoul(str, NULL, 0); | ||
1280 | |||
1281 | if (level > 100) | ||
1282 | return -EFAULT; | ||
1283 | |||
1284 | /* validate through the list of available levels */ | ||
1285 | for (i = 2; i < dev->brightness->count; i++) | ||
1286 | if (level == dev->brightness->levels[i]) { | ||
1287 | if (!acpi_video_device_lcd_set_level(dev, level)) | ||
1288 | return count; | ||
1289 | break; | ||
1290 | } | ||
1291 | |||
1292 | return -EINVAL; | ||
1293 | } | ||
1294 | |||
1295 | static int acpi_video_device_EDID_seq_show(struct seq_file *seq, void *offset) | ||
1296 | { | ||
1297 | struct acpi_video_device *dev = seq->private; | ||
1298 | int status; | ||
1299 | int i; | ||
1300 | union acpi_object *edid = NULL; | ||
1301 | |||
1302 | |||
1303 | if (!dev) | ||
1304 | goto out; | ||
1305 | |||
1306 | status = acpi_video_device_EDID(dev, &edid, 128); | ||
1307 | if (ACPI_FAILURE(status)) { | ||
1308 | status = acpi_video_device_EDID(dev, &edid, 256); | ||
1309 | } | ||
1310 | |||
1311 | if (ACPI_FAILURE(status)) { | ||
1312 | goto out; | ||
1313 | } | ||
1314 | |||
1315 | if (edid && edid->type == ACPI_TYPE_BUFFER) { | ||
1316 | for (i = 0; i < edid->buffer.length; i++) | ||
1317 | seq_putc(seq, edid->buffer.pointer[i]); | ||
1318 | } | ||
1319 | |||
1320 | out: | ||
1321 | if (!edid) | ||
1322 | seq_printf(seq, "<not supported>\n"); | ||
1323 | else | ||
1324 | kfree(edid); | ||
1325 | |||
1326 | return 0; | ||
1327 | } | ||
1328 | |||
1329 | static int | ||
1330 | acpi_video_device_EDID_open_fs(struct inode *inode, struct file *file) | ||
1331 | { | ||
1332 | return single_open(file, acpi_video_device_EDID_seq_show, | ||
1333 | PDE(inode)->data); | ||
1334 | } | ||
1335 | |||
1336 | static int acpi_video_device_add_fs(struct acpi_device *device) | ||
1337 | { | ||
1338 | struct proc_dir_entry *entry, *device_dir; | ||
1339 | struct acpi_video_device *vid_dev; | ||
1340 | |||
1341 | vid_dev = acpi_driver_data(device); | ||
1342 | if (!vid_dev) | ||
1343 | return -ENODEV; | ||
1344 | |||
1345 | device_dir = proc_mkdir(acpi_device_bid(device), | ||
1346 | vid_dev->video->dir); | ||
1347 | if (!device_dir) | ||
1348 | return -ENOMEM; | ||
1349 | |||
1350 | /* 'info' [R] */ | ||
1351 | entry = proc_create_data("info", S_IRUGO, device_dir, | ||
1352 | &acpi_video_device_info_fops, acpi_driver_data(device)); | ||
1353 | if (!entry) | ||
1354 | goto err_remove_dir; | ||
1355 | |||
1356 | /* 'state' [R/W] */ | ||
1357 | entry = proc_create_data("state", S_IFREG | S_IRUGO | S_IWUSR, | ||
1358 | device_dir, | ||
1359 | &acpi_video_device_state_fops, | ||
1360 | acpi_driver_data(device)); | ||
1361 | if (!entry) | ||
1362 | goto err_remove_info; | ||
1363 | |||
1364 | /* 'brightness' [R/W] */ | ||
1365 | entry = proc_create_data("brightness", S_IFREG | S_IRUGO | S_IWUSR, | ||
1366 | device_dir, | ||
1367 | &acpi_video_device_brightness_fops, | ||
1368 | acpi_driver_data(device)); | ||
1369 | if (!entry) | ||
1370 | goto err_remove_state; | ||
1371 | |||
1372 | /* 'EDID' [R] */ | ||
1373 | entry = proc_create_data("EDID", S_IRUGO, device_dir, | ||
1374 | &acpi_video_device_EDID_fops, | ||
1375 | acpi_driver_data(device)); | ||
1376 | if (!entry) | ||
1377 | goto err_remove_brightness; | ||
1378 | |||
1379 | acpi_device_dir(device) = device_dir; | ||
1380 | |||
1381 | return 0; | ||
1382 | |||
1383 | err_remove_brightness: | ||
1384 | remove_proc_entry("brightness", device_dir); | ||
1385 | err_remove_state: | ||
1386 | remove_proc_entry("state", device_dir); | ||
1387 | err_remove_info: | ||
1388 | remove_proc_entry("info", device_dir); | ||
1389 | err_remove_dir: | ||
1390 | remove_proc_entry(acpi_device_bid(device), vid_dev->video->dir); | ||
1391 | return -ENOMEM; | ||
1392 | } | ||
1393 | |||
1394 | static int acpi_video_device_remove_fs(struct acpi_device *device) | ||
1395 | { | ||
1396 | struct acpi_video_device *vid_dev; | ||
1397 | struct proc_dir_entry *device_dir; | ||
1398 | |||
1399 | vid_dev = acpi_driver_data(device); | ||
1400 | if (!vid_dev || !vid_dev->video || !vid_dev->video->dir) | ||
1401 | return -ENODEV; | ||
1402 | |||
1403 | device_dir = acpi_device_dir(device); | ||
1404 | if (device_dir) { | ||
1405 | remove_proc_entry("info", device_dir); | ||
1406 | remove_proc_entry("state", device_dir); | ||
1407 | remove_proc_entry("brightness", device_dir); | ||
1408 | remove_proc_entry("EDID", device_dir); | ||
1409 | remove_proc_entry(acpi_device_bid(device), vid_dev->video->dir); | ||
1410 | acpi_device_dir(device) = NULL; | ||
1411 | } | ||
1412 | |||
1413 | return 0; | ||
1414 | } | ||
1415 | |||
1416 | /* video bus */ | ||
1417 | static int acpi_video_bus_info_seq_show(struct seq_file *seq, void *offset) | ||
1418 | { | ||
1419 | struct acpi_video_bus *video = seq->private; | ||
1420 | |||
1421 | |||
1422 | if (!video) | ||
1423 | goto end; | ||
1424 | |||
1425 | seq_printf(seq, "Switching heads: %s\n", | ||
1426 | video->flags.multihead ? "yes" : "no"); | ||
1427 | seq_printf(seq, "Video ROM: %s\n", | ||
1428 | video->flags.rom ? "yes" : "no"); | ||
1429 | seq_printf(seq, "Device to be POSTed on boot: %s\n", | ||
1430 | video->flags.post ? "yes" : "no"); | ||
1431 | |||
1432 | end: | ||
1433 | return 0; | ||
1434 | } | ||
1435 | |||
1436 | static int acpi_video_bus_info_open_fs(struct inode *inode, struct file *file) | ||
1437 | { | ||
1438 | return single_open(file, acpi_video_bus_info_seq_show, | ||
1439 | PDE(inode)->data); | ||
1440 | } | ||
1441 | |||
1442 | static int acpi_video_bus_ROM_seq_show(struct seq_file *seq, void *offset) | ||
1443 | { | ||
1444 | struct acpi_video_bus *video = seq->private; | ||
1445 | |||
1446 | |||
1447 | if (!video) | ||
1448 | goto end; | ||
1449 | |||
1450 | printk(KERN_INFO PREFIX "Please implement %s\n", __func__); | ||
1451 | seq_printf(seq, "<TODO>\n"); | ||
1452 | |||
1453 | end: | ||
1454 | return 0; | ||
1455 | } | ||
1456 | |||
1457 | static int acpi_video_bus_ROM_open_fs(struct inode *inode, struct file *file) | ||
1458 | { | ||
1459 | return single_open(file, acpi_video_bus_ROM_seq_show, PDE(inode)->data); | ||
1460 | } | ||
1461 | |||
1462 | static int | ||
1463 | acpi_video_bus_POST_options(struct acpi_video_bus *video, | ||
1464 | unsigned long long *options) | ||
1465 | { | ||
1466 | int status; | ||
1467 | |||
1468 | status = acpi_evaluate_integer(video->device->handle, "_VPO", | ||
1469 | NULL, options); | ||
1470 | *options &= 3; | ||
1471 | |||
1472 | return status; | ||
1473 | } | ||
1474 | |||
1475 | static int acpi_video_bus_POST_info_seq_show(struct seq_file *seq, void *offset) | ||
1476 | { | ||
1477 | struct acpi_video_bus *video = seq->private; | ||
1478 | unsigned long long options; | ||
1479 | int status; | ||
1480 | |||
1481 | |||
1482 | if (!video) | ||
1483 | goto end; | ||
1484 | |||
1485 | status = acpi_video_bus_POST_options(video, &options); | ||
1486 | if (ACPI_SUCCESS(status)) { | ||
1487 | if (!(options & 1)) { | ||
1488 | printk(KERN_WARNING PREFIX | ||
1489 | "The motherboard VGA device is not listed as a possible POST device.\n"); | ||
1490 | printk(KERN_WARNING PREFIX | ||
1491 | "This indicates a BIOS bug. Please contact the manufacturer.\n"); | ||
1492 | } | ||
1493 | printk(KERN_WARNING "%llx\n", options); | ||
1494 | seq_printf(seq, "can POST: <integrated video>"); | ||
1495 | if (options & 2) | ||
1496 | seq_printf(seq, " <PCI video>"); | ||
1497 | if (options & 4) | ||
1498 | seq_printf(seq, " <AGP video>"); | ||
1499 | seq_putc(seq, '\n'); | ||
1500 | } else | ||
1501 | seq_printf(seq, "<not supported>\n"); | ||
1502 | end: | ||
1503 | return 0; | ||
1504 | } | ||
1505 | |||
1506 | static int | ||
1507 | acpi_video_bus_POST_info_open_fs(struct inode *inode, struct file *file) | ||
1508 | { | ||
1509 | return single_open(file, acpi_video_bus_POST_info_seq_show, | ||
1510 | PDE(inode)->data); | ||
1511 | } | ||
1512 | |||
1513 | static int | ||
1514 | acpi_video_bus_get_POST(struct acpi_video_bus *video, unsigned long long *id) | ||
1515 | { | ||
1516 | int status; | ||
1517 | |||
1518 | status = acpi_evaluate_integer(video->device->handle, "_GPD", NULL, id); | ||
1519 | |||
1520 | return status; | ||
1521 | } | ||
1522 | |||
1523 | static int acpi_video_bus_POST_seq_show(struct seq_file *seq, void *offset) | ||
1524 | { | ||
1525 | struct acpi_video_bus *video = seq->private; | ||
1526 | int status; | ||
1527 | unsigned long long id; | ||
1528 | |||
1529 | |||
1530 | if (!video) | ||
1531 | goto end; | ||
1532 | |||
1533 | status = acpi_video_bus_get_POST(video, &id); | ||
1534 | if (!ACPI_SUCCESS(status)) { | ||
1535 | seq_printf(seq, "<not supported>\n"); | ||
1536 | goto end; | ||
1537 | } | ||
1538 | seq_printf(seq, "device POSTed is <%s>\n", device_decode[id & 3]); | ||
1539 | |||
1540 | end: | ||
1541 | return 0; | ||
1542 | } | ||
1543 | |||
1544 | static int acpi_video_bus_DOS_seq_show(struct seq_file *seq, void *offset) | ||
1545 | { | ||
1546 | struct acpi_video_bus *video = seq->private; | ||
1547 | |||
1548 | |||
1549 | seq_printf(seq, "DOS setting: <%d>\n", video->dos_setting); | ||
1550 | |||
1551 | return 0; | ||
1552 | } | ||
1553 | |||
1554 | static int acpi_video_bus_POST_open_fs(struct inode *inode, struct file *file) | ||
1555 | { | ||
1556 | return single_open(file, acpi_video_bus_POST_seq_show, | ||
1557 | PDE(inode)->data); | ||
1558 | } | ||
1559 | |||
1560 | static int acpi_video_bus_DOS_open_fs(struct inode *inode, struct file *file) | ||
1561 | { | ||
1562 | return single_open(file, acpi_video_bus_DOS_seq_show, PDE(inode)->data); | ||
1563 | } | ||
1564 | |||
1565 | static int | ||
1566 | acpi_video_bus_set_POST(struct acpi_video_bus *video, unsigned long option) | ||
1567 | { | ||
1568 | int status; | ||
1569 | unsigned long long tmp; | ||
1570 | union acpi_object arg0 = { ACPI_TYPE_INTEGER }; | ||
1571 | struct acpi_object_list args = { 1, &arg0 }; | ||
1572 | |||
1573 | |||
1574 | arg0.integer.value = option; | ||
1575 | |||
1576 | status = acpi_evaluate_integer(video->device->handle, "_SPD", | ||
1577 | &args, &tmp); | ||
1578 | if (ACPI_SUCCESS(status)) | ||
1579 | status = tmp ? (-EINVAL) : (AE_OK); | ||
1580 | |||
1581 | return status; | ||
1582 | } | ||
1583 | |||
1584 | static ssize_t | ||
1585 | acpi_video_bus_write_POST(struct file *file, | ||
1586 | const char __user * buffer, | ||
1587 | size_t count, loff_t * data) | ||
1588 | { | ||
1589 | int status; | ||
1590 | struct seq_file *m = file->private_data; | ||
1591 | struct acpi_video_bus *video = m->private; | ||
1592 | char str[12] = { 0 }; | ||
1593 | unsigned long long opt, options; | ||
1594 | |||
1595 | |||
1596 | if (!video || count >= sizeof(str)) | ||
1597 | return -EINVAL; | ||
1598 | |||
1599 | status = acpi_video_bus_POST_options(video, &options); | ||
1600 | if (!ACPI_SUCCESS(status)) | ||
1601 | return -EINVAL; | ||
1602 | |||
1603 | if (copy_from_user(str, buffer, count)) | ||
1604 | return -EFAULT; | ||
1605 | |||
1606 | str[count] = 0; | ||
1607 | opt = strtoul(str, NULL, 0); | ||
1608 | if (opt > 3) | ||
1609 | return -EFAULT; | ||
1610 | |||
1611 | /* just in case an OEM 'forgot' the motherboard... */ | ||
1612 | options |= 1; | ||
1613 | |||
1614 | if (options & (1ul << opt)) { | ||
1615 | status = acpi_video_bus_set_POST(video, opt); | ||
1616 | if (!ACPI_SUCCESS(status)) | ||
1617 | return -EFAULT; | ||
1618 | |||
1619 | } | ||
1620 | |||
1621 | return count; | ||
1622 | } | ||
1623 | |||
1624 | static ssize_t | ||
1625 | acpi_video_bus_write_DOS(struct file *file, | ||
1626 | const char __user * buffer, | ||
1627 | size_t count, loff_t * data) | ||
1628 | { | ||
1629 | int status; | ||
1630 | struct seq_file *m = file->private_data; | ||
1631 | struct acpi_video_bus *video = m->private; | ||
1632 | char str[12] = { 0 }; | ||
1633 | unsigned long opt; | ||
1634 | |||
1635 | |||
1636 | if (!video || count >= sizeof(str)) | ||
1637 | return -EINVAL; | ||
1638 | |||
1639 | if (copy_from_user(str, buffer, count)) | ||
1640 | return -EFAULT; | ||
1641 | |||
1642 | str[count] = 0; | ||
1643 | opt = strtoul(str, NULL, 0); | ||
1644 | if (opt > 7) | ||
1645 | return -EFAULT; | ||
1646 | |||
1647 | status = acpi_video_bus_DOS(video, opt & 0x3, (opt & 0x4) >> 2); | ||
1648 | |||
1649 | if (!ACPI_SUCCESS(status)) | ||
1650 | return -EFAULT; | ||
1651 | |||
1652 | return count; | ||
1653 | } | ||
1654 | |||
1655 | static int acpi_video_bus_add_fs(struct acpi_device *device) | ||
1656 | { | ||
1657 | struct acpi_video_bus *video = acpi_driver_data(device); | ||
1658 | struct proc_dir_entry *device_dir; | ||
1659 | struct proc_dir_entry *entry; | ||
1660 | |||
1661 | device_dir = proc_mkdir(acpi_device_bid(device), acpi_video_dir); | ||
1662 | if (!device_dir) | ||
1663 | return -ENOMEM; | ||
1664 | |||
1665 | /* 'info' [R] */ | ||
1666 | entry = proc_create_data("info", S_IRUGO, device_dir, | ||
1667 | &acpi_video_bus_info_fops, | ||
1668 | acpi_driver_data(device)); | ||
1669 | if (!entry) | ||
1670 | goto err_remove_dir; | ||
1671 | |||
1672 | /* 'ROM' [R] */ | ||
1673 | entry = proc_create_data("ROM", S_IRUGO, device_dir, | ||
1674 | &acpi_video_bus_ROM_fops, | ||
1675 | acpi_driver_data(device)); | ||
1676 | if (!entry) | ||
1677 | goto err_remove_info; | ||
1678 | |||
1679 | /* 'POST_info' [R] */ | ||
1680 | entry = proc_create_data("POST_info", S_IRUGO, device_dir, | ||
1681 | &acpi_video_bus_POST_info_fops, | ||
1682 | acpi_driver_data(device)); | ||
1683 | if (!entry) | ||
1684 | goto err_remove_rom; | ||
1685 | |||
1686 | /* 'POST' [R/W] */ | ||
1687 | entry = proc_create_data("POST", S_IFREG | S_IRUGO | S_IWUSR, | ||
1688 | device_dir, | ||
1689 | &acpi_video_bus_POST_fops, | ||
1690 | acpi_driver_data(device)); | ||
1691 | if (!entry) | ||
1692 | goto err_remove_post_info; | ||
1693 | |||
1694 | /* 'DOS' [R/W] */ | ||
1695 | entry = proc_create_data("DOS", S_IFREG | S_IRUGO | S_IWUSR, | ||
1696 | device_dir, | ||
1697 | &acpi_video_bus_DOS_fops, | ||
1698 | acpi_driver_data(device)); | ||
1699 | if (!entry) | ||
1700 | goto err_remove_post; | ||
1701 | |||
1702 | video->dir = acpi_device_dir(device) = device_dir; | ||
1703 | return 0; | ||
1704 | |||
1705 | err_remove_post: | ||
1706 | remove_proc_entry("POST", device_dir); | ||
1707 | err_remove_post_info: | ||
1708 | remove_proc_entry("POST_info", device_dir); | ||
1709 | err_remove_rom: | ||
1710 | remove_proc_entry("ROM", device_dir); | ||
1711 | err_remove_info: | ||
1712 | remove_proc_entry("info", device_dir); | ||
1713 | err_remove_dir: | ||
1714 | remove_proc_entry(acpi_device_bid(device), acpi_video_dir); | ||
1715 | return -ENOMEM; | ||
1716 | } | ||
1717 | |||
1718 | static int acpi_video_bus_remove_fs(struct acpi_device *device) | ||
1719 | { | ||
1720 | struct proc_dir_entry *device_dir = acpi_device_dir(device); | ||
1721 | |||
1722 | if (device_dir) { | ||
1723 | remove_proc_entry("info", device_dir); | ||
1724 | remove_proc_entry("ROM", device_dir); | ||
1725 | remove_proc_entry("POST_info", device_dir); | ||
1726 | remove_proc_entry("POST", device_dir); | ||
1727 | remove_proc_entry("DOS", device_dir); | ||
1728 | remove_proc_entry(acpi_device_bid(device), acpi_video_dir); | ||
1729 | acpi_device_dir(device) = NULL; | ||
1730 | } | ||
1731 | |||
1732 | return 0; | ||
1733 | } | ||
1734 | #else | ||
1735 | static inline int acpi_video_device_add_fs(struct acpi_device *device) | ||
1736 | { | ||
1737 | return 0; | ||
1738 | } | ||
1739 | static inline int acpi_video_device_remove_fs(struct acpi_device *device) | ||
1740 | { | ||
1741 | return 0; | ||
1742 | } | ||
1743 | static inline int acpi_video_bus_add_fs(struct acpi_device *device) | ||
1744 | { | ||
1745 | return 0; | ||
1746 | } | ||
1747 | static inline int acpi_video_bus_remove_fs(struct acpi_device *device) | ||
1748 | { | ||
1749 | return 0; | ||
1750 | } | ||
1751 | #endif /* CONFIG_ACPI_PROCFS */ | ||
1752 | |||
1753 | /* -------------------------------------------------------------------------- | ||
1754 | Driver Interface | 1007 | Driver Interface |
1755 | -------------------------------------------------------------------------- */ | 1008 | -------------------------------------------------------------------------- */ |
1756 | 1009 | ||
@@ -1877,8 +1130,6 @@ acpi_video_bus_get_one_device(struct acpi_device *device, | |||
1877 | list_add_tail(&data->entry, &video->video_device_list); | 1130 | list_add_tail(&data->entry, &video->video_device_list); |
1878 | mutex_unlock(&video->device_list_lock); | 1131 | mutex_unlock(&video->device_list_lock); |
1879 | 1132 | ||
1880 | acpi_video_device_add_fs(device); | ||
1881 | |||
1882 | return 0; | 1133 | return 0; |
1883 | } | 1134 | } |
1884 | 1135 | ||
@@ -2181,8 +1432,6 @@ static int acpi_video_bus_put_one_device(struct acpi_video_device *device) | |||
2181 | if (!device || !device->video) | 1432 | if (!device || !device->video) |
2182 | return -ENOENT; | 1433 | return -ENOENT; |
2183 | 1434 | ||
2184 | acpi_video_device_remove_fs(device->dev); | ||
2185 | |||
2186 | status = acpi_remove_notify_handler(device->dev->handle, | 1435 | status = acpi_remove_notify_handler(device->dev->handle, |
2187 | ACPI_DEVICE_NOTIFY, | 1436 | ACPI_DEVICE_NOTIFY, |
2188 | acpi_video_device_notify); | 1437 | acpi_video_device_notify); |
@@ -2466,10 +1715,6 @@ static int acpi_video_bus_add(struct acpi_device *device) | |||
2466 | if (error) | 1715 | if (error) |
2467 | goto err_free_video; | 1716 | goto err_free_video; |
2468 | 1717 | ||
2469 | error = acpi_video_bus_add_fs(device); | ||
2470 | if (error) | ||
2471 | goto err_free_video; | ||
2472 | |||
2473 | mutex_init(&video->device_list_lock); | 1718 | mutex_init(&video->device_list_lock); |
2474 | INIT_LIST_HEAD(&video->video_device_list); | 1719 | INIT_LIST_HEAD(&video->video_device_list); |
2475 | 1720 | ||
@@ -2522,7 +1767,6 @@ static int acpi_video_bus_add(struct acpi_device *device) | |||
2522 | acpi_video_bus_stop_devices(video); | 1767 | acpi_video_bus_stop_devices(video); |
2523 | acpi_video_bus_put_devices(video); | 1768 | acpi_video_bus_put_devices(video); |
2524 | kfree(video->attached_array); | 1769 | kfree(video->attached_array); |
2525 | acpi_video_bus_remove_fs(device); | ||
2526 | err_free_video: | 1770 | err_free_video: |
2527 | kfree(video); | 1771 | kfree(video); |
2528 | device->driver_data = NULL; | 1772 | device->driver_data = NULL; |
@@ -2544,7 +1788,6 @@ static int acpi_video_bus_remove(struct acpi_device *device, int type) | |||
2544 | 1788 | ||
2545 | acpi_video_bus_stop_devices(video); | 1789 | acpi_video_bus_stop_devices(video); |
2546 | acpi_video_bus_put_devices(video); | 1790 | acpi_video_bus_put_devices(video); |
2547 | acpi_video_bus_remove_fs(device); | ||
2548 | 1791 | ||
2549 | input_unregister_device(video->input); | 1792 | input_unregister_device(video->input); |
2550 | kfree(video->attached_array); | 1793 | kfree(video->attached_array); |
@@ -2584,17 +1827,9 @@ int acpi_video_register(void) | |||
2584 | return 0; | 1827 | return 0; |
2585 | } | 1828 | } |
2586 | 1829 | ||
2587 | #ifdef CONFIG_ACPI_PROCFS | ||
2588 | acpi_video_dir = proc_mkdir(ACPI_VIDEO_CLASS, acpi_root_dir); | ||
2589 | if (!acpi_video_dir) | ||
2590 | return -ENODEV; | ||
2591 | #endif | ||
2592 | |||
2593 | result = acpi_bus_register_driver(&acpi_video_bus); | 1830 | result = acpi_bus_register_driver(&acpi_video_bus); |
2594 | if (result < 0) { | 1831 | if (result < 0) |
2595 | remove_proc_entry(ACPI_VIDEO_CLASS, acpi_root_dir); | ||
2596 | return -ENODEV; | 1832 | return -ENODEV; |
2597 | } | ||
2598 | 1833 | ||
2599 | /* | 1834 | /* |
2600 | * When the acpi_video_bus is loaded successfully, increase | 1835 | * When the acpi_video_bus is loaded successfully, increase |
@@ -2617,10 +1852,6 @@ void acpi_video_unregister(void) | |||
2617 | } | 1852 | } |
2618 | acpi_bus_unregister_driver(&acpi_video_bus); | 1853 | acpi_bus_unregister_driver(&acpi_video_bus); |
2619 | 1854 | ||
2620 | #ifdef CONFIG_ACPI_PROCFS | ||
2621 | remove_proc_entry(ACPI_VIDEO_CLASS, acpi_root_dir); | ||
2622 | #endif | ||
2623 | |||
2624 | register_count = 0; | 1855 | register_count = 0; |
2625 | 1856 | ||
2626 | return; | 1857 | return; |
diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index c5fef01b3c9..b8367612659 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c | |||
@@ -59,8 +59,8 @@ acpi_backlight_cap_match(acpi_handle handle, u32 level, void *context, | |||
59 | "support\n")); | 59 | "support\n")); |
60 | *cap |= ACPI_VIDEO_BACKLIGHT; | 60 | *cap |= ACPI_VIDEO_BACKLIGHT; |
61 | if (ACPI_FAILURE(acpi_get_handle(handle, "_BQC", &h_dummy))) | 61 | if (ACPI_FAILURE(acpi_get_handle(handle, "_BQC", &h_dummy))) |
62 | printk(KERN_WARNING FW_BUG PREFIX "ACPI brightness " | 62 | printk(KERN_WARNING FW_BUG PREFIX "No _BQC method, " |
63 | "control misses _BQC function\n"); | 63 | "cannot determine initial brightness\n"); |
64 | /* We have backlight support, no need to scan further */ | 64 | /* We have backlight support, no need to scan further */ |
65 | return AE_CTRL_TERMINATE; | 65 | return AE_CTRL_TERMINATE; |
66 | } | 66 | } |