Linux-libre 5.4.48-gnu
[librecmc/linux-libre.git] / drivers / acpi / acpica / utlock.c
1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2 /******************************************************************************
3  *
4  * Module Name: utlock - Reader/Writer lock interfaces
5  *
6  * Copyright (C) 2000 - 2019, Intel Corp.
7  *
8  *****************************************************************************/
9
10 #include <acpi/acpi.h>
11 #include "accommon.h"
12
13 #define _COMPONENT          ACPI_UTILITIES
14 ACPI_MODULE_NAME("utlock")
15
16 /*******************************************************************************
17  *
18  * FUNCTION:    acpi_ut_create_rw_lock
19  *              acpi_ut_delete_rw_lock
20  *
21  * PARAMETERS:  lock                - Pointer to a valid RW lock
22  *
23  * RETURN:      Status
24  *
25  * DESCRIPTION: Reader/writer lock creation and deletion interfaces.
26  *
27  ******************************************************************************/
28 acpi_status acpi_ut_create_rw_lock(struct acpi_rw_lock *lock)
29 {
30         acpi_status status;
31
32         lock->num_readers = 0;
33         status = acpi_os_create_mutex(&lock->reader_mutex);
34         if (ACPI_FAILURE(status)) {
35                 return (status);
36         }
37
38         status = acpi_os_create_mutex(&lock->writer_mutex);
39         return (status);
40 }
41
42 void acpi_ut_delete_rw_lock(struct acpi_rw_lock *lock)
43 {
44
45         acpi_os_delete_mutex(lock->reader_mutex);
46         acpi_os_delete_mutex(lock->writer_mutex);
47
48         lock->num_readers = 0;
49         lock->reader_mutex = NULL;
50         lock->writer_mutex = NULL;
51 }
52
53 /*******************************************************************************
54  *
55  * FUNCTION:    acpi_ut_acquire_read_lock
56  *              acpi_ut_release_read_lock
57  *
58  * PARAMETERS:  lock                - Pointer to a valid RW lock
59  *
60  * RETURN:      Status
61  *
62  * DESCRIPTION: Reader interfaces for reader/writer locks. On acquisition,
63  *              only the first reader acquires the write mutex. On release,
64  *              only the last reader releases the write mutex. Although this
65  *              algorithm can in theory starve writers, this should not be a
66  *              problem with ACPICA since the subsystem is infrequently used
67  *              in comparison to (for example) an I/O system.
68  *
69  ******************************************************************************/
70
71 acpi_status acpi_ut_acquire_read_lock(struct acpi_rw_lock *lock)
72 {
73         acpi_status status;
74
75         status = acpi_os_acquire_mutex(lock->reader_mutex, ACPI_WAIT_FOREVER);
76         if (ACPI_FAILURE(status)) {
77                 return (status);
78         }
79
80         /* Acquire the write lock only for the first reader */
81
82         lock->num_readers++;
83         if (lock->num_readers == 1) {
84                 status =
85                     acpi_os_acquire_mutex(lock->writer_mutex,
86                                           ACPI_WAIT_FOREVER);
87         }
88
89         acpi_os_release_mutex(lock->reader_mutex);
90         return (status);
91 }
92
93 acpi_status acpi_ut_release_read_lock(struct acpi_rw_lock *lock)
94 {
95         acpi_status status;
96
97         status = acpi_os_acquire_mutex(lock->reader_mutex, ACPI_WAIT_FOREVER);
98         if (ACPI_FAILURE(status)) {
99                 return (status);
100         }
101
102         /* Release the write lock only for the very last reader */
103
104         lock->num_readers--;
105         if (lock->num_readers == 0) {
106                 acpi_os_release_mutex(lock->writer_mutex);
107         }
108
109         acpi_os_release_mutex(lock->reader_mutex);
110         return (status);
111 }
112
113 /*******************************************************************************
114  *
115  * FUNCTION:    acpi_ut_acquire_write_lock
116  *              acpi_ut_release_write_lock
117  *
118  * PARAMETERS:  lock                - Pointer to a valid RW lock
119  *
120  * RETURN:      Status
121  *
122  * DESCRIPTION: Writer interfaces for reader/writer locks. Simply acquire or
123  *              release the writer mutex associated with the lock. Acquisition
124  *              of the lock is fully exclusive and will block all readers and
125  *              writers until it is released.
126  *
127  ******************************************************************************/
128
129 acpi_status acpi_ut_acquire_write_lock(struct acpi_rw_lock *lock)
130 {
131         acpi_status status;
132
133         status = acpi_os_acquire_mutex(lock->writer_mutex, ACPI_WAIT_FOREVER);
134         return (status);
135 }
136
137 void acpi_ut_release_write_lock(struct acpi_rw_lock *lock)
138 {
139
140         acpi_os_release_mutex(lock->writer_mutex);
141 }