aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/events/evmisc.c8
-rw-r--r--drivers/acpi/events/evregion.c15
-rw-r--r--drivers/acpi/events/evxface.c6
-rw-r--r--drivers/acpi/executer/excreate.c5
-rw-r--r--drivers/acpi/executer/exsystem.c30
-rw-r--r--drivers/acpi/executer/exutils.c104
-rw-r--r--drivers/acpi/hardware/hwsleep.c5
-rw-r--r--drivers/acpi/ibm_acpi.c19
-rw-r--r--drivers/acpi/namespace/nseval.c11
-rw-r--r--drivers/acpi/namespace/nsinit.c7
-rw-r--r--drivers/acpi/namespace/nsxfeval.c11
-rw-r--r--drivers/acpi/processor_idle.c38
-rw-r--r--drivers/acpi/tables.c57
13 files changed, 191 insertions, 125 deletions
diff --git a/drivers/acpi/events/evmisc.c b/drivers/acpi/events/evmisc.c
index 3a799b9b5df5..cae786ca8600 100644
--- a/drivers/acpi/events/evmisc.c
+++ b/drivers/acpi/events/evmisc.c
@@ -196,11 +196,15 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node * node,
196 notify_info->notify.value = (u16) notify_value; 196 notify_info->notify.value = (u16) notify_value;
197 notify_info->notify.handler_obj = handler_obj; 197 notify_info->notify.handler_obj = handler_obj;
198 198
199 acpi_ex_relinquish_interpreter(); 199 acpi_ex_exit_interpreter();
200 200
201 acpi_ev_notify_dispatch(notify_info); 201 acpi_ev_notify_dispatch(notify_info);
202 202
203 acpi_ex_reacquire_interpreter(); 203 status = acpi_ex_enter_interpreter();
204 if (ACPI_FAILURE(status)) {
205 return_ACPI_STATUS(status);
206 }
207
204 } 208 }
205 209
206 if (!handler_obj) { 210 if (!handler_obj) {
diff --git a/drivers/acpi/events/evregion.c b/drivers/acpi/events/evregion.c
index e99f0c435a47..96b0e8431748 100644
--- a/drivers/acpi/events/evregion.c
+++ b/drivers/acpi/events/evregion.c
@@ -291,6 +291,7 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj,
291 u32 bit_width, acpi_integer * value) 291 u32 bit_width, acpi_integer * value)
292{ 292{
293 acpi_status status; 293 acpi_status status;
294 acpi_status status2;
294 acpi_adr_space_handler handler; 295 acpi_adr_space_handler handler;
295 acpi_adr_space_setup region_setup; 296 acpi_adr_space_setup region_setup;
296 union acpi_operand_object *handler_desc; 297 union acpi_operand_object *handler_desc;
@@ -344,7 +345,7 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj,
344 * setup will potentially execute control methods 345 * setup will potentially execute control methods
345 * (e.g., _REG method for this region) 346 * (e.g., _REG method for this region)
346 */ 347 */
347 acpi_ex_relinquish_interpreter(); 348 acpi_ex_exit_interpreter();
348 349
349 status = region_setup(region_obj, ACPI_REGION_ACTIVATE, 350 status = region_setup(region_obj, ACPI_REGION_ACTIVATE,
350 handler_desc->address_space.context, 351 handler_desc->address_space.context,
@@ -352,7 +353,10 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj,
352 353
353 /* Re-enter the interpreter */ 354 /* Re-enter the interpreter */
354 355
355 acpi_ex_reacquire_interpreter(); 356 status2 = acpi_ex_enter_interpreter();
357 if (ACPI_FAILURE(status2)) {
358 return_ACPI_STATUS(status2);
359 }
356 360
357 /* Check for failure of the Region Setup */ 361 /* Check for failure of the Region Setup */
358 362
@@ -405,7 +409,7 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj,
405 * exit the interpreter because the handler *might* block -- we don't 409 * exit the interpreter because the handler *might* block -- we don't
406 * know what it will do, so we can't hold the lock on the intepreter. 410 * know what it will do, so we can't hold the lock on the intepreter.
407 */ 411 */
408 acpi_ex_relinquish_interpreter(); 412 acpi_ex_exit_interpreter();
409 } 413 }
410 414
411 /* Call the handler */ 415 /* Call the handler */
@@ -426,7 +430,10 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj,
426 * We just returned from a non-default handler, we must re-enter the 430 * We just returned from a non-default handler, we must re-enter the
427 * interpreter 431 * interpreter
428 */ 432 */
429 acpi_ex_reacquire_interpreter(); 433 status2 = acpi_ex_enter_interpreter();
434 if (ACPI_FAILURE(status2)) {
435 return_ACPI_STATUS(status2);
436 }
430 } 437 }
431 438
432 return_ACPI_STATUS(status); 439 return_ACPI_STATUS(status);
diff --git a/drivers/acpi/events/evxface.c b/drivers/acpi/events/evxface.c
index 685a103a3587..a3379bafa676 100644
--- a/drivers/acpi/events/evxface.c
+++ b/drivers/acpi/events/evxface.c
@@ -768,9 +768,11 @@ acpi_status acpi_acquire_global_lock(u16 timeout, u32 * handle)
768 return (AE_BAD_PARAMETER); 768 return (AE_BAD_PARAMETER);
769 } 769 }
770 770
771 /* Must lock interpreter to prevent race conditions */ 771 status = acpi_ex_enter_interpreter();
772 if (ACPI_FAILURE(status)) {
773 return (status);
774 }
772 775
773 acpi_ex_enter_interpreter();
774 status = acpi_ev_acquire_global_lock(timeout); 776 status = acpi_ev_acquire_global_lock(timeout);
775 acpi_ex_exit_interpreter(); 777 acpi_ex_exit_interpreter();
776 778
diff --git a/drivers/acpi/executer/excreate.c b/drivers/acpi/executer/excreate.c
index 7c38528a7e83..ae97812681a3 100644
--- a/drivers/acpi/executer/excreate.c
+++ b/drivers/acpi/executer/excreate.c
@@ -583,7 +583,10 @@ acpi_ex_create_method(u8 * aml_start,
583 * Get the sync_level. If method is serialized, a mutex will be 583 * Get the sync_level. If method is serialized, a mutex will be
584 * created for this method when it is parsed. 584 * created for this method when it is parsed.
585 */ 585 */
586 if (method_flags & AML_METHOD_SERIALIZED) { 586 if (acpi_gbl_all_methods_serialized) {
587 obj_desc->method.sync_level = 0;
588 obj_desc->method.method_flags |= AML_METHOD_SERIALIZED;
589 } else if (method_flags & AML_METHOD_SERIALIZED) {
587 /* 590 /*
588 * ACPI 1.0: sync_level = 0 591 * ACPI 1.0: sync_level = 0
589 * ACPI 2.0: sync_level = sync_level in method declaration 592 * ACPI 2.0: sync_level = sync_level in method declaration
diff --git a/drivers/acpi/executer/exsystem.c b/drivers/acpi/executer/exsystem.c
index 9460baff3032..b2edf620ba89 100644
--- a/drivers/acpi/executer/exsystem.c
+++ b/drivers/acpi/executer/exsystem.c
@@ -66,6 +66,7 @@ ACPI_MODULE_NAME("exsystem")
66acpi_status acpi_ex_system_wait_semaphore(acpi_semaphore semaphore, u16 timeout) 66acpi_status acpi_ex_system_wait_semaphore(acpi_semaphore semaphore, u16 timeout)
67{ 67{
68 acpi_status status; 68 acpi_status status;
69 acpi_status status2;
69 70
70 ACPI_FUNCTION_TRACE(ex_system_wait_semaphore); 71 ACPI_FUNCTION_TRACE(ex_system_wait_semaphore);
71 72
@@ -78,7 +79,7 @@ acpi_status acpi_ex_system_wait_semaphore(acpi_semaphore semaphore, u16 timeout)
78 79
79 /* We must wait, so unlock the interpreter */ 80 /* We must wait, so unlock the interpreter */
80 81
81 acpi_ex_relinquish_interpreter(); 82 acpi_ex_exit_interpreter();
82 83
83 status = acpi_os_wait_semaphore(semaphore, 1, timeout); 84 status = acpi_os_wait_semaphore(semaphore, 1, timeout);
84 85
@@ -88,7 +89,13 @@ acpi_status acpi_ex_system_wait_semaphore(acpi_semaphore semaphore, u16 timeout)
88 89
89 /* Reacquire the interpreter */ 90 /* Reacquire the interpreter */
90 91
91 acpi_ex_reacquire_interpreter(); 92 status2 = acpi_ex_enter_interpreter();
93 if (ACPI_FAILURE(status2)) {
94
95 /* Report fatal error, could not acquire interpreter */
96
97 return_ACPI_STATUS(status2);
98 }
92 } 99 }
93 100
94 return_ACPI_STATUS(status); 101 return_ACPI_STATUS(status);
@@ -112,6 +119,7 @@ acpi_status acpi_ex_system_wait_semaphore(acpi_semaphore semaphore, u16 timeout)
112acpi_status acpi_ex_system_wait_mutex(acpi_mutex mutex, u16 timeout) 119acpi_status acpi_ex_system_wait_mutex(acpi_mutex mutex, u16 timeout)
113{ 120{
114 acpi_status status; 121 acpi_status status;
122 acpi_status status2;
115 123
116 ACPI_FUNCTION_TRACE(ex_system_wait_mutex); 124 ACPI_FUNCTION_TRACE(ex_system_wait_mutex);
117 125
@@ -124,7 +132,7 @@ acpi_status acpi_ex_system_wait_mutex(acpi_mutex mutex, u16 timeout)
124 132
125 /* We must wait, so unlock the interpreter */ 133 /* We must wait, so unlock the interpreter */
126 134
127 acpi_ex_relinquish_interpreter(); 135 acpi_ex_exit_interpreter();
128 136
129 status = acpi_os_acquire_mutex(mutex, timeout); 137 status = acpi_os_acquire_mutex(mutex, timeout);
130 138
@@ -134,7 +142,13 @@ acpi_status acpi_ex_system_wait_mutex(acpi_mutex mutex, u16 timeout)
134 142
135 /* Reacquire the interpreter */ 143 /* Reacquire the interpreter */
136 144
137 acpi_ex_reacquire_interpreter(); 145 status2 = acpi_ex_enter_interpreter();
146 if (ACPI_FAILURE(status2)) {
147
148 /* Report fatal error, could not acquire interpreter */
149
150 return_ACPI_STATUS(status2);
151 }
138 } 152 }
139 153
140 return_ACPI_STATUS(status); 154 return_ACPI_STATUS(status);
@@ -195,18 +209,20 @@ acpi_status acpi_ex_system_do_stall(u32 how_long)
195 209
196acpi_status acpi_ex_system_do_suspend(acpi_integer how_long) 210acpi_status acpi_ex_system_do_suspend(acpi_integer how_long)
197{ 211{
212 acpi_status status;
213
198 ACPI_FUNCTION_ENTRY(); 214 ACPI_FUNCTION_ENTRY();
199 215
200 /* Since this thread will sleep, we must release the interpreter */ 216 /* Since this thread will sleep, we must release the interpreter */
201 217
202 acpi_ex_relinquish_interpreter(); 218 acpi_ex_exit_interpreter();
203 219
204 acpi_os_sleep(how_long); 220 acpi_os_sleep(how_long);
205 221
206 /* And now we must get the interpreter again */ 222 /* And now we must get the interpreter again */
207 223
208 acpi_ex_reacquire_interpreter(); 224 status = acpi_ex_enter_interpreter();
209 return (AE_OK); 225 return (status);
210} 226}
211 227
212/******************************************************************************* 228/*******************************************************************************
diff --git a/drivers/acpi/executer/exutils.c b/drivers/acpi/executer/exutils.c
index 6b0aeccbb69b..aea461f3a48c 100644
--- a/drivers/acpi/executer/exutils.c
+++ b/drivers/acpi/executer/exutils.c
@@ -76,15 +76,14 @@ static u32 acpi_ex_digits_needed(acpi_integer value, u32 base);
76 * 76 *
77 * PARAMETERS: None 77 * PARAMETERS: None
78 * 78 *
79 * RETURN: None 79 * RETURN: Status
80 * 80 *
81 * DESCRIPTION: Enter the interpreter execution region. Failure to enter 81 * DESCRIPTION: Enter the interpreter execution region. Failure to enter
82 * the interpreter region is a fatal system error. Used in 82 * the interpreter region is a fatal system error
83 * conjunction with exit_interpreter.
84 * 83 *
85 ******************************************************************************/ 84 ******************************************************************************/
86 85
87void acpi_ex_enter_interpreter(void) 86acpi_status acpi_ex_enter_interpreter(void)
88{ 87{
89 acpi_status status; 88 acpi_status status;
90 89
@@ -92,42 +91,10 @@ void acpi_ex_enter_interpreter(void)
92 91
93 status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER); 92 status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER);
94 if (ACPI_FAILURE(status)) { 93 if (ACPI_FAILURE(status)) {
95 ACPI_ERROR((AE_INFO, 94 ACPI_ERROR((AE_INFO, "Could not acquire interpreter mutex"));
96 "Could not acquire AML Interpreter mutex"));
97 } 95 }
98 96
99 return_VOID; 97 return_ACPI_STATUS(status);
100}
101
102/*******************************************************************************
103 *
104 * FUNCTION: acpi_ex_reacquire_interpreter
105 *
106 * PARAMETERS: None
107 *
108 * RETURN: None
109 *
110 * DESCRIPTION: Reacquire the interpreter execution region from within the
111 * interpreter code. Failure to enter the interpreter region is a
112 * fatal system error. Used in conjuction with
113 * relinquish_interpreter
114 *
115 ******************************************************************************/
116
117void acpi_ex_reacquire_interpreter(void)
118{
119 ACPI_FUNCTION_TRACE(ex_reacquire_interpreter);
120
121 /*
122 * If the global serialized flag is set, do not release the interpreter,
123 * since it was not actually released by acpi_ex_relinquish_interpreter.
124 * This forces the interpreter to be single threaded.
125 */
126 if (!acpi_gbl_all_methods_serialized) {
127 acpi_ex_enter_interpreter();
128 }
129
130 return_VOID;
131} 98}
132 99
133/******************************************************************************* 100/*******************************************************************************
@@ -138,9 +105,17 @@ void acpi_ex_reacquire_interpreter(void)
138 * 105 *
139 * RETURN: None 106 * RETURN: None
140 * 107 *
141 * DESCRIPTION: Exit the interpreter execution region. This is the top level 108 * DESCRIPTION: Exit the interpreter execution region
142 * routine used to exit the interpreter when all processing has 109 *
143 * been completed. 110 * Cases where the interpreter is unlocked:
111 * 1) Completion of the execution of a control method
112 * 2) Method blocked on a Sleep() AML opcode
113 * 3) Method blocked on an Acquire() AML opcode
114 * 4) Method blocked on a Wait() AML opcode
115 * 5) Method blocked to acquire the global lock
116 * 6) Method blocked to execute a serialized control method that is
117 * already executing
118 * 7) About to invoke a user-installed opregion handler
144 * 119 *
145 ******************************************************************************/ 120 ******************************************************************************/
146 121
@@ -152,46 +127,7 @@ void acpi_ex_exit_interpreter(void)
152 127
153 status = acpi_ut_release_mutex(ACPI_MTX_INTERPRETER); 128 status = acpi_ut_release_mutex(ACPI_MTX_INTERPRETER);
154 if (ACPI_FAILURE(status)) { 129 if (ACPI_FAILURE(status)) {
155 ACPI_ERROR((AE_INFO, 130 ACPI_ERROR((AE_INFO, "Could not release interpreter mutex"));
156 "Could not release AML Interpreter mutex"));
157 }
158
159 return_VOID;
160}
161
162/*******************************************************************************
163 *
164 * FUNCTION: acpi_ex_relinquish_interpreter
165 *
166 * PARAMETERS: None
167 *
168 * RETURN: None
169 *
170 * DESCRIPTION: Exit the interpreter execution region, from within the
171 * interpreter - before attempting an operation that will possibly
172 * block the running thread.
173 *
174 * Cases where the interpreter is unlocked internally
175 * 1) Method to be blocked on a Sleep() AML opcode
176 * 2) Method to be blocked on an Acquire() AML opcode
177 * 3) Method to be blocked on a Wait() AML opcode
178 * 4) Method to be blocked to acquire the global lock
179 * 5) Method to be blocked waiting to execute a serialized control method
180 * that is currently executing
181 * 6) About to invoke a user-installed opregion handler
182 *
183 ******************************************************************************/
184
185void acpi_ex_relinquish_interpreter(void)
186{
187 ACPI_FUNCTION_TRACE(ex_relinquish_interpreter);
188
189 /*
190 * If the global serialized flag is set, do not release the interpreter.
191 * This forces the interpreter to be single threaded.
192 */
193 if (!acpi_gbl_all_methods_serialized) {
194 acpi_ex_exit_interpreter();
195 } 131 }
196 132
197 return_VOID; 133 return_VOID;
@@ -205,8 +141,8 @@ void acpi_ex_relinquish_interpreter(void)
205 * 141 *
206 * RETURN: none 142 * RETURN: none
207 * 143 *
208 * DESCRIPTION: Truncate an ACPI Integer to 32 bits if the execution mode is 144 * DESCRIPTION: Truncate a number to 32-bits if the currently executing method
209 * 32-bit, as determined by the revision of the DSDT. 145 * belongs to a 32-bit ACPI table.
210 * 146 *
211 ******************************************************************************/ 147 ******************************************************************************/
212 148
diff --git a/drivers/acpi/hardware/hwsleep.c b/drivers/acpi/hardware/hwsleep.c
index 8fa93125fd4c..c84b1faba28c 100644
--- a/drivers/acpi/hardware/hwsleep.c
+++ b/drivers/acpi/hardware/hwsleep.c
@@ -300,6 +300,11 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
300 /* 300 /*
301 * 2) Enable all wakeup GPEs 301 * 2) Enable all wakeup GPEs
302 */ 302 */
303 status = acpi_hw_disable_all_gpes();
304 if (ACPI_FAILURE(status)) {
305 return_ACPI_STATUS(status);
306 }
307
303 acpi_gbl_system_awake_and_running = FALSE; 308 acpi_gbl_system_awake_and_running = FALSE;
304 309
305 status = acpi_hw_enable_all_wakeup_gpes(); 310 status = acpi_hw_enable_all_wakeup_gpes();
diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c
index 36901362fd24..dc1096608f43 100644
--- a/drivers/acpi/ibm_acpi.c
+++ b/drivers/acpi/ibm_acpi.c
@@ -2507,7 +2507,7 @@ static int __init setup_notify(struct ibm_struct *ibm)
2507 ret = acpi_bus_get_device(*ibm->handle, &ibm->device); 2507 ret = acpi_bus_get_device(*ibm->handle, &ibm->device);
2508 if (ret < 0) { 2508 if (ret < 0) {
2509 printk(IBM_ERR "%s device not present\n", ibm->name); 2509 printk(IBM_ERR "%s device not present\n", ibm->name);
2510 return 0; 2510 return -ENODEV;
2511 } 2511 }
2512 2512
2513 acpi_driver_data(ibm->device) = ibm; 2513 acpi_driver_data(ibm->device) = ibm;
@@ -2516,8 +2516,13 @@ static int __init setup_notify(struct ibm_struct *ibm)
2516 status = acpi_install_notify_handler(*ibm->handle, ibm->type, 2516 status = acpi_install_notify_handler(*ibm->handle, ibm->type,
2517 dispatch_notify, ibm); 2517 dispatch_notify, ibm);
2518 if (ACPI_FAILURE(status)) { 2518 if (ACPI_FAILURE(status)) {
2519 printk(IBM_ERR "acpi_install_notify_handler(%s) failed: %d\n", 2519 if (status == AE_ALREADY_EXISTS) {
2520 ibm->name, status); 2520 printk(IBM_NOTICE "another device driver is already handling %s events\n",
2521 ibm->name);
2522 } else {
2523 printk(IBM_ERR "acpi_install_notify_handler(%s) failed: %d\n",
2524 ibm->name, status);
2525 }
2521 return -ENODEV; 2526 return -ENODEV;
2522 } 2527 }
2523 ibm->notify_installed = 1; 2528 ibm->notify_installed = 1;
@@ -2553,6 +2558,8 @@ static int __init register_driver(struct ibm_struct *ibm)
2553 return ret; 2558 return ret;
2554} 2559}
2555 2560
2561static void ibm_exit(struct ibm_struct *ibm);
2562
2556static int __init ibm_init(struct ibm_struct *ibm) 2563static int __init ibm_init(struct ibm_struct *ibm)
2557{ 2564{
2558 int ret; 2565 int ret;
@@ -2594,6 +2601,12 @@ static int __init ibm_init(struct ibm_struct *ibm)
2594 2601
2595 if (ibm->notify) { 2602 if (ibm->notify) {
2596 ret = setup_notify(ibm); 2603 ret = setup_notify(ibm);
2604 if (ret == -ENODEV) {
2605 printk(IBM_NOTICE "disabling subdriver %s\n",
2606 ibm->name);
2607 ibm_exit(ibm);
2608 return 0;
2609 }
2597 if (ret < 0) 2610 if (ret < 0)
2598 return ret; 2611 return ret;
2599 } 2612 }
diff --git a/drivers/acpi/namespace/nseval.c b/drivers/acpi/namespace/nseval.c
index aa6370c67ec1..26fd0dd6953d 100644
--- a/drivers/acpi/namespace/nseval.c
+++ b/drivers/acpi/namespace/nseval.c
@@ -154,7 +154,11 @@ acpi_status acpi_ns_evaluate(struct acpi_evaluate_info *info)
154 * Execute the method via the interpreter. The interpreter is locked 154 * Execute the method via the interpreter. The interpreter is locked
155 * here before calling into the AML parser 155 * here before calling into the AML parser
156 */ 156 */
157 acpi_ex_enter_interpreter(); 157 status = acpi_ex_enter_interpreter();
158 if (ACPI_FAILURE(status)) {
159 return_ACPI_STATUS(status);
160 }
161
158 status = acpi_ps_execute_method(info); 162 status = acpi_ps_execute_method(info);
159 acpi_ex_exit_interpreter(); 163 acpi_ex_exit_interpreter();
160 } else { 164 } else {
@@ -178,7 +182,10 @@ acpi_status acpi_ns_evaluate(struct acpi_evaluate_info *info)
178 * resolution, we must lock it because we could access an opregion. 182 * resolution, we must lock it because we could access an opregion.
179 * The opregion access code assumes that the interpreter is locked. 183 * The opregion access code assumes that the interpreter is locked.
180 */ 184 */
181 acpi_ex_enter_interpreter(); 185 status = acpi_ex_enter_interpreter();
186 if (ACPI_FAILURE(status)) {
187 return_ACPI_STATUS(status);
188 }
182 189
183 /* Function has a strange interface */ 190 /* Function has a strange interface */
184 191
diff --git a/drivers/acpi/namespace/nsinit.c b/drivers/acpi/namespace/nsinit.c
index 33db2241044e..c4ab615f77fe 100644
--- a/drivers/acpi/namespace/nsinit.c
+++ b/drivers/acpi/namespace/nsinit.c
@@ -214,7 +214,7 @@ acpi_ns_init_one_object(acpi_handle obj_handle,
214 u32 level, void *context, void **return_value) 214 u32 level, void *context, void **return_value)
215{ 215{
216 acpi_object_type type; 216 acpi_object_type type;
217 acpi_status status = AE_OK; 217 acpi_status status;
218 struct acpi_init_walk_info *info = 218 struct acpi_init_walk_info *info =
219 (struct acpi_init_walk_info *)context; 219 (struct acpi_init_walk_info *)context;
220 struct acpi_namespace_node *node = 220 struct acpi_namespace_node *node =
@@ -268,7 +268,10 @@ acpi_ns_init_one_object(acpi_handle obj_handle,
268 /* 268 /*
269 * Must lock the interpreter before executing AML code 269 * Must lock the interpreter before executing AML code
270 */ 270 */
271 acpi_ex_enter_interpreter(); 271 status = acpi_ex_enter_interpreter();
272 if (ACPI_FAILURE(status)) {
273 return (status);
274 }
272 275
273 /* 276 /*
274 * Each of these types can contain executable AML code within the 277 * Each of these types can contain executable AML code within the
diff --git a/drivers/acpi/namespace/nsxfeval.c b/drivers/acpi/namespace/nsxfeval.c
index 7ac6ace50059..8904d0fae6a2 100644
--- a/drivers/acpi/namespace/nsxfeval.c
+++ b/drivers/acpi/namespace/nsxfeval.c
@@ -170,6 +170,7 @@ acpi_evaluate_object(acpi_handle handle,
170 struct acpi_buffer *return_buffer) 170 struct acpi_buffer *return_buffer)
171{ 171{
172 acpi_status status; 172 acpi_status status;
173 acpi_status status2;
173 struct acpi_evaluate_info *info; 174 struct acpi_evaluate_info *info;
174 acpi_size buffer_space_needed; 175 acpi_size buffer_space_needed;
175 u32 i; 176 u32 i;
@@ -328,12 +329,14 @@ acpi_evaluate_object(acpi_handle handle,
328 * Delete the internal return object. NOTE: Interpreter must be 329 * Delete the internal return object. NOTE: Interpreter must be
329 * locked to avoid race condition. 330 * locked to avoid race condition.
330 */ 331 */
331 acpi_ex_enter_interpreter(); 332 status2 = acpi_ex_enter_interpreter();
333 if (ACPI_SUCCESS(status2)) {
332 334
333 /* Remove one reference on the return object (should delete it) */ 335 /* Remove one reference on the return object (should delete it) */
334 336
335 acpi_ut_remove_reference(info->return_object); 337 acpi_ut_remove_reference(info->return_object);
336 acpi_ex_exit_interpreter(); 338 acpi_ex_exit_interpreter();
339 }
337 } 340 }
338 341
339 cleanup: 342 cleanup:
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 60773005b8af..562124ed785e 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -89,6 +89,12 @@ module_param(nocst, uint, 0000);
89static unsigned int bm_history __read_mostly = 89static unsigned int bm_history __read_mostly =
90 (HZ >= 800 ? 0xFFFFFFFF : ((1U << (HZ / 25)) - 1)); 90 (HZ >= 800 ? 0xFFFFFFFF : ((1U << (HZ / 25)) - 1));
91module_param(bm_history, uint, 0644); 91module_param(bm_history, uint, 0644);
92
93static unsigned use_ipi = 2;
94module_param(use_ipi, uint, 0644);
95MODULE_PARM_DESC(use_ipi, "IPI (vs. LAPIC) irqs for not waking up from C2/C3"
96 " machines. 0=apic, 1=ipi, 2=auto\n");
97
92/* -------------------------------------------------------------------------- 98/* --------------------------------------------------------------------------
93 Power Management 99 Power Management
94 -------------------------------------------------------------------------- */ 100 -------------------------------------------------------------------------- */
@@ -260,9 +266,8 @@ static void acpi_cstate_enter(struct acpi_processor_cx *cstate)
260 266
261/* 267/*
262 * Some BIOS implementations switch to C3 in the published C2 state. 268 * Some BIOS implementations switch to C3 in the published C2 state.
263 * This seems to be a common problem on AMD boxen, but other vendors 269 * This seems to be a common problem on AMD boxen and Intel Dothan/Banias
264 * are affected too. We pick the most conservative approach: we assume 270 * Pentium M machines.
265 * that the local APIC stops in both C2 and C3.
266 */ 271 */
267static void acpi_timer_check_state(int state, struct acpi_processor *pr, 272static void acpi_timer_check_state(int state, struct acpi_processor *pr,
268 struct acpi_processor_cx *cx) 273 struct acpi_processor_cx *cx)
@@ -276,8 +281,17 @@ static void acpi_timer_check_state(int state, struct acpi_processor *pr,
276 if (pwr->timer_broadcast_on_state < state) 281 if (pwr->timer_broadcast_on_state < state)
277 return; 282 return;
278 283
279 if (cx->type >= ACPI_STATE_C2) 284 if (cx->type >= ACPI_STATE_C2) {
280 pr->power.timer_broadcast_on_state = state; 285 if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD)
286 pr->power.timer_broadcast_on_state = state;
287 else if ((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL &&
288 boot_cpu_data.x86 == 6) &&
289 (boot_cpu_data.x86_model == 13 ||
290 boot_cpu_data.x86_model == 9))
291 {
292 pr->power.timer_broadcast_on_state = state;
293 }
294 }
281} 295}
282 296
283static void acpi_propagate_timer_broadcast(struct acpi_processor *pr) 297static void acpi_propagate_timer_broadcast(struct acpi_processor *pr)
@@ -292,10 +306,16 @@ static void acpi_propagate_timer_broadcast(struct acpi_processor *pr)
292#else 306#else
293 cpumask_t mask = cpumask_of_cpu(pr->id); 307 cpumask_t mask = cpumask_of_cpu(pr->id);
294 308
295 if (pr->power.timer_broadcast_on_state < INT_MAX) 309 if (use_ipi == 0)
296 on_each_cpu(switch_APIC_timer_to_ipi, &mask, 1, 1); 310 on_each_cpu(switch_APIC_timer_to_ipi, &mask, 1, 1);
297 else 311 else if (use_ipi == 1)
298 on_each_cpu(switch_ipi_to_APIC_timer, &mask, 1, 1); 312 on_each_cpu(switch_ipi_to_APIC_timer, &mask, 1, 1);
313 else {
314 if (pr->power.timer_broadcast_on_state < INT_MAX)
315 on_each_cpu(switch_APIC_timer_to_ipi, &mask, 1, 1);
316 else
317 on_each_cpu(switch_ipi_to_APIC_timer, &mask, 1, 1);
318 }
299#endif 319#endif
300} 320}
301 321
@@ -1013,13 +1033,13 @@ static int acpi_processor_power_verify(struct acpi_processor *pr)
1013 1033
1014 case ACPI_STATE_C2: 1034 case ACPI_STATE_C2:
1015 acpi_processor_power_verify_c2(cx); 1035 acpi_processor_power_verify_c2(cx);
1016 if (cx->valid) 1036 if (cx->valid && use_ipi != 0 && use_ipi != 1)
1017 acpi_timer_check_state(i, pr, cx); 1037 acpi_timer_check_state(i, pr, cx);
1018 break; 1038 break;
1019 1039
1020 case ACPI_STATE_C3: 1040 case ACPI_STATE_C3:
1021 acpi_processor_power_verify_c3(pr, cx); 1041 acpi_processor_power_verify_c3(pr, cx);
1022 if (cx->valid) 1042 if (cx->valid && use_ipi != 0 && use_ipi != 1)
1023 acpi_timer_check_state(i, pr, cx); 1043 acpi_timer_check_state(i, pr, cx);
1024 break; 1044 break;
1025 } 1045 }
diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
index 849e2c361804..96792a6cc164 100644
--- a/drivers/acpi/tables.c
+++ b/drivers/acpi/tables.c
@@ -42,7 +42,9 @@ static char *mps_inti_flags_trigger[] = { "dfl", "edge", "res", "level" };
42 42
43static struct acpi_table_desc initial_tables[ACPI_MAX_TABLES] __initdata; 43static struct acpi_table_desc initial_tables[ACPI_MAX_TABLES] __initdata;
44 44
45void acpi_table_print_madt_entry(struct acpi_subtable_header * header) 45static int acpi_apic_instance __initdata = 2;
46
47void acpi_table_print_madt_entry(struct acpi_subtable_header *header)
46{ 48{
47 if (!header) 49 if (!header)
48 return; 50 return;
@@ -183,8 +185,10 @@ acpi_table_parse_entries(char *id,
183 if (!handler) 185 if (!handler)
184 return -EINVAL; 186 return -EINVAL;
185 187
186 /* Locate the table (if exists). There should only be one. */ 188 if (strncmp(id, ACPI_SIG_MADT, 4) == 0)
187 acpi_get_table(id, 0, &table_header); 189 acpi_get_table(id, acpi_apic_instance, &table_header);
190 else
191 acpi_get_table(id, 0, &table_header);
188 192
189 if (!table_header) { 193 if (!table_header) {
190 printk(KERN_WARNING PREFIX "%4.4s not present\n", id); 194 printk(KERN_WARNING PREFIX "%4.4s not present\n", id);
@@ -237,10 +241,15 @@ acpi_table_parse_madt(enum acpi_madt_type id,
237int __init acpi_table_parse(char *id, acpi_table_handler handler) 241int __init acpi_table_parse(char *id, acpi_table_handler handler)
238{ 242{
239 struct acpi_table_header *table = NULL; 243 struct acpi_table_header *table = NULL;
244
240 if (!handler) 245 if (!handler)
241 return -EINVAL; 246 return -EINVAL;
242 247
243 acpi_get_table(id, 0, &table); 248 if (strncmp(id, ACPI_SIG_MADT, 4) == 0)
249 acpi_get_table(id, acpi_apic_instance, &table);
250 else
251 acpi_get_table(id, 0, &table);
252
244 if (table) { 253 if (table) {
245 handler(table); 254 handler(table);
246 return 0; 255 return 0;
@@ -248,6 +257,31 @@ int __init acpi_table_parse(char *id, acpi_table_handler handler)
248 return 1; 257 return 1;
249} 258}
250 259
260/*
261 * The BIOS is supposed to supply a single APIC/MADT,
262 * but some report two. Provide a knob to use either.
263 * (don't you wish instance 0 and 1 were not the same?)
264 */
265static void __init check_multiple_madt(void)
266{
267 struct acpi_table_header *table = NULL;
268
269 acpi_get_table(ACPI_SIG_MADT, 2, &table);
270 if (table) {
271 printk(KERN_WARNING PREFIX
272 "BIOS bug: multiple APIC/MADT found,"
273 " using %d\n", acpi_apic_instance);
274 printk(KERN_WARNING PREFIX
275 "If \"acpi_apic_instance=%d\" works better, "
276 "notify linux-acpi@vger.kernel.org\n",
277 acpi_apic_instance ? 0 : 2);
278
279 } else
280 acpi_apic_instance = 0;
281
282 return;
283}
284
251/* 285/*
252 * acpi_table_init() 286 * acpi_table_init()
253 * 287 *
@@ -257,9 +291,22 @@ int __init acpi_table_parse(char *id, acpi_table_handler handler)
257 * result: sdt_entry[] is initialized 291 * result: sdt_entry[] is initialized
258 */ 292 */
259 293
260
261int __init acpi_table_init(void) 294int __init acpi_table_init(void)
262{ 295{
263 acpi_initialize_tables(initial_tables, ACPI_MAX_TABLES, 0); 296 acpi_initialize_tables(initial_tables, ACPI_MAX_TABLES, 0);
297 check_multiple_madt();
298 return 0;
299}
300
301static int __init acpi_parse_apic_instance(char *str)
302{
303
304 acpi_apic_instance = simple_strtoul(str, NULL, 0);
305
306 printk(KERN_NOTICE PREFIX "Shall use APIC/MADT table %d\n",
307 acpi_apic_instance);
308
264 return 0; 309 return 0;
265} 310}
311
312early_param("acpi_apic_instance", acpi_parse_apic_instance);