1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2 /*******************************************************************************
3  *
4  * Module Name: utxfmutex - external AML mutex access functions
5  *
6  ******************************************************************************/
7 
8 #include <acpi/acpi.h>
9 #include "accommon.h"
10 #include "acnamesp.h"
11 
12 #define _COMPONENT          ACPI_UTILITIES
13 ACPI_MODULE_NAME("utxfmutex")
14 
15 /* Local prototypes */
16 static acpi_status
17 acpi_ut_get_mutex_object(acpi_handle handle,
18 			 acpi_string pathname,
19 			 union acpi_operand_object **ret_obj);
20 
21 /*******************************************************************************
22  *
23  * FUNCTION:    acpi_ut_get_mutex_object
24  *
25  * PARAMETERS:  handle              - Mutex or prefix handle (optional)
26  *              pathname            - Mutex pathname (optional)
27  *              ret_obj             - Where the mutex object is returned
28  *
29  * RETURN:      Status
30  *
31  * DESCRIPTION: Get an AML mutex object. The mutex node is pointed to by
32  *              Handle:Pathname. Either Handle or Pathname can be NULL, but
33  *              not both.
34  *
35  ******************************************************************************/
36 
37 static acpi_status
acpi_ut_get_mutex_object(acpi_handle handle,acpi_string pathname,union acpi_operand_object ** ret_obj)38 acpi_ut_get_mutex_object(acpi_handle handle,
39 			 acpi_string pathname,
40 			 union acpi_operand_object **ret_obj)
41 {
42 	struct acpi_namespace_node *mutex_node;
43 	union acpi_operand_object *mutex_obj;
44 	acpi_status status;
45 
46 	/* Parameter validation */
47 
48 	if (!ret_obj || (!handle && !pathname)) {
49 		return (AE_BAD_PARAMETER);
50 	}
51 
52 	/* Get a the namespace node for the mutex */
53 
54 	mutex_node = handle;
55 	if (pathname != NULL) {
56 		status =
57 		    acpi_get_handle(handle, pathname,
58 				    ACPI_CAST_PTR(acpi_handle, &mutex_node));
59 		if (ACPI_FAILURE(status)) {
60 			return (status);
61 		}
62 	}
63 
64 	/* Ensure that we actually have a Mutex object */
65 
66 	if (!mutex_node || (mutex_node->type != ACPI_TYPE_MUTEX)) {
67 		return (AE_TYPE);
68 	}
69 
70 	/* Get the low-level mutex object */
71 
72 	mutex_obj = acpi_ns_get_attached_object(mutex_node);
73 	if (!mutex_obj) {
74 		return (AE_NULL_OBJECT);
75 	}
76 
77 	*ret_obj = mutex_obj;
78 	return (AE_OK);
79 }
80 
81 /*******************************************************************************
82  *
83  * FUNCTION:    acpi_acquire_mutex
84  *
85  * PARAMETERS:  handle              - Mutex or prefix handle (optional)
86  *              pathname            - Mutex pathname (optional)
87  *              timeout             - Max time to wait for the lock (millisec)
88  *
89  * RETURN:      Status
90  *
91  * DESCRIPTION: Acquire an AML mutex. This is a device driver interface to
92  *              AML mutex objects, and allows for transaction locking between
93  *              drivers and AML code. The mutex node is pointed to by
94  *              Handle:Pathname. Either Handle or Pathname can be NULL, but
95  *              not both.
96  *
97  ******************************************************************************/
98 
99 acpi_status
acpi_acquire_mutex(acpi_handle handle,acpi_string pathname,u16 timeout)100 acpi_acquire_mutex(acpi_handle handle, acpi_string pathname, u16 timeout)
101 {
102 	acpi_status status;
103 	union acpi_operand_object *mutex_obj;
104 
105 	/* Get the low-level mutex associated with Handle:Pathname */
106 
107 	status = acpi_ut_get_mutex_object(handle, pathname, &mutex_obj);
108 	if (ACPI_FAILURE(status)) {
109 		return (status);
110 	}
111 
112 	/* Acquire the OS mutex */
113 
114 	status = acpi_os_acquire_mutex(mutex_obj->mutex.os_mutex, timeout);
115 	return (status);
116 }
117 
ACPI_EXPORT_SYMBOL(acpi_acquire_mutex)118 ACPI_EXPORT_SYMBOL(acpi_acquire_mutex)
119 
120 /*******************************************************************************
121  *
122  * FUNCTION:    acpi_release_mutex
123  *
124  * PARAMETERS:  handle              - Mutex or prefix handle (optional)
125  *              pathname            - Mutex pathname (optional)
126  *
127  * RETURN:      Status
128  *
129  * DESCRIPTION: Release an AML mutex. This is a device driver interface to
130  *              AML mutex objects, and allows for transaction locking between
131  *              drivers and AML code. The mutex node is pointed to by
132  *              Handle:Pathname. Either Handle or Pathname can be NULL, but
133  *              not both.
134  *
135  ******************************************************************************/
136 acpi_status acpi_release_mutex(acpi_handle handle, acpi_string pathname)
137 {
138 	acpi_status status;
139 	union acpi_operand_object *mutex_obj;
140 
141 	/* Get the low-level mutex associated with Handle:Pathname */
142 
143 	status = acpi_ut_get_mutex_object(handle, pathname, &mutex_obj);
144 	if (ACPI_FAILURE(status)) {
145 		return (status);
146 	}
147 
148 	/* Release the OS mutex */
149 
150 	acpi_os_release_mutex(mutex_obj->mutex.os_mutex);
151 	return (AE_OK);
152 }
153 
154 ACPI_EXPORT_SYMBOL(acpi_release_mutex)
155