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