aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/acpi/dispatcher/dsmethod.c12
-rw-r--r--drivers/acpi/events/evmisc.c11
-rw-r--r--drivers/acpi/events/evxface.c26
-rw-r--r--drivers/acpi/executer/exfield.c24
-rw-r--r--drivers/acpi/executer/exmutex.c194
-rw-r--r--drivers/acpi/executer/exutils.c58
-rw-r--r--drivers/acpi/namespace/nsaccess.c3
-rw-r--r--drivers/acpi/utilities/utdelete.c2
-rw-r--r--include/acpi/acglobal.h20
-rw-r--r--include/acpi/acinterp.h11
-rw-r--r--include/acpi/acobject.h3
11 files changed, 219 insertions, 145 deletions
diff --git a/drivers/acpi/dispatcher/dsmethod.c b/drivers/acpi/dispatcher/dsmethod.c
index 1cbe61905824..c50c0cd5d717 100644
--- a/drivers/acpi/dispatcher/dsmethod.c
+++ b/drivers/acpi/dispatcher/dsmethod.c
@@ -232,9 +232,9 @@ acpi_ds_begin_method_execution(struct acpi_namespace_node *method_node,
232 * recursive call. 232 * recursive call.
233 */ 233 */
234 if (!walk_state || 234 if (!walk_state ||
235 !obj_desc->method.mutex->mutex.owner_thread || 235 !obj_desc->method.mutex->mutex.thread_id ||
236 (walk_state->thread != 236 (walk_state->thread->thread_id !=
237 obj_desc->method.mutex->mutex.owner_thread)) { 237 obj_desc->method.mutex->mutex.thread_id)) {
238 /* 238 /*
239 * Acquire the method mutex. This releases the interpreter if we 239 * Acquire the method mutex. This releases the interpreter if we
240 * block (and reacquires it before it returns) 240 * block (and reacquires it before it returns)
@@ -254,8 +254,8 @@ acpi_ds_begin_method_execution(struct acpi_namespace_node *method_node,
254 original_sync_level = 254 original_sync_level =
255 walk_state->thread->current_sync_level; 255 walk_state->thread->current_sync_level;
256 256
257 obj_desc->method.mutex->mutex.owner_thread = 257 obj_desc->method.mutex->mutex.thread_id =
258 walk_state->thread; 258 walk_state->thread->thread_id;
259 walk_state->thread->current_sync_level = 259 walk_state->thread->current_sync_level =
260 obj_desc->method.sync_level; 260 obj_desc->method.sync_level;
261 } else { 261 } else {
@@ -569,7 +569,7 @@ acpi_ds_terminate_control_method(union acpi_operand_object *method_desc,
569 569
570 acpi_os_release_mutex(method_desc->method.mutex->mutex. 570 acpi_os_release_mutex(method_desc->method.mutex->mutex.
571 os_mutex); 571 os_mutex);
572 method_desc->method.mutex->mutex.owner_thread = NULL; 572 method_desc->method.mutex->mutex.thread_id = 0;
573 } 573 }
574 } 574 }
575 575
diff --git a/drivers/acpi/events/evmisc.c b/drivers/acpi/events/evmisc.c
index 21cb749d0c75..2d34663dc1ed 100644
--- a/drivers/acpi/events/evmisc.c
+++ b/drivers/acpi/events/evmisc.c
@@ -439,7 +439,8 @@ acpi_status acpi_ev_acquire_global_lock(u16 timeout)
439 * Only one thread can acquire the GL at a time, the global_lock_mutex 439 * Only one thread can acquire the GL at a time, the global_lock_mutex
440 * enforces this. This interface releases the interpreter if we must wait. 440 * enforces this. This interface releases the interpreter if we must wait.
441 */ 441 */
442 status = acpi_ex_system_wait_mutex(acpi_gbl_global_lock_mutex, 0); 442 status = acpi_ex_system_wait_mutex(
443 acpi_gbl_global_lock_mutex->mutex.os_mutex, 0);
443 if (status == AE_TIME) { 444 if (status == AE_TIME) {
444 if (acpi_ev_global_lock_thread_id == acpi_os_get_thread_id()) { 445 if (acpi_ev_global_lock_thread_id == acpi_os_get_thread_id()) {
445 acpi_ev_global_lock_acquired++; 446 acpi_ev_global_lock_acquired++;
@@ -448,9 +449,9 @@ acpi_status acpi_ev_acquire_global_lock(u16 timeout)
448 } 449 }
449 450
450 if (ACPI_FAILURE(status)) { 451 if (ACPI_FAILURE(status)) {
451 status = 452 status = acpi_ex_system_wait_mutex(
452 acpi_ex_system_wait_mutex(acpi_gbl_global_lock_mutex, 453 acpi_gbl_global_lock_mutex->mutex.os_mutex,
453 timeout); 454 timeout);
454 } 455 }
455 if (ACPI_FAILURE(status)) { 456 if (ACPI_FAILURE(status)) {
456 return_ACPI_STATUS(status); 457 return_ACPI_STATUS(status);
@@ -555,7 +556,7 @@ acpi_status acpi_ev_release_global_lock(void)
555 /* Release the local GL mutex */ 556 /* Release the local GL mutex */
556 acpi_ev_global_lock_thread_id = NULL; 557 acpi_ev_global_lock_thread_id = NULL;
557 acpi_ev_global_lock_acquired = 0; 558 acpi_ev_global_lock_acquired = 0;
558 acpi_os_release_mutex(acpi_gbl_global_lock_mutex); 559 acpi_os_release_mutex(acpi_gbl_global_lock_mutex->mutex.os_mutex);
559 return_ACPI_STATUS(status); 560 return_ACPI_STATUS(status);
560} 561}
561 562
diff --git a/drivers/acpi/events/evxface.c b/drivers/acpi/events/evxface.c
index 6d866a01f5f4..dbf34a5fc1e0 100644
--- a/drivers/acpi/events/evxface.c
+++ b/drivers/acpi/events/evxface.c
@@ -758,6 +758,12 @@ ACPI_EXPORT_SYMBOL(acpi_remove_gpe_handler)
758 * 758 *
759 * DESCRIPTION: Acquire the ACPI Global Lock 759 * DESCRIPTION: Acquire the ACPI Global Lock
760 * 760 *
761 * Note: Allows callers with the same thread ID to acquire the global lock
762 * multiple times. In other words, externally, the behavior of the global lock
763 * is identical to an AML mutex. On the first acquire, a new handle is
764 * returned. On any subsequent calls to acquire by the same thread, the same
765 * handle is returned.
766 *
761 ******************************************************************************/ 767 ******************************************************************************/
762acpi_status acpi_acquire_global_lock(u16 timeout, u32 * handle) 768acpi_status acpi_acquire_global_lock(u16 timeout, u32 * handle)
763{ 769{
@@ -770,14 +776,26 @@ acpi_status acpi_acquire_global_lock(u16 timeout, u32 * handle)
770 /* Must lock interpreter to prevent race conditions */ 776 /* Must lock interpreter to prevent race conditions */
771 777
772 acpi_ex_enter_interpreter(); 778 acpi_ex_enter_interpreter();
773 status = acpi_ev_acquire_global_lock(timeout); 779
774 acpi_ex_exit_interpreter(); 780 status = acpi_ex_acquire_mutex_object(timeout,
781 acpi_gbl_global_lock_mutex,
782 acpi_os_get_thread_id());
775 783
776 if (ACPI_SUCCESS(status)) { 784 if (ACPI_SUCCESS(status)) {
777 acpi_gbl_global_lock_handle++; 785 /*
786 * If this was the first acquisition of the Global Lock by this thread,
787 * create a new handle. Otherwise, return the existing handle.
788 */
789 if (acpi_gbl_global_lock_mutex->mutex.acquisition_depth == 1) {
790 acpi_gbl_global_lock_handle++;
791 }
792
793 /* Return the global lock handle */
794
778 *handle = acpi_gbl_global_lock_handle; 795 *handle = acpi_gbl_global_lock_handle;
779 } 796 }
780 797
798 acpi_ex_exit_interpreter();
781 return (status); 799 return (status);
782} 800}
783 801
@@ -802,7 +820,7 @@ acpi_status acpi_release_global_lock(u32 handle)
802 return (AE_NOT_ACQUIRED); 820 return (AE_NOT_ACQUIRED);
803 } 821 }
804 822
805 status = acpi_ev_release_global_lock(); 823 status = acpi_ex_release_mutex_object(acpi_gbl_global_lock_mutex);
806 return (status); 824 return (status);
807} 825}
808 826
diff --git a/drivers/acpi/executer/exfield.c b/drivers/acpi/executer/exfield.c
index 2d88a3d8d1ad..e66b367c4fb6 100644
--- a/drivers/acpi/executer/exfield.c
+++ b/drivers/acpi/executer/exfield.c
@@ -71,7 +71,6 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state,
71 union acpi_operand_object *buffer_desc; 71 union acpi_operand_object *buffer_desc;
72 acpi_size length; 72 acpi_size length;
73 void *buffer; 73 void *buffer;
74 u8 locked;
75 74
76 ACPI_FUNCTION_TRACE_PTR(ex_read_data_from_field, obj_desc); 75 ACPI_FUNCTION_TRACE_PTR(ex_read_data_from_field, obj_desc);
77 76
@@ -111,9 +110,7 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state,
111 110
112 /* Lock entire transaction if requested */ 111 /* Lock entire transaction if requested */
113 112
114 locked = 113 acpi_ex_acquire_global_lock(obj_desc->common_field.field_flags);
115 acpi_ex_acquire_global_lock(obj_desc->common_field.
116 field_flags);
117 114
118 /* 115 /*
119 * Perform the read. 116 * Perform the read.
@@ -125,7 +122,7 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state,
125 buffer.pointer), 122 buffer.pointer),
126 ACPI_READ | (obj_desc->field. 123 ACPI_READ | (obj_desc->field.
127 attribute << 16)); 124 attribute << 16));
128 acpi_ex_release_global_lock(locked); 125 acpi_ex_release_global_lock();
129 goto exit; 126 goto exit;
130 } 127 }
131 128
@@ -175,13 +172,12 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state,
175 172
176 /* Lock entire transaction if requested */ 173 /* Lock entire transaction if requested */
177 174
178 locked = 175 acpi_ex_acquire_global_lock(obj_desc->common_field.field_flags);
179 acpi_ex_acquire_global_lock(obj_desc->common_field.field_flags);
180 176
181 /* Read from the field */ 177 /* Read from the field */
182 178
183 status = acpi_ex_extract_from_field(obj_desc, buffer, (u32) length); 179 status = acpi_ex_extract_from_field(obj_desc, buffer, (u32) length);
184 acpi_ex_release_global_lock(locked); 180 acpi_ex_release_global_lock();
185 181
186 exit: 182 exit:
187 if (ACPI_FAILURE(status)) { 183 if (ACPI_FAILURE(status)) {
@@ -217,7 +213,6 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc,
217 u32 required_length; 213 u32 required_length;
218 void *buffer; 214 void *buffer;
219 void *new_buffer; 215 void *new_buffer;
220 u8 locked;
221 union acpi_operand_object *buffer_desc; 216 union acpi_operand_object *buffer_desc;
222 217
223 ACPI_FUNCTION_TRACE_PTR(ex_write_data_to_field, obj_desc); 218 ACPI_FUNCTION_TRACE_PTR(ex_write_data_to_field, obj_desc);
@@ -278,9 +273,7 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc,
278 273
279 /* Lock entire transaction if requested */ 274 /* Lock entire transaction if requested */
280 275
281 locked = 276 acpi_ex_acquire_global_lock(obj_desc->common_field.field_flags);
282 acpi_ex_acquire_global_lock(obj_desc->common_field.
283 field_flags);
284 277
285 /* 278 /*
286 * Perform the write (returns status and perhaps data in the 279 * Perform the write (returns status and perhaps data in the
@@ -291,7 +284,7 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc,
291 (acpi_integer *) buffer, 284 (acpi_integer *) buffer,
292 ACPI_WRITE | (obj_desc->field. 285 ACPI_WRITE | (obj_desc->field.
293 attribute << 16)); 286 attribute << 16));
294 acpi_ex_release_global_lock(locked); 287 acpi_ex_release_global_lock();
295 288
296 *result_desc = buffer_desc; 289 *result_desc = buffer_desc;
297 return_ACPI_STATUS(status); 290 return_ACPI_STATUS(status);
@@ -366,13 +359,12 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc,
366 359
367 /* Lock entire transaction if requested */ 360 /* Lock entire transaction if requested */
368 361
369 locked = 362 acpi_ex_acquire_global_lock(obj_desc->common_field.field_flags);
370 acpi_ex_acquire_global_lock(obj_desc->common_field.field_flags);
371 363
372 /* Write to the field */ 364 /* Write to the field */
373 365
374 status = acpi_ex_insert_into_field(obj_desc, buffer, length); 366 status = acpi_ex_insert_into_field(obj_desc, buffer, length);
375 acpi_ex_release_global_lock(locked); 367 acpi_ex_release_global_lock();
376 368
377 /* Free temporary buffer if we used one */ 369 /* Free temporary buffer if we used one */
378 370
diff --git a/drivers/acpi/executer/exmutex.c b/drivers/acpi/executer/exmutex.c
index 6748e3ef0997..0bebe751aac5 100644
--- a/drivers/acpi/executer/exmutex.c
+++ b/drivers/acpi/executer/exmutex.c
@@ -126,6 +126,66 @@ acpi_ex_link_mutex(union acpi_operand_object *obj_desc,
126 126
127/******************************************************************************* 127/*******************************************************************************
128 * 128 *
129 * FUNCTION: acpi_ex_acquire_mutex_object
130 *
131 * PARAMETERS: time_desc - Timeout in milliseconds
132 * obj_desc - Mutex object
133 * Thread - Current thread state
134 *
135 * RETURN: Status
136 *
137 * DESCRIPTION: Acquire an AML mutex, low-level interface
138 *
139 ******************************************************************************/
140
141acpi_status
142acpi_ex_acquire_mutex_object(u16 timeout,
143 union acpi_operand_object *obj_desc,
144 acpi_thread_id thread_id)
145{
146 acpi_status status;
147
148 ACPI_FUNCTION_TRACE_PTR(ex_acquire_mutex_object, obj_desc);
149
150 /* Support for multiple acquires by the owning thread */
151
152 if (obj_desc->mutex.thread_id == thread_id) {
153 /*
154 * The mutex is already owned by this thread, just increment the
155 * acquisition depth
156 */
157 obj_desc->mutex.acquisition_depth++;
158 return_ACPI_STATUS(AE_OK);
159 }
160
161 /* Acquire the mutex, wait if necessary. Special case for Global Lock */
162
163 if (obj_desc == acpi_gbl_global_lock_mutex) {
164 status = acpi_ev_acquire_global_lock(timeout);
165 } else {
166 status = acpi_ex_system_wait_mutex(obj_desc->mutex.os_mutex,
167 timeout);
168 }
169
170 if (ACPI_FAILURE(status)) {
171
172 /* Includes failure from a timeout on time_desc */
173
174 return_ACPI_STATUS(status);
175 }
176
177 /* Have the mutex: update mutex and save the sync_level */
178
179 obj_desc->mutex.thread_id = thread_id;
180 obj_desc->mutex.acquisition_depth = 1;
181 obj_desc->mutex.original_sync_level = 0;
182 obj_desc->mutex.owner_thread = NULL; /* Used only for AML Acquire() */
183
184 return_ACPI_STATUS(AE_OK);
185}
186
187/*******************************************************************************
188 *
129 * FUNCTION: acpi_ex_acquire_mutex 189 * FUNCTION: acpi_ex_acquire_mutex
130 * 190 *
131 * PARAMETERS: time_desc - Timeout integer 191 * PARAMETERS: time_desc - Timeout integer
@@ -161,7 +221,7 @@ acpi_ex_acquire_mutex(union acpi_operand_object *time_desc,
161 } 221 }
162 222
163 /* 223 /*
164 * Current Sync must be less than or equal to the sync level of the 224 * Current Sync level must be less than or equal to the sync level of the
165 * mutex. This mechanism provides some deadlock prevention 225 * mutex. This mechanism provides some deadlock prevention
166 */ 226 */
167 if (walk_state->thread->current_sync_level > obj_desc->mutex.sync_level) { 227 if (walk_state->thread->current_sync_level > obj_desc->mutex.sync_level) {
@@ -172,51 +232,70 @@ acpi_ex_acquire_mutex(union acpi_operand_object *time_desc,
172 return_ACPI_STATUS(AE_AML_MUTEX_ORDER); 232 return_ACPI_STATUS(AE_AML_MUTEX_ORDER);
173 } 233 }
174 234
175 /* Support for multiple acquires by the owning thread */ 235 status = acpi_ex_acquire_mutex_object((u16) time_desc->integer.value,
236 obj_desc,
237 walk_state->thread->thread_id);
238 if (ACPI_SUCCESS(status) && obj_desc->mutex.acquisition_depth == 1) {
239 obj_desc->mutex.owner_thread = walk_state->thread;
240 obj_desc->mutex.original_sync_level =
241 walk_state->thread->current_sync_level;
242 walk_state->thread->current_sync_level =
243 obj_desc->mutex.sync_level;
176 244
177 if (obj_desc->mutex.owner_thread) { 245 /* Link the mutex to the current thread for force-unlock at method exit */
178 if (obj_desc->mutex.owner_thread->thread_id == 246
179 walk_state->thread->thread_id) { 247 acpi_ex_link_mutex(obj_desc, walk_state->thread);
180 /*
181 * The mutex is already owned by this thread, just increment the
182 * acquisition depth
183 */
184 obj_desc->mutex.acquisition_depth++;
185 return_ACPI_STATUS(AE_OK);
186 }
187 } 248 }
188 249
189 /* Acquire the mutex, wait if necessary. Special case for Global Lock */ 250 return_ACPI_STATUS(status);
251}
190 252
191 if (obj_desc->mutex.os_mutex == acpi_gbl_global_lock_mutex) { 253/*******************************************************************************
192 status = 254 *
193 acpi_ev_acquire_global_lock((u16) time_desc->integer.value); 255 * FUNCTION: acpi_ex_release_mutex_object
194 } else { 256 *
195 status = acpi_ex_system_wait_mutex(obj_desc->mutex.os_mutex, 257 * PARAMETERS: obj_desc - The object descriptor for this op
196 (u16) time_desc->integer. 258 *
197 value); 259 * RETURN: Status
198 } 260 *
261 * DESCRIPTION: Release a previously acquired Mutex, low level interface.
262 *
263 ******************************************************************************/
199 264
200 if (ACPI_FAILURE(status)) { 265acpi_status acpi_ex_release_mutex_object(union acpi_operand_object *obj_desc)
266{
267 acpi_status status = AE_OK;
201 268
202 /* Includes failure from a timeout on time_desc */ 269 ACPI_FUNCTION_TRACE(ex_release_mutex_object);
203 270
204 return_ACPI_STATUS(status); 271 /* Match multiple Acquires with multiple Releases */
272
273 obj_desc->mutex.acquisition_depth--;
274 if (obj_desc->mutex.acquisition_depth != 0) {
275
276 /* Just decrement the depth and return */
277
278 return_ACPI_STATUS(AE_OK);
205 } 279 }
206 280
207 /* Have the mutex: update mutex and walk info and save the sync_level */ 281 if (obj_desc->mutex.owner_thread) {
208 282
209 obj_desc->mutex.owner_thread = walk_state->thread; 283 /* Unlink the mutex from the owner's list */
210 obj_desc->mutex.acquisition_depth = 1; 284
211 obj_desc->mutex.original_sync_level = 285 acpi_ex_unlink_mutex(obj_desc);
212 walk_state->thread->current_sync_level; 286 obj_desc->mutex.owner_thread = NULL;
287 }
213 288
214 walk_state->thread->current_sync_level = obj_desc->mutex.sync_level; 289 /* Release the mutex, special case for Global Lock */
215 290
216 /* Link the mutex to the current thread for force-unlock at method exit */ 291 if (obj_desc == acpi_gbl_global_lock_mutex) {
292 status = acpi_ev_release_global_lock();
293 } else {
294 acpi_os_release_mutex(obj_desc->mutex.os_mutex);
295 }
217 296
218 acpi_ex_link_mutex(obj_desc, walk_state->thread); 297 obj_desc->mutex.thread_id = 0;
219 return_ACPI_STATUS(AE_OK); 298 return_ACPI_STATUS(status);
220} 299}
221 300
222/******************************************************************************* 301/*******************************************************************************
@@ -253,22 +332,13 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc,
253 return_ACPI_STATUS(AE_AML_MUTEX_NOT_ACQUIRED); 332 return_ACPI_STATUS(AE_AML_MUTEX_NOT_ACQUIRED);
254 } 333 }
255 334
256 /* Sanity check: we must have a valid thread ID */
257
258 if (!walk_state->thread) {
259 ACPI_ERROR((AE_INFO,
260 "Cannot release Mutex [%4.4s], null thread info",
261 acpi_ut_get_node_name(obj_desc->mutex.node)));
262 return_ACPI_STATUS(AE_AML_INTERNAL);
263 }
264
265 /* 335 /*
266 * The Mutex is owned, but this thread must be the owner. 336 * The Mutex is owned, but this thread must be the owner.
267 * Special case for Global Lock, any thread can release 337 * Special case for Global Lock, any thread can release
268 */ 338 */
269 if ((obj_desc->mutex.owner_thread->thread_id != 339 if ((obj_desc->mutex.owner_thread->thread_id !=
270 walk_state->thread->thread_id) 340 walk_state->thread->thread_id)
271 && (obj_desc->mutex.os_mutex != acpi_gbl_global_lock_mutex)) { 341 && (obj_desc != acpi_gbl_global_lock_mutex)) {
272 ACPI_ERROR((AE_INFO, 342 ACPI_ERROR((AE_INFO,
273 "Thread %lX cannot release Mutex [%4.4s] acquired by thread %lX", 343 "Thread %lX cannot release Mutex [%4.4s] acquired by thread %lX",
274 (unsigned long)walk_state->thread->thread_id, 344 (unsigned long)walk_state->thread->thread_id,
@@ -278,6 +348,15 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc,
278 return_ACPI_STATUS(AE_AML_NOT_OWNER); 348 return_ACPI_STATUS(AE_AML_NOT_OWNER);
279 } 349 }
280 350
351 /* Sanity check: we must have a valid thread ID */
352
353 if (!walk_state->thread) {
354 ACPI_ERROR((AE_INFO,
355 "Cannot release Mutex [%4.4s], null thread info",
356 acpi_ut_get_node_name(obj_desc->mutex.node)));
357 return_ACPI_STATUS(AE_AML_INTERNAL);
358 }
359
281 /* 360 /*
282 * The sync level of the mutex must be less than or equal to the current 361 * The sync level of the mutex must be less than or equal to the current
283 * sync level 362 * sync level
@@ -289,34 +368,12 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc,
289 return_ACPI_STATUS(AE_AML_MUTEX_ORDER); 368 return_ACPI_STATUS(AE_AML_MUTEX_ORDER);
290 } 369 }
291 370
292 /* Match multiple Acquires with multiple Releases */ 371 status = acpi_ex_release_mutex_object(obj_desc);
293
294 obj_desc->mutex.acquisition_depth--;
295 if (obj_desc->mutex.acquisition_depth != 0) {
296
297 /* Just decrement the depth and return */
298
299 return_ACPI_STATUS(AE_OK);
300 }
301
302 /* Unlink the mutex from the owner's list */
303 372
304 acpi_ex_unlink_mutex(obj_desc); 373 /* Restore sync_level */
305
306 /* Release the mutex, special case for Global Lock */
307 374
308 if (obj_desc->mutex.os_mutex == acpi_gbl_global_lock_mutex) {
309 status = acpi_ev_release_global_lock();
310 } else {
311 acpi_os_release_mutex(obj_desc->mutex.os_mutex);
312 }
313
314 /* Update the mutex and restore sync_level */
315
316 obj_desc->mutex.owner_thread = NULL;
317 walk_state->thread->current_sync_level = 375 walk_state->thread->current_sync_level =
318 obj_desc->mutex.original_sync_level; 376 obj_desc->mutex.original_sync_level;
319
320 return_ACPI_STATUS(status); 377 return_ACPI_STATUS(status);
321} 378}
322 379
@@ -357,7 +414,7 @@ void acpi_ex_release_all_mutexes(struct acpi_thread_state *thread)
357 414
358 /* Release the mutex, special case for Global Lock */ 415 /* Release the mutex, special case for Global Lock */
359 416
360 if (obj_desc->mutex.os_mutex == acpi_gbl_global_lock_mutex) { 417 if (obj_desc == acpi_gbl_global_lock_mutex) {
361 418
362 /* Ignore errors */ 419 /* Ignore errors */
363 420
@@ -369,6 +426,7 @@ void acpi_ex_release_all_mutexes(struct acpi_thread_state *thread)
369 /* Mark mutex unowned */ 426 /* Mark mutex unowned */
370 427
371 obj_desc->mutex.owner_thread = NULL; 428 obj_desc->mutex.owner_thread = NULL;
429 obj_desc->mutex.thread_id = 0;
372 430
373 /* Update Thread sync_level (Last mutex is the important one) */ 431 /* Update Thread sync_level (Last mutex is the important one) */
374 432
diff --git a/drivers/acpi/executer/exutils.c b/drivers/acpi/executer/exutils.c
index 6b0aeccbb69b..c0837af0acb1 100644
--- a/drivers/acpi/executer/exutils.c
+++ b/drivers/acpi/executer/exutils.c
@@ -240,72 +240,66 @@ void acpi_ex_truncate_for32bit_table(union acpi_operand_object *obj_desc)
240 * PARAMETERS: field_flags - Flags with Lock rule: 240 * PARAMETERS: field_flags - Flags with Lock rule:
241 * always_lock or never_lock 241 * always_lock or never_lock
242 * 242 *
243 * RETURN: TRUE/FALSE indicating whether the lock was actually acquired 243 * RETURN: None
244 * 244 *
245 * DESCRIPTION: Obtain the global lock and keep track of this fact via two 245 * DESCRIPTION: Obtain the ACPI hardware Global Lock, only if the field
246 * methods. A global variable keeps the state of the lock, and 246 * flags specifiy that it is to be obtained before field access.
247 * the state is returned to the caller.
248 * 247 *
249 ******************************************************************************/ 248 ******************************************************************************/
250 249
251u8 acpi_ex_acquire_global_lock(u32 field_flags) 250void acpi_ex_acquire_global_lock(u32 field_flags)
252{ 251{
253 u8 locked = FALSE;
254 acpi_status status; 252 acpi_status status;
255 253
256 ACPI_FUNCTION_TRACE(ex_acquire_global_lock); 254 ACPI_FUNCTION_TRACE(ex_acquire_global_lock);
257 255
258 /* Only attempt lock if the always_lock bit is set */ 256 /* Only use the lock if the always_lock bit is set */
257
258 if (!(field_flags & AML_FIELD_LOCK_RULE_MASK)) {
259 return_VOID;
260 }
259 261
260 if (field_flags & AML_FIELD_LOCK_RULE_MASK) { 262 /* Attempt to get the global lock, wait forever */
261 263
262 /* We should attempt to get the lock, wait forever */ 264 status = acpi_ex_acquire_mutex_object(ACPI_WAIT_FOREVER,
265 acpi_gbl_global_lock_mutex,
266 acpi_os_get_thread_id());
263 267
264 status = acpi_ev_acquire_global_lock(ACPI_WAIT_FOREVER); 268 if (ACPI_FAILURE(status)) {
265 if (ACPI_SUCCESS(status)) { 269 ACPI_EXCEPTION((AE_INFO, status,
266 locked = TRUE; 270 "Could not acquire Global Lock"));
267 } else {
268 ACPI_EXCEPTION((AE_INFO, status,
269 "Could not acquire Global Lock"));
270 }
271 } 271 }
272 272
273 return_UINT8(locked); 273 return_VOID;
274} 274}
275 275
276/******************************************************************************* 276/*******************************************************************************
277 * 277 *
278 * FUNCTION: acpi_ex_release_global_lock 278 * FUNCTION: acpi_ex_release_global_lock
279 * 279 *
280 * PARAMETERS: locked_by_me - Return value from corresponding call to 280 * PARAMETERS: None
281 * acquire_global_lock.
282 * 281 *
283 * RETURN: None 282 * RETURN: None
284 * 283 *
285 * DESCRIPTION: Release the global lock if it is locked. 284 * DESCRIPTION: Release the ACPI hardware Global Lock
286 * 285 *
287 ******************************************************************************/ 286 ******************************************************************************/
288 287
289void acpi_ex_release_global_lock(u8 locked_by_me) 288void acpi_ex_release_global_lock(void)
290{ 289{
291 acpi_status status; 290 acpi_status status;
292 291
293 ACPI_FUNCTION_TRACE(ex_release_global_lock); 292 ACPI_FUNCTION_TRACE(ex_release_global_lock);
294 293
295 /* Only attempt unlock if the caller locked it */ 294 /* Release the global lock */
296
297 if (locked_by_me) {
298 295
299 /* OK, now release the lock */ 296 status = acpi_ex_release_mutex_object(acpi_gbl_global_lock_mutex);
300 297 if (ACPI_FAILURE(status)) {
301 status = acpi_ev_release_global_lock();
302 if (ACPI_FAILURE(status)) {
303 298
304 /* Report the error, but there isn't much else we can do */ 299 /* Report the error, but there isn't much else we can do */
305 300
306 ACPI_EXCEPTION((AE_INFO, status, 301 ACPI_EXCEPTION((AE_INFO, status,
307 "Could not release ACPI Global Lock")); 302 "Could not release Global Lock"));
308 }
309 } 303 }
310 304
311 return_VOID; 305 return_VOID;
diff --git a/drivers/acpi/namespace/nsaccess.c b/drivers/acpi/namespace/nsaccess.c
index 57faf598bad8..32a01673cae8 100644
--- a/drivers/acpi/namespace/nsaccess.c
+++ b/drivers/acpi/namespace/nsaccess.c
@@ -208,8 +208,7 @@ acpi_status acpi_ns_root_initialize(void)
208 /* Special case for ACPI Global Lock */ 208 /* Special case for ACPI Global Lock */
209 209
210 if (ACPI_STRCMP(init_val->name, "_GL_") == 0) { 210 if (ACPI_STRCMP(init_val->name, "_GL_") == 0) {
211 acpi_gbl_global_lock_mutex = 211 acpi_gbl_global_lock_mutex = obj_desc;
212 obj_desc->mutex.os_mutex;
213 212
214 /* Create additional counting semaphore for global lock */ 213 /* Create additional counting semaphore for global lock */
215 214
diff --git a/drivers/acpi/utilities/utdelete.c b/drivers/acpi/utilities/utdelete.c
index f777cebdc46d..dcb34f805714 100644
--- a/drivers/acpi/utilities/utdelete.c
+++ b/drivers/acpi/utilities/utdelete.c
@@ -158,7 +158,7 @@ static void acpi_ut_delete_internal_obj(union acpi_operand_object *object)
158 "***** Mutex %p, OS Mutex %p\n", 158 "***** Mutex %p, OS Mutex %p\n",
159 object, object->mutex.os_mutex)); 159 object, object->mutex.os_mutex));
160 160
161 if (object->mutex.os_mutex == acpi_gbl_global_lock_mutex) { 161 if (object == acpi_gbl_global_lock_mutex) {
162 162
163 /* Global Lock has extra semaphore */ 163 /* Global Lock has extra semaphore */
164 164
diff --git a/include/acpi/acglobal.h b/include/acpi/acglobal.h
index 47a1fd8f2d8a..e91008eaef2d 100644
--- a/include/acpi/acglobal.h
+++ b/include/acpi/acglobal.h
@@ -170,10 +170,14 @@ ACPI_EXTERN u8 acpi_gbl_integer_nybble_width;
170ACPI_EXTERN struct acpi_mutex_info acpi_gbl_mutex_info[ACPI_NUM_MUTEX]; 170ACPI_EXTERN struct acpi_mutex_info acpi_gbl_mutex_info[ACPI_NUM_MUTEX];
171 171
172/* 172/*
173 * Global lock semaphore works in conjunction with the actual HW global lock 173 * Global lock mutex is an actual AML mutex object
174 * Global lock semaphore works in conjunction with the HW global lock
174 */ 175 */
175ACPI_EXTERN acpi_mutex acpi_gbl_global_lock_mutex; 176ACPI_EXTERN union acpi_operand_object *acpi_gbl_global_lock_mutex;
176ACPI_EXTERN acpi_semaphore acpi_gbl_global_lock_semaphore; 177ACPI_EXTERN acpi_semaphore acpi_gbl_global_lock_semaphore;
178ACPI_EXTERN u16 acpi_gbl_global_lock_handle;
179ACPI_EXTERN u8 acpi_gbl_global_lock_acquired;
180ACPI_EXTERN u8 acpi_gbl_global_lock_present;
177 181
178/* 182/*
179 * Spinlocks are used for interfaces that can be possibly called at 183 * Spinlocks are used for interfaces that can be possibly called at
@@ -215,22 +219,22 @@ ACPI_EXTERN acpi_exception_handler acpi_gbl_exception_handler;
215ACPI_EXTERN acpi_init_handler acpi_gbl_init_handler; 219ACPI_EXTERN acpi_init_handler acpi_gbl_init_handler;
216ACPI_EXTERN struct acpi_walk_state *acpi_gbl_breakpoint_walk; 220ACPI_EXTERN struct acpi_walk_state *acpi_gbl_breakpoint_walk;
217 221
222/* Owner ID support */
223
224ACPI_EXTERN u32 acpi_gbl_owner_id_mask[ACPI_NUM_OWNERID_MASKS];
225ACPI_EXTERN u8 acpi_gbl_last_owner_id_index;
226ACPI_EXTERN u8 acpi_gbl_next_owner_id_offset;
227
218/* Misc */ 228/* Misc */
219 229
220ACPI_EXTERN u32 acpi_gbl_original_mode; 230ACPI_EXTERN u32 acpi_gbl_original_mode;
221ACPI_EXTERN u32 acpi_gbl_rsdp_original_location; 231ACPI_EXTERN u32 acpi_gbl_rsdp_original_location;
222ACPI_EXTERN u32 acpi_gbl_ns_lookup_count; 232ACPI_EXTERN u32 acpi_gbl_ns_lookup_count;
223ACPI_EXTERN u32 acpi_gbl_ps_find_count; 233ACPI_EXTERN u32 acpi_gbl_ps_find_count;
224ACPI_EXTERN u32 acpi_gbl_owner_id_mask[ACPI_NUM_OWNERID_MASKS];
225ACPI_EXTERN u16 acpi_gbl_pm1_enable_register_save; 234ACPI_EXTERN u16 acpi_gbl_pm1_enable_register_save;
226ACPI_EXTERN u16 acpi_gbl_global_lock_handle;
227ACPI_EXTERN u8 acpi_gbl_last_owner_id_index;
228ACPI_EXTERN u8 acpi_gbl_next_owner_id_offset;
229ACPI_EXTERN u8 acpi_gbl_debugger_configuration; 235ACPI_EXTERN u8 acpi_gbl_debugger_configuration;
230ACPI_EXTERN u8 acpi_gbl_global_lock_acquired;
231ACPI_EXTERN u8 acpi_gbl_step_to_next_call; 236ACPI_EXTERN u8 acpi_gbl_step_to_next_call;
232ACPI_EXTERN u8 acpi_gbl_acpi_hardware_present; 237ACPI_EXTERN u8 acpi_gbl_acpi_hardware_present;
233ACPI_EXTERN u8 acpi_gbl_global_lock_present;
234ACPI_EXTERN u8 acpi_gbl_events_initialized; 238ACPI_EXTERN u8 acpi_gbl_events_initialized;
235ACPI_EXTERN u8 acpi_gbl_system_awake_and_running; 239ACPI_EXTERN u8 acpi_gbl_system_awake_and_running;
236 240
diff --git a/include/acpi/acinterp.h b/include/acpi/acinterp.h
index ce7c9d653910..23863886e808 100644
--- a/include/acpi/acinterp.h
+++ b/include/acpi/acinterp.h
@@ -248,9 +248,16 @@ acpi_ex_acquire_mutex(union acpi_operand_object *time_desc,
248 struct acpi_walk_state *walk_state); 248 struct acpi_walk_state *walk_state);
249 249
250acpi_status 250acpi_status
251acpi_ex_acquire_mutex_object(u16 timeout,
252 union acpi_operand_object *obj_desc,
253 acpi_thread_id thread_id);
254
255acpi_status
251acpi_ex_release_mutex(union acpi_operand_object *obj_desc, 256acpi_ex_release_mutex(union acpi_operand_object *obj_desc,
252 struct acpi_walk_state *walk_state); 257 struct acpi_walk_state *walk_state);
253 258
259acpi_status acpi_ex_release_mutex_object(union acpi_operand_object *obj_desc);
260
254void acpi_ex_release_all_mutexes(struct acpi_thread_state *thread); 261void acpi_ex_release_all_mutexes(struct acpi_thread_state *thread);
255 262
256void acpi_ex_unlink_mutex(union acpi_operand_object *obj_desc); 263void acpi_ex_unlink_mutex(union acpi_operand_object *obj_desc);
@@ -455,9 +462,9 @@ void acpi_ex_relinquish_interpreter(void);
455 462
456void acpi_ex_truncate_for32bit_table(union acpi_operand_object *obj_desc); 463void acpi_ex_truncate_for32bit_table(union acpi_operand_object *obj_desc);
457 464
458u8 acpi_ex_acquire_global_lock(u32 rule); 465void acpi_ex_acquire_global_lock(u32 rule);
459 466
460void acpi_ex_release_global_lock(u8 locked); 467void acpi_ex_release_global_lock(void);
461 468
462void acpi_ex_eisa_id_to_string(u32 numeric_id, char *out_string); 469void acpi_ex_eisa_id_to_string(u32 numeric_id, char *out_string);
463 470
diff --git a/include/acpi/acobject.h b/include/acpi/acobject.h
index 7e1211a8b8fa..2461bb9ab3e9 100644
--- a/include/acpi/acobject.h
+++ b/include/acpi/acobject.h
@@ -155,8 +155,9 @@ struct acpi_object_event {
155struct acpi_object_mutex { 155struct acpi_object_mutex {
156 ACPI_OBJECT_COMMON_HEADER u8 sync_level; /* 0-15, specified in Mutex() call */ 156 ACPI_OBJECT_COMMON_HEADER u8 sync_level; /* 0-15, specified in Mutex() call */
157 u16 acquisition_depth; /* Allow multiple Acquires, same thread */ 157 u16 acquisition_depth; /* Allow multiple Acquires, same thread */
158 struct acpi_thread_state *owner_thread; /* Current owner of the mutex */
159 acpi_mutex os_mutex; /* Actual OS synchronization object */ 158 acpi_mutex os_mutex; /* Actual OS synchronization object */
159 acpi_thread_id thread_id; /* Current owner of the mutex */
160 struct acpi_thread_state *owner_thread; /* Current owner of the mutex */
160 union acpi_operand_object *prev; /* Link for list of acquired mutexes */ 161 union acpi_operand_object *prev; /* Link for list of acquired mutexes */
161 union acpi_operand_object *next; /* Link for list of acquired mutexes */ 162 union acpi_operand_object *next; /* Link for list of acquired mutexes */
162 struct acpi_namespace_node *node; /* Containing namespace node */ 163 struct acpi_namespace_node *node; /* Containing namespace node */