GNU Linux-libre 4.19.286-gnu1
[releases.git] / drivers / acpi / acpica / utmutex.c
1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2 /*******************************************************************************
3  *
4  * Module Name: utmutex - local mutex support
5  *
6  ******************************************************************************/
7
8 #include <acpi/acpi.h>
9 #include "accommon.h"
10
11 #define _COMPONENT          ACPI_UTILITIES
12 ACPI_MODULE_NAME("utmutex")
13
14 /* Local prototypes */
15 static acpi_status acpi_ut_create_mutex(acpi_mutex_handle mutex_id);
16
17 static void acpi_ut_delete_mutex(acpi_mutex_handle mutex_id);
18
19 /*******************************************************************************
20  *
21  * FUNCTION:    acpi_ut_mutex_initialize
22  *
23  * PARAMETERS:  None.
24  *
25  * RETURN:      Status
26  *
27  * DESCRIPTION: Create the system mutex objects. This includes mutexes,
28  *              spin locks, and reader/writer locks.
29  *
30  ******************************************************************************/
31
32 acpi_status acpi_ut_mutex_initialize(void)
33 {
34         u32 i;
35         acpi_status status;
36
37         ACPI_FUNCTION_TRACE(ut_mutex_initialize);
38
39         /* Create each of the predefined mutex objects */
40
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);
45                 }
46         }
47
48         /* Create the spinlocks for use at interrupt level or for speed */
49
50         status = acpi_os_create_lock (&acpi_gbl_gpe_lock);
51         if (ACPI_FAILURE (status)) {
52                 return_ACPI_STATUS (status);
53         }
54
55         status = acpi_os_create_raw_lock(&acpi_gbl_hardware_lock);
56         if (ACPI_FAILURE (status)) {
57                 return_ACPI_STATUS (status);
58         }
59
60         status = acpi_os_create_lock(&acpi_gbl_reference_count_lock);
61         if (ACPI_FAILURE(status)) {
62                 return_ACPI_STATUS(status);
63         }
64
65         /* Mutex for _OSI support */
66
67         status = acpi_os_create_mutex(&acpi_gbl_osi_mutex);
68         if (ACPI_FAILURE(status)) {
69                 return_ACPI_STATUS(status);
70         }
71
72         /* Create the reader/writer lock for namespace access */
73
74         status = acpi_ut_create_rw_lock(&acpi_gbl_namespace_rw_lock);
75         if (ACPI_FAILURE(status)) {
76                 return_ACPI_STATUS(status);
77         }
78
79         return_ACPI_STATUS(status);
80 }
81
82 /*******************************************************************************
83  *
84  * FUNCTION:    acpi_ut_mutex_terminate
85  *
86  * PARAMETERS:  None.
87  *
88  * RETURN:      None.
89  *
90  * DESCRIPTION: Delete all of the system mutex objects. This includes mutexes,
91  *              spin locks, and reader/writer locks.
92  *
93  ******************************************************************************/
94
95 void acpi_ut_mutex_terminate(void)
96 {
97         u32 i;
98
99         ACPI_FUNCTION_TRACE(ut_mutex_terminate);
100
101         /* Delete each predefined mutex object */
102
103         for (i = 0; i < ACPI_NUM_MUTEX; i++) {
104                 acpi_ut_delete_mutex(i);
105         }
106
107         acpi_os_delete_mutex(acpi_gbl_osi_mutex);
108
109         /* Delete the spinlocks */
110
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);
114
115         /* Delete the reader/writer lock */
116
117         acpi_ut_delete_rw_lock(&acpi_gbl_namespace_rw_lock);
118         return_VOID;
119 }
120
121 /*******************************************************************************
122  *
123  * FUNCTION:    acpi_ut_create_mutex
124  *
125  * PARAMETERS:  mutex_ID        - ID of the mutex to be created
126  *
127  * RETURN:      Status
128  *
129  * DESCRIPTION: Create a mutex object.
130  *
131  ******************************************************************************/
132
133 static acpi_status acpi_ut_create_mutex(acpi_mutex_handle mutex_id)
134 {
135         acpi_status status = AE_OK;
136
137         ACPI_FUNCTION_TRACE_U32(ut_create_mutex, mutex_id);
138
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;
145         }
146
147         return_ACPI_STATUS(status);
148 }
149
150 /*******************************************************************************
151  *
152  * FUNCTION:    acpi_ut_delete_mutex
153  *
154  * PARAMETERS:  mutex_ID        - ID of the mutex to be deleted
155  *
156  * RETURN:      Status
157  *
158  * DESCRIPTION: Delete a mutex object.
159  *
160  ******************************************************************************/
161
162 static void acpi_ut_delete_mutex(acpi_mutex_handle mutex_id)
163 {
164
165         ACPI_FUNCTION_TRACE_U32(ut_delete_mutex, mutex_id);
166
167         acpi_os_delete_mutex(acpi_gbl_mutex_info[mutex_id].mutex);
168
169         acpi_gbl_mutex_info[mutex_id].mutex = NULL;
170         acpi_gbl_mutex_info[mutex_id].thread_id = ACPI_MUTEX_NOT_ACQUIRED;
171
172         return_VOID;
173 }
174
175 /*******************************************************************************
176  *
177  * FUNCTION:    acpi_ut_acquire_mutex
178  *
179  * PARAMETERS:  mutex_ID        - ID of the mutex to be acquired
180  *
181  * RETURN:      Status
182  *
183  * DESCRIPTION: Acquire a mutex object.
184  *
185  ******************************************************************************/
186
187 acpi_status acpi_ut_acquire_mutex(acpi_mutex_handle mutex_id)
188 {
189         acpi_status status;
190         acpi_thread_id this_thread_id;
191
192         ACPI_FUNCTION_NAME(ut_acquire_mutex);
193
194         if (mutex_id > ACPI_MAX_MUTEX) {
195                 return (AE_BAD_PARAMETER);
196         }
197
198         this_thread_id = acpi_os_get_thread_id();
199
200 #ifdef ACPI_MUTEX_DEBUG
201         {
202                 u32 i;
203                 /*
204                  * Mutex debug code, for internal debugging only.
205                  *
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.
210                  */
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));
219
220                                         return (AE_ALREADY_ACQUIRED);
221                                 }
222
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)));
228
229                                 return (AE_ACQUIRE_DEADLOCK);
230                         }
231                 }
232         }
233 #endif
234
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)));
239
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)));
248
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));
256         }
257
258         return (status);
259 }
260
261 /*******************************************************************************
262  *
263  * FUNCTION:    acpi_ut_release_mutex
264  *
265  * PARAMETERS:  mutex_ID        - ID of the mutex to be released
266  *
267  * RETURN:      Status
268  *
269  * DESCRIPTION: Release a mutex object.
270  *
271  ******************************************************************************/
272
273 acpi_status acpi_ut_release_mutex(acpi_mutex_handle mutex_id)
274 {
275         ACPI_FUNCTION_NAME(ut_release_mutex);
276
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)));
280
281         if (mutex_id > ACPI_MAX_MUTEX) {
282                 return (AE_BAD_PARAMETER);
283         }
284
285         /*
286          * Mutex must be acquired in order to release it!
287          */
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));
292
293                 return (AE_NOT_ACQUIRED);
294         }
295 #ifdef ACPI_MUTEX_DEBUG
296         {
297                 u32 i;
298                 /*
299                  * Mutex debug code, for internal debugging only.
300                  *
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.
305                  */
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;
311                                 }
312
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)));
317
318                                 return (AE_RELEASE_DEADLOCK);
319                         }
320                 }
321         }
322 #endif
323
324         /* Mark unlocked FIRST */
325
326         acpi_gbl_mutex_info[mutex_id].thread_id = ACPI_MUTEX_NOT_ACQUIRED;
327
328         acpi_os_release_mutex(acpi_gbl_mutex_info[mutex_id].mutex);
329         return (AE_OK);
330 }