diff options
Diffstat (limited to 'drivers/acpi')
47 files changed, 896 insertions, 744 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 431f8b439553..7ec7d88c5999 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig | |||
@@ -266,6 +266,7 @@ config ACPI_DEBUG_FUNC_TRACE | |||
266 | 266 | ||
267 | config ACPI_PCI_SLOT | 267 | config ACPI_PCI_SLOT |
268 | tristate "PCI slot detection driver" | 268 | tristate "PCI slot detection driver" |
269 | depends on SYSFS | ||
269 | default n | 270 | default n |
270 | help | 271 | help |
271 | This driver creates entries in /sys/bus/pci/slots/ for all PCI | 272 | This driver creates entries in /sys/bus/pci/slots/ for all PCI |
diff --git a/drivers/acpi/acpica/acevents.h b/drivers/acpi/acpica/acevents.h index 07e20135f01b..0bba148a2c61 100644 --- a/drivers/acpi/acpica/acevents.h +++ b/drivers/acpi/acpica/acevents.h | |||
@@ -139,7 +139,7 @@ acpi_status acpi_ev_initialize_op_regions(void); | |||
139 | acpi_status | 139 | acpi_status |
140 | acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, | 140 | acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, |
141 | u32 function, | 141 | u32 function, |
142 | acpi_physical_address address, | 142 | u32 region_offset, |
143 | u32 bit_width, acpi_integer * value); | 143 | u32 bit_width, acpi_integer * value); |
144 | 144 | ||
145 | acpi_status | 145 | acpi_status |
diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index 16e5210ae936..3d87362d17ed 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h | |||
@@ -362,9 +362,6 @@ extern u8 acpi_gbl_method_executing; | |||
362 | extern u8 acpi_gbl_abort_method; | 362 | extern u8 acpi_gbl_abort_method; |
363 | extern u8 acpi_gbl_db_terminate_threads; | 363 | extern u8 acpi_gbl_db_terminate_threads; |
364 | 364 | ||
365 | ACPI_EXTERN int optind; | ||
366 | ACPI_EXTERN char *optarg; | ||
367 | |||
368 | ACPI_EXTERN u8 acpi_gbl_db_opt_tables; | 365 | ACPI_EXTERN u8 acpi_gbl_db_opt_tables; |
369 | ACPI_EXTERN u8 acpi_gbl_db_opt_stats; | 366 | ACPI_EXTERN u8 acpi_gbl_db_opt_stats; |
370 | ACPI_EXTERN u8 acpi_gbl_db_opt_ini_methods; | 367 | ACPI_EXTERN u8 acpi_gbl_db_opt_ini_methods; |
diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index 2ec394a328e9..ee986edfa0da 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h | |||
@@ -205,6 +205,7 @@ struct acpi_namespace_node { | |||
205 | #define ANOBJ_METHOD_LOCAL 0x08 /* Node is a method local */ | 205 | #define ANOBJ_METHOD_LOCAL 0x08 /* Node is a method local */ |
206 | #define ANOBJ_SUBTREE_HAS_INI 0x10 /* Used to optimize device initialization */ | 206 | #define ANOBJ_SUBTREE_HAS_INI 0x10 /* Used to optimize device initialization */ |
207 | #define ANOBJ_EVALUATED 0x20 /* Set on first evaluation of node */ | 207 | #define ANOBJ_EVALUATED 0x20 /* Set on first evaluation of node */ |
208 | #define ANOBJ_ALLOCATED_BUFFER 0x40 /* Method AML buffer is dynamic (install_method) */ | ||
208 | 209 | ||
209 | #define ANOBJ_IS_EXTERNAL 0x08 /* i_aSL only: This object created via External() */ | 210 | #define ANOBJ_IS_EXTERNAL 0x08 /* i_aSL only: This object created via External() */ |
210 | #define ANOBJ_METHOD_NO_RETVAL 0x10 /* i_aSL only: Method has no return value */ | 211 | #define ANOBJ_METHOD_NO_RETVAL 0x10 /* i_aSL only: Method has no return value */ |
@@ -788,11 +789,14 @@ struct acpi_bit_register_info { | |||
788 | /* For control registers, both ignored and reserved bits must be preserved */ | 789 | /* For control registers, both ignored and reserved bits must be preserved */ |
789 | 790 | ||
790 | /* | 791 | /* |
791 | * The ACPI spec says to ignore PM1_CTL.SCI_EN (bit 0) | 792 | * For PM1 control, the SCI enable bit (bit 0, SCI_EN) is defined by the |
792 | * but we need to be able to write ACPI_BITREG_SCI_ENABLE directly | 793 | * ACPI specification to be a "preserved" bit - "OSPM always preserves this |
793 | * as a BIOS workaround on some machines. | 794 | * bit position", section 4.7.3.2.1. However, on some machines the OS must |
795 | * write a one to this bit after resume for the machine to work properly. | ||
796 | * To enable this, we no longer attempt to preserve this bit. No machines | ||
797 | * are known to fail if the bit is not preserved. (May 2009) | ||
794 | */ | 798 | */ |
795 | #define ACPI_PM1_CONTROL_IGNORED_BITS 0x0200 /* Bits 9 */ | 799 | #define ACPI_PM1_CONTROL_IGNORED_BITS 0x0200 /* Bit 9 */ |
796 | #define ACPI_PM1_CONTROL_RESERVED_BITS 0xC1F8 /* Bits 14-15, 3-8 */ | 800 | #define ACPI_PM1_CONTROL_RESERVED_BITS 0xC1F8 /* Bits 14-15, 3-8 */ |
797 | #define ACPI_PM1_CONTROL_PRESERVED_BITS \ | 801 | #define ACPI_PM1_CONTROL_PRESERVED_BITS \ |
798 | (ACPI_PM1_CONTROL_IGNORED_BITS | ACPI_PM1_CONTROL_RESERVED_BITS) | 802 | (ACPI_PM1_CONTROL_IGNORED_BITS | ACPI_PM1_CONTROL_RESERVED_BITS) |
diff --git a/drivers/acpi/acpica/acnamesp.h b/drivers/acpi/acpica/acnamesp.h index 46cb5b46d280..94cdc2b8cb93 100644 --- a/drivers/acpi/acpica/acnamesp.h +++ b/drivers/acpi/acpica/acnamesp.h | |||
@@ -99,10 +99,19 @@ acpi_ns_walk_namespace(acpi_object_type type, | |||
99 | acpi_walk_callback user_function, | 99 | acpi_walk_callback user_function, |
100 | void *context, void **return_value); | 100 | void *context, void **return_value); |
101 | 101 | ||
102 | struct acpi_namespace_node *acpi_ns_get_next_node(acpi_object_type type, struct acpi_namespace_node | 102 | struct acpi_namespace_node *acpi_ns_get_next_node(struct acpi_namespace_node |
103 | *parent, struct acpi_namespace_node | 103 | *parent, |
104 | struct acpi_namespace_node | ||
104 | *child); | 105 | *child); |
105 | 106 | ||
107 | struct acpi_namespace_node *acpi_ns_get_next_node_typed(acpi_object_type type, | ||
108 | struct | ||
109 | acpi_namespace_node | ||
110 | *parent, | ||
111 | struct | ||
112 | acpi_namespace_node | ||
113 | *child); | ||
114 | |||
106 | /* | 115 | /* |
107 | * nsparse - table parsing | 116 | * nsparse - table parsing |
108 | */ | 117 | */ |
diff --git a/drivers/acpi/acpica/amlcode.h b/drivers/acpi/acpica/amlcode.h index ff851c5df698..067f967eb389 100644 --- a/drivers/acpi/acpica/amlcode.h +++ b/drivers/acpi/acpica/amlcode.h | |||
@@ -483,7 +483,7 @@ typedef enum { | |||
483 | 483 | ||
484 | #define AML_METHOD_ARG_COUNT 0x07 | 484 | #define AML_METHOD_ARG_COUNT 0x07 |
485 | #define AML_METHOD_SERIALIZED 0x08 | 485 | #define AML_METHOD_SERIALIZED 0x08 |
486 | #define AML_METHOD_SYNCH_LEVEL 0xF0 | 486 | #define AML_METHOD_SYNC_LEVEL 0xF0 |
487 | 487 | ||
488 | /* METHOD_FLAGS_ARG_COUNT is not used internally, define additional flags */ | 488 | /* METHOD_FLAGS_ARG_COUNT is not used internally, define additional flags */ |
489 | 489 | ||
diff --git a/drivers/acpi/acpica/dsobject.c b/drivers/acpi/acpica/dsobject.c index dab3f48f0b42..02e6caad4a76 100644 --- a/drivers/acpi/acpica/dsobject.c +++ b/drivers/acpi/acpica/dsobject.c | |||
@@ -734,7 +734,8 @@ acpi_ds_init_object_from_op(struct acpi_walk_state *walk_state, | |||
734 | 734 | ||
735 | /* Local ID (0-7) is (AML opcode - base AML_LOCAL_OP) */ | 735 | /* Local ID (0-7) is (AML opcode - base AML_LOCAL_OP) */ |
736 | 736 | ||
737 | obj_desc->reference.value = opcode - AML_LOCAL_OP; | 737 | obj_desc->reference.value = |
738 | ((u32)opcode) - AML_LOCAL_OP; | ||
738 | obj_desc->reference.class = ACPI_REFCLASS_LOCAL; | 739 | obj_desc->reference.class = ACPI_REFCLASS_LOCAL; |
739 | 740 | ||
740 | #ifndef ACPI_NO_METHOD_EXECUTION | 741 | #ifndef ACPI_NO_METHOD_EXECUTION |
@@ -754,7 +755,7 @@ acpi_ds_init_object_from_op(struct acpi_walk_state *walk_state, | |||
754 | 755 | ||
755 | /* Arg ID (0-6) is (AML opcode - base AML_ARG_OP) */ | 756 | /* Arg ID (0-6) is (AML opcode - base AML_ARG_OP) */ |
756 | 757 | ||
757 | obj_desc->reference.value = opcode - AML_ARG_OP; | 758 | obj_desc->reference.value = ((u32)opcode) - AML_ARG_OP; |
758 | obj_desc->reference.class = ACPI_REFCLASS_ARG; | 759 | obj_desc->reference.class = ACPI_REFCLASS_ARG; |
759 | 760 | ||
760 | #ifndef ACPI_NO_METHOD_EXECUTION | 761 | #ifndef ACPI_NO_METHOD_EXECUTION |
diff --git a/drivers/acpi/acpica/dsopcode.c b/drivers/acpi/acpica/dsopcode.c index b4c87b5053e6..584d766e6f12 100644 --- a/drivers/acpi/acpica/dsopcode.c +++ b/drivers/acpi/acpica/dsopcode.c | |||
@@ -1386,14 +1386,19 @@ acpi_ds_exec_end_control_op(struct acpi_walk_state * walk_state, | |||
1386 | 1386 | ||
1387 | case AML_BREAK_POINT_OP: | 1387 | case AML_BREAK_POINT_OP: |
1388 | 1388 | ||
1389 | /* Call up to the OS service layer to handle this */ | 1389 | /* |
1390 | 1390 | * Set the single-step flag. This will cause the debugger (if present) | |
1391 | status = | 1391 | * to break to the console within the AML debugger at the start of the |
1392 | acpi_os_signal(ACPI_SIGNAL_BREAKPOINT, | 1392 | * next AML instruction. |
1393 | "Executed AML Breakpoint opcode"); | 1393 | */ |
1394 | ACPI_DEBUGGER_EXEC(acpi_gbl_cm_single_step = TRUE); | ||
1395 | ACPI_DEBUGGER_EXEC(acpi_os_printf | ||
1396 | ("**break** Executed AML BreakPoint opcode\n")); | ||
1394 | 1397 | ||
1395 | /* If and when it returns, all done. */ | 1398 | /* Call to the OSL in case OS wants a piece of the action */ |
1396 | 1399 | ||
1400 | status = acpi_os_signal(ACPI_SIGNAL_BREAKPOINT, | ||
1401 | "Executed AML Breakpoint opcode"); | ||
1397 | break; | 1402 | break; |
1398 | 1403 | ||
1399 | case AML_BREAK_OP: | 1404 | case AML_BREAK_OP: |
diff --git a/drivers/acpi/acpica/dswstate.c b/drivers/acpi/acpica/dswstate.c index 40f92bf7dce5..e46c821cf572 100644 --- a/drivers/acpi/acpica/dswstate.c +++ b/drivers/acpi/acpica/dswstate.c | |||
@@ -102,7 +102,7 @@ acpi_ds_result_pop(union acpi_operand_object **object, | |||
102 | /* Return object of the top element and clean that top element result stack */ | 102 | /* Return object of the top element and clean that top element result stack */ |
103 | 103 | ||
104 | walk_state->result_count--; | 104 | walk_state->result_count--; |
105 | index = walk_state->result_count % ACPI_RESULTS_FRAME_OBJ_NUM; | 105 | index = (u32)walk_state->result_count % ACPI_RESULTS_FRAME_OBJ_NUM; |
106 | 106 | ||
107 | *object = state->results.obj_desc[index]; | 107 | *object = state->results.obj_desc[index]; |
108 | if (!*object) { | 108 | if (!*object) { |
@@ -186,7 +186,7 @@ acpi_ds_result_push(union acpi_operand_object * object, | |||
186 | 186 | ||
187 | /* Assign the address of object to the top free element of result stack */ | 187 | /* Assign the address of object to the top free element of result stack */ |
188 | 188 | ||
189 | index = walk_state->result_count % ACPI_RESULTS_FRAME_OBJ_NUM; | 189 | index = (u32)walk_state->result_count % ACPI_RESULTS_FRAME_OBJ_NUM; |
190 | state->results.obj_desc[index] = object; | 190 | state->results.obj_desc[index] = object; |
191 | walk_state->result_count++; | 191 | walk_state->result_count++; |
192 | 192 | ||
diff --git a/drivers/acpi/acpica/evregion.c b/drivers/acpi/acpica/evregion.c index 538d63264555..98c7f9c62653 100644 --- a/drivers/acpi/acpica/evregion.c +++ b/drivers/acpi/acpica/evregion.c | |||
@@ -275,7 +275,7 @@ acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function) | |||
275 | * | 275 | * |
276 | * PARAMETERS: region_obj - Internal region object | 276 | * PARAMETERS: region_obj - Internal region object |
277 | * Function - Read or Write operation | 277 | * Function - Read or Write operation |
278 | * Address - Where in the space to read or write | 278 | * region_offset - Where in the region to read or write |
279 | * bit_width - Field width in bits (8, 16, 32, or 64) | 279 | * bit_width - Field width in bits (8, 16, 32, or 64) |
280 | * Value - Pointer to in or out value, must be | 280 | * Value - Pointer to in or out value, must be |
281 | * full 64-bit acpi_integer | 281 | * full 64-bit acpi_integer |
@@ -290,7 +290,7 @@ acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function) | |||
290 | acpi_status | 290 | acpi_status |
291 | acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, | 291 | acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, |
292 | u32 function, | 292 | u32 function, |
293 | acpi_physical_address address, | 293 | u32 region_offset, |
294 | u32 bit_width, acpi_integer * value) | 294 | u32 bit_width, acpi_integer * value) |
295 | { | 295 | { |
296 | acpi_status status; | 296 | acpi_status status; |
@@ -396,7 +396,8 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, | |||
396 | ACPI_DEBUG_PRINT((ACPI_DB_OPREGION, | 396 | ACPI_DEBUG_PRINT((ACPI_DB_OPREGION, |
397 | "Handler %p (@%p) Address %8.8X%8.8X [%s]\n", | 397 | "Handler %p (@%p) Address %8.8X%8.8X [%s]\n", |
398 | ®ion_obj->region.handler->address_space, handler, | 398 | ®ion_obj->region.handler->address_space, handler, |
399 | ACPI_FORMAT_NATIVE_UINT(address), | 399 | ACPI_FORMAT_NATIVE_UINT(region_obj->region.address + |
400 | region_offset), | ||
400 | acpi_ut_get_region_name(region_obj->region. | 401 | acpi_ut_get_region_name(region_obj->region. |
401 | space_id))); | 402 | space_id))); |
402 | 403 | ||
@@ -412,8 +413,9 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, | |||
412 | 413 | ||
413 | /* Call the handler */ | 414 | /* Call the handler */ |
414 | 415 | ||
415 | status = handler(function, address, bit_width, value, | 416 | status = handler(function, |
416 | handler_desc->address_space.context, | 417 | (region_obj->region.address + region_offset), |
418 | bit_width, value, handler_desc->address_space.context, | ||
417 | region_obj2->extra.region_context); | 419 | region_obj2->extra.region_context); |
418 | 420 | ||
419 | if (ACPI_FAILURE(status)) { | 421 | if (ACPI_FAILURE(status)) { |
diff --git a/drivers/acpi/acpica/evxfevnt.c b/drivers/acpi/acpica/evxfevnt.c index d0a080747ec3..4721f58fe42c 100644 --- a/drivers/acpi/acpica/evxfevnt.c +++ b/drivers/acpi/acpica/evxfevnt.c | |||
@@ -51,7 +51,7 @@ | |||
51 | ACPI_MODULE_NAME("evxfevnt") | 51 | ACPI_MODULE_NAME("evxfevnt") |
52 | 52 | ||
53 | /* Local prototypes */ | 53 | /* Local prototypes */ |
54 | acpi_status | 54 | static acpi_status |
55 | acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info, | 55 | acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info, |
56 | struct acpi_gpe_block_info *gpe_block, void *context); | 56 | struct acpi_gpe_block_info *gpe_block, void *context); |
57 | 57 | ||
@@ -785,7 +785,7 @@ ACPI_EXPORT_SYMBOL(acpi_get_gpe_device) | |||
785 | * block device. NULL if the GPE is one of the FADT-defined GPEs. | 785 | * block device. NULL if the GPE is one of the FADT-defined GPEs. |
786 | * | 786 | * |
787 | ******************************************************************************/ | 787 | ******************************************************************************/ |
788 | acpi_status | 788 | static acpi_status |
789 | acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info, | 789 | acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info, |
790 | struct acpi_gpe_block_info *gpe_block, void *context) | 790 | struct acpi_gpe_block_info *gpe_block, void *context) |
791 | { | 791 | { |
diff --git a/drivers/acpi/acpica/exconfig.c b/drivers/acpi/acpica/exconfig.c index 3deb20a126b2..277fd609611a 100644 --- a/drivers/acpi/acpica/exconfig.c +++ b/drivers/acpi/acpica/exconfig.c | |||
@@ -47,6 +47,7 @@ | |||
47 | #include "acnamesp.h" | 47 | #include "acnamesp.h" |
48 | #include "actables.h" | 48 | #include "actables.h" |
49 | #include "acdispat.h" | 49 | #include "acdispat.h" |
50 | #include "acevents.h" | ||
50 | 51 | ||
51 | #define _COMPONENT ACPI_EXECUTER | 52 | #define _COMPONENT ACPI_EXECUTER |
52 | ACPI_MODULE_NAME("exconfig") | 53 | ACPI_MODULE_NAME("exconfig") |
@@ -57,6 +58,10 @@ acpi_ex_add_table(u32 table_index, | |||
57 | struct acpi_namespace_node *parent_node, | 58 | struct acpi_namespace_node *parent_node, |
58 | union acpi_operand_object **ddb_handle); | 59 | union acpi_operand_object **ddb_handle); |
59 | 60 | ||
61 | static acpi_status | ||
62 | acpi_ex_region_read(union acpi_operand_object *obj_desc, | ||
63 | u32 length, u8 *buffer); | ||
64 | |||
60 | /******************************************************************************* | 65 | /******************************************************************************* |
61 | * | 66 | * |
62 | * FUNCTION: acpi_ex_add_table | 67 | * FUNCTION: acpi_ex_add_table |
@@ -91,6 +96,7 @@ acpi_ex_add_table(u32 table_index, | |||
91 | 96 | ||
92 | /* Init the table handle */ | 97 | /* Init the table handle */ |
93 | 98 | ||
99 | obj_desc->common.flags |= AOPOBJ_DATA_VALID; | ||
94 | obj_desc->reference.class = ACPI_REFCLASS_TABLE; | 100 | obj_desc->reference.class = ACPI_REFCLASS_TABLE; |
95 | *ddb_handle = obj_desc; | 101 | *ddb_handle = obj_desc; |
96 | 102 | ||
@@ -229,6 +235,8 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state, | |||
229 | walk_state); | 235 | walk_state); |
230 | if (ACPI_FAILURE(status)) { | 236 | if (ACPI_FAILURE(status)) { |
231 | (void)acpi_ex_unload_table(ddb_handle); | 237 | (void)acpi_ex_unload_table(ddb_handle); |
238 | |||
239 | acpi_ut_remove_reference(ddb_handle); | ||
232 | return_ACPI_STATUS(status); | 240 | return_ACPI_STATUS(status); |
233 | } | 241 | } |
234 | } | 242 | } |
@@ -254,6 +262,47 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state, | |||
254 | 262 | ||
255 | /******************************************************************************* | 263 | /******************************************************************************* |
256 | * | 264 | * |
265 | * FUNCTION: acpi_ex_region_read | ||
266 | * | ||
267 | * PARAMETERS: obj_desc - Region descriptor | ||
268 | * Length - Number of bytes to read | ||
269 | * Buffer - Pointer to where to put the data | ||
270 | * | ||
271 | * RETURN: Status | ||
272 | * | ||
273 | * DESCRIPTION: Read data from an operation region. The read starts from the | ||
274 | * beginning of the region. | ||
275 | * | ||
276 | ******************************************************************************/ | ||
277 | |||
278 | static acpi_status | ||
279 | acpi_ex_region_read(union acpi_operand_object *obj_desc, u32 length, u8 *buffer) | ||
280 | { | ||
281 | acpi_status status; | ||
282 | acpi_integer value; | ||
283 | u32 region_offset = 0; | ||
284 | u32 i; | ||
285 | |||
286 | /* Bytewise reads */ | ||
287 | |||
288 | for (i = 0; i < length; i++) { | ||
289 | status = acpi_ev_address_space_dispatch(obj_desc, ACPI_READ, | ||
290 | region_offset, 8, | ||
291 | &value); | ||
292 | if (ACPI_FAILURE(status)) { | ||
293 | return status; | ||
294 | } | ||
295 | |||
296 | *buffer = (u8)value; | ||
297 | buffer++; | ||
298 | region_offset++; | ||
299 | } | ||
300 | |||
301 | return AE_OK; | ||
302 | } | ||
303 | |||
304 | /******************************************************************************* | ||
305 | * | ||
257 | * FUNCTION: acpi_ex_load_op | 306 | * FUNCTION: acpi_ex_load_op |
258 | * | 307 | * |
259 | * PARAMETERS: obj_desc - Region or Buffer/Field where the table will be | 308 | * PARAMETERS: obj_desc - Region or Buffer/Field where the table will be |
@@ -314,18 +363,23 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, | |||
314 | } | 363 | } |
315 | } | 364 | } |
316 | 365 | ||
317 | /* | 366 | /* Get the table header first so we can get the table length */ |
318 | * Map the table header and get the actual table length. The region | 367 | |
319 | * length is not guaranteed to be the same as the table length. | 368 | table = ACPI_ALLOCATE(sizeof(struct acpi_table_header)); |
320 | */ | ||
321 | table = acpi_os_map_memory(obj_desc->region.address, | ||
322 | sizeof(struct acpi_table_header)); | ||
323 | if (!table) { | 369 | if (!table) { |
324 | return_ACPI_STATUS(AE_NO_MEMORY); | 370 | return_ACPI_STATUS(AE_NO_MEMORY); |
325 | } | 371 | } |
326 | 372 | ||
373 | status = | ||
374 | acpi_ex_region_read(obj_desc, | ||
375 | sizeof(struct acpi_table_header), | ||
376 | ACPI_CAST_PTR(u8, table)); | ||
327 | length = table->length; | 377 | length = table->length; |
328 | acpi_os_unmap_memory(table, sizeof(struct acpi_table_header)); | 378 | ACPI_FREE(table); |
379 | |||
380 | if (ACPI_FAILURE(status)) { | ||
381 | return_ACPI_STATUS(status); | ||
382 | } | ||
329 | 383 | ||
330 | /* Must have at least an ACPI table header */ | 384 | /* Must have at least an ACPI table header */ |
331 | 385 | ||
@@ -334,10 +388,19 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, | |||
334 | } | 388 | } |
335 | 389 | ||
336 | /* | 390 | /* |
337 | * The memory region is not guaranteed to remain stable and we must | 391 | * The original implementation simply mapped the table, with no copy. |
338 | * copy the table to a local buffer. For example, the memory region | 392 | * However, the memory region is not guaranteed to remain stable and |
339 | * is corrupted after suspend on some machines. Dynamically loaded | 393 | * we must copy the table to a local buffer. For example, the memory |
340 | * tables are usually small, so this overhead is minimal. | 394 | * region is corrupted after suspend on some machines. Dynamically |
395 | * loaded tables are usually small, so this overhead is minimal. | ||
396 | * | ||
397 | * The latest implementation (5/2009) does not use a mapping at all. | ||
398 | * We use the low-level operation region interface to read the table | ||
399 | * instead of the obvious optimization of using a direct mapping. | ||
400 | * This maintains a consistent use of operation regions across the | ||
401 | * entire subsystem. This is important if additional processing must | ||
402 | * be performed in the (possibly user-installed) operation region | ||
403 | * handler. For example, acpi_exec and ASLTS depend on this. | ||
341 | */ | 404 | */ |
342 | 405 | ||
343 | /* Allocate a buffer for the table */ | 406 | /* Allocate a buffer for the table */ |
@@ -347,17 +410,16 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, | |||
347 | return_ACPI_STATUS(AE_NO_MEMORY); | 410 | return_ACPI_STATUS(AE_NO_MEMORY); |
348 | } | 411 | } |
349 | 412 | ||
350 | /* Map the entire table and copy it */ | 413 | /* Read the entire table */ |
351 | 414 | ||
352 | table = acpi_os_map_memory(obj_desc->region.address, length); | 415 | status = acpi_ex_region_read(obj_desc, length, |
353 | if (!table) { | 416 | ACPI_CAST_PTR(u8, |
417 | table_desc.pointer)); | ||
418 | if (ACPI_FAILURE(status)) { | ||
354 | ACPI_FREE(table_desc.pointer); | 419 | ACPI_FREE(table_desc.pointer); |
355 | return_ACPI_STATUS(AE_NO_MEMORY); | 420 | return_ACPI_STATUS(status); |
356 | } | 421 | } |
357 | 422 | ||
358 | ACPI_MEMCPY(table_desc.pointer, table, length); | ||
359 | acpi_os_unmap_memory(table, length); | ||
360 | |||
361 | table_desc.address = obj_desc->region.address; | 423 | table_desc.address = obj_desc->region.address; |
362 | break; | 424 | break; |
363 | 425 | ||
@@ -454,6 +516,10 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, | |||
454 | return_ACPI_STATUS(status); | 516 | return_ACPI_STATUS(status); |
455 | } | 517 | } |
456 | 518 | ||
519 | /* Remove the reference by added by acpi_ex_store above */ | ||
520 | |||
521 | acpi_ut_remove_reference(ddb_handle); | ||
522 | |||
457 | /* Invoke table handler if present */ | 523 | /* Invoke table handler if present */ |
458 | 524 | ||
459 | if (acpi_gbl_table_handler) { | 525 | if (acpi_gbl_table_handler) { |
@@ -495,13 +561,18 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle) | |||
495 | 561 | ||
496 | /* | 562 | /* |
497 | * Validate the handle | 563 | * Validate the handle |
498 | * Although the handle is partially validated in acpi_ex_reconfiguration(), | 564 | * Although the handle is partially validated in acpi_ex_reconfiguration() |
499 | * when it calls acpi_ex_resolve_operands(), the handle is more completely | 565 | * when it calls acpi_ex_resolve_operands(), the handle is more completely |
500 | * validated here. | 566 | * validated here. |
567 | * | ||
568 | * Handle must be a valid operand object of type reference. Also, the | ||
569 | * ddb_handle must still be marked valid (table has not been previously | ||
570 | * unloaded) | ||
501 | */ | 571 | */ |
502 | if ((!ddb_handle) || | 572 | if ((!ddb_handle) || |
503 | (ACPI_GET_DESCRIPTOR_TYPE(ddb_handle) != ACPI_DESC_TYPE_OPERAND) || | 573 | (ACPI_GET_DESCRIPTOR_TYPE(ddb_handle) != ACPI_DESC_TYPE_OPERAND) || |
504 | (ddb_handle->common.type != ACPI_TYPE_LOCAL_REFERENCE)) { | 574 | (ddb_handle->common.type != ACPI_TYPE_LOCAL_REFERENCE) || |
575 | (!(ddb_handle->common.flags & AOPOBJ_DATA_VALID))) { | ||
505 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 576 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
506 | } | 577 | } |
507 | 578 | ||
@@ -509,6 +580,12 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle) | |||
509 | 580 | ||
510 | table_index = table_desc->reference.value; | 581 | table_index = table_desc->reference.value; |
511 | 582 | ||
583 | /* Ensure the table is still loaded */ | ||
584 | |||
585 | if (!acpi_tb_is_table_loaded(table_index)) { | ||
586 | return_ACPI_STATUS(AE_NOT_EXIST); | ||
587 | } | ||
588 | |||
512 | /* Invoke table handler if present */ | 589 | /* Invoke table handler if present */ |
513 | 590 | ||
514 | if (acpi_gbl_table_handler) { | 591 | if (acpi_gbl_table_handler) { |
@@ -530,8 +607,10 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle) | |||
530 | (void)acpi_tb_release_owner_id(table_index); | 607 | (void)acpi_tb_release_owner_id(table_index); |
531 | acpi_tb_set_table_loaded_flag(table_index, FALSE); | 608 | acpi_tb_set_table_loaded_flag(table_index, FALSE); |
532 | 609 | ||
533 | /* Table unloaded, remove a reference to the ddb_handle object */ | 610 | /* |
534 | 611 | * Invalidate the handle. We do this because the handle may be stored | |
535 | acpi_ut_remove_reference(ddb_handle); | 612 | * in a named object and may not be actually deleted until much later. |
613 | */ | ||
614 | ddb_handle->common.flags &= ~AOPOBJ_DATA_VALID; | ||
536 | return_ACPI_STATUS(AE_OK); | 615 | return_ACPI_STATUS(AE_OK); |
537 | } | 616 | } |
diff --git a/drivers/acpi/acpica/excreate.c b/drivers/acpi/acpica/excreate.c index a57ad2564ab0..02b25d233d99 100644 --- a/drivers/acpi/acpica/excreate.c +++ b/drivers/acpi/acpica/excreate.c | |||
@@ -502,7 +502,7 @@ acpi_ex_create_method(u8 * aml_start, | |||
502 | * ACPI 2.0: sync_level = sync_level in method declaration | 502 | * ACPI 2.0: sync_level = sync_level in method declaration |
503 | */ | 503 | */ |
504 | obj_desc->method.sync_level = (u8) | 504 | obj_desc->method.sync_level = (u8) |
505 | ((method_flags & AML_METHOD_SYNCH_LEVEL) >> 4); | 505 | ((method_flags & AML_METHOD_SYNC_LEVEL) >> 4); |
506 | } | 506 | } |
507 | 507 | ||
508 | /* Attach the new object to the method Node */ | 508 | /* Attach the new object to the method Node */ |
diff --git a/drivers/acpi/acpica/exdump.c b/drivers/acpi/acpica/exdump.c index 89d141fdae0b..ec524614e708 100644 --- a/drivers/acpi/acpica/exdump.c +++ b/drivers/acpi/acpica/exdump.c | |||
@@ -120,9 +120,11 @@ static struct acpi_exdump_info acpi_ex_dump_event[2] = { | |||
120 | {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(event.os_semaphore), "OsSemaphore"} | 120 | {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(event.os_semaphore), "OsSemaphore"} |
121 | }; | 121 | }; |
122 | 122 | ||
123 | static struct acpi_exdump_info acpi_ex_dump_method[8] = { | 123 | static struct acpi_exdump_info acpi_ex_dump_method[9] = { |
124 | {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_method), NULL}, | 124 | {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_method), NULL}, |
125 | {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.param_count), "ParamCount"}, | 125 | {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.method_flags), "Method Flags"}, |
126 | {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.param_count), | ||
127 | "Parameter Count"}, | ||
126 | {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.sync_level), "Sync Level"}, | 128 | {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.sync_level), "Sync Level"}, |
127 | {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(method.mutex), "Mutex"}, | 129 | {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(method.mutex), "Mutex"}, |
128 | {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.owner_id), "Owner Id"}, | 130 | {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.owner_id), "Owner Id"}, |
diff --git a/drivers/acpi/acpica/exfldio.c b/drivers/acpi/acpica/exfldio.c index 99cee61e655d..d4075b821021 100644 --- a/drivers/acpi/acpica/exfldio.c +++ b/drivers/acpi/acpica/exfldio.c | |||
@@ -222,7 +222,7 @@ acpi_ex_access_region(union acpi_operand_object *obj_desc, | |||
222 | { | 222 | { |
223 | acpi_status status; | 223 | acpi_status status; |
224 | union acpi_operand_object *rgn_desc; | 224 | union acpi_operand_object *rgn_desc; |
225 | acpi_physical_address address; | 225 | u32 region_offset; |
226 | 226 | ||
227 | ACPI_FUNCTION_TRACE(ex_access_region); | 227 | ACPI_FUNCTION_TRACE(ex_access_region); |
228 | 228 | ||
@@ -243,7 +243,7 @@ acpi_ex_access_region(union acpi_operand_object *obj_desc, | |||
243 | * 3) The current offset into the field | 243 | * 3) The current offset into the field |
244 | */ | 244 | */ |
245 | rgn_desc = obj_desc->common_field.region_obj; | 245 | rgn_desc = obj_desc->common_field.region_obj; |
246 | address = rgn_desc->region.address + | 246 | region_offset = |
247 | obj_desc->common_field.base_byte_offset + field_datum_byte_offset; | 247 | obj_desc->common_field.base_byte_offset + field_datum_byte_offset; |
248 | 248 | ||
249 | if ((function & ACPI_IO_MASK) == ACPI_READ) { | 249 | if ((function & ACPI_IO_MASK) == ACPI_READ) { |
@@ -260,16 +260,18 @@ acpi_ex_access_region(union acpi_operand_object *obj_desc, | |||
260 | obj_desc->common_field.access_byte_width, | 260 | obj_desc->common_field.access_byte_width, |
261 | obj_desc->common_field.base_byte_offset, | 261 | obj_desc->common_field.base_byte_offset, |
262 | field_datum_byte_offset, ACPI_CAST_PTR(void, | 262 | field_datum_byte_offset, ACPI_CAST_PTR(void, |
263 | address))); | 263 | (rgn_desc-> |
264 | region. | ||
265 | address + | ||
266 | region_offset)))); | ||
264 | 267 | ||
265 | /* Invoke the appropriate address_space/op_region handler */ | 268 | /* Invoke the appropriate address_space/op_region handler */ |
266 | 269 | ||
267 | status = acpi_ev_address_space_dispatch(rgn_desc, function, | 270 | status = |
268 | address, | 271 | acpi_ev_address_space_dispatch(rgn_desc, function, region_offset, |
269 | ACPI_MUL_8(obj_desc-> | 272 | ACPI_MUL_8(obj_desc->common_field. |
270 | common_field. | 273 | access_byte_width), |
271 | access_byte_width), | 274 | value); |
272 | value); | ||
273 | 275 | ||
274 | if (ACPI_FAILURE(status)) { | 276 | if (ACPI_FAILURE(status)) { |
275 | if (status == AE_NOT_IMPLEMENTED) { | 277 | if (status == AE_NOT_IMPLEMENTED) { |
diff --git a/drivers/acpi/acpica/exmutex.c b/drivers/acpi/acpica/exmutex.c index d301c1f363ef..2f0114202b05 100644 --- a/drivers/acpi/acpica/exmutex.c +++ b/drivers/acpi/acpica/exmutex.c | |||
@@ -83,6 +83,15 @@ void acpi_ex_unlink_mutex(union acpi_operand_object *obj_desc) | |||
83 | 83 | ||
84 | if (obj_desc->mutex.prev) { | 84 | if (obj_desc->mutex.prev) { |
85 | (obj_desc->mutex.prev)->mutex.next = obj_desc->mutex.next; | 85 | (obj_desc->mutex.prev)->mutex.next = obj_desc->mutex.next; |
86 | |||
87 | /* | ||
88 | * Migrate the previous sync level associated with this mutex to the | ||
89 | * previous mutex on the list so that it may be preserved. This handles | ||
90 | * the case where several mutexes have been acquired at the same level, | ||
91 | * but are not released in opposite order. | ||
92 | */ | ||
93 | (obj_desc->mutex.prev)->mutex.original_sync_level = | ||
94 | obj_desc->mutex.original_sync_level; | ||
86 | } else { | 95 | } else { |
87 | thread->acquired_mutex_list = obj_desc->mutex.next; | 96 | thread->acquired_mutex_list = obj_desc->mutex.next; |
88 | } | 97 | } |
@@ -349,6 +358,7 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc, | |||
349 | struct acpi_walk_state *walk_state) | 358 | struct acpi_walk_state *walk_state) |
350 | { | 359 | { |
351 | acpi_status status = AE_OK; | 360 | acpi_status status = AE_OK; |
361 | u8 previous_sync_level; | ||
352 | 362 | ||
353 | ACPI_FUNCTION_TRACE(ex_release_mutex); | 363 | ACPI_FUNCTION_TRACE(ex_release_mutex); |
354 | 364 | ||
@@ -373,11 +383,12 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc, | |||
373 | walk_state->thread->thread_id) | 383 | walk_state->thread->thread_id) |
374 | && (obj_desc != acpi_gbl_global_lock_mutex)) { | 384 | && (obj_desc != acpi_gbl_global_lock_mutex)) { |
375 | ACPI_ERROR((AE_INFO, | 385 | ACPI_ERROR((AE_INFO, |
376 | "Thread %lX cannot release Mutex [%4.4s] acquired by thread %lX", | 386 | "Thread %p cannot release Mutex [%4.4s] acquired by thread %p", |
377 | (unsigned long)walk_state->thread->thread_id, | 387 | ACPI_CAST_PTR(void, walk_state->thread->thread_id), |
378 | acpi_ut_get_node_name(obj_desc->mutex.node), | 388 | acpi_ut_get_node_name(obj_desc->mutex.node), |
379 | (unsigned long)obj_desc->mutex.owner_thread-> | 389 | ACPI_CAST_PTR(void, |
380 | thread_id)); | 390 | obj_desc->mutex.owner_thread-> |
391 | thread_id))); | ||
381 | return_ACPI_STATUS(AE_AML_NOT_OWNER); | 392 | return_ACPI_STATUS(AE_AML_NOT_OWNER); |
382 | } | 393 | } |
383 | 394 | ||
@@ -391,10 +402,14 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc, | |||
391 | } | 402 | } |
392 | 403 | ||
393 | /* | 404 | /* |
394 | * The sync level of the mutex must be less than or equal to the current | 405 | * The sync level of the mutex must be equal to the current sync level. In |
395 | * sync level | 406 | * other words, the current level means that at least one mutex at that |
407 | * level is currently being held. Attempting to release a mutex of a | ||
408 | * different level can only mean that the mutex ordering rule is being | ||
409 | * violated. This behavior is clarified in ACPI 4.0 specification. | ||
396 | */ | 410 | */ |
397 | if (obj_desc->mutex.sync_level > walk_state->thread->current_sync_level) { | 411 | if (obj_desc->mutex.sync_level != |
412 | walk_state->thread->current_sync_level) { | ||
398 | ACPI_ERROR((AE_INFO, | 413 | ACPI_ERROR((AE_INFO, |
399 | "Cannot release Mutex [%4.4s], SyncLevel mismatch: mutex %d current %d", | 414 | "Cannot release Mutex [%4.4s], SyncLevel mismatch: mutex %d current %d", |
400 | acpi_ut_get_node_name(obj_desc->mutex.node), | 415 | acpi_ut_get_node_name(obj_desc->mutex.node), |
@@ -403,14 +418,24 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc, | |||
403 | return_ACPI_STATUS(AE_AML_MUTEX_ORDER); | 418 | return_ACPI_STATUS(AE_AML_MUTEX_ORDER); |
404 | } | 419 | } |
405 | 420 | ||
421 | /* | ||
422 | * Get the previous sync_level from the head of the acquired mutex list. | ||
423 | * This handles the case where several mutexes at the same level have been | ||
424 | * acquired, but are not released in reverse order. | ||
425 | */ | ||
426 | previous_sync_level = | ||
427 | walk_state->thread->acquired_mutex_list->mutex.original_sync_level; | ||
428 | |||
406 | status = acpi_ex_release_mutex_object(obj_desc); | 429 | status = acpi_ex_release_mutex_object(obj_desc); |
430 | if (ACPI_FAILURE(status)) { | ||
431 | return_ACPI_STATUS(status); | ||
432 | } | ||
407 | 433 | ||
408 | if (obj_desc->mutex.acquisition_depth == 0) { | 434 | if (obj_desc->mutex.acquisition_depth == 0) { |
409 | 435 | ||
410 | /* Restore the original sync_level */ | 436 | /* Restore the previous sync_level */ |
411 | 437 | ||
412 | walk_state->thread->current_sync_level = | 438 | walk_state->thread->current_sync_level = previous_sync_level; |
413 | obj_desc->mutex.original_sync_level; | ||
414 | } | 439 | } |
415 | return_ACPI_STATUS(status); | 440 | return_ACPI_STATUS(status); |
416 | } | 441 | } |
diff --git a/drivers/acpi/acpica/exstore.c b/drivers/acpi/acpica/exstore.c index 90d606196c99..6efd07a4f779 100644 --- a/drivers/acpi/acpica/exstore.c +++ b/drivers/acpi/acpica/exstore.c | |||
@@ -193,10 +193,12 @@ acpi_ex_do_debug_object(union acpi_operand_object *source_desc, | |||
193 | 193 | ||
194 | case ACPI_REFCLASS_TABLE: | 194 | case ACPI_REFCLASS_TABLE: |
195 | 195 | ||
196 | /* Case for ddb_handle */ | ||
197 | |||
196 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, | 198 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, |
197 | "Table Index 0x%X\n", | 199 | "Table Index 0x%X\n", |
198 | source_desc->reference.value)); | 200 | source_desc->reference.value)); |
199 | break; | 201 | return; |
200 | 202 | ||
201 | default: | 203 | default: |
202 | break; | 204 | break; |
diff --git a/drivers/acpi/acpica/hwregs.c b/drivers/acpi/acpica/hwregs.c index 7b2fb602b5cb..23d5505cb1f7 100644 --- a/drivers/acpi/acpica/hwregs.c +++ b/drivers/acpi/acpica/hwregs.c | |||
@@ -81,9 +81,9 @@ acpi_status acpi_hw_clear_acpi_status(void) | |||
81 | 81 | ||
82 | ACPI_FUNCTION_TRACE(hw_clear_acpi_status); | 82 | ACPI_FUNCTION_TRACE(hw_clear_acpi_status); |
83 | 83 | ||
84 | ACPI_DEBUG_PRINT((ACPI_DB_IO, "About to write %04X to %0llX\n", | 84 | ACPI_DEBUG_PRINT((ACPI_DB_IO, "About to write %04X to %8.8X%8.8X\n", |
85 | ACPI_BITMASK_ALL_FIXED_STATUS, | 85 | ACPI_BITMASK_ALL_FIXED_STATUS, |
86 | acpi_gbl_xpm1a_status.address)); | 86 | ACPI_FORMAT_UINT64(acpi_gbl_xpm1a_status.address))); |
87 | 87 | ||
88 | lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock); | 88 | lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock); |
89 | 89 | ||
diff --git a/drivers/acpi/acpica/nsalloc.c b/drivers/acpi/acpica/nsalloc.c index aceb93111967..efc971ab7d65 100644 --- a/drivers/acpi/acpica/nsalloc.c +++ b/drivers/acpi/acpica/nsalloc.c | |||
@@ -334,9 +334,7 @@ void acpi_ns_delete_namespace_subtree(struct acpi_namespace_node *parent_node) | |||
334 | 334 | ||
335 | /* Get the next node in this scope (NULL if none) */ | 335 | /* Get the next node in this scope (NULL if none) */ |
336 | 336 | ||
337 | child_node = | 337 | child_node = acpi_ns_get_next_node(parent_node, child_node); |
338 | acpi_ns_get_next_node(ACPI_TYPE_ANY, parent_node, | ||
339 | child_node); | ||
340 | if (child_node) { | 338 | if (child_node) { |
341 | 339 | ||
342 | /* Found a child node - detach any attached object */ | 340 | /* Found a child node - detach any attached object */ |
@@ -345,8 +343,7 @@ void acpi_ns_delete_namespace_subtree(struct acpi_namespace_node *parent_node) | |||
345 | 343 | ||
346 | /* Check if this node has any children */ | 344 | /* Check if this node has any children */ |
347 | 345 | ||
348 | if (acpi_ns_get_next_node | 346 | if (child_node->child) { |
349 | (ACPI_TYPE_ANY, child_node, NULL)) { | ||
350 | /* | 347 | /* |
351 | * There is at least one child of this node, | 348 | * There is at least one child of this node, |
352 | * visit the node | 349 | * visit the node |
@@ -432,9 +429,7 @@ void acpi_ns_delete_namespace_by_owner(acpi_owner_id owner_id) | |||
432 | * Get the next child of this parent node. When child_node is NULL, | 429 | * Get the next child of this parent node. When child_node is NULL, |
433 | * the first child of the parent is returned | 430 | * the first child of the parent is returned |
434 | */ | 431 | */ |
435 | child_node = | 432 | child_node = acpi_ns_get_next_node(parent_node, child_node); |
436 | acpi_ns_get_next_node(ACPI_TYPE_ANY, parent_node, | ||
437 | child_node); | ||
438 | 433 | ||
439 | if (deletion_node) { | 434 | if (deletion_node) { |
440 | acpi_ns_delete_children(deletion_node); | 435 | acpi_ns_delete_children(deletion_node); |
@@ -452,8 +447,7 @@ void acpi_ns_delete_namespace_by_owner(acpi_owner_id owner_id) | |||
452 | 447 | ||
453 | /* Check if this node has any children */ | 448 | /* Check if this node has any children */ |
454 | 449 | ||
455 | if (acpi_ns_get_next_node | 450 | if (child_node->child) { |
456 | (ACPI_TYPE_ANY, child_node, NULL)) { | ||
457 | /* | 451 | /* |
458 | * There is at least one child of this node, | 452 | * There is at least one child of this node, |
459 | * visit the node | 453 | * visit the node |
diff --git a/drivers/acpi/acpica/nsnames.c b/drivers/acpi/acpica/nsnames.c index ae3dc10a7e81..af8e6bcee07e 100644 --- a/drivers/acpi/acpica/nsnames.c +++ b/drivers/acpi/acpica/nsnames.c | |||
@@ -149,7 +149,7 @@ char *acpi_ns_get_external_pathname(struct acpi_namespace_node *node) | |||
149 | 149 | ||
150 | name_buffer = ACPI_ALLOCATE_ZEROED(size); | 150 | name_buffer = ACPI_ALLOCATE_ZEROED(size); |
151 | if (!name_buffer) { | 151 | if (!name_buffer) { |
152 | ACPI_ERROR((AE_INFO, "Allocation failure")); | 152 | ACPI_ERROR((AE_INFO, "Could not allocate %u bytes", (u32)size)); |
153 | return_PTR(NULL); | 153 | return_PTR(NULL); |
154 | } | 154 | } |
155 | 155 | ||
diff --git a/drivers/acpi/acpica/nsobject.c b/drivers/acpi/acpica/nsobject.c index 3eb20bfda9d8..60f3af08d28c 100644 --- a/drivers/acpi/acpica/nsobject.c +++ b/drivers/acpi/acpica/nsobject.c | |||
@@ -213,6 +213,15 @@ void acpi_ns_detach_object(struct acpi_namespace_node *node) | |||
213 | return_VOID; | 213 | return_VOID; |
214 | } | 214 | } |
215 | 215 | ||
216 | if (node->flags & ANOBJ_ALLOCATED_BUFFER) { | ||
217 | |||
218 | /* Free the dynamic aml buffer */ | ||
219 | |||
220 | if (obj_desc->common.type == ACPI_TYPE_METHOD) { | ||
221 | ACPI_FREE(obj_desc->method.aml_start); | ||
222 | } | ||
223 | } | ||
224 | |||
216 | /* Clear the entry in all cases */ | 225 | /* Clear the entry in all cases */ |
217 | 226 | ||
218 | node->object = NULL; | 227 | node->object = NULL; |
diff --git a/drivers/acpi/acpica/nspredef.c b/drivers/acpi/acpica/nspredef.c index d9e8cbc6e679..7f8e066b12a3 100644 --- a/drivers/acpi/acpica/nspredef.c +++ b/drivers/acpi/acpica/nspredef.c | |||
@@ -144,7 +144,7 @@ acpi_ns_check_predefined_names(struct acpi_namespace_node *node, | |||
144 | 144 | ||
145 | pathname = acpi_ns_get_external_pathname(node); | 145 | pathname = acpi_ns_get_external_pathname(node); |
146 | if (!pathname) { | 146 | if (!pathname) { |
147 | pathname = ACPI_CAST_PTR(char, predefined->info.name); | 147 | return AE_OK; /* Could not get pathname, ignore */ |
148 | } | 148 | } |
149 | 149 | ||
150 | /* | 150 | /* |
@@ -230,10 +230,7 @@ acpi_ns_check_predefined_names(struct acpi_namespace_node *node, | |||
230 | } | 230 | } |
231 | 231 | ||
232 | exit: | 232 | exit: |
233 | if (pathname != predefined->info.name) { | 233 | ACPI_FREE(pathname); |
234 | ACPI_FREE(pathname); | ||
235 | } | ||
236 | |||
237 | return (status); | 234 | return (status); |
238 | } | 235 | } |
239 | 236 | ||
diff --git a/drivers/acpi/acpica/nssearch.c b/drivers/acpi/acpica/nssearch.c index f9b4f51bf8f2..7e865639a928 100644 --- a/drivers/acpi/acpica/nssearch.c +++ b/drivers/acpi/acpica/nssearch.c | |||
@@ -45,6 +45,10 @@ | |||
45 | #include "accommon.h" | 45 | #include "accommon.h" |
46 | #include "acnamesp.h" | 46 | #include "acnamesp.h" |
47 | 47 | ||
48 | #ifdef ACPI_ASL_COMPILER | ||
49 | #include "amlcode.h" | ||
50 | #endif | ||
51 | |||
48 | #define _COMPONENT ACPI_NAMESPACE | 52 | #define _COMPONENT ACPI_NAMESPACE |
49 | ACPI_MODULE_NAME("nssearch") | 53 | ACPI_MODULE_NAME("nssearch") |
50 | 54 | ||
diff --git a/drivers/acpi/acpica/nswalk.c b/drivers/acpi/acpica/nswalk.c index 83e3aa6d4b9b..35539df5c75d 100644 --- a/drivers/acpi/acpica/nswalk.c +++ b/drivers/acpi/acpica/nswalk.c | |||
@@ -52,8 +52,7 @@ ACPI_MODULE_NAME("nswalk") | |||
52 | * | 52 | * |
53 | * FUNCTION: acpi_ns_get_next_node | 53 | * FUNCTION: acpi_ns_get_next_node |
54 | * | 54 | * |
55 | * PARAMETERS: Type - Type of node to be searched for | 55 | * PARAMETERS: parent_node - Parent node whose children we are |
56 | * parent_node - Parent node whose children we are | ||
57 | * getting | 56 | * getting |
58 | * child_node - Previous child that was found. | 57 | * child_node - Previous child that was found. |
59 | * The NEXT child will be returned | 58 | * The NEXT child will be returned |
@@ -66,27 +65,68 @@ ACPI_MODULE_NAME("nswalk") | |||
66 | * within Scope is returned. | 65 | * within Scope is returned. |
67 | * | 66 | * |
68 | ******************************************************************************/ | 67 | ******************************************************************************/ |
69 | struct acpi_namespace_node *acpi_ns_get_next_node(acpi_object_type type, struct acpi_namespace_node | 68 | struct acpi_namespace_node *acpi_ns_get_next_node(struct acpi_namespace_node |
70 | *parent_node, struct acpi_namespace_node | 69 | *parent_node, |
70 | struct acpi_namespace_node | ||
71 | *child_node) | 71 | *child_node) |
72 | { | 72 | { |
73 | struct acpi_namespace_node *next_node = NULL; | ||
74 | |||
75 | ACPI_FUNCTION_ENTRY(); | 73 | ACPI_FUNCTION_ENTRY(); |
76 | 74 | ||
77 | if (!child_node) { | 75 | if (!child_node) { |
78 | 76 | ||
79 | /* It's really the parent's _scope_ that we want */ | 77 | /* It's really the parent's _scope_ that we want */ |
80 | 78 | ||
81 | next_node = parent_node->child; | 79 | return parent_node->child; |
82 | } | 80 | } |
83 | 81 | ||
84 | else { | 82 | /* |
85 | /* Start search at the NEXT node */ | 83 | * Get the next node. |
86 | 84 | * | |
87 | next_node = acpi_ns_get_next_valid_node(child_node); | 85 | * If we are at the end of this peer list, return NULL |
86 | */ | ||
87 | if (child_node->flags & ANOBJ_END_OF_PEER_LIST) { | ||
88 | return NULL; | ||
88 | } | 89 | } |
89 | 90 | ||
91 | /* Otherwise just return the next peer */ | ||
92 | |||
93 | return child_node->peer; | ||
94 | } | ||
95 | |||
96 | /******************************************************************************* | ||
97 | * | ||
98 | * FUNCTION: acpi_ns_get_next_node_typed | ||
99 | * | ||
100 | * PARAMETERS: Type - Type of node to be searched for | ||
101 | * parent_node - Parent node whose children we are | ||
102 | * getting | ||
103 | * child_node - Previous child that was found. | ||
104 | * The NEXT child will be returned | ||
105 | * | ||
106 | * RETURN: struct acpi_namespace_node - Pointer to the NEXT child or NULL if | ||
107 | * none is found. | ||
108 | * | ||
109 | * DESCRIPTION: Return the next peer node within the namespace. If Handle | ||
110 | * is valid, Scope is ignored. Otherwise, the first node | ||
111 | * within Scope is returned. | ||
112 | * | ||
113 | ******************************************************************************/ | ||
114 | |||
115 | struct acpi_namespace_node *acpi_ns_get_next_node_typed(acpi_object_type type, | ||
116 | struct | ||
117 | acpi_namespace_node | ||
118 | *parent_node, | ||
119 | struct | ||
120 | acpi_namespace_node | ||
121 | *child_node) | ||
122 | { | ||
123 | struct acpi_namespace_node *next_node = NULL; | ||
124 | |||
125 | ACPI_FUNCTION_ENTRY(); | ||
126 | |||
127 | next_node = acpi_ns_get_next_node(parent_node, child_node); | ||
128 | |||
129 | |||
90 | /* If any type is OK, we are done */ | 130 | /* If any type is OK, we are done */ |
91 | 131 | ||
92 | if (type == ACPI_TYPE_ANY) { | 132 | if (type == ACPI_TYPE_ANY) { |
@@ -186,9 +226,7 @@ acpi_ns_walk_namespace(acpi_object_type type, | |||
186 | /* Get the next node in this scope. Null if not found */ | 226 | /* Get the next node in this scope. Null if not found */ |
187 | 227 | ||
188 | status = AE_OK; | 228 | status = AE_OK; |
189 | child_node = | 229 | child_node = acpi_ns_get_next_node(parent_node, child_node); |
190 | acpi_ns_get_next_node(ACPI_TYPE_ANY, parent_node, | ||
191 | child_node); | ||
192 | if (child_node) { | 230 | if (child_node) { |
193 | 231 | ||
194 | /* Found next child, get the type if we are not searching for ANY */ | 232 | /* Found next child, get the type if we are not searching for ANY */ |
@@ -269,8 +307,7 @@ acpi_ns_walk_namespace(acpi_object_type type, | |||
269 | * function has specified that the maximum depth has been reached. | 307 | * function has specified that the maximum depth has been reached. |
270 | */ | 308 | */ |
271 | if ((level < max_depth) && (status != AE_CTRL_DEPTH)) { | 309 | if ((level < max_depth) && (status != AE_CTRL_DEPTH)) { |
272 | if (acpi_ns_get_next_node | 310 | if (child_node->child) { |
273 | (ACPI_TYPE_ANY, child_node, NULL)) { | ||
274 | 311 | ||
275 | /* There is at least one child of this node, visit it */ | 312 | /* There is at least one child of this node, visit it */ |
276 | 313 | ||
diff --git a/drivers/acpi/acpica/nsxfname.c b/drivers/acpi/acpica/nsxfname.c index 9589fea24997..f23593d6add4 100644 --- a/drivers/acpi/acpica/nsxfname.c +++ b/drivers/acpi/acpica/nsxfname.c | |||
@@ -45,6 +45,8 @@ | |||
45 | #include <acpi/acpi.h> | 45 | #include <acpi/acpi.h> |
46 | #include "accommon.h" | 46 | #include "accommon.h" |
47 | #include "acnamesp.h" | 47 | #include "acnamesp.h" |
48 | #include "acparser.h" | ||
49 | #include "amlcode.h" | ||
48 | 50 | ||
49 | #define _COMPONENT ACPI_NAMESPACE | 51 | #define _COMPONENT ACPI_NAMESPACE |
50 | ACPI_MODULE_NAME("nsxfname") | 52 | ACPI_MODULE_NAME("nsxfname") |
@@ -358,3 +360,151 @@ acpi_get_object_info(acpi_handle handle, struct acpi_buffer * buffer) | |||
358 | } | 360 | } |
359 | 361 | ||
360 | ACPI_EXPORT_SYMBOL(acpi_get_object_info) | 362 | ACPI_EXPORT_SYMBOL(acpi_get_object_info) |
363 | |||
364 | /****************************************************************************** | ||
365 | * | ||
366 | * FUNCTION: acpi_install_method | ||
367 | * | ||
368 | * PARAMETERS: Buffer - An ACPI table containing one control method | ||
369 | * | ||
370 | * RETURN: Status | ||
371 | * | ||
372 | * DESCRIPTION: Install a control method into the namespace. If the method | ||
373 | * name already exists in the namespace, it is overwritten. The | ||
374 | * input buffer must contain a valid DSDT or SSDT containing a | ||
375 | * single control method. | ||
376 | * | ||
377 | ******************************************************************************/ | ||
378 | acpi_status acpi_install_method(u8 *buffer) | ||
379 | { | ||
380 | struct acpi_table_header *table = | ||
381 | ACPI_CAST_PTR(struct acpi_table_header, buffer); | ||
382 | u8 *aml_buffer; | ||
383 | u8 *aml_start; | ||
384 | char *path; | ||
385 | struct acpi_namespace_node *node; | ||
386 | union acpi_operand_object *method_obj; | ||
387 | struct acpi_parse_state parser_state; | ||
388 | u32 aml_length; | ||
389 | u16 opcode; | ||
390 | u8 method_flags; | ||
391 | acpi_status status; | ||
392 | |||
393 | /* Parameter validation */ | ||
394 | |||
395 | if (!buffer) { | ||
396 | return AE_BAD_PARAMETER; | ||
397 | } | ||
398 | |||
399 | /* Table must be a DSDT or SSDT */ | ||
400 | |||
401 | if (!ACPI_COMPARE_NAME(table->signature, ACPI_SIG_DSDT) && | ||
402 | !ACPI_COMPARE_NAME(table->signature, ACPI_SIG_SSDT)) { | ||
403 | return AE_BAD_HEADER; | ||
404 | } | ||
405 | |||
406 | /* First AML opcode in the table must be a control method */ | ||
407 | |||
408 | parser_state.aml = buffer + sizeof(struct acpi_table_header); | ||
409 | opcode = acpi_ps_peek_opcode(&parser_state); | ||
410 | if (opcode != AML_METHOD_OP) { | ||
411 | return AE_BAD_PARAMETER; | ||
412 | } | ||
413 | |||
414 | /* Extract method information from the raw AML */ | ||
415 | |||
416 | parser_state.aml += acpi_ps_get_opcode_size(opcode); | ||
417 | parser_state.pkg_end = acpi_ps_get_next_package_end(&parser_state); | ||
418 | path = acpi_ps_get_next_namestring(&parser_state); | ||
419 | method_flags = *parser_state.aml++; | ||
420 | aml_start = parser_state.aml; | ||
421 | aml_length = ACPI_PTR_DIFF(parser_state.pkg_end, aml_start); | ||
422 | |||
423 | /* | ||
424 | * Allocate resources up-front. We don't want to have to delete a new | ||
425 | * node from the namespace if we cannot allocate memory. | ||
426 | */ | ||
427 | aml_buffer = ACPI_ALLOCATE(aml_length); | ||
428 | if (!aml_buffer) { | ||
429 | return AE_NO_MEMORY; | ||
430 | } | ||
431 | |||
432 | method_obj = acpi_ut_create_internal_object(ACPI_TYPE_METHOD); | ||
433 | if (!method_obj) { | ||
434 | ACPI_FREE(aml_buffer); | ||
435 | return AE_NO_MEMORY; | ||
436 | } | ||
437 | |||
438 | /* Lock namespace for acpi_ns_lookup, we may be creating a new node */ | ||
439 | |||
440 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | ||
441 | if (ACPI_FAILURE(status)) { | ||
442 | goto error_exit; | ||
443 | } | ||
444 | |||
445 | /* The lookup either returns an existing node or creates a new one */ | ||
446 | |||
447 | status = | ||
448 | acpi_ns_lookup(NULL, path, ACPI_TYPE_METHOD, ACPI_IMODE_LOAD_PASS1, | ||
449 | ACPI_NS_DONT_OPEN_SCOPE | ACPI_NS_ERROR_IF_FOUND, | ||
450 | NULL, &node); | ||
451 | |||
452 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | ||
453 | |||
454 | if (ACPI_FAILURE(status)) { /* ns_lookup */ | ||
455 | if (status != AE_ALREADY_EXISTS) { | ||
456 | goto error_exit; | ||
457 | } | ||
458 | |||
459 | /* Node existed previously, make sure it is a method node */ | ||
460 | |||
461 | if (node->type != ACPI_TYPE_METHOD) { | ||
462 | status = AE_TYPE; | ||
463 | goto error_exit; | ||
464 | } | ||
465 | } | ||
466 | |||
467 | /* Copy the method AML to the local buffer */ | ||
468 | |||
469 | ACPI_MEMCPY(aml_buffer, aml_start, aml_length); | ||
470 | |||
471 | /* Initialize the method object with the new method's information */ | ||
472 | |||
473 | method_obj->method.aml_start = aml_buffer; | ||
474 | method_obj->method.aml_length = aml_length; | ||
475 | |||
476 | method_obj->method.param_count = (u8) | ||
477 | (method_flags & AML_METHOD_ARG_COUNT); | ||
478 | |||
479 | method_obj->method.method_flags = (u8) | ||
480 | (method_flags & ~AML_METHOD_ARG_COUNT); | ||
481 | |||
482 | if (method_flags & AML_METHOD_SERIALIZED) { | ||
483 | method_obj->method.sync_level = (u8) | ||
484 | ((method_flags & AML_METHOD_SYNC_LEVEL) >> 4); | ||
485 | } | ||
486 | |||
487 | /* | ||
488 | * Now that it is complete, we can attach the new method object to | ||
489 | * the method Node (detaches/deletes any existing object) | ||
490 | */ | ||
491 | status = acpi_ns_attach_object(node, method_obj, ACPI_TYPE_METHOD); | ||
492 | |||
493 | /* | ||
494 | * Flag indicates AML buffer is dynamic, must be deleted later. | ||
495 | * Must be set only after attach above. | ||
496 | */ | ||
497 | node->flags |= ANOBJ_ALLOCATED_BUFFER; | ||
498 | |||
499 | /* Remove local reference to the method object */ | ||
500 | |||
501 | acpi_ut_remove_reference(method_obj); | ||
502 | return status; | ||
503 | |||
504 | error_exit: | ||
505 | |||
506 | ACPI_FREE(aml_buffer); | ||
507 | ACPI_FREE(method_obj); | ||
508 | return status; | ||
509 | } | ||
510 | ACPI_EXPORT_SYMBOL(acpi_install_method) | ||
diff --git a/drivers/acpi/acpica/nsxfobj.c b/drivers/acpi/acpica/nsxfobj.c index 1c7efc15225f..4071bad4458e 100644 --- a/drivers/acpi/acpica/nsxfobj.c +++ b/drivers/acpi/acpica/nsxfobj.c | |||
@@ -162,6 +162,7 @@ ACPI_EXPORT_SYMBOL(acpi_get_type) | |||
162 | acpi_status acpi_get_parent(acpi_handle handle, acpi_handle * ret_handle) | 162 | acpi_status acpi_get_parent(acpi_handle handle, acpi_handle * ret_handle) |
163 | { | 163 | { |
164 | struct acpi_namespace_node *node; | 164 | struct acpi_namespace_node *node; |
165 | struct acpi_namespace_node *parent_node; | ||
165 | acpi_status status; | 166 | acpi_status status; |
166 | 167 | ||
167 | if (!ret_handle) { | 168 | if (!ret_handle) { |
@@ -189,12 +190,12 @@ acpi_status acpi_get_parent(acpi_handle handle, acpi_handle * ret_handle) | |||
189 | 190 | ||
190 | /* Get the parent entry */ | 191 | /* Get the parent entry */ |
191 | 192 | ||
192 | *ret_handle = | 193 | parent_node = acpi_ns_get_parent_node(node); |
193 | acpi_ns_convert_entry_to_handle(acpi_ns_get_parent_node(node)); | 194 | *ret_handle = acpi_ns_convert_entry_to_handle(parent_node); |
194 | 195 | ||
195 | /* Return exception if parent is null */ | 196 | /* Return exception if parent is null */ |
196 | 197 | ||
197 | if (!acpi_ns_get_parent_node(node)) { | 198 | if (!parent_node) { |
198 | status = AE_NULL_ENTRY; | 199 | status = AE_NULL_ENTRY; |
199 | } | 200 | } |
200 | 201 | ||
@@ -268,7 +269,7 @@ acpi_get_next_object(acpi_object_type type, | |||
268 | 269 | ||
269 | /* Internal function does the real work */ | 270 | /* Internal function does the real work */ |
270 | 271 | ||
271 | node = acpi_ns_get_next_node(type, parent_node, child_node); | 272 | node = acpi_ns_get_next_node_typed(type, parent_node, child_node); |
272 | if (!node) { | 273 | if (!node) { |
273 | status = AE_NOT_FOUND; | 274 | status = AE_NOT_FOUND; |
274 | goto unlock_and_exit; | 275 | goto unlock_and_exit; |
diff --git a/drivers/acpi/acpica/rscalc.c b/drivers/acpi/acpica/rscalc.c index 88b5a2c4814d..3c4dcc3d1069 100644 --- a/drivers/acpi/acpica/rscalc.c +++ b/drivers/acpi/acpica/rscalc.c | |||
@@ -547,7 +547,7 @@ acpi_rs_get_pci_routing_table_length(union acpi_operand_object *package_object, | |||
547 | 547 | ||
548 | if (!package_element || | 548 | if (!package_element || |
549 | (package_element->common.type != ACPI_TYPE_PACKAGE)) { | 549 | (package_element->common.type != ACPI_TYPE_PACKAGE)) { |
550 | return_ACPI_STATUS (AE_AML_OPERAND_TYPE); | 550 | return_ACPI_STATUS(AE_AML_OPERAND_TYPE); |
551 | } | 551 | } |
552 | 552 | ||
553 | /* | 553 | /* |
@@ -593,9 +593,6 @@ acpi_rs_get_pci_routing_table_length(union acpi_operand_object *package_object, | |||
593 | } else { | 593 | } else { |
594 | temp_size_needed += | 594 | temp_size_needed += |
595 | acpi_ns_get_pathname_length((*sub_object_list)->reference.node); | 595 | acpi_ns_get_pathname_length((*sub_object_list)->reference.node); |
596 | if (!temp_size_needed) { | ||
597 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
598 | } | ||
599 | } | 596 | } |
600 | } else { | 597 | } else { |
601 | /* | 598 | /* |
diff --git a/drivers/acpi/acpica/rsxface.c b/drivers/acpi/acpica/rsxface.c index 69a2aa5b5d83..395212bcd19b 100644 --- a/drivers/acpi/acpica/rsxface.c +++ b/drivers/acpi/acpica/rsxface.c | |||
@@ -338,13 +338,17 @@ acpi_resource_to_address64(struct acpi_resource *resource, | |||
338 | switch (resource->type) { | 338 | switch (resource->type) { |
339 | case ACPI_RESOURCE_TYPE_ADDRESS16: | 339 | case ACPI_RESOURCE_TYPE_ADDRESS16: |
340 | 340 | ||
341 | address16 = (struct acpi_resource_address16 *)&resource->data; | 341 | address16 = |
342 | ACPI_CAST_PTR(struct acpi_resource_address16, | ||
343 | &resource->data); | ||
342 | ACPI_COPY_ADDRESS(out, address16); | 344 | ACPI_COPY_ADDRESS(out, address16); |
343 | break; | 345 | break; |
344 | 346 | ||
345 | case ACPI_RESOURCE_TYPE_ADDRESS32: | 347 | case ACPI_RESOURCE_TYPE_ADDRESS32: |
346 | 348 | ||
347 | address32 = (struct acpi_resource_address32 *)&resource->data; | 349 | address32 = |
350 | ACPI_CAST_PTR(struct acpi_resource_address32, | ||
351 | &resource->data); | ||
348 | ACPI_COPY_ADDRESS(out, address32); | 352 | ACPI_COPY_ADDRESS(out, address32); |
349 | break; | 353 | break; |
350 | 354 | ||
diff --git a/drivers/acpi/acpica/tbfadt.c b/drivers/acpi/acpica/tbfadt.c index 71e655d14cb0..82b02dcb942e 100644 --- a/drivers/acpi/acpica/tbfadt.c +++ b/drivers/acpi/acpica/tbfadt.c | |||
@@ -284,9 +284,9 @@ void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length) | |||
284 | if (length > sizeof(struct acpi_table_fadt)) { | 284 | if (length > sizeof(struct acpi_table_fadt)) { |
285 | ACPI_WARNING((AE_INFO, | 285 | ACPI_WARNING((AE_INFO, |
286 | "FADT (revision %u) is longer than ACPI 2.0 version, " | 286 | "FADT (revision %u) is longer than ACPI 2.0 version, " |
287 | "truncating length 0x%X to 0x%zX", | 287 | "truncating length 0x%X to 0x%X", |
288 | table->revision, (unsigned)length, | 288 | table->revision, length, |
289 | sizeof(struct acpi_table_fadt))); | 289 | (u32)sizeof(struct acpi_table_fadt))); |
290 | } | 290 | } |
291 | 291 | ||
292 | /* Clear the entire local FADT */ | 292 | /* Clear the entire local FADT */ |
@@ -441,7 +441,7 @@ static void acpi_tb_convert_fadt(void) | |||
441 | &acpi_gbl_FADT, | 441 | &acpi_gbl_FADT, |
442 | fadt_info_table | 442 | fadt_info_table |
443 | [i].length), | 443 | [i].length), |
444 | address32); | 444 | (u64) address32); |
445 | } | 445 | } |
446 | } | 446 | } |
447 | } | 447 | } |
@@ -469,7 +469,6 @@ static void acpi_tb_convert_fadt(void) | |||
469 | static void acpi_tb_validate_fadt(void) | 469 | static void acpi_tb_validate_fadt(void) |
470 | { | 470 | { |
471 | char *name; | 471 | char *name; |
472 | u32 *address32; | ||
473 | struct acpi_generic_address *address64; | 472 | struct acpi_generic_address *address64; |
474 | u8 length; | 473 | u8 length; |
475 | u32 i; | 474 | u32 i; |
@@ -505,15 +504,12 @@ static void acpi_tb_validate_fadt(void) | |||
505 | 504 | ||
506 | for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) { | 505 | for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) { |
507 | /* | 506 | /* |
508 | * Generate pointers to the 32-bit and 64-bit addresses, get the | 507 | * Generate pointer to the 64-bit address, get the register |
509 | * register length (width), and the register name | 508 | * length (width) and the register name |
510 | */ | 509 | */ |
511 | address64 = ACPI_ADD_PTR(struct acpi_generic_address, | 510 | address64 = ACPI_ADD_PTR(struct acpi_generic_address, |
512 | &acpi_gbl_FADT, | 511 | &acpi_gbl_FADT, |
513 | fadt_info_table[i].address64); | 512 | fadt_info_table[i].address64); |
514 | address32 = | ||
515 | ACPI_ADD_PTR(u32, &acpi_gbl_FADT, | ||
516 | fadt_info_table[i].address32); | ||
517 | length = | 513 | length = |
518 | *ACPI_ADD_PTR(u8, &acpi_gbl_FADT, | 514 | *ACPI_ADD_PTR(u8, &acpi_gbl_FADT, |
519 | fadt_info_table[i].length); | 515 | fadt_info_table[i].length); |
diff --git a/drivers/acpi/acpica/tbinstal.c b/drivers/acpi/acpica/tbinstal.c index f865d5a096de..63e82329a9e8 100644 --- a/drivers/acpi/acpica/tbinstal.c +++ b/drivers/acpi/acpica/tbinstal.c | |||
@@ -472,7 +472,7 @@ acpi_status acpi_tb_delete_namespace_by_owner(u32 table_index) | |||
472 | * lock may block, and also since the execution of a namespace walk | 472 | * lock may block, and also since the execution of a namespace walk |
473 | * must be allowed to use the interpreter. | 473 | * must be allowed to use the interpreter. |
474 | */ | 474 | */ |
475 | acpi_ut_release_mutex(ACPI_MTX_INTERPRETER); | 475 | (void)acpi_ut_release_mutex(ACPI_MTX_INTERPRETER); |
476 | status = acpi_ut_acquire_write_lock(&acpi_gbl_namespace_rw_lock); | 476 | status = acpi_ut_acquire_write_lock(&acpi_gbl_namespace_rw_lock); |
477 | 477 | ||
478 | acpi_ns_delete_namespace_by_owner(owner_id); | 478 | acpi_ns_delete_namespace_by_owner(owner_id); |
diff --git a/drivers/acpi/acpica/utcopy.c b/drivers/acpi/acpica/utcopy.c index 919624f123d5..0f0c64bf8ac9 100644 --- a/drivers/acpi/acpica/utcopy.c +++ b/drivers/acpi/acpica/utcopy.c | |||
@@ -676,6 +676,7 @@ acpi_ut_copy_simple_object(union acpi_operand_object *source_desc, | |||
676 | { | 676 | { |
677 | u16 reference_count; | 677 | u16 reference_count; |
678 | union acpi_operand_object *next_object; | 678 | union acpi_operand_object *next_object; |
679 | acpi_status status; | ||
679 | 680 | ||
680 | /* Save fields from destination that we don't want to overwrite */ | 681 | /* Save fields from destination that we don't want to overwrite */ |
681 | 682 | ||
@@ -768,6 +769,28 @@ acpi_ut_copy_simple_object(union acpi_operand_object *source_desc, | |||
768 | } | 769 | } |
769 | break; | 770 | break; |
770 | 771 | ||
772 | /* | ||
773 | * For Mutex and Event objects, we cannot simply copy the underlying | ||
774 | * OS object. We must create a new one. | ||
775 | */ | ||
776 | case ACPI_TYPE_MUTEX: | ||
777 | |||
778 | status = acpi_os_create_mutex(&dest_desc->mutex.os_mutex); | ||
779 | if (ACPI_FAILURE(status)) { | ||
780 | return status; | ||
781 | } | ||
782 | break; | ||
783 | |||
784 | case ACPI_TYPE_EVENT: | ||
785 | |||
786 | status = acpi_os_create_semaphore(ACPI_NO_UNIT_LIMIT, 0, | ||
787 | &dest_desc->event. | ||
788 | os_semaphore); | ||
789 | if (ACPI_FAILURE(status)) { | ||
790 | return status; | ||
791 | } | ||
792 | break; | ||
793 | |||
771 | default: | 794 | default: |
772 | /* Nothing to do for other simple objects */ | 795 | /* Nothing to do for other simple objects */ |
773 | break; | 796 | break; |
diff --git a/drivers/acpi/acpica/utdebug.c b/drivers/acpi/acpica/utdebug.c index 38821f53042c..527d729f6815 100644 --- a/drivers/acpi/acpica/utdebug.c +++ b/drivers/acpi/acpica/utdebug.c | |||
@@ -179,9 +179,9 @@ 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 %lX to TID %lX ****\n\n", | 182 | ("\n**** Context Switch from TID %p to TID %p ****\n\n", |
183 | (unsigned long)acpi_gbl_prev_thread_id, | 183 | ACPI_CAST_PTR(void, acpi_gbl_prev_thread_id), |
184 | (unsigned long)thread_id); | 184 | ACPI_CAST_PTR(void, thread_id)); |
185 | } | 185 | } |
186 | 186 | ||
187 | acpi_gbl_prev_thread_id = thread_id; | 187 | acpi_gbl_prev_thread_id = thread_id; |
@@ -194,7 +194,7 @@ acpi_debug_print(u32 requested_debug_level, | |||
194 | acpi_os_printf("%8s-%04ld ", module_name, line_number); | 194 | acpi_os_printf("%8s-%04ld ", module_name, line_number); |
195 | 195 | ||
196 | if (ACPI_LV_THREADS & acpi_dbg_level) { | 196 | if (ACPI_LV_THREADS & acpi_dbg_level) { |
197 | acpi_os_printf("[%04lX] ", (unsigned long)thread_id); | 197 | acpi_os_printf("[%p] ", ACPI_CAST_PTR(void, thread_id)); |
198 | } | 198 | } |
199 | 199 | ||
200 | acpi_os_printf("[%02ld] %-22.22s: ", | 200 | acpi_os_printf("[%02ld] %-22.22s: ", |
diff --git a/drivers/acpi/acpica/utdelete.c b/drivers/acpi/acpica/utdelete.c index a5ee23bc4f55..bc1710315088 100644 --- a/drivers/acpi/acpica/utdelete.c +++ b/drivers/acpi/acpica/utdelete.c | |||
@@ -75,6 +75,7 @@ static void acpi_ut_delete_internal_obj(union acpi_operand_object *object) | |||
75 | union acpi_operand_object *handler_desc; | 75 | union acpi_operand_object *handler_desc; |
76 | union acpi_operand_object *second_desc; | 76 | union acpi_operand_object *second_desc; |
77 | union acpi_operand_object *next_desc; | 77 | union acpi_operand_object *next_desc; |
78 | union acpi_operand_object **last_obj_ptr; | ||
78 | 79 | ||
79 | ACPI_FUNCTION_TRACE_PTR(ut_delete_internal_obj, object); | 80 | ACPI_FUNCTION_TRACE_PTR(ut_delete_internal_obj, object); |
80 | 81 | ||
@@ -223,6 +224,26 @@ static void acpi_ut_delete_internal_obj(union acpi_operand_object *object) | |||
223 | */ | 224 | */ |
224 | handler_desc = object->region.handler; | 225 | handler_desc = object->region.handler; |
225 | if (handler_desc) { | 226 | if (handler_desc) { |
227 | next_desc = | ||
228 | handler_desc->address_space.region_list; | ||
229 | last_obj_ptr = | ||
230 | &handler_desc->address_space.region_list; | ||
231 | |||
232 | /* Remove the region object from the handler's list */ | ||
233 | |||
234 | while (next_desc) { | ||
235 | if (next_desc == object) { | ||
236 | *last_obj_ptr = | ||
237 | next_desc->region.next; | ||
238 | break; | ||
239 | } | ||
240 | |||
241 | /* Walk the linked list of handler */ | ||
242 | |||
243 | last_obj_ptr = &next_desc->region.next; | ||
244 | next_desc = next_desc->region.next; | ||
245 | } | ||
246 | |||
226 | if (handler_desc->address_space.handler_flags & | 247 | if (handler_desc->address_space.handler_flags & |
227 | ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) { | 248 | ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) { |
228 | 249 | ||
diff --git a/drivers/acpi/acpica/utmisc.c b/drivers/acpi/acpica/utmisc.c index 1c9e250caefb..fbe782348b0b 100644 --- a/drivers/acpi/acpica/utmisc.c +++ b/drivers/acpi/acpica/utmisc.c | |||
@@ -1033,11 +1033,12 @@ acpi_error(const char *module_name, u32 line_number, const char *format, ...) | |||
1033 | { | 1033 | { |
1034 | va_list args; | 1034 | va_list args; |
1035 | 1035 | ||
1036 | acpi_os_printf("ACPI Error (%s-%04d): ", module_name, line_number); | 1036 | acpi_os_printf("ACPI Error: "); |
1037 | 1037 | ||
1038 | va_start(args, format); | 1038 | va_start(args, format); |
1039 | acpi_os_vprintf(format, args); | 1039 | acpi_os_vprintf(format, args); |
1040 | acpi_os_printf(" [%X]\n", ACPI_CA_VERSION); | 1040 | acpi_os_printf(" %8.8X %s-%u\n", ACPI_CA_VERSION, module_name, |
1041 | line_number); | ||
1041 | va_end(args); | 1042 | va_end(args); |
1042 | } | 1043 | } |
1043 | 1044 | ||
@@ -1047,12 +1048,12 @@ acpi_exception(const char *module_name, | |||
1047 | { | 1048 | { |
1048 | va_list args; | 1049 | va_list args; |
1049 | 1050 | ||
1050 | acpi_os_printf("ACPI Exception (%s-%04d): %s, ", module_name, | 1051 | acpi_os_printf("ACPI Exception: %s, ", acpi_format_exception(status)); |
1051 | line_number, acpi_format_exception(status)); | ||
1052 | 1052 | ||
1053 | va_start(args, format); | 1053 | va_start(args, format); |
1054 | acpi_os_vprintf(format, args); | 1054 | acpi_os_vprintf(format, args); |
1055 | acpi_os_printf(" [%X]\n", ACPI_CA_VERSION); | 1055 | acpi_os_printf(" %8.8X %s-%u\n", ACPI_CA_VERSION, module_name, |
1056 | line_number); | ||
1056 | va_end(args); | 1057 | va_end(args); |
1057 | } | 1058 | } |
1058 | 1059 | ||
@@ -1061,11 +1062,12 @@ acpi_warning(const char *module_name, u32 line_number, const char *format, ...) | |||
1061 | { | 1062 | { |
1062 | va_list args; | 1063 | va_list args; |
1063 | 1064 | ||
1064 | acpi_os_printf("ACPI Warning (%s-%04d): ", module_name, line_number); | 1065 | acpi_os_printf("ACPI Warning: "); |
1065 | 1066 | ||
1066 | va_start(args, format); | 1067 | va_start(args, format); |
1067 | acpi_os_vprintf(format, args); | 1068 | acpi_os_vprintf(format, args); |
1068 | acpi_os_printf(" [%X]\n", ACPI_CA_VERSION); | 1069 | acpi_os_printf(" %8.8X %s-%u\n", ACPI_CA_VERSION, module_name, |
1070 | line_number); | ||
1069 | va_end(args); | 1071 | va_end(args); |
1070 | } | 1072 | } |
1071 | 1073 | ||
@@ -1074,10 +1076,6 @@ acpi_info(const char *module_name, u32 line_number, const char *format, ...) | |||
1074 | { | 1076 | { |
1075 | va_list args; | 1077 | va_list args; |
1076 | 1078 | ||
1077 | /* | ||
1078 | * Removed module_name, line_number, and acpica version, not needed | ||
1079 | * for info output | ||
1080 | */ | ||
1081 | acpi_os_printf("ACPI: "); | 1079 | acpi_os_printf("ACPI: "); |
1082 | 1080 | ||
1083 | va_start(args, format); | 1081 | va_start(args, format); |
diff --git a/drivers/acpi/acpica/utmutex.c b/drivers/acpi/acpica/utmutex.c index 26c93a748e64..80bb65154117 100644 --- a/drivers/acpi/acpica/utmutex.c +++ b/drivers/acpi/acpica/utmutex.c | |||
@@ -230,17 +230,18 @@ acpi_status acpi_ut_acquire_mutex(acpi_mutex_handle mutex_id) | |||
230 | if (acpi_gbl_mutex_info[i].thread_id == this_thread_id) { | 230 | if (acpi_gbl_mutex_info[i].thread_id == this_thread_id) { |
231 | if (i == mutex_id) { | 231 | if (i == mutex_id) { |
232 | ACPI_ERROR((AE_INFO, | 232 | ACPI_ERROR((AE_INFO, |
233 | "Mutex [%s] already acquired by this thread [%X]", | 233 | "Mutex [%s] already acquired by this thread [%p]", |
234 | acpi_ut_get_mutex_name | 234 | acpi_ut_get_mutex_name |
235 | (mutex_id), | 235 | (mutex_id), |
236 | this_thread_id)); | 236 | ACPI_CAST_PTR(void, |
237 | this_thread_id))); | ||
237 | 238 | ||
238 | return (AE_ALREADY_ACQUIRED); | 239 | return (AE_ALREADY_ACQUIRED); |
239 | } | 240 | } |
240 | 241 | ||
241 | ACPI_ERROR((AE_INFO, | 242 | ACPI_ERROR((AE_INFO, |
242 | "Invalid acquire order: Thread %X owns [%s], wants [%s]", | 243 | "Invalid acquire order: Thread %p owns [%s], wants [%s]", |
243 | this_thread_id, | 244 | ACPI_CAST_PTR(void, this_thread_id), |
244 | acpi_ut_get_mutex_name(i), | 245 | acpi_ut_get_mutex_name(i), |
245 | acpi_ut_get_mutex_name(mutex_id))); | 246 | acpi_ut_get_mutex_name(mutex_id))); |
246 | 247 | ||
@@ -251,24 +252,24 @@ acpi_status acpi_ut_acquire_mutex(acpi_mutex_handle mutex_id) | |||
251 | #endif | 252 | #endif |
252 | 253 | ||
253 | ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, | 254 | ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, |
254 | "Thread %lX attempting to acquire Mutex [%s]\n", | 255 | "Thread %p attempting to acquire Mutex [%s]\n", |
255 | (unsigned long)this_thread_id, | 256 | ACPI_CAST_PTR(void, this_thread_id), |
256 | acpi_ut_get_mutex_name(mutex_id))); | 257 | acpi_ut_get_mutex_name(mutex_id))); |
257 | 258 | ||
258 | status = acpi_os_acquire_mutex(acpi_gbl_mutex_info[mutex_id].mutex, | 259 | status = acpi_os_acquire_mutex(acpi_gbl_mutex_info[mutex_id].mutex, |
259 | ACPI_WAIT_FOREVER); | 260 | ACPI_WAIT_FOREVER); |
260 | if (ACPI_SUCCESS(status)) { | 261 | if (ACPI_SUCCESS(status)) { |
261 | ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, | 262 | ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, |
262 | "Thread %lX acquired Mutex [%s]\n", | 263 | "Thread %p acquired Mutex [%s]\n", |
263 | (unsigned long)this_thread_id, | 264 | ACPI_CAST_PTR(void, this_thread_id), |
264 | acpi_ut_get_mutex_name(mutex_id))); | 265 | acpi_ut_get_mutex_name(mutex_id))); |
265 | 266 | ||
266 | acpi_gbl_mutex_info[mutex_id].use_count++; | 267 | acpi_gbl_mutex_info[mutex_id].use_count++; |
267 | acpi_gbl_mutex_info[mutex_id].thread_id = this_thread_id; | 268 | acpi_gbl_mutex_info[mutex_id].thread_id = this_thread_id; |
268 | } else { | 269 | } else { |
269 | ACPI_EXCEPTION((AE_INFO, status, | 270 | ACPI_EXCEPTION((AE_INFO, status, |
270 | "Thread %lX could not acquire Mutex [%X]", | 271 | "Thread %p could not acquire Mutex [%X]", |
271 | (unsigned long)this_thread_id, mutex_id)); | 272 | ACPI_CAST_PTR(void, this_thread_id), mutex_id)); |
272 | } | 273 | } |
273 | 274 | ||
274 | return (status); | 275 | return (status); |
@@ -293,9 +294,8 @@ acpi_status acpi_ut_release_mutex(acpi_mutex_handle mutex_id) | |||
293 | ACPI_FUNCTION_NAME(ut_release_mutex); | 294 | ACPI_FUNCTION_NAME(ut_release_mutex); |
294 | 295 | ||
295 | this_thread_id = acpi_os_get_thread_id(); | 296 | this_thread_id = acpi_os_get_thread_id(); |
296 | ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, | 297 | ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Thread %p releasing Mutex [%s]\n", |
297 | "Thread %lX releasing Mutex [%s]\n", | 298 | ACPI_CAST_PTR(void, this_thread_id), |
298 | (unsigned long)this_thread_id, | ||
299 | acpi_ut_get_mutex_name(mutex_id))); | 299 | acpi_ut_get_mutex_name(mutex_id))); |
300 | 300 | ||
301 | if (mutex_id > ACPI_MAX_MUTEX) { | 301 | if (mutex_id > ACPI_MAX_MUTEX) { |
diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c index 09c69806c1fc..f6baa77deefb 100644 --- a/drivers/acpi/blacklist.c +++ b/drivers/acpi/blacklist.c | |||
@@ -192,6 +192,22 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { | |||
192 | DMI_MATCH(DMI_PRODUCT_NAME, "ESPRIMO Mobile V5505"), | 192 | DMI_MATCH(DMI_PRODUCT_NAME, "ESPRIMO Mobile V5505"), |
193 | }, | 193 | }, |
194 | }, | 194 | }, |
195 | { | ||
196 | .callback = dmi_disable_osi_vista, | ||
197 | .ident = "Sony VGN-NS10J_S", | ||
198 | .matches = { | ||
199 | DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), | ||
200 | DMI_MATCH(DMI_PRODUCT_NAME, "VGN-NS10J_S"), | ||
201 | }, | ||
202 | }, | ||
203 | { | ||
204 | .callback = dmi_disable_osi_vista, | ||
205 | .ident = "Sony VGN-SR290J", | ||
206 | .matches = { | ||
207 | DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), | ||
208 | DMI_MATCH(DMI_PRODUCT_NAME, "Sony VGN-SR290J"), | ||
209 | }, | ||
210 | }, | ||
195 | 211 | ||
196 | /* | 212 | /* |
197 | * BIOS invocation of _OSI(Linux) is almost always a BIOS bug. | 213 | * BIOS invocation of _OSI(Linux) is almost always a BIOS bug. |
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index 8bd2c2a6884d..a8a5c29958c8 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c | |||
@@ -140,46 +140,6 @@ struct device *acpi_get_physical_device(acpi_handle handle) | |||
140 | 140 | ||
141 | EXPORT_SYMBOL(acpi_get_physical_device); | 141 | EXPORT_SYMBOL(acpi_get_physical_device); |
142 | 142 | ||
143 | /* ToDo: When a PCI bridge is found, return the PCI device behind the bridge | ||
144 | * This should work in general, but did not on a Lenovo T61 for the | ||
145 | * graphics card. But this must be fixed when the PCI device is | ||
146 | * bound and the kernel device struct is attached to the acpi device | ||
147 | * Note: A success call will increase reference count by one | ||
148 | * Do call put_device(dev) on the returned device then | ||
149 | */ | ||
150 | struct device *acpi_get_physical_pci_device(acpi_handle handle) | ||
151 | { | ||
152 | struct device *dev; | ||
153 | long long device_id; | ||
154 | acpi_status status; | ||
155 | |||
156 | status = | ||
157 | acpi_evaluate_integer(handle, "_ADR", NULL, &device_id); | ||
158 | |||
159 | if (ACPI_FAILURE(status)) | ||
160 | return NULL; | ||
161 | |||
162 | /* We need to attempt to determine whether the _ADR refers to a | ||
163 | PCI device or not. There's no terribly good way to do this, | ||
164 | so the best we can hope for is to assume that there'll never | ||
165 | be a device in the host bridge */ | ||
166 | if (device_id >= 0x10000) { | ||
167 | /* It looks like a PCI device. Does it exist? */ | ||
168 | dev = acpi_get_physical_device(handle); | ||
169 | } else { | ||
170 | /* It doesn't look like a PCI device. Does its parent | ||
171 | exist? */ | ||
172 | acpi_handle phandle; | ||
173 | if (acpi_get_parent(handle, &phandle)) | ||
174 | return NULL; | ||
175 | dev = acpi_get_physical_device(phandle); | ||
176 | } | ||
177 | if (!dev) | ||
178 | return NULL; | ||
179 | return dev; | ||
180 | } | ||
181 | EXPORT_SYMBOL(acpi_get_physical_pci_device); | ||
182 | |||
183 | static int acpi_bind_one(struct device *dev, acpi_handle handle) | 143 | static int acpi_bind_one(struct device *dev, acpi_handle handle) |
184 | { | 144 | { |
185 | struct acpi_device *acpi_dev; | 145 | struct acpi_device *acpi_dev; |
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index d916bea729f1..71670719d61a 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c | |||
@@ -79,6 +79,7 @@ static acpi_osd_handler acpi_irq_handler; | |||
79 | static void *acpi_irq_context; | 79 | static void *acpi_irq_context; |
80 | static struct workqueue_struct *kacpid_wq; | 80 | static struct workqueue_struct *kacpid_wq; |
81 | static struct workqueue_struct *kacpi_notify_wq; | 81 | static struct workqueue_struct *kacpi_notify_wq; |
82 | static struct workqueue_struct *kacpi_hotplug_wq; | ||
82 | 83 | ||
83 | struct acpi_res_list { | 84 | struct acpi_res_list { |
84 | resource_size_t start; | 85 | resource_size_t start; |
@@ -192,8 +193,10 @@ acpi_status acpi_os_initialize1(void) | |||
192 | { | 193 | { |
193 | kacpid_wq = create_singlethread_workqueue("kacpid"); | 194 | kacpid_wq = create_singlethread_workqueue("kacpid"); |
194 | kacpi_notify_wq = create_singlethread_workqueue("kacpi_notify"); | 195 | kacpi_notify_wq = create_singlethread_workqueue("kacpi_notify"); |
196 | kacpi_hotplug_wq = create_singlethread_workqueue("kacpi_hotplug"); | ||
195 | BUG_ON(!kacpid_wq); | 197 | BUG_ON(!kacpid_wq); |
196 | BUG_ON(!kacpi_notify_wq); | 198 | BUG_ON(!kacpi_notify_wq); |
199 | BUG_ON(!kacpi_hotplug_wq); | ||
197 | return AE_OK; | 200 | return AE_OK; |
198 | } | 201 | } |
199 | 202 | ||
@@ -206,6 +209,7 @@ acpi_status acpi_os_terminate(void) | |||
206 | 209 | ||
207 | destroy_workqueue(kacpid_wq); | 210 | destroy_workqueue(kacpid_wq); |
208 | destroy_workqueue(kacpi_notify_wq); | 211 | destroy_workqueue(kacpi_notify_wq); |
212 | destroy_workqueue(kacpi_hotplug_wq); | ||
209 | 213 | ||
210 | return AE_OK; | 214 | return AE_OK; |
211 | } | 215 | } |
@@ -716,6 +720,7 @@ static acpi_status __acpi_os_execute(acpi_execute_type type, | |||
716 | acpi_status status = AE_OK; | 720 | acpi_status status = AE_OK; |
717 | struct acpi_os_dpc *dpc; | 721 | struct acpi_os_dpc *dpc; |
718 | struct workqueue_struct *queue; | 722 | struct workqueue_struct *queue; |
723 | work_func_t func; | ||
719 | int ret; | 724 | int ret; |
720 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | 725 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, |
721 | "Scheduling function [%p(%p)] for deferred execution.\n", | 726 | "Scheduling function [%p(%p)] for deferred execution.\n", |
@@ -740,15 +745,17 @@ static acpi_status __acpi_os_execute(acpi_execute_type type, | |||
740 | dpc->function = function; | 745 | dpc->function = function; |
741 | dpc->context = context; | 746 | dpc->context = context; |
742 | 747 | ||
743 | if (!hp) { | 748 | /* |
744 | INIT_WORK(&dpc->work, acpi_os_execute_deferred); | 749 | * We can't run hotplug code in keventd_wq/kacpid_wq/kacpid_notify_wq |
745 | queue = (type == OSL_NOTIFY_HANDLER) ? | 750 | * because the hotplug code may call driver .remove() functions, |
746 | kacpi_notify_wq : kacpid_wq; | 751 | * which invoke flush_scheduled_work/acpi_os_wait_events_complete |
747 | ret = queue_work(queue, &dpc->work); | 752 | * to flush these workqueues. |
748 | } else { | 753 | */ |
749 | INIT_WORK(&dpc->work, acpi_os_execute_hp_deferred); | 754 | queue = hp ? kacpi_hotplug_wq : |
750 | ret = schedule_work(&dpc->work); | 755 | (type == OSL_NOTIFY_HANDLER ? kacpi_notify_wq : kacpid_wq); |
751 | } | 756 | func = hp ? acpi_os_execute_hp_deferred : acpi_os_execute_deferred; |
757 | INIT_WORK(&dpc->work, func); | ||
758 | ret = queue_work(queue, &dpc->work); | ||
752 | 759 | ||
753 | if (!ret) { | 760 | if (!ret) { |
754 | printk(KERN_ERR PREFIX | 761 | printk(KERN_ERR PREFIX |
diff --git a/drivers/acpi/pci_bind.c b/drivers/acpi/pci_bind.c index bc46de3d967f..a5a77b78a723 100644 --- a/drivers/acpi/pci_bind.c +++ b/drivers/acpi/pci_bind.c | |||
@@ -24,12 +24,7 @@ | |||
24 | */ | 24 | */ |
25 | 25 | ||
26 | #include <linux/kernel.h> | 26 | #include <linux/kernel.h> |
27 | #include <linux/module.h> | ||
28 | #include <linux/init.h> | ||
29 | #include <linux/types.h> | 27 | #include <linux/types.h> |
30 | #include <linux/proc_fs.h> | ||
31 | #include <linux/spinlock.h> | ||
32 | #include <linux/pm.h> | ||
33 | #include <linux/pci.h> | 28 | #include <linux/pci.h> |
34 | #include <linux/acpi.h> | 29 | #include <linux/acpi.h> |
35 | #include <acpi/acpi_bus.h> | 30 | #include <acpi/acpi_bus.h> |
@@ -38,310 +33,76 @@ | |||
38 | #define _COMPONENT ACPI_PCI_COMPONENT | 33 | #define _COMPONENT ACPI_PCI_COMPONENT |
39 | ACPI_MODULE_NAME("pci_bind"); | 34 | ACPI_MODULE_NAME("pci_bind"); |
40 | 35 | ||
41 | struct acpi_pci_data { | 36 | static int acpi_pci_unbind(struct acpi_device *device) |
42 | struct acpi_pci_id id; | ||
43 | struct pci_bus *bus; | ||
44 | struct pci_dev *dev; | ||
45 | }; | ||
46 | |||
47 | static int acpi_pci_unbind(struct acpi_device *device); | ||
48 | |||
49 | static void acpi_pci_data_handler(acpi_handle handle, u32 function, | ||
50 | void *context) | ||
51 | { | ||
52 | |||
53 | /* TBD: Anything we need to do here? */ | ||
54 | |||
55 | return; | ||
56 | } | ||
57 | |||
58 | /** | ||
59 | * acpi_get_pci_id | ||
60 | * ------------------ | ||
61 | * This function is used by the ACPI Interpreter (a.k.a. Core Subsystem) | ||
62 | * to resolve PCI information for ACPI-PCI devices defined in the namespace. | ||
63 | * This typically occurs when resolving PCI operation region information. | ||
64 | */ | ||
65 | acpi_status acpi_get_pci_id(acpi_handle handle, struct acpi_pci_id *id) | ||
66 | { | 37 | { |
67 | int result = 0; | 38 | struct pci_dev *dev; |
68 | acpi_status status = AE_OK; | ||
69 | struct acpi_device *device = NULL; | ||
70 | struct acpi_pci_data *data = NULL; | ||
71 | |||
72 | |||
73 | if (!id) | ||
74 | return AE_BAD_PARAMETER; | ||
75 | |||
76 | result = acpi_bus_get_device(handle, &device); | ||
77 | if (result) { | ||
78 | printk(KERN_ERR PREFIX | ||
79 | "Invalid ACPI Bus context for device %s\n", | ||
80 | acpi_device_bid(device)); | ||
81 | return AE_NOT_EXIST; | ||
82 | } | ||
83 | |||
84 | status = acpi_get_data(handle, acpi_pci_data_handler, (void **)&data); | ||
85 | if (ACPI_FAILURE(status) || !data) { | ||
86 | ACPI_EXCEPTION((AE_INFO, status, | ||
87 | "Invalid ACPI-PCI context for device %s", | ||
88 | acpi_device_bid(device))); | ||
89 | return status; | ||
90 | } | ||
91 | 39 | ||
92 | *id = data->id; | 40 | dev = acpi_get_pci_dev(device->handle); |
41 | if (!dev || !dev->subordinate) | ||
42 | goto out; | ||
93 | 43 | ||
94 | /* | 44 | acpi_pci_irq_del_prt(dev->subordinate); |
95 | id->segment = data->id.segment; | ||
96 | id->bus = data->id.bus; | ||
97 | id->device = data->id.device; | ||
98 | id->function = data->id.function; | ||
99 | */ | ||
100 | 45 | ||
101 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 46 | device->ops.bind = NULL; |
102 | "Device %s has PCI address %04x:%02x:%02x.%d\n", | 47 | device->ops.unbind = NULL; |
103 | acpi_device_bid(device), id->segment, id->bus, | ||
104 | id->device, id->function)); | ||
105 | 48 | ||
106 | return AE_OK; | 49 | out: |
50 | pci_dev_put(dev); | ||
51 | return 0; | ||
107 | } | 52 | } |
108 | 53 | ||
109 | EXPORT_SYMBOL(acpi_get_pci_id); | 54 | static int acpi_pci_bind(struct acpi_device *device) |
110 | |||
111 | int acpi_pci_bind(struct acpi_device *device) | ||
112 | { | 55 | { |
113 | int result = 0; | ||
114 | acpi_status status; | 56 | acpi_status status; |
115 | struct acpi_pci_data *data; | ||
116 | struct acpi_pci_data *pdata; | ||
117 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
118 | acpi_handle handle; | 57 | acpi_handle handle; |
58 | struct pci_bus *bus; | ||
59 | struct pci_dev *dev; | ||
119 | 60 | ||
120 | if (!device || !device->parent) | 61 | dev = acpi_get_pci_dev(device->handle); |
121 | return -EINVAL; | 62 | if (!dev) |
122 | 63 | return 0; | |
123 | data = kzalloc(sizeof(struct acpi_pci_data), GFP_KERNEL); | ||
124 | if (!data) | ||
125 | return -ENOMEM; | ||
126 | |||
127 | status = acpi_get_name(device->handle, ACPI_FULL_PATHNAME, &buffer); | ||
128 | if (ACPI_FAILURE(status)) { | ||
129 | kfree(data); | ||
130 | return -ENODEV; | ||
131 | } | ||
132 | |||
133 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Binding PCI device [%s]...\n", | ||
134 | (char *)buffer.pointer)); | ||
135 | |||
136 | /* | ||
137 | * Segment & Bus | ||
138 | * ------------- | ||
139 | * These are obtained via the parent device's ACPI-PCI context. | ||
140 | */ | ||
141 | status = acpi_get_data(device->parent->handle, acpi_pci_data_handler, | ||
142 | (void **)&pdata); | ||
143 | if (ACPI_FAILURE(status) || !pdata || !pdata->bus) { | ||
144 | ACPI_EXCEPTION((AE_INFO, status, | ||
145 | "Invalid ACPI-PCI context for parent device %s", | ||
146 | acpi_device_bid(device->parent))); | ||
147 | result = -ENODEV; | ||
148 | goto end; | ||
149 | } | ||
150 | data->id.segment = pdata->id.segment; | ||
151 | data->id.bus = pdata->bus->number; | ||
152 | |||
153 | /* | ||
154 | * Device & Function | ||
155 | * ----------------- | ||
156 | * These are simply obtained from the device's _ADR method. Note | ||
157 | * that a value of zero is valid. | ||
158 | */ | ||
159 | data->id.device = device->pnp.bus_address >> 16; | ||
160 | data->id.function = device->pnp.bus_address & 0xFFFF; | ||
161 | |||
162 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "...to %04x:%02x:%02x.%d\n", | ||
163 | data->id.segment, data->id.bus, data->id.device, | ||
164 | data->id.function)); | ||
165 | |||
166 | /* | ||
167 | * TBD: Support slot devices (e.g. function=0xFFFF). | ||
168 | */ | ||
169 | |||
170 | /* | ||
171 | * Locate PCI Device | ||
172 | * ----------------- | ||
173 | * Locate matching device in PCI namespace. If it doesn't exist | ||
174 | * this typically means that the device isn't currently inserted | ||
175 | * (e.g. docking station, port replicator, etc.). | ||
176 | */ | ||
177 | data->dev = pci_get_slot(pdata->bus, | ||
178 | PCI_DEVFN(data->id.device, data->id.function)); | ||
179 | if (!data->dev) { | ||
180 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
181 | "Device %04x:%02x:%02x.%d not present in PCI namespace\n", | ||
182 | data->id.segment, data->id.bus, | ||
183 | data->id.device, data->id.function)); | ||
184 | result = -ENODEV; | ||
185 | goto end; | ||
186 | } | ||
187 | if (!data->dev->bus) { | ||
188 | printk(KERN_ERR PREFIX | ||
189 | "Device %04x:%02x:%02x.%d has invalid 'bus' field\n", | ||
190 | data->id.segment, data->id.bus, | ||
191 | data->id.device, data->id.function); | ||
192 | result = -ENODEV; | ||
193 | goto end; | ||
194 | } | ||
195 | 64 | ||
196 | /* | 65 | /* |
197 | * PCI Bridge? | 66 | * Install the 'bind' function to facilitate callbacks for |
198 | * ----------- | 67 | * children of the P2P bridge. |
199 | * If so, set the 'bus' field and install the 'bind' function to | ||
200 | * facilitate callbacks for all of its children. | ||
201 | */ | 68 | */ |
202 | if (data->dev->subordinate) { | 69 | if (dev->subordinate) { |
203 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 70 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
204 | "Device %04x:%02x:%02x.%d is a PCI bridge\n", | 71 | "Device %04x:%02x:%02x.%d is a PCI bridge\n", |
205 | data->id.segment, data->id.bus, | 72 | pci_domain_nr(dev->bus), dev->bus->number, |
206 | data->id.device, data->id.function)); | 73 | PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn))); |
207 | data->bus = data->dev->subordinate; | ||
208 | device->ops.bind = acpi_pci_bind; | 74 | device->ops.bind = acpi_pci_bind; |
209 | device->ops.unbind = acpi_pci_unbind; | 75 | device->ops.unbind = acpi_pci_unbind; |
210 | } | 76 | } |
211 | 77 | ||
212 | /* | 78 | /* |
213 | * Attach ACPI-PCI Context | 79 | * Evaluate and parse _PRT, if exists. This code allows parsing of |
214 | * ----------------------- | 80 | * _PRT objects within the scope of non-bridge devices. Note that |
215 | * Thus binding the ACPI and PCI devices. | 81 | * _PRTs within the scope of a PCI bridge assume the bridge's |
216 | */ | 82 | * subordinate bus number. |
217 | status = acpi_attach_data(device->handle, acpi_pci_data_handler, data); | ||
218 | if (ACPI_FAILURE(status)) { | ||
219 | ACPI_EXCEPTION((AE_INFO, status, | ||
220 | "Unable to attach ACPI-PCI context to device %s", | ||
221 | acpi_device_bid(device))); | ||
222 | result = -ENODEV; | ||
223 | goto end; | ||
224 | } | ||
225 | |||
226 | /* | ||
227 | * PCI Routing Table | ||
228 | * ----------------- | ||
229 | * Evaluate and parse _PRT, if exists. This code is independent of | ||
230 | * PCI bridges (above) to allow parsing of _PRT objects within the | ||
231 | * scope of non-bridge devices. Note that _PRTs within the scope of | ||
232 | * a PCI bridge assume the bridge's subordinate bus number. | ||
233 | * | 83 | * |
234 | * TBD: Can _PRTs exist within the scope of non-bridge PCI devices? | 84 | * TBD: Can _PRTs exist within the scope of non-bridge PCI devices? |
235 | */ | 85 | */ |
236 | status = acpi_get_handle(device->handle, METHOD_NAME__PRT, &handle); | 86 | status = acpi_get_handle(device->handle, METHOD_NAME__PRT, &handle); |
237 | if (ACPI_SUCCESS(status)) { | ||
238 | if (data->bus) /* PCI-PCI bridge */ | ||
239 | acpi_pci_irq_add_prt(device->handle, data->id.segment, | ||
240 | data->bus->number); | ||
241 | else /* non-bridge PCI device */ | ||
242 | acpi_pci_irq_add_prt(device->handle, data->id.segment, | ||
243 | data->id.bus); | ||
244 | } | ||
245 | |||
246 | end: | ||
247 | kfree(buffer.pointer); | ||
248 | if (result) { | ||
249 | pci_dev_put(data->dev); | ||
250 | kfree(data); | ||
251 | } | ||
252 | return result; | ||
253 | } | ||
254 | |||
255 | static int acpi_pci_unbind(struct acpi_device *device) | ||
256 | { | ||
257 | int result = 0; | ||
258 | acpi_status status; | ||
259 | struct acpi_pci_data *data; | ||
260 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
261 | |||
262 | |||
263 | if (!device || !device->parent) | ||
264 | return -EINVAL; | ||
265 | |||
266 | status = acpi_get_name(device->handle, ACPI_FULL_PATHNAME, &buffer); | ||
267 | if (ACPI_FAILURE(status)) | 87 | if (ACPI_FAILURE(status)) |
268 | return -ENODEV; | 88 | goto out; |
269 | 89 | ||
270 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Unbinding PCI device [%s]...\n", | 90 | if (dev->subordinate) |
271 | (char *) buffer.pointer)); | 91 | bus = dev->subordinate; |
272 | kfree(buffer.pointer); | 92 | else |
93 | bus = dev->bus; | ||
273 | 94 | ||
274 | status = | 95 | acpi_pci_irq_add_prt(device->handle, bus); |
275 | acpi_get_data(device->handle, acpi_pci_data_handler, | ||
276 | (void **)&data); | ||
277 | if (ACPI_FAILURE(status)) { | ||
278 | result = -ENODEV; | ||
279 | goto end; | ||
280 | } | ||
281 | 96 | ||
282 | status = acpi_detach_data(device->handle, acpi_pci_data_handler); | 97 | out: |
283 | if (ACPI_FAILURE(status)) { | 98 | pci_dev_put(dev); |
284 | ACPI_EXCEPTION((AE_INFO, status, | 99 | return 0; |
285 | "Unable to detach data from device %s", | ||
286 | acpi_device_bid(device))); | ||
287 | result = -ENODEV; | ||
288 | goto end; | ||
289 | } | ||
290 | if (data->dev->subordinate) { | ||
291 | acpi_pci_irq_del_prt(data->id.segment, data->bus->number); | ||
292 | } | ||
293 | pci_dev_put(data->dev); | ||
294 | kfree(data); | ||
295 | |||
296 | end: | ||
297 | return result; | ||
298 | } | 100 | } |
299 | 101 | ||
300 | int | 102 | int acpi_pci_bind_root(struct acpi_device *device) |
301 | acpi_pci_bind_root(struct acpi_device *device, | ||
302 | struct acpi_pci_id *id, struct pci_bus *bus) | ||
303 | { | 103 | { |
304 | int result = 0; | ||
305 | acpi_status status; | ||
306 | struct acpi_pci_data *data = NULL; | ||
307 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
308 | |||
309 | if (!device || !id || !bus) { | ||
310 | return -EINVAL; | ||
311 | } | ||
312 | |||
313 | data = kzalloc(sizeof(struct acpi_pci_data), GFP_KERNEL); | ||
314 | if (!data) | ||
315 | return -ENOMEM; | ||
316 | |||
317 | data->id = *id; | ||
318 | data->bus = bus; | ||
319 | device->ops.bind = acpi_pci_bind; | 104 | device->ops.bind = acpi_pci_bind; |
320 | device->ops.unbind = acpi_pci_unbind; | 105 | device->ops.unbind = acpi_pci_unbind; |
321 | 106 | ||
322 | status = acpi_get_name(device->handle, ACPI_FULL_PATHNAME, &buffer); | 107 | return 0; |
323 | if (ACPI_FAILURE(status)) { | ||
324 | kfree (data); | ||
325 | return -ENODEV; | ||
326 | } | ||
327 | |||
328 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Binding PCI root bridge [%s] to " | ||
329 | "%04x:%02x\n", (char *)buffer.pointer, | ||
330 | id->segment, id->bus)); | ||
331 | |||
332 | status = acpi_attach_data(device->handle, acpi_pci_data_handler, data); | ||
333 | if (ACPI_FAILURE(status)) { | ||
334 | ACPI_EXCEPTION((AE_INFO, status, | ||
335 | "Unable to attach ACPI-PCI context to device %s", | ||
336 | (char *)buffer.pointer)); | ||
337 | result = -ENODEV; | ||
338 | goto end; | ||
339 | } | ||
340 | |||
341 | end: | ||
342 | kfree(buffer.pointer); | ||
343 | if (result != 0) | ||
344 | kfree(data); | ||
345 | |||
346 | return result; | ||
347 | } | 108 | } |
diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c index 51b9f8280f88..b794eb88ab90 100644 --- a/drivers/acpi/pci_irq.c +++ b/drivers/acpi/pci_irq.c | |||
@@ -182,7 +182,7 @@ static void do_prt_fixups(struct acpi_prt_entry *entry, | |||
182 | } | 182 | } |
183 | } | 183 | } |
184 | 184 | ||
185 | static int acpi_pci_irq_add_entry(acpi_handle handle, int segment, int bus, | 185 | static int acpi_pci_irq_add_entry(acpi_handle handle, struct pci_bus *bus, |
186 | struct acpi_pci_routing_table *prt) | 186 | struct acpi_pci_routing_table *prt) |
187 | { | 187 | { |
188 | struct acpi_prt_entry *entry; | 188 | struct acpi_prt_entry *entry; |
@@ -196,8 +196,8 @@ static int acpi_pci_irq_add_entry(acpi_handle handle, int segment, int bus, | |||
196 | * 1=INTA, 2=INTB. We use the PCI encoding throughout, so convert | 196 | * 1=INTA, 2=INTB. We use the PCI encoding throughout, so convert |
197 | * it here. | 197 | * it here. |
198 | */ | 198 | */ |
199 | entry->id.segment = segment; | 199 | entry->id.segment = pci_domain_nr(bus); |
200 | entry->id.bus = bus; | 200 | entry->id.bus = bus->number; |
201 | entry->id.device = (prt->address >> 16) & 0xFFFF; | 201 | entry->id.device = (prt->address >> 16) & 0xFFFF; |
202 | entry->pin = prt->pin + 1; | 202 | entry->pin = prt->pin + 1; |
203 | 203 | ||
@@ -242,7 +242,7 @@ static int acpi_pci_irq_add_entry(acpi_handle handle, int segment, int bus, | |||
242 | return 0; | 242 | return 0; |
243 | } | 243 | } |
244 | 244 | ||
245 | int acpi_pci_irq_add_prt(acpi_handle handle, int segment, int bus) | 245 | int acpi_pci_irq_add_prt(acpi_handle handle, struct pci_bus *bus) |
246 | { | 246 | { |
247 | acpi_status status; | 247 | acpi_status status; |
248 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | 248 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; |
@@ -271,7 +271,7 @@ int acpi_pci_irq_add_prt(acpi_handle handle, int segment, int bus) | |||
271 | 271 | ||
272 | entry = buffer.pointer; | 272 | entry = buffer.pointer; |
273 | while (entry && (entry->length > 0)) { | 273 | while (entry && (entry->length > 0)) { |
274 | acpi_pci_irq_add_entry(handle, segment, bus, entry); | 274 | acpi_pci_irq_add_entry(handle, bus, entry); |
275 | entry = (struct acpi_pci_routing_table *) | 275 | entry = (struct acpi_pci_routing_table *) |
276 | ((unsigned long)entry + entry->length); | 276 | ((unsigned long)entry + entry->length); |
277 | } | 277 | } |
@@ -280,16 +280,17 @@ int acpi_pci_irq_add_prt(acpi_handle handle, int segment, int bus) | |||
280 | return 0; | 280 | return 0; |
281 | } | 281 | } |
282 | 282 | ||
283 | void acpi_pci_irq_del_prt(int segment, int bus) | 283 | void acpi_pci_irq_del_prt(struct pci_bus *bus) |
284 | { | 284 | { |
285 | struct acpi_prt_entry *entry, *tmp; | 285 | struct acpi_prt_entry *entry, *tmp; |
286 | 286 | ||
287 | printk(KERN_DEBUG | 287 | printk(KERN_DEBUG |
288 | "ACPI: Delete PCI Interrupt Routing Table for %04x:%02x\n", | 288 | "ACPI: Delete PCI Interrupt Routing Table for %04x:%02x\n", |
289 | segment, bus); | 289 | pci_domain_nr(bus), bus->number); |
290 | spin_lock(&acpi_prt_lock); | 290 | spin_lock(&acpi_prt_lock); |
291 | list_for_each_entry_safe(entry, tmp, &acpi_prt_list, list) { | 291 | list_for_each_entry_safe(entry, tmp, &acpi_prt_list, list) { |
292 | if (segment == entry->id.segment && bus == entry->id.bus) { | 292 | if (pci_domain_nr(bus) == entry->id.segment |
293 | && bus->number == entry->id.bus) { | ||
293 | list_del(&entry->list); | 294 | list_del(&entry->list); |
294 | kfree(entry); | 295 | kfree(entry); |
295 | } | 296 | } |
@@ -401,7 +402,8 @@ int acpi_pci_irq_enable(struct pci_dev *dev) | |||
401 | /* Interrupt Line values above 0xF are forbidden */ | 402 | /* Interrupt Line values above 0xF are forbidden */ |
402 | if (dev->irq > 0 && (dev->irq <= 0xF)) { | 403 | if (dev->irq > 0 && (dev->irq <= 0xF)) { |
403 | printk(" - using IRQ %d\n", dev->irq); | 404 | printk(" - using IRQ %d\n", dev->irq); |
404 | acpi_register_gsi(dev->irq, ACPI_LEVEL_SENSITIVE, | 405 | acpi_register_gsi(&dev->dev, dev->irq, |
406 | ACPI_LEVEL_SENSITIVE, | ||
405 | ACPI_ACTIVE_LOW); | 407 | ACPI_ACTIVE_LOW); |
406 | return 0; | 408 | return 0; |
407 | } else { | 409 | } else { |
@@ -410,7 +412,7 @@ int acpi_pci_irq_enable(struct pci_dev *dev) | |||
410 | } | 412 | } |
411 | } | 413 | } |
412 | 414 | ||
413 | rc = acpi_register_gsi(gsi, triggering, polarity); | 415 | rc = acpi_register_gsi(&dev->dev, gsi, triggering, polarity); |
414 | if (rc < 0) { | 416 | if (rc < 0) { |
415 | dev_warn(&dev->dev, "PCI INT %c: failed to register GSI\n", | 417 | dev_warn(&dev->dev, "PCI INT %c: failed to register GSI\n", |
416 | pin_name(pin)); | 418 | pin_name(pin)); |
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index 196f97d00956..8a5bf3b356fa 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c | |||
@@ -63,9 +63,10 @@ static struct acpi_driver acpi_pci_root_driver = { | |||
63 | 63 | ||
64 | struct acpi_pci_root { | 64 | struct acpi_pci_root { |
65 | struct list_head node; | 65 | struct list_head node; |
66 | struct acpi_device * device; | 66 | struct acpi_device *device; |
67 | struct acpi_pci_id id; | ||
68 | struct pci_bus *bus; | 67 | struct pci_bus *bus; |
68 | u16 segment; | ||
69 | u8 bus_nr; | ||
69 | 70 | ||
70 | u32 osc_support_set; /* _OSC state of support bits */ | 71 | u32 osc_support_set; /* _OSC state of support bits */ |
71 | u32 osc_control_set; /* _OSC state of control bits */ | 72 | u32 osc_control_set; /* _OSC state of control bits */ |
@@ -82,7 +83,7 @@ static DEFINE_MUTEX(osc_lock); | |||
82 | int acpi_pci_register_driver(struct acpi_pci_driver *driver) | 83 | int acpi_pci_register_driver(struct acpi_pci_driver *driver) |
83 | { | 84 | { |
84 | int n = 0; | 85 | int n = 0; |
85 | struct list_head *entry; | 86 | struct acpi_pci_root *root; |
86 | 87 | ||
87 | struct acpi_pci_driver **pptr = &sub_driver; | 88 | struct acpi_pci_driver **pptr = &sub_driver; |
88 | while (*pptr) | 89 | while (*pptr) |
@@ -92,9 +93,7 @@ int acpi_pci_register_driver(struct acpi_pci_driver *driver) | |||
92 | if (!driver->add) | 93 | if (!driver->add) |
93 | return 0; | 94 | return 0; |
94 | 95 | ||
95 | list_for_each(entry, &acpi_pci_roots) { | 96 | list_for_each_entry(root, &acpi_pci_roots, node) { |
96 | struct acpi_pci_root *root; | ||
97 | root = list_entry(entry, struct acpi_pci_root, node); | ||
98 | driver->add(root->device->handle); | 97 | driver->add(root->device->handle); |
99 | n++; | 98 | n++; |
100 | } | 99 | } |
@@ -106,7 +105,7 @@ EXPORT_SYMBOL(acpi_pci_register_driver); | |||
106 | 105 | ||
107 | void acpi_pci_unregister_driver(struct acpi_pci_driver *driver) | 106 | void acpi_pci_unregister_driver(struct acpi_pci_driver *driver) |
108 | { | 107 | { |
109 | struct list_head *entry; | 108 | struct acpi_pci_root *root; |
110 | 109 | ||
111 | struct acpi_pci_driver **pptr = &sub_driver; | 110 | struct acpi_pci_driver **pptr = &sub_driver; |
112 | while (*pptr) { | 111 | while (*pptr) { |
@@ -120,28 +119,48 @@ void acpi_pci_unregister_driver(struct acpi_pci_driver *driver) | |||
120 | if (!driver->remove) | 119 | if (!driver->remove) |
121 | return; | 120 | return; |
122 | 121 | ||
123 | list_for_each(entry, &acpi_pci_roots) { | 122 | list_for_each_entry(root, &acpi_pci_roots, node) |
124 | struct acpi_pci_root *root; | ||
125 | root = list_entry(entry, struct acpi_pci_root, node); | ||
126 | driver->remove(root->device->handle); | 123 | driver->remove(root->device->handle); |
127 | } | ||
128 | } | 124 | } |
129 | 125 | ||
130 | EXPORT_SYMBOL(acpi_pci_unregister_driver); | 126 | EXPORT_SYMBOL(acpi_pci_unregister_driver); |
131 | 127 | ||
132 | acpi_handle acpi_get_pci_rootbridge_handle(unsigned int seg, unsigned int bus) | 128 | acpi_handle acpi_get_pci_rootbridge_handle(unsigned int seg, unsigned int bus) |
133 | { | 129 | { |
134 | struct acpi_pci_root *tmp; | 130 | struct acpi_pci_root *root; |
135 | 131 | ||
136 | list_for_each_entry(tmp, &acpi_pci_roots, node) { | 132 | list_for_each_entry(root, &acpi_pci_roots, node) |
137 | if ((tmp->id.segment == (u16) seg) && (tmp->id.bus == (u16) bus)) | 133 | if ((root->segment == (u16) seg) && (root->bus_nr == (u16) bus)) |
138 | return tmp->device->handle; | 134 | return root->device->handle; |
139 | } | ||
140 | return NULL; | 135 | return NULL; |
141 | } | 136 | } |
142 | 137 | ||
143 | EXPORT_SYMBOL_GPL(acpi_get_pci_rootbridge_handle); | 138 | EXPORT_SYMBOL_GPL(acpi_get_pci_rootbridge_handle); |
144 | 139 | ||
140 | /** | ||
141 | * acpi_is_root_bridge - determine whether an ACPI CA node is a PCI root bridge | ||
142 | * @handle - the ACPI CA node in question. | ||
143 | * | ||
144 | * Note: we could make this API take a struct acpi_device * instead, but | ||
145 | * for now, it's more convenient to operate on an acpi_handle. | ||
146 | */ | ||
147 | int acpi_is_root_bridge(acpi_handle handle) | ||
148 | { | ||
149 | int ret; | ||
150 | struct acpi_device *device; | ||
151 | |||
152 | ret = acpi_bus_get_device(handle, &device); | ||
153 | if (ret) | ||
154 | return 0; | ||
155 | |||
156 | ret = acpi_match_device_ids(device, root_device_ids); | ||
157 | if (ret) | ||
158 | return 0; | ||
159 | else | ||
160 | return 1; | ||
161 | } | ||
162 | EXPORT_SYMBOL_GPL(acpi_is_root_bridge); | ||
163 | |||
145 | static acpi_status | 164 | static acpi_status |
146 | get_root_bridge_busnr_callback(struct acpi_resource *resource, void *data) | 165 | get_root_bridge_busnr_callback(struct acpi_resource *resource, void *data) |
147 | { | 166 | { |
@@ -161,19 +180,22 @@ get_root_bridge_busnr_callback(struct acpi_resource *resource, void *data) | |||
161 | return AE_OK; | 180 | return AE_OK; |
162 | } | 181 | } |
163 | 182 | ||
164 | static acpi_status try_get_root_bridge_busnr(acpi_handle handle, int *busnum) | 183 | static acpi_status try_get_root_bridge_busnr(acpi_handle handle, |
184 | unsigned long long *bus) | ||
165 | { | 185 | { |
166 | acpi_status status; | 186 | acpi_status status; |
187 | int busnum; | ||
167 | 188 | ||
168 | *busnum = -1; | 189 | busnum = -1; |
169 | status = | 190 | status = |
170 | acpi_walk_resources(handle, METHOD_NAME__CRS, | 191 | acpi_walk_resources(handle, METHOD_NAME__CRS, |
171 | get_root_bridge_busnr_callback, busnum); | 192 | get_root_bridge_busnr_callback, &busnum); |
172 | if (ACPI_FAILURE(status)) | 193 | if (ACPI_FAILURE(status)) |
173 | return status; | 194 | return status; |
174 | /* Check if we really get a bus number from _CRS */ | 195 | /* Check if we really get a bus number from _CRS */ |
175 | if (*busnum == -1) | 196 | if (busnum == -1) |
176 | return AE_ERROR; | 197 | return AE_ERROR; |
198 | *bus = busnum; | ||
177 | return AE_OK; | 199 | return AE_OK; |
178 | } | 200 | } |
179 | 201 | ||
@@ -298,6 +320,7 @@ static acpi_status acpi_pci_osc_support(struct acpi_pci_root *root, u32 flags) | |||
298 | static struct acpi_pci_root *acpi_pci_find_root(acpi_handle handle) | 320 | static struct acpi_pci_root *acpi_pci_find_root(acpi_handle handle) |
299 | { | 321 | { |
300 | struct acpi_pci_root *root; | 322 | struct acpi_pci_root *root; |
323 | |||
301 | list_for_each_entry(root, &acpi_pci_roots, node) { | 324 | list_for_each_entry(root, &acpi_pci_roots, node) { |
302 | if (root->device->handle == handle) | 325 | if (root->device->handle == handle) |
303 | return root; | 326 | return root; |
@@ -305,6 +328,87 @@ static struct acpi_pci_root *acpi_pci_find_root(acpi_handle handle) | |||
305 | return NULL; | 328 | return NULL; |
306 | } | 329 | } |
307 | 330 | ||
331 | struct acpi_handle_node { | ||
332 | struct list_head node; | ||
333 | acpi_handle handle; | ||
334 | }; | ||
335 | |||
336 | /** | ||
337 | * acpi_get_pci_dev - convert ACPI CA handle to struct pci_dev | ||
338 | * @handle: the handle in question | ||
339 | * | ||
340 | * Given an ACPI CA handle, the desired PCI device is located in the | ||
341 | * list of PCI devices. | ||
342 | * | ||
343 | * If the device is found, its reference count is increased and this | ||
344 | * function returns a pointer to its data structure. The caller must | ||
345 | * decrement the reference count by calling pci_dev_put(). | ||
346 | * If no device is found, %NULL is returned. | ||
347 | */ | ||
348 | struct pci_dev *acpi_get_pci_dev(acpi_handle handle) | ||
349 | { | ||
350 | int dev, fn; | ||
351 | unsigned long long adr; | ||
352 | acpi_status status; | ||
353 | acpi_handle phandle; | ||
354 | struct pci_bus *pbus; | ||
355 | struct pci_dev *pdev = NULL; | ||
356 | struct acpi_handle_node *node, *tmp; | ||
357 | struct acpi_pci_root *root; | ||
358 | LIST_HEAD(device_list); | ||
359 | |||
360 | /* | ||
361 | * Walk up the ACPI CA namespace until we reach a PCI root bridge. | ||
362 | */ | ||
363 | phandle = handle; | ||
364 | while (!acpi_is_root_bridge(phandle)) { | ||
365 | node = kzalloc(sizeof(struct acpi_handle_node), GFP_KERNEL); | ||
366 | if (!node) | ||
367 | goto out; | ||
368 | |||
369 | INIT_LIST_HEAD(&node->node); | ||
370 | node->handle = phandle; | ||
371 | list_add(&node->node, &device_list); | ||
372 | |||
373 | status = acpi_get_parent(phandle, &phandle); | ||
374 | if (ACPI_FAILURE(status)) | ||
375 | goto out; | ||
376 | } | ||
377 | |||
378 | root = acpi_pci_find_root(phandle); | ||
379 | if (!root) | ||
380 | goto out; | ||
381 | |||
382 | pbus = root->bus; | ||
383 | |||
384 | /* | ||
385 | * Now, walk back down the PCI device tree until we return to our | ||
386 | * original handle. Assumes that everything between the PCI root | ||
387 | * bridge and the device we're looking for must be a P2P bridge. | ||
388 | */ | ||
389 | list_for_each_entry(node, &device_list, node) { | ||
390 | acpi_handle hnd = node->handle; | ||
391 | status = acpi_evaluate_integer(hnd, "_ADR", NULL, &adr); | ||
392 | if (ACPI_FAILURE(status)) | ||
393 | goto out; | ||
394 | dev = (adr >> 16) & 0xffff; | ||
395 | fn = adr & 0xffff; | ||
396 | |||
397 | pdev = pci_get_slot(pbus, PCI_DEVFN(dev, fn)); | ||
398 | if (hnd == handle) | ||
399 | break; | ||
400 | |||
401 | pbus = pdev->subordinate; | ||
402 | pci_dev_put(pdev); | ||
403 | } | ||
404 | out: | ||
405 | list_for_each_entry_safe(node, tmp, &device_list, node) | ||
406 | kfree(node); | ||
407 | |||
408 | return pdev; | ||
409 | } | ||
410 | EXPORT_SYMBOL_GPL(acpi_get_pci_dev); | ||
411 | |||
308 | /** | 412 | /** |
309 | * acpi_pci_osc_control_set - commit requested control to Firmware | 413 | * acpi_pci_osc_control_set - commit requested control to Firmware |
310 | * @handle: acpi_handle for the target ACPI object | 414 | * @handle: acpi_handle for the target ACPI object |
@@ -363,31 +467,46 @@ EXPORT_SYMBOL(acpi_pci_osc_control_set); | |||
363 | 467 | ||
364 | static int __devinit acpi_pci_root_add(struct acpi_device *device) | 468 | static int __devinit acpi_pci_root_add(struct acpi_device *device) |
365 | { | 469 | { |
366 | int result = 0; | 470 | unsigned long long segment, bus; |
367 | struct acpi_pci_root *root = NULL; | 471 | acpi_status status; |
368 | struct acpi_pci_root *tmp; | 472 | int result; |
369 | acpi_status status = AE_OK; | 473 | struct acpi_pci_root *root; |
370 | unsigned long long value = 0; | 474 | acpi_handle handle; |
371 | acpi_handle handle = NULL; | ||
372 | struct acpi_device *child; | 475 | struct acpi_device *child; |
373 | u32 flags, base_flags; | 476 | u32 flags, base_flags; |
374 | 477 | ||
478 | segment = 0; | ||
479 | status = acpi_evaluate_integer(device->handle, METHOD_NAME__SEG, NULL, | ||
480 | &segment); | ||
481 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { | ||
482 | printk(KERN_ERR PREFIX "can't evaluate _SEG\n"); | ||
483 | return -ENODEV; | ||
484 | } | ||
375 | 485 | ||
376 | if (!device) | 486 | /* Check _CRS first, then _BBN. If no _BBN, default to zero. */ |
377 | return -EINVAL; | 487 | bus = 0; |
488 | status = try_get_root_bridge_busnr(device->handle, &bus); | ||
489 | if (ACPI_FAILURE(status)) { | ||
490 | status = acpi_evaluate_integer(device->handle, METHOD_NAME__BBN, NULL, &bus); | ||
491 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { | ||
492 | printk(KERN_ERR PREFIX | ||
493 | "no bus number in _CRS and can't evaluate _BBN\n"); | ||
494 | return -ENODEV; | ||
495 | } | ||
496 | } | ||
378 | 497 | ||
379 | root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL); | 498 | root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL); |
380 | if (!root) | 499 | if (!root) |
381 | return -ENOMEM; | 500 | return -ENOMEM; |
382 | INIT_LIST_HEAD(&root->node); | ||
383 | 501 | ||
502 | INIT_LIST_HEAD(&root->node); | ||
384 | root->device = device; | 503 | root->device = device; |
504 | root->segment = segment & 0xFFFF; | ||
505 | root->bus_nr = bus & 0xFF; | ||
385 | strcpy(acpi_device_name(device), ACPI_PCI_ROOT_DEVICE_NAME); | 506 | strcpy(acpi_device_name(device), ACPI_PCI_ROOT_DEVICE_NAME); |
386 | strcpy(acpi_device_class(device), ACPI_PCI_ROOT_CLASS); | 507 | strcpy(acpi_device_class(device), ACPI_PCI_ROOT_CLASS); |
387 | device->driver_data = root; | 508 | device->driver_data = root; |
388 | 509 | ||
389 | device->ops.bind = acpi_pci_bind; | ||
390 | |||
391 | /* | 510 | /* |
392 | * All supported architectures that use ACPI have support for | 511 | * All supported architectures that use ACPI have support for |
393 | * PCI domains, so we indicate this in _OSC support capabilities. | 512 | * PCI domains, so we indicate this in _OSC support capabilities. |
@@ -395,79 +514,6 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) | |||
395 | flags = base_flags = OSC_PCI_SEGMENT_GROUPS_SUPPORT; | 514 | flags = base_flags = OSC_PCI_SEGMENT_GROUPS_SUPPORT; |
396 | acpi_pci_osc_support(root, flags); | 515 | acpi_pci_osc_support(root, flags); |
397 | 516 | ||
398 | /* | ||
399 | * Segment | ||
400 | * ------- | ||
401 | * Obtained via _SEG, if exists, otherwise assumed to be zero (0). | ||
402 | */ | ||
403 | status = acpi_evaluate_integer(device->handle, METHOD_NAME__SEG, NULL, | ||
404 | &value); | ||
405 | switch (status) { | ||
406 | case AE_OK: | ||
407 | root->id.segment = (u16) value; | ||
408 | break; | ||
409 | case AE_NOT_FOUND: | ||
410 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
411 | "Assuming segment 0 (no _SEG)\n")); | ||
412 | root->id.segment = 0; | ||
413 | break; | ||
414 | default: | ||
415 | ACPI_EXCEPTION((AE_INFO, status, "Evaluating _SEG")); | ||
416 | result = -ENODEV; | ||
417 | goto end; | ||
418 | } | ||
419 | |||
420 | /* | ||
421 | * Bus | ||
422 | * --- | ||
423 | * Obtained via _BBN, if exists, otherwise assumed to be zero (0). | ||
424 | */ | ||
425 | status = acpi_evaluate_integer(device->handle, METHOD_NAME__BBN, NULL, | ||
426 | &value); | ||
427 | switch (status) { | ||
428 | case AE_OK: | ||
429 | root->id.bus = (u16) value; | ||
430 | break; | ||
431 | case AE_NOT_FOUND: | ||
432 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Assuming bus 0 (no _BBN)\n")); | ||
433 | root->id.bus = 0; | ||
434 | break; | ||
435 | default: | ||
436 | ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BBN")); | ||
437 | result = -ENODEV; | ||
438 | goto end; | ||
439 | } | ||
440 | |||
441 | /* Some systems have wrong _BBN */ | ||
442 | list_for_each_entry(tmp, &acpi_pci_roots, node) { | ||
443 | if ((tmp->id.segment == root->id.segment) | ||
444 | && (tmp->id.bus == root->id.bus)) { | ||
445 | int bus = 0; | ||
446 | acpi_status status; | ||
447 | |||
448 | printk(KERN_ERR PREFIX | ||
449 | "Wrong _BBN value, reboot" | ||
450 | " and use option 'pci=noacpi'\n"); | ||
451 | |||
452 | status = try_get_root_bridge_busnr(device->handle, &bus); | ||
453 | if (ACPI_FAILURE(status)) | ||
454 | break; | ||
455 | if (bus != root->id.bus) { | ||
456 | printk(KERN_INFO PREFIX | ||
457 | "PCI _CRS %d overrides _BBN 0\n", bus); | ||
458 | root->id.bus = bus; | ||
459 | } | ||
460 | break; | ||
461 | } | ||
462 | } | ||
463 | /* | ||
464 | * Device & Function | ||
465 | * ----------------- | ||
466 | * Obtained from _ADR (which has already been evaluated for us). | ||
467 | */ | ||
468 | root->id.device = device->pnp.bus_address >> 16; | ||
469 | root->id.function = device->pnp.bus_address & 0xFFFF; | ||
470 | |||
471 | /* | 517 | /* |
472 | * TBD: Need PCI interface for enumeration/configuration of roots. | 518 | * TBD: Need PCI interface for enumeration/configuration of roots. |
473 | */ | 519 | */ |
@@ -477,7 +523,7 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) | |||
477 | 523 | ||
478 | printk(KERN_INFO PREFIX "%s [%s] (%04x:%02x)\n", | 524 | printk(KERN_INFO PREFIX "%s [%s] (%04x:%02x)\n", |
479 | acpi_device_name(device), acpi_device_bid(device), | 525 | acpi_device_name(device), acpi_device_bid(device), |
480 | root->id.segment, root->id.bus); | 526 | root->segment, root->bus_nr); |
481 | 527 | ||
482 | /* | 528 | /* |
483 | * Scan the Root Bridge | 529 | * Scan the Root Bridge |
@@ -486,11 +532,11 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) | |||
486 | * PCI namespace does not get created until this call is made (and | 532 | * PCI namespace does not get created until this call is made (and |
487 | * thus the root bridge's pci_dev does not exist). | 533 | * thus the root bridge's pci_dev does not exist). |
488 | */ | 534 | */ |
489 | root->bus = pci_acpi_scan_root(device, root->id.segment, root->id.bus); | 535 | root->bus = pci_acpi_scan_root(device, segment, bus); |
490 | if (!root->bus) { | 536 | if (!root->bus) { |
491 | printk(KERN_ERR PREFIX | 537 | printk(KERN_ERR PREFIX |
492 | "Bus %04x:%02x not present in PCI namespace\n", | 538 | "Bus %04x:%02x not present in PCI namespace\n", |
493 | root->id.segment, root->id.bus); | 539 | root->segment, root->bus_nr); |
494 | result = -ENODEV; | 540 | result = -ENODEV; |
495 | goto end; | 541 | goto end; |
496 | } | 542 | } |
@@ -500,7 +546,7 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) | |||
500 | * ----------------------- | 546 | * ----------------------- |
501 | * Thus binding the ACPI and PCI devices. | 547 | * Thus binding the ACPI and PCI devices. |
502 | */ | 548 | */ |
503 | result = acpi_pci_bind_root(device, &root->id, root->bus); | 549 | result = acpi_pci_bind_root(device); |
504 | if (result) | 550 | if (result) |
505 | goto end; | 551 | goto end; |
506 | 552 | ||
@@ -511,8 +557,7 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) | |||
511 | */ | 557 | */ |
512 | status = acpi_get_handle(device->handle, METHOD_NAME__PRT, &handle); | 558 | status = acpi_get_handle(device->handle, METHOD_NAME__PRT, &handle); |
513 | if (ACPI_SUCCESS(status)) | 559 | if (ACPI_SUCCESS(status)) |
514 | result = acpi_pci_irq_add_prt(device->handle, root->id.segment, | 560 | result = acpi_pci_irq_add_prt(device->handle, root->bus); |
515 | root->id.bus); | ||
516 | 561 | ||
517 | /* | 562 | /* |
518 | * Scan and bind all _ADR-Based Devices | 563 | * Scan and bind all _ADR-Based Devices |
@@ -531,42 +576,28 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) | |||
531 | if (flags != base_flags) | 576 | if (flags != base_flags) |
532 | acpi_pci_osc_support(root, flags); | 577 | acpi_pci_osc_support(root, flags); |
533 | 578 | ||
534 | end: | 579 | return 0; |
535 | if (result) { | ||
536 | if (!list_empty(&root->node)) | ||
537 | list_del(&root->node); | ||
538 | kfree(root); | ||
539 | } | ||
540 | 580 | ||
581 | end: | ||
582 | if (!list_empty(&root->node)) | ||
583 | list_del(&root->node); | ||
584 | kfree(root); | ||
541 | return result; | 585 | return result; |
542 | } | 586 | } |
543 | 587 | ||
544 | static int acpi_pci_root_start(struct acpi_device *device) | 588 | static int acpi_pci_root_start(struct acpi_device *device) |
545 | { | 589 | { |
546 | struct acpi_pci_root *root; | 590 | struct acpi_pci_root *root = acpi_driver_data(device); |
547 | 591 | ||
548 | 592 | pci_bus_add_devices(root->bus); | |
549 | list_for_each_entry(root, &acpi_pci_roots, node) { | 593 | return 0; |
550 | if (root->device == device) { | ||
551 | pci_bus_add_devices(root->bus); | ||
552 | return 0; | ||
553 | } | ||
554 | } | ||
555 | return -ENODEV; | ||
556 | } | 594 | } |
557 | 595 | ||
558 | static int acpi_pci_root_remove(struct acpi_device *device, int type) | 596 | static int acpi_pci_root_remove(struct acpi_device *device, int type) |
559 | { | 597 | { |
560 | struct acpi_pci_root *root = NULL; | 598 | struct acpi_pci_root *root = acpi_driver_data(device); |
561 | |||
562 | |||
563 | if (!device || !acpi_driver_data(device)) | ||
564 | return -EINVAL; | ||
565 | |||
566 | root = acpi_driver_data(device); | ||
567 | 599 | ||
568 | kfree(root); | 600 | kfree(root); |
569 | |||
570 | return 0; | 601 | return 0; |
571 | } | 602 | } |
572 | 603 | ||
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index 56665a63bf19..d74365d4a6e7 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c | |||
@@ -194,7 +194,7 @@ static int acpi_power_get_list_state(struct acpi_handle_list *list, int *state) | |||
194 | 194 | ||
195 | static int acpi_power_on(acpi_handle handle, struct acpi_device *dev) | 195 | static int acpi_power_on(acpi_handle handle, struct acpi_device *dev) |
196 | { | 196 | { |
197 | int result = 0, state; | 197 | int result = 0; |
198 | int found = 0; | 198 | int found = 0; |
199 | acpi_status status = AE_OK; | 199 | acpi_status status = AE_OK; |
200 | struct acpi_power_resource *resource = NULL; | 200 | struct acpi_power_resource *resource = NULL; |
@@ -236,18 +236,6 @@ static int acpi_power_on(acpi_handle handle, struct acpi_device *dev) | |||
236 | if (ACPI_FAILURE(status)) | 236 | if (ACPI_FAILURE(status)) |
237 | return -ENODEV; | 237 | return -ENODEV; |
238 | 238 | ||
239 | if (!acpi_power_nocheck) { | ||
240 | /* | ||
241 | * If acpi_power_nocheck is set, it is unnecessary to check | ||
242 | * the power state after power transition. | ||
243 | */ | ||
244 | result = acpi_power_get_state(resource->device->handle, | ||
245 | &state); | ||
246 | if (result) | ||
247 | return result; | ||
248 | if (state != ACPI_POWER_RESOURCE_STATE_ON) | ||
249 | return -ENOEXEC; | ||
250 | } | ||
251 | /* Update the power resource's _device_ power state */ | 239 | /* Update the power resource's _device_ power state */ |
252 | resource->device->power.state = ACPI_STATE_D0; | 240 | resource->device->power.state = ACPI_STATE_D0; |
253 | 241 | ||
@@ -258,7 +246,7 @@ static int acpi_power_on(acpi_handle handle, struct acpi_device *dev) | |||
258 | 246 | ||
259 | static int acpi_power_off_device(acpi_handle handle, struct acpi_device *dev) | 247 | static int acpi_power_off_device(acpi_handle handle, struct acpi_device *dev) |
260 | { | 248 | { |
261 | int result = 0, state; | 249 | int result = 0; |
262 | acpi_status status = AE_OK; | 250 | acpi_status status = AE_OK; |
263 | struct acpi_power_resource *resource = NULL; | 251 | struct acpi_power_resource *resource = NULL; |
264 | struct list_head *node, *next; | 252 | struct list_head *node, *next; |
@@ -293,18 +281,6 @@ static int acpi_power_off_device(acpi_handle handle, struct acpi_device *dev) | |||
293 | if (ACPI_FAILURE(status)) | 281 | if (ACPI_FAILURE(status)) |
294 | return -ENODEV; | 282 | return -ENODEV; |
295 | 283 | ||
296 | if (!acpi_power_nocheck) { | ||
297 | /* | ||
298 | * If acpi_power_nocheck is set, it is unnecessary to check | ||
299 | * the power state after power transition. | ||
300 | */ | ||
301 | result = acpi_power_get_state(handle, &state); | ||
302 | if (result) | ||
303 | return result; | ||
304 | if (state != ACPI_POWER_RESOURCE_STATE_OFF) | ||
305 | return -ENOEXEC; | ||
306 | } | ||
307 | |||
308 | /* Update the power resource's _device_ power state */ | 284 | /* Update the power resource's _device_ power state */ |
309 | resource->device->power.state = ACPI_STATE_D3; | 285 | resource->device->power.state = ACPI_STATE_D3; |
310 | 286 | ||
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index 23f0fb84f1c1..84e0f3c07442 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c | |||
@@ -89,7 +89,7 @@ static int acpi_processor_handle_eject(struct acpi_processor *pr); | |||
89 | 89 | ||
90 | static const struct acpi_device_id processor_device_ids[] = { | 90 | static const struct acpi_device_id processor_device_ids[] = { |
91 | {ACPI_PROCESSOR_OBJECT_HID, 0}, | 91 | {ACPI_PROCESSOR_OBJECT_HID, 0}, |
92 | {ACPI_PROCESSOR_HID, 0}, | 92 | {"ACPI0007", 0}, |
93 | {"", 0}, | 93 | {"", 0}, |
94 | }; | 94 | }; |
95 | MODULE_DEVICE_TABLE(acpi, processor_device_ids); | 95 | MODULE_DEVICE_TABLE(acpi, processor_device_ids); |
@@ -596,7 +596,21 @@ static int acpi_processor_get_info(struct acpi_device *device) | |||
596 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 596 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
597 | "No bus mastering arbitration control\n")); | 597 | "No bus mastering arbitration control\n")); |
598 | 598 | ||
599 | if (!strcmp(acpi_device_hid(device), ACPI_PROCESSOR_HID)) { | 599 | if (!strcmp(acpi_device_hid(device), ACPI_PROCESSOR_OBJECT_HID)) { |
600 | /* Declared with "Processor" statement; match ProcessorID */ | ||
601 | status = acpi_evaluate_object(pr->handle, NULL, NULL, &buffer); | ||
602 | if (ACPI_FAILURE(status)) { | ||
603 | printk(KERN_ERR PREFIX "Evaluating processor object\n"); | ||
604 | return -ENODEV; | ||
605 | } | ||
606 | |||
607 | /* | ||
608 | * TBD: Synch processor ID (via LAPIC/LSAPIC structures) on SMP. | ||
609 | * >>> 'acpi_get_processor_id(acpi_id, &id)' in | ||
610 | * arch/xxx/acpi.c | ||
611 | */ | ||
612 | pr->acpi_id = object.processor.proc_id; | ||
613 | } else { | ||
600 | /* | 614 | /* |
601 | * Declared with "Device" statement; match _UID. | 615 | * Declared with "Device" statement; match _UID. |
602 | * Note that we don't handle string _UIDs yet. | 616 | * Note that we don't handle string _UIDs yet. |
@@ -611,20 +625,6 @@ static int acpi_processor_get_info(struct acpi_device *device) | |||
611 | } | 625 | } |
612 | device_declaration = 1; | 626 | device_declaration = 1; |
613 | pr->acpi_id = value; | 627 | pr->acpi_id = value; |
614 | } else { | ||
615 | /* Declared with "Processor" statement; match ProcessorID */ | ||
616 | status = acpi_evaluate_object(pr->handle, NULL, NULL, &buffer); | ||
617 | if (ACPI_FAILURE(status)) { | ||
618 | printk(KERN_ERR PREFIX "Evaluating processor object\n"); | ||
619 | return -ENODEV; | ||
620 | } | ||
621 | |||
622 | /* | ||
623 | * TBD: Synch processor ID (via LAPIC/LSAPIC structures) on SMP. | ||
624 | * >>> 'acpi_get_processor_id(acpi_id, &id)' in | ||
625 | * arch/xxx/acpi.c | ||
626 | */ | ||
627 | pr->acpi_id = object.processor.proc_id; | ||
628 | } | 628 | } |
629 | cpu_index = get_cpu_id(pr->handle, device_declaration, pr->acpi_id); | 629 | cpu_index = get_cpu_id(pr->handle, device_declaration, pr->acpi_id); |
630 | 630 | ||
@@ -649,7 +649,16 @@ static int acpi_processor_get_info(struct acpi_device *device) | |||
649 | return -ENODEV; | 649 | return -ENODEV; |
650 | } | 650 | } |
651 | } | 651 | } |
652 | 652 | /* | |
653 | * On some boxes several processors use the same processor bus id. | ||
654 | * But they are located in different scope. For example: | ||
655 | * \_SB.SCK0.CPU0 | ||
656 | * \_SB.SCK1.CPU0 | ||
657 | * Rename the processor device bus id. And the new bus id will be | ||
658 | * generated as the following format: | ||
659 | * CPU+CPU ID. | ||
660 | */ | ||
661 | sprintf(acpi_device_bid(device), "CPU%X", pr->id); | ||
653 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Processor [%d:%d]\n", pr->id, | 662 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Processor [%d:%d]\n", pr->id, |
654 | pr->acpi_id)); | 663 | pr->acpi_id)); |
655 | 664 | ||
@@ -731,6 +740,8 @@ static int __cpuinit acpi_processor_start(struct acpi_device *device) | |||
731 | /* _PDC call should be done before doing anything else (if reqd.). */ | 740 | /* _PDC call should be done before doing anything else (if reqd.). */ |
732 | arch_acpi_processor_init_pdc(pr); | 741 | arch_acpi_processor_init_pdc(pr); |
733 | acpi_processor_set_pdc(pr); | 742 | acpi_processor_set_pdc(pr); |
743 | arch_acpi_processor_cleanup_pdc(pr); | ||
744 | |||
734 | #ifdef CONFIG_CPU_FREQ | 745 | #ifdef CONFIG_CPU_FREQ |
735 | acpi_processor_ppc_has_changed(pr); | 746 | acpi_processor_ppc_has_changed(pr); |
736 | #endif | 747 | #endif |
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 10a2d913635a..0efa59e7e3af 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c | |||
@@ -139,7 +139,7 @@ static void acpi_safe_halt(void) | |||
139 | * are affected too. We pick the most conservative approach: we assume | 139 | * are affected too. We pick the most conservative approach: we assume |
140 | * that the local APIC stops in both C2 and C3. | 140 | * that the local APIC stops in both C2 and C3. |
141 | */ | 141 | */ |
142 | static void acpi_timer_check_state(int state, struct acpi_processor *pr, | 142 | static void lapic_timer_check_state(int state, struct acpi_processor *pr, |
143 | struct acpi_processor_cx *cx) | 143 | struct acpi_processor_cx *cx) |
144 | { | 144 | { |
145 | struct acpi_processor_power *pwr = &pr->power; | 145 | struct acpi_processor_power *pwr = &pr->power; |
@@ -162,7 +162,7 @@ static void acpi_timer_check_state(int state, struct acpi_processor *pr, | |||
162 | pr->power.timer_broadcast_on_state = state; | 162 | pr->power.timer_broadcast_on_state = state; |
163 | } | 163 | } |
164 | 164 | ||
165 | static void acpi_propagate_timer_broadcast(struct acpi_processor *pr) | 165 | static void lapic_timer_propagate_broadcast(struct acpi_processor *pr) |
166 | { | 166 | { |
167 | unsigned long reason; | 167 | unsigned long reason; |
168 | 168 | ||
@@ -173,7 +173,7 @@ static void acpi_propagate_timer_broadcast(struct acpi_processor *pr) | |||
173 | } | 173 | } |
174 | 174 | ||
175 | /* Power(C) State timer broadcast control */ | 175 | /* Power(C) State timer broadcast control */ |
176 | static void acpi_state_timer_broadcast(struct acpi_processor *pr, | 176 | static void lapic_timer_state_broadcast(struct acpi_processor *pr, |
177 | struct acpi_processor_cx *cx, | 177 | struct acpi_processor_cx *cx, |
178 | int broadcast) | 178 | int broadcast) |
179 | { | 179 | { |
@@ -190,10 +190,10 @@ static void acpi_state_timer_broadcast(struct acpi_processor *pr, | |||
190 | 190 | ||
191 | #else | 191 | #else |
192 | 192 | ||
193 | static void acpi_timer_check_state(int state, struct acpi_processor *pr, | 193 | static void lapic_timer_check_state(int state, struct acpi_processor *pr, |
194 | struct acpi_processor_cx *cstate) { } | 194 | struct acpi_processor_cx *cstate) { } |
195 | static void acpi_propagate_timer_broadcast(struct acpi_processor *pr) { } | 195 | static void lapic_timer_propagate_broadcast(struct acpi_processor *pr) { } |
196 | static void acpi_state_timer_broadcast(struct acpi_processor *pr, | 196 | static void lapic_timer_state_broadcast(struct acpi_processor *pr, |
197 | struct acpi_processor_cx *cx, | 197 | struct acpi_processor_cx *cx, |
198 | int broadcast) | 198 | int broadcast) |
199 | { | 199 | { |
@@ -515,7 +515,8 @@ static void acpi_processor_power_verify_c2(struct acpi_processor_cx *cx) | |||
515 | static void acpi_processor_power_verify_c3(struct acpi_processor *pr, | 515 | static void acpi_processor_power_verify_c3(struct acpi_processor *pr, |
516 | struct acpi_processor_cx *cx) | 516 | struct acpi_processor_cx *cx) |
517 | { | 517 | { |
518 | static int bm_check_flag; | 518 | static int bm_check_flag = -1; |
519 | static int bm_control_flag = -1; | ||
519 | 520 | ||
520 | 521 | ||
521 | if (!cx->address) | 522 | if (!cx->address) |
@@ -545,12 +546,14 @@ static void acpi_processor_power_verify_c3(struct acpi_processor *pr, | |||
545 | } | 546 | } |
546 | 547 | ||
547 | /* All the logic here assumes flags.bm_check is same across all CPUs */ | 548 | /* All the logic here assumes flags.bm_check is same across all CPUs */ |
548 | if (!bm_check_flag) { | 549 | if (bm_check_flag == -1) { |
549 | /* Determine whether bm_check is needed based on CPU */ | 550 | /* Determine whether bm_check is needed based on CPU */ |
550 | acpi_processor_power_init_bm_check(&(pr->flags), pr->id); | 551 | acpi_processor_power_init_bm_check(&(pr->flags), pr->id); |
551 | bm_check_flag = pr->flags.bm_check; | 552 | bm_check_flag = pr->flags.bm_check; |
553 | bm_control_flag = pr->flags.bm_control; | ||
552 | } else { | 554 | } else { |
553 | pr->flags.bm_check = bm_check_flag; | 555 | pr->flags.bm_check = bm_check_flag; |
556 | pr->flags.bm_control = bm_control_flag; | ||
554 | } | 557 | } |
555 | 558 | ||
556 | if (pr->flags.bm_check) { | 559 | if (pr->flags.bm_check) { |
@@ -614,29 +617,25 @@ static int acpi_processor_power_verify(struct acpi_processor *pr) | |||
614 | switch (cx->type) { | 617 | switch (cx->type) { |
615 | case ACPI_STATE_C1: | 618 | case ACPI_STATE_C1: |
616 | cx->valid = 1; | 619 | cx->valid = 1; |
617 | acpi_timer_check_state(i, pr, cx); | ||
618 | break; | 620 | break; |
619 | 621 | ||
620 | case ACPI_STATE_C2: | 622 | case ACPI_STATE_C2: |
621 | acpi_processor_power_verify_c2(cx); | 623 | acpi_processor_power_verify_c2(cx); |
622 | if (cx->valid) | ||
623 | acpi_timer_check_state(i, pr, cx); | ||
624 | break; | 624 | break; |
625 | 625 | ||
626 | case ACPI_STATE_C3: | 626 | case ACPI_STATE_C3: |
627 | acpi_processor_power_verify_c3(pr, cx); | 627 | acpi_processor_power_verify_c3(pr, cx); |
628 | if (cx->valid) | ||
629 | acpi_timer_check_state(i, pr, cx); | ||
630 | break; | 628 | break; |
631 | } | 629 | } |
632 | if (cx->valid) | 630 | if (!cx->valid) |
633 | tsc_check_state(cx->type); | 631 | continue; |
634 | 632 | ||
635 | if (cx->valid) | 633 | lapic_timer_check_state(i, pr, cx); |
636 | working++; | 634 | tsc_check_state(cx->type); |
635 | working++; | ||
637 | } | 636 | } |
638 | 637 | ||
639 | acpi_propagate_timer_broadcast(pr); | 638 | lapic_timer_propagate_broadcast(pr); |
640 | 639 | ||
641 | return (working); | 640 | return (working); |
642 | } | 641 | } |
@@ -839,7 +838,7 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev, | |||
839 | return 0; | 838 | return 0; |
840 | } | 839 | } |
841 | 840 | ||
842 | acpi_state_timer_broadcast(pr, cx, 1); | 841 | lapic_timer_state_broadcast(pr, cx, 1); |
843 | kt1 = ktime_get_real(); | 842 | kt1 = ktime_get_real(); |
844 | acpi_idle_do_entry(cx); | 843 | acpi_idle_do_entry(cx); |
845 | kt2 = ktime_get_real(); | 844 | kt2 = ktime_get_real(); |
@@ -847,7 +846,7 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev, | |||
847 | 846 | ||
848 | local_irq_enable(); | 847 | local_irq_enable(); |
849 | cx->usage++; | 848 | cx->usage++; |
850 | acpi_state_timer_broadcast(pr, cx, 0); | 849 | lapic_timer_state_broadcast(pr, cx, 0); |
851 | 850 | ||
852 | return idle_time; | 851 | return idle_time; |
853 | } | 852 | } |
@@ -892,7 +891,7 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, | |||
892 | * Must be done before busmaster disable as we might need to | 891 | * Must be done before busmaster disable as we might need to |
893 | * access HPET ! | 892 | * access HPET ! |
894 | */ | 893 | */ |
895 | acpi_state_timer_broadcast(pr, cx, 1); | 894 | lapic_timer_state_broadcast(pr, cx, 1); |
896 | 895 | ||
897 | if (cx->type == ACPI_STATE_C3) | 896 | if (cx->type == ACPI_STATE_C3) |
898 | ACPI_FLUSH_CPU_CACHE(); | 897 | ACPI_FLUSH_CPU_CACHE(); |
@@ -914,7 +913,7 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, | |||
914 | 913 | ||
915 | cx->usage++; | 914 | cx->usage++; |
916 | 915 | ||
917 | acpi_state_timer_broadcast(pr, cx, 0); | 916 | lapic_timer_state_broadcast(pr, cx, 0); |
918 | cx->time += sleep_ticks; | 917 | cx->time += sleep_ticks; |
919 | return idle_time; | 918 | return idle_time; |
920 | } | 919 | } |
@@ -981,7 +980,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, | |||
981 | * Must be done before busmaster disable as we might need to | 980 | * Must be done before busmaster disable as we might need to |
982 | * access HPET ! | 981 | * access HPET ! |
983 | */ | 982 | */ |
984 | acpi_state_timer_broadcast(pr, cx, 1); | 983 | lapic_timer_state_broadcast(pr, cx, 1); |
985 | 984 | ||
986 | kt1 = ktime_get_real(); | 985 | kt1 = ktime_get_real(); |
987 | /* | 986 | /* |
@@ -1026,7 +1025,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, | |||
1026 | 1025 | ||
1027 | cx->usage++; | 1026 | cx->usage++; |
1028 | 1027 | ||
1029 | acpi_state_timer_broadcast(pr, cx, 0); | 1028 | lapic_timer_state_broadcast(pr, cx, 0); |
1030 | cx->time += sleep_ticks; | 1029 | cx->time += sleep_ticks; |
1031 | return idle_time; | 1030 | return idle_time; |
1032 | } | 1031 | } |
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 8ff510b91d88..781435d7e369 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
@@ -95,7 +95,7 @@ acpi_device_modalias_show(struct device *dev, struct device_attribute *attr, cha | |||
95 | } | 95 | } |
96 | static DEVICE_ATTR(modalias, 0444, acpi_device_modalias_show, NULL); | 96 | static DEVICE_ATTR(modalias, 0444, acpi_device_modalias_show, NULL); |
97 | 97 | ||
98 | static int acpi_bus_hot_remove_device(void *context) | 98 | static void acpi_bus_hot_remove_device(void *context) |
99 | { | 99 | { |
100 | struct acpi_device *device; | 100 | struct acpi_device *device; |
101 | acpi_handle handle = context; | 101 | acpi_handle handle = context; |
@@ -104,10 +104,10 @@ static int acpi_bus_hot_remove_device(void *context) | |||
104 | acpi_status status = AE_OK; | 104 | acpi_status status = AE_OK; |
105 | 105 | ||
106 | if (acpi_bus_get_device(handle, &device)) | 106 | if (acpi_bus_get_device(handle, &device)) |
107 | return 0; | 107 | return; |
108 | 108 | ||
109 | if (!device) | 109 | if (!device) |
110 | return 0; | 110 | return; |
111 | 111 | ||
112 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 112 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
113 | "Hot-removing device %s...\n", dev_name(&device->dev))); | 113 | "Hot-removing device %s...\n", dev_name(&device->dev))); |
@@ -115,7 +115,7 @@ static int acpi_bus_hot_remove_device(void *context) | |||
115 | if (acpi_bus_trim(device, 1)) { | 115 | if (acpi_bus_trim(device, 1)) { |
116 | printk(KERN_ERR PREFIX | 116 | printk(KERN_ERR PREFIX |
117 | "Removing device failed\n"); | 117 | "Removing device failed\n"); |
118 | return -1; | 118 | return; |
119 | } | 119 | } |
120 | 120 | ||
121 | /* power off device */ | 121 | /* power off device */ |
@@ -142,9 +142,10 @@ static int acpi_bus_hot_remove_device(void *context) | |||
142 | */ | 142 | */ |
143 | status = acpi_evaluate_object(handle, "_EJ0", &arg_list, NULL); | 143 | status = acpi_evaluate_object(handle, "_EJ0", &arg_list, NULL); |
144 | if (ACPI_FAILURE(status)) | 144 | if (ACPI_FAILURE(status)) |
145 | return -ENODEV; | 145 | printk(KERN_WARNING PREFIX |
146 | "Eject device failed\n"); | ||
146 | 147 | ||
147 | return 0; | 148 | return; |
148 | } | 149 | } |
149 | 150 | ||
150 | static ssize_t | 151 | static ssize_t |
@@ -155,7 +156,6 @@ acpi_eject_store(struct device *d, struct device_attribute *attr, | |||
155 | acpi_status status; | 156 | acpi_status status; |
156 | acpi_object_type type = 0; | 157 | acpi_object_type type = 0; |
157 | struct acpi_device *acpi_device = to_acpi_device(d); | 158 | struct acpi_device *acpi_device = to_acpi_device(d); |
158 | struct task_struct *task; | ||
159 | 159 | ||
160 | if ((!count) || (buf[0] != '1')) { | 160 | if ((!count) || (buf[0] != '1')) { |
161 | return -EINVAL; | 161 | return -EINVAL; |
@@ -172,11 +172,7 @@ acpi_eject_store(struct device *d, struct device_attribute *attr, | |||
172 | goto err; | 172 | goto err; |
173 | } | 173 | } |
174 | 174 | ||
175 | /* remove the device in another thread to fix the deadlock issue */ | 175 | acpi_os_hotplug_execute(acpi_bus_hot_remove_device, acpi_device->handle); |
176 | task = kthread_run(acpi_bus_hot_remove_device, | ||
177 | acpi_device->handle, "acpi_hot_remove_device"); | ||
178 | if (IS_ERR(task)) | ||
179 | ret = PTR_ERR(task); | ||
180 | err: | 176 | err: |
181 | return ret; | 177 | return ret; |
182 | } | 178 | } |
@@ -198,12 +194,12 @@ acpi_device_path_show(struct device *dev, struct device_attribute *attr, char *b | |||
198 | int result; | 194 | int result; |
199 | 195 | ||
200 | result = acpi_get_name(acpi_dev->handle, ACPI_FULL_PATHNAME, &path); | 196 | result = acpi_get_name(acpi_dev->handle, ACPI_FULL_PATHNAME, &path); |
201 | if(result) | 197 | if (result) |
202 | goto end; | 198 | goto end; |
203 | 199 | ||
204 | result = sprintf(buf, "%s\n", (char*)path.pointer); | 200 | result = sprintf(buf, "%s\n", (char*)path.pointer); |
205 | kfree(path.pointer); | 201 | kfree(path.pointer); |
206 | end: | 202 | end: |
207 | return result; | 203 | return result; |
208 | } | 204 | } |
209 | static DEVICE_ATTR(path, 0444, acpi_device_path_show, NULL); | 205 | static DEVICE_ATTR(path, 0444, acpi_device_path_show, NULL); |
@@ -217,21 +213,21 @@ static int acpi_device_setup_files(struct acpi_device *dev) | |||
217 | /* | 213 | /* |
218 | * Devices gotten from FADT don't have a "path" attribute | 214 | * Devices gotten from FADT don't have a "path" attribute |
219 | */ | 215 | */ |
220 | if(dev->handle) { | 216 | if (dev->handle) { |
221 | result = device_create_file(&dev->dev, &dev_attr_path); | 217 | result = device_create_file(&dev->dev, &dev_attr_path); |
222 | if(result) | 218 | if (result) |
223 | goto end; | 219 | goto end; |
224 | } | 220 | } |
225 | 221 | ||
226 | if(dev->flags.hardware_id) { | 222 | if (dev->flags.hardware_id) { |
227 | result = device_create_file(&dev->dev, &dev_attr_hid); | 223 | result = device_create_file(&dev->dev, &dev_attr_hid); |
228 | if(result) | 224 | if (result) |
229 | goto end; | 225 | goto end; |
230 | } | 226 | } |
231 | 227 | ||
232 | if (dev->flags.hardware_id || dev->flags.compatible_ids){ | 228 | if (dev->flags.hardware_id || dev->flags.compatible_ids) { |
233 | result = device_create_file(&dev->dev, &dev_attr_modalias); | 229 | result = device_create_file(&dev->dev, &dev_attr_modalias); |
234 | if(result) | 230 | if (result) |
235 | goto end; | 231 | goto end; |
236 | } | 232 | } |
237 | 233 | ||
@@ -242,7 +238,7 @@ static int acpi_device_setup_files(struct acpi_device *dev) | |||
242 | status = acpi_get_handle(dev->handle, "_EJ0", &temp); | 238 | status = acpi_get_handle(dev->handle, "_EJ0", &temp); |
243 | if (ACPI_SUCCESS(status)) | 239 | if (ACPI_SUCCESS(status)) |
244 | result = device_create_file(&dev->dev, &dev_attr_eject); | 240 | result = device_create_file(&dev->dev, &dev_attr_eject); |
245 | end: | 241 | end: |
246 | return result; | 242 | return result; |
247 | } | 243 | } |
248 | 244 | ||
@@ -262,9 +258,9 @@ static void acpi_device_remove_files(struct acpi_device *dev) | |||
262 | if (dev->flags.hardware_id || dev->flags.compatible_ids) | 258 | if (dev->flags.hardware_id || dev->flags.compatible_ids) |
263 | device_remove_file(&dev->dev, &dev_attr_modalias); | 259 | device_remove_file(&dev->dev, &dev_attr_modalias); |
264 | 260 | ||
265 | if(dev->flags.hardware_id) | 261 | if (dev->flags.hardware_id) |
266 | device_remove_file(&dev->dev, &dev_attr_hid); | 262 | device_remove_file(&dev->dev, &dev_attr_hid); |
267 | if(dev->handle) | 263 | if (dev->handle) |
268 | device_remove_file(&dev->dev, &dev_attr_path); | 264 | device_remove_file(&dev->dev, &dev_attr_path); |
269 | } | 265 | } |
270 | /* -------------------------------------------------------------------------- | 266 | /* -------------------------------------------------------------------------- |
@@ -512,7 +508,7 @@ static int acpi_device_register(struct acpi_device *device, | |||
512 | break; | 508 | break; |
513 | } | 509 | } |
514 | } | 510 | } |
515 | if(!found) { | 511 | if (!found) { |
516 | acpi_device_bus_id = new_bus_id; | 512 | acpi_device_bus_id = new_bus_id; |
517 | strcpy(acpi_device_bus_id->bus_id, device->flags.hardware_id ? device->pnp.hardware_id : "device"); | 513 | strcpy(acpi_device_bus_id->bus_id, device->flags.hardware_id ? device->pnp.hardware_id : "device"); |
518 | acpi_device_bus_id->instance_no = 0; | 514 | acpi_device_bus_id->instance_no = 0; |
@@ -530,22 +526,21 @@ static int acpi_device_register(struct acpi_device *device, | |||
530 | if (device->parent) | 526 | if (device->parent) |
531 | device->dev.parent = &parent->dev; | 527 | device->dev.parent = &parent->dev; |
532 | device->dev.bus = &acpi_bus_type; | 528 | device->dev.bus = &acpi_bus_type; |
533 | device_initialize(&device->dev); | ||
534 | device->dev.release = &acpi_device_release; | 529 | device->dev.release = &acpi_device_release; |
535 | result = device_add(&device->dev); | 530 | result = device_register(&device->dev); |
536 | if(result) { | 531 | if (result) { |
537 | dev_err(&device->dev, "Error adding device\n"); | 532 | dev_err(&device->dev, "Error registering device\n"); |
538 | goto end; | 533 | goto end; |
539 | } | 534 | } |
540 | 535 | ||
541 | result = acpi_device_setup_files(device); | 536 | result = acpi_device_setup_files(device); |
542 | if(result) | 537 | if (result) |
543 | printk(KERN_ERR PREFIX "Error creating sysfs interface for device %s\n", | 538 | printk(KERN_ERR PREFIX "Error creating sysfs interface for device %s\n", |
544 | dev_name(&device->dev)); | 539 | dev_name(&device->dev)); |
545 | 540 | ||
546 | device->removal_type = ACPI_BUS_REMOVAL_NORMAL; | 541 | device->removal_type = ACPI_BUS_REMOVAL_NORMAL; |
547 | return 0; | 542 | return 0; |
548 | end: | 543 | end: |
549 | mutex_lock(&acpi_device_lock); | 544 | mutex_lock(&acpi_device_lock); |
550 | if (device->parent) | 545 | if (device->parent) |
551 | list_del(&device->node); | 546 | list_del(&device->node); |
@@ -577,7 +572,7 @@ static void acpi_device_unregister(struct acpi_device *device, int type) | |||
577 | * @device: the device to add and initialize | 572 | * @device: the device to add and initialize |
578 | * @driver: driver for the device | 573 | * @driver: driver for the device |
579 | * | 574 | * |
580 | * Used to initialize a device via its device driver. Called whenever a | 575 | * Used to initialize a device via its device driver. Called whenever a |
581 | * driver is bound to a device. Invokes the driver's add() ops. | 576 | * driver is bound to a device. Invokes the driver's add() ops. |
582 | */ | 577 | */ |
583 | static int | 578 | static int |
@@ -585,7 +580,6 @@ acpi_bus_driver_init(struct acpi_device *device, struct acpi_driver *driver) | |||
585 | { | 580 | { |
586 | int result = 0; | 581 | int result = 0; |
587 | 582 | ||
588 | |||
589 | if (!device || !driver) | 583 | if (!device || !driver) |
590 | return -EINVAL; | 584 | return -EINVAL; |
591 | 585 | ||
@@ -802,7 +796,7 @@ static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device) | |||
802 | if (!acpi_match_device_ids(device, button_device_ids)) | 796 | if (!acpi_match_device_ids(device, button_device_ids)) |
803 | device->wakeup.flags.run_wake = 1; | 797 | device->wakeup.flags.run_wake = 1; |
804 | 798 | ||
805 | end: | 799 | end: |
806 | if (ACPI_FAILURE(status)) | 800 | if (ACPI_FAILURE(status)) |
807 | device->flags.wake_capable = 0; | 801 | device->flags.wake_capable = 0; |
808 | return 0; | 802 | return 0; |
@@ -1070,7 +1064,7 @@ static void acpi_device_set_id(struct acpi_device *device, | |||
1070 | break; | 1064 | break; |
1071 | } | 1065 | } |
1072 | 1066 | ||
1073 | /* | 1067 | /* |
1074 | * \_SB | 1068 | * \_SB |
1075 | * ---- | 1069 | * ---- |
1076 | * Fix for the system root bus device -- the only root-level device. | 1070 | * Fix for the system root bus device -- the only root-level device. |
@@ -1320,7 +1314,7 @@ acpi_add_single_object(struct acpi_device **child, | |||
1320 | device->parent->ops.bind(device); | 1314 | device->parent->ops.bind(device); |
1321 | } | 1315 | } |
1322 | 1316 | ||
1323 | end: | 1317 | end: |
1324 | if (!result) | 1318 | if (!result) |
1325 | *child = device; | 1319 | *child = device; |
1326 | else { | 1320 | else { |
@@ -1464,7 +1458,6 @@ acpi_bus_add(struct acpi_device **child, | |||
1464 | 1458 | ||
1465 | return result; | 1459 | return result; |
1466 | } | 1460 | } |
1467 | |||
1468 | EXPORT_SYMBOL(acpi_bus_add); | 1461 | EXPORT_SYMBOL(acpi_bus_add); |
1469 | 1462 | ||
1470 | int acpi_bus_start(struct acpi_device *device) | 1463 | int acpi_bus_start(struct acpi_device *device) |
@@ -1484,7 +1477,6 @@ int acpi_bus_start(struct acpi_device *device) | |||
1484 | } | 1477 | } |
1485 | return result; | 1478 | return result; |
1486 | } | 1479 | } |
1487 | |||
1488 | EXPORT_SYMBOL(acpi_bus_start); | 1480 | EXPORT_SYMBOL(acpi_bus_start); |
1489 | 1481 | ||
1490 | int acpi_bus_trim(struct acpi_device *start, int rmdevice) | 1482 | int acpi_bus_trim(struct acpi_device *start, int rmdevice) |
@@ -1542,7 +1534,6 @@ int acpi_bus_trim(struct acpi_device *start, int rmdevice) | |||
1542 | } | 1534 | } |
1543 | EXPORT_SYMBOL_GPL(acpi_bus_trim); | 1535 | EXPORT_SYMBOL_GPL(acpi_bus_trim); |
1544 | 1536 | ||
1545 | |||
1546 | static int acpi_bus_scan_fixed(struct acpi_device *root) | 1537 | static int acpi_bus_scan_fixed(struct acpi_device *root) |
1547 | { | 1538 | { |
1548 | int result = 0; | 1539 | int result = 0; |
@@ -1610,6 +1601,6 @@ int __init acpi_scan_init(void) | |||
1610 | if (result) | 1601 | if (result) |
1611 | acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL); | 1602 | acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL); |
1612 | 1603 | ||
1613 | Done: | 1604 | Done: |
1614 | return result; | 1605 | return result; |
1615 | } | 1606 | } |
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 9de143af3625..8851315ce858 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c | |||
@@ -76,6 +76,7 @@ MODULE_LICENSE("GPL"); | |||
76 | static int brightness_switch_enabled = 1; | 76 | static int brightness_switch_enabled = 1; |
77 | module_param(brightness_switch_enabled, bool, 0644); | 77 | module_param(brightness_switch_enabled, bool, 0644); |
78 | 78 | ||
79 | static int register_count = 0; | ||
79 | static int acpi_video_bus_add(struct acpi_device *device); | 80 | static int acpi_video_bus_add(struct acpi_device *device); |
80 | static int acpi_video_bus_remove(struct acpi_device *device, int type); | 81 | static int acpi_video_bus_remove(struct acpi_device *device, int type); |
81 | static int acpi_video_resume(struct acpi_device *device); | 82 | static int acpi_video_resume(struct acpi_device *device); |
@@ -586,6 +587,14 @@ static struct dmi_system_id video_dmi_table[] __initdata = { | |||
586 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5315"), | 587 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5315"), |
587 | }, | 588 | }, |
588 | }, | 589 | }, |
590 | { | ||
591 | .callback = video_set_bqc_offset, | ||
592 | .ident = "Acer Aspire 7720", | ||
593 | .matches = { | ||
594 | DMI_MATCH(DMI_BOARD_VENDOR, "Acer"), | ||
595 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 7720"), | ||
596 | }, | ||
597 | }, | ||
589 | {} | 598 | {} |
590 | }; | 599 | }; |
591 | 600 | ||
@@ -1059,15 +1068,15 @@ static void acpi_video_bus_find_cap(struct acpi_video_bus *video) | |||
1059 | static int acpi_video_bus_check(struct acpi_video_bus *video) | 1068 | static int acpi_video_bus_check(struct acpi_video_bus *video) |
1060 | { | 1069 | { |
1061 | acpi_status status = -ENOENT; | 1070 | acpi_status status = -ENOENT; |
1062 | struct device *dev; | 1071 | struct pci_dev *dev; |
1063 | 1072 | ||
1064 | if (!video) | 1073 | if (!video) |
1065 | return -EINVAL; | 1074 | return -EINVAL; |
1066 | 1075 | ||
1067 | dev = acpi_get_physical_pci_device(video->device->handle); | 1076 | dev = acpi_get_pci_dev(video->device->handle); |
1068 | if (!dev) | 1077 | if (!dev) |
1069 | return -ENODEV; | 1078 | return -ENODEV; |
1070 | put_device(dev); | 1079 | pci_dev_put(dev); |
1071 | 1080 | ||
1072 | /* Since there is no HID, CID and so on for VGA driver, we have | 1081 | /* Since there is no HID, CID and so on for VGA driver, we have |
1073 | * to check well known required nodes. | 1082 | * to check well known required nodes. |
@@ -2324,6 +2333,13 @@ static int __init intel_opregion_present(void) | |||
2324 | int acpi_video_register(void) | 2333 | int acpi_video_register(void) |
2325 | { | 2334 | { |
2326 | int result = 0; | 2335 | int result = 0; |
2336 | if (register_count) { | ||
2337 | /* | ||
2338 | * if the function of acpi_video_register is already called, | ||
2339 | * don't register the acpi_vide_bus again and return no error. | ||
2340 | */ | ||
2341 | return 0; | ||
2342 | } | ||
2327 | 2343 | ||
2328 | acpi_video_dir = proc_mkdir(ACPI_VIDEO_CLASS, acpi_root_dir); | 2344 | acpi_video_dir = proc_mkdir(ACPI_VIDEO_CLASS, acpi_root_dir); |
2329 | if (!acpi_video_dir) | 2345 | if (!acpi_video_dir) |
@@ -2335,10 +2351,35 @@ int acpi_video_register(void) | |||
2335 | return -ENODEV; | 2351 | return -ENODEV; |
2336 | } | 2352 | } |
2337 | 2353 | ||
2354 | /* | ||
2355 | * When the acpi_video_bus is loaded successfully, increase | ||
2356 | * the counter reference. | ||
2357 | */ | ||
2358 | register_count = 1; | ||
2359 | |||
2338 | return 0; | 2360 | return 0; |
2339 | } | 2361 | } |
2340 | EXPORT_SYMBOL(acpi_video_register); | 2362 | EXPORT_SYMBOL(acpi_video_register); |
2341 | 2363 | ||
2364 | void acpi_video_unregister(void) | ||
2365 | { | ||
2366 | if (!register_count) { | ||
2367 | /* | ||
2368 | * If the acpi video bus is already unloaded, don't | ||
2369 | * unload it again and return directly. | ||
2370 | */ | ||
2371 | return; | ||
2372 | } | ||
2373 | acpi_bus_unregister_driver(&acpi_video_bus); | ||
2374 | |||
2375 | remove_proc_entry(ACPI_VIDEO_CLASS, acpi_root_dir); | ||
2376 | |||
2377 | register_count = 0; | ||
2378 | |||
2379 | return; | ||
2380 | } | ||
2381 | EXPORT_SYMBOL(acpi_video_unregister); | ||
2382 | |||
2342 | /* | 2383 | /* |
2343 | * This is kind of nasty. Hardware using Intel chipsets may require | 2384 | * This is kind of nasty. Hardware using Intel chipsets may require |
2344 | * the video opregion code to be run first in order to initialise | 2385 | * the video opregion code to be run first in order to initialise |
@@ -2356,16 +2397,12 @@ static int __init acpi_video_init(void) | |||
2356 | return acpi_video_register(); | 2397 | return acpi_video_register(); |
2357 | } | 2398 | } |
2358 | 2399 | ||
2359 | void acpi_video_exit(void) | 2400 | static void __exit acpi_video_exit(void) |
2360 | { | 2401 | { |
2361 | 2402 | acpi_video_unregister(); | |
2362 | acpi_bus_unregister_driver(&acpi_video_bus); | ||
2363 | |||
2364 | remove_proc_entry(ACPI_VIDEO_CLASS, acpi_root_dir); | ||
2365 | 2403 | ||
2366 | return; | 2404 | return; |
2367 | } | 2405 | } |
2368 | EXPORT_SYMBOL(acpi_video_exit); | ||
2369 | 2406 | ||
2370 | module_init(acpi_video_init); | 2407 | module_init(acpi_video_init); |
2371 | module_exit(acpi_video_exit); | 2408 | module_exit(acpi_video_exit); |
diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index 09737275e25f..7cd2b63435ea 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c | |||
@@ -10,7 +10,7 @@ | |||
10 | * assinged | 10 | * assinged |
11 | * | 11 | * |
12 | * After PCI devices are glued with ACPI devices | 12 | * After PCI devices are glued with ACPI devices |
13 | * acpi_get_physical_pci_device() can be called to identify ACPI graphics | 13 | * acpi_get_pci_dev() can be called to identify ACPI graphics |
14 | * devices for which a real graphics card is plugged in | 14 | * devices for which a real graphics card is plugged in |
15 | * | 15 | * |
16 | * Now acpi_video_get_capabilities() can be called to check which | 16 | * Now acpi_video_get_capabilities() can be called to check which |
@@ -36,6 +36,7 @@ | |||
36 | 36 | ||
37 | #include <linux/acpi.h> | 37 | #include <linux/acpi.h> |
38 | #include <linux/dmi.h> | 38 | #include <linux/dmi.h> |
39 | #include <linux/pci.h> | ||
39 | 40 | ||
40 | ACPI_MODULE_NAME("video"); | 41 | ACPI_MODULE_NAME("video"); |
41 | #define _COMPONENT ACPI_VIDEO_COMPONENT | 42 | #define _COMPONENT ACPI_VIDEO_COMPONENT |
@@ -109,7 +110,7 @@ static acpi_status | |||
109 | find_video(acpi_handle handle, u32 lvl, void *context, void **rv) | 110 | find_video(acpi_handle handle, u32 lvl, void *context, void **rv) |
110 | { | 111 | { |
111 | long *cap = context; | 112 | long *cap = context; |
112 | struct device *dev; | 113 | struct pci_dev *dev; |
113 | struct acpi_device *acpi_dev; | 114 | struct acpi_device *acpi_dev; |
114 | 115 | ||
115 | const struct acpi_device_id video_ids[] = { | 116 | const struct acpi_device_id video_ids[] = { |
@@ -120,10 +121,10 @@ find_video(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
120 | return AE_OK; | 121 | return AE_OK; |
121 | 122 | ||
122 | if (!acpi_match_device_ids(acpi_dev, video_ids)) { | 123 | if (!acpi_match_device_ids(acpi_dev, video_ids)) { |
123 | dev = acpi_get_physical_pci_device(handle); | 124 | dev = acpi_get_pci_dev(handle); |
124 | if (!dev) | 125 | if (!dev) |
125 | return AE_OK; | 126 | return AE_OK; |
126 | put_device(dev); | 127 | pci_dev_put(dev); |
127 | *cap |= acpi_is_video_device(acpi_dev); | 128 | *cap |= acpi_is_video_device(acpi_dev); |
128 | } | 129 | } |
129 | return AE_OK; | 130 | return AE_OK; |