Linux 4.19.133
[linux/fpc-iii.git] / drivers / acpi / acpica / utmutex.c
blob2e465e6a0ab65a30f462a8aedff78a54d9e6df99
1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2 /*******************************************************************************
4 * Module Name: utmutex - local mutex support
6 ******************************************************************************/
8 #include <acpi/acpi.h>
9 #include "accommon.h"
11 #define _COMPONENT ACPI_UTILITIES
12 ACPI_MODULE_NAME("utmutex")
14 /* Local prototypes */
15 static acpi_status acpi_ut_create_mutex(acpi_mutex_handle mutex_id);
17 static void acpi_ut_delete_mutex(acpi_mutex_handle mutex_id);
19 /*******************************************************************************
21 * FUNCTION: acpi_ut_mutex_initialize
23 * PARAMETERS: None.
25 * RETURN: Status
27 * DESCRIPTION: Create the system mutex objects. This includes mutexes,
28 * spin locks, and reader/writer locks.
30 ******************************************************************************/
32 acpi_status acpi_ut_mutex_initialize(void)
34 u32 i;
35 acpi_status status;
37 ACPI_FUNCTION_TRACE(ut_mutex_initialize);
39 /* Create each of the predefined mutex objects */
41 for (i = 0; i < ACPI_NUM_MUTEX; i++) {
42 status = acpi_ut_create_mutex(i);
43 if (ACPI_FAILURE(status)) {
44 return_ACPI_STATUS(status);
48 /* Create the spinlocks for use at interrupt level or for speed */
50 status = acpi_os_create_lock (&acpi_gbl_gpe_lock);
51 if (ACPI_FAILURE (status)) {
52 return_ACPI_STATUS (status);
55 status = acpi_os_create_raw_lock(&acpi_gbl_hardware_lock);
56 if (ACPI_FAILURE (status)) {
57 return_ACPI_STATUS (status);
60 status = acpi_os_create_lock(&acpi_gbl_reference_count_lock);
61 if (ACPI_FAILURE(status)) {
62 return_ACPI_STATUS(status);
65 /* Mutex for _OSI support */
67 status = acpi_os_create_mutex(&acpi_gbl_osi_mutex);
68 if (ACPI_FAILURE(status)) {
69 return_ACPI_STATUS(status);
72 /* Create the reader/writer lock for namespace access */
74 status = acpi_ut_create_rw_lock(&acpi_gbl_namespace_rw_lock);
75 if (ACPI_FAILURE(status)) {
76 return_ACPI_STATUS(status);
79 return_ACPI_STATUS(status);
82 /*******************************************************************************
84 * FUNCTION: acpi_ut_mutex_terminate
86 * PARAMETERS: None.
88 * RETURN: None.
90 * DESCRIPTION: Delete all of the system mutex objects. This includes mutexes,
91 * spin locks, and reader/writer locks.
93 ******************************************************************************/
95 void acpi_ut_mutex_terminate(void)
97 u32 i;
99 ACPI_FUNCTION_TRACE(ut_mutex_terminate);
101 /* Delete each predefined mutex object */
103 for (i = 0; i < ACPI_NUM_MUTEX; i++) {
104 acpi_ut_delete_mutex(i);
107 acpi_os_delete_mutex(acpi_gbl_osi_mutex);
109 /* Delete the spinlocks */
111 acpi_os_delete_lock(acpi_gbl_gpe_lock);
112 acpi_os_delete_raw_lock(acpi_gbl_hardware_lock);
113 acpi_os_delete_lock(acpi_gbl_reference_count_lock);
115 /* Delete the reader/writer lock */
117 acpi_ut_delete_rw_lock(&acpi_gbl_namespace_rw_lock);
118 return_VOID;
121 /*******************************************************************************
123 * FUNCTION: acpi_ut_create_mutex
125 * PARAMETERS: mutex_ID - ID of the mutex to be created
127 * RETURN: Status
129 * DESCRIPTION: Create a mutex object.
131 ******************************************************************************/
133 static acpi_status acpi_ut_create_mutex(acpi_mutex_handle mutex_id)
135 acpi_status status = AE_OK;
137 ACPI_FUNCTION_TRACE_U32(ut_create_mutex, mutex_id);
139 if (!acpi_gbl_mutex_info[mutex_id].mutex) {
140 status =
141 acpi_os_create_mutex(&acpi_gbl_mutex_info[mutex_id].mutex);
142 acpi_gbl_mutex_info[mutex_id].thread_id =
143 ACPI_MUTEX_NOT_ACQUIRED;
144 acpi_gbl_mutex_info[mutex_id].use_count = 0;
147 return_ACPI_STATUS(status);
150 /*******************************************************************************
152 * FUNCTION: acpi_ut_delete_mutex
154 * PARAMETERS: mutex_ID - ID of the mutex to be deleted
156 * RETURN: Status
158 * DESCRIPTION: Delete a mutex object.
160 ******************************************************************************/
162 static void acpi_ut_delete_mutex(acpi_mutex_handle mutex_id)
165 ACPI_FUNCTION_TRACE_U32(ut_delete_mutex, mutex_id);
167 acpi_os_delete_mutex(acpi_gbl_mutex_info[mutex_id].mutex);
169 acpi_gbl_mutex_info[mutex_id].mutex = NULL;
170 acpi_gbl_mutex_info[mutex_id].thread_id = ACPI_MUTEX_NOT_ACQUIRED;
172 return_VOID;
175 /*******************************************************************************
177 * FUNCTION: acpi_ut_acquire_mutex
179 * PARAMETERS: mutex_ID - ID of the mutex to be acquired
181 * RETURN: Status
183 * DESCRIPTION: Acquire a mutex object.
185 ******************************************************************************/
187 acpi_status acpi_ut_acquire_mutex(acpi_mutex_handle mutex_id)
189 acpi_status status;
190 acpi_thread_id this_thread_id;
192 ACPI_FUNCTION_NAME(ut_acquire_mutex);
194 if (mutex_id > ACPI_MAX_MUTEX) {
195 return (AE_BAD_PARAMETER);
198 this_thread_id = acpi_os_get_thread_id();
200 #ifdef ACPI_MUTEX_DEBUG
202 u32 i;
204 * Mutex debug code, for internal debugging only.
206 * Deadlock prevention. Check if this thread owns any mutexes of value
207 * greater than or equal to this one. If so, the thread has violated
208 * the mutex ordering rule. This indicates a coding error somewhere in
209 * the ACPI subsystem code.
211 for (i = mutex_id; i < ACPI_NUM_MUTEX; i++) {
212 if (acpi_gbl_mutex_info[i].thread_id == this_thread_id) {
213 if (i == mutex_id) {
214 ACPI_ERROR((AE_INFO,
215 "Mutex [%s] already acquired by this thread [%u]",
216 acpi_ut_get_mutex_name
217 (mutex_id),
218 (u32)this_thread_id));
220 return (AE_ALREADY_ACQUIRED);
223 ACPI_ERROR((AE_INFO,
224 "Invalid acquire order: Thread %u owns [%s], wants [%s]",
225 (u32)this_thread_id,
226 acpi_ut_get_mutex_name(i),
227 acpi_ut_get_mutex_name(mutex_id)));
229 return (AE_ACQUIRE_DEADLOCK);
233 #endif
235 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
236 "Thread %u attempting to acquire Mutex [%s]\n",
237 (u32)this_thread_id,
238 acpi_ut_get_mutex_name(mutex_id)));
240 status =
241 acpi_os_acquire_mutex(acpi_gbl_mutex_info[mutex_id].mutex,
242 ACPI_WAIT_FOREVER);
243 if (ACPI_SUCCESS(status)) {
244 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
245 "Thread %u acquired Mutex [%s]\n",
246 (u32)this_thread_id,
247 acpi_ut_get_mutex_name(mutex_id)));
249 acpi_gbl_mutex_info[mutex_id].use_count++;
250 acpi_gbl_mutex_info[mutex_id].thread_id = this_thread_id;
251 } else {
252 ACPI_EXCEPTION((AE_INFO, status,
253 "Thread %u could not acquire Mutex [%s] (0x%X)",
254 (u32)this_thread_id,
255 acpi_ut_get_mutex_name(mutex_id), mutex_id));
258 return (status);
261 /*******************************************************************************
263 * FUNCTION: acpi_ut_release_mutex
265 * PARAMETERS: mutex_ID - ID of the mutex to be released
267 * RETURN: Status
269 * DESCRIPTION: Release a mutex object.
271 ******************************************************************************/
273 acpi_status acpi_ut_release_mutex(acpi_mutex_handle mutex_id)
275 ACPI_FUNCTION_NAME(ut_release_mutex);
277 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Thread %u releasing Mutex [%s]\n",
278 (u32)acpi_os_get_thread_id(),
279 acpi_ut_get_mutex_name(mutex_id)));
281 if (mutex_id > ACPI_MAX_MUTEX) {
282 return (AE_BAD_PARAMETER);
286 * Mutex must be acquired in order to release it!
288 if (acpi_gbl_mutex_info[mutex_id].thread_id == ACPI_MUTEX_NOT_ACQUIRED) {
289 ACPI_ERROR((AE_INFO,
290 "Mutex [%s] (0x%X) is not acquired, cannot release",
291 acpi_ut_get_mutex_name(mutex_id), mutex_id));
293 return (AE_NOT_ACQUIRED);
295 #ifdef ACPI_MUTEX_DEBUG
297 u32 i;
299 * Mutex debug code, for internal debugging only.
301 * Deadlock prevention. Check if this thread owns any mutexes of value
302 * greater than this one. If so, the thread has violated the mutex
303 * ordering rule. This indicates a coding error somewhere in
304 * the ACPI subsystem code.
306 for (i = mutex_id; i < ACPI_NUM_MUTEX; i++) {
307 if (acpi_gbl_mutex_info[i].thread_id ==
308 acpi_os_get_thread_id()) {
309 if (i == mutex_id) {
310 continue;
313 ACPI_ERROR((AE_INFO,
314 "Invalid release order: owns [%s], releasing [%s]",
315 acpi_ut_get_mutex_name(i),
316 acpi_ut_get_mutex_name(mutex_id)));
318 return (AE_RELEASE_DEADLOCK);
322 #endif
324 /* Mark unlocked FIRST */
326 acpi_gbl_mutex_info[mutex_id].thread_id = ACPI_MUTEX_NOT_ACQUIRED;
328 acpi_os_release_mutex(acpi_gbl_mutex_info[mutex_id].mutex);
329 return (AE_OK);