0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <acpi/acpi.h>
0011 #include "accommon.h"
0012 #include "acevents.h"
0013 #include "acinterp.h"
0014
0015 #define _COMPONENT ACPI_EVENTS
0016 ACPI_MODULE_NAME("evglock")
0017 #if (!ACPI_REDUCED_HARDWARE)
0018
0019 static u32 acpi_ev_global_lock_handler(void *context);
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033 acpi_status acpi_ev_init_global_lock_handler(void)
0034 {
0035 acpi_status status;
0036
0037 ACPI_FUNCTION_TRACE(ev_init_global_lock_handler);
0038
0039
0040
0041 if (acpi_gbl_reduced_hardware) {
0042 return_ACPI_STATUS(AE_OK);
0043 }
0044
0045
0046
0047 status = acpi_install_fixed_event_handler(ACPI_EVENT_GLOBAL,
0048 acpi_ev_global_lock_handler,
0049 NULL);
0050
0051
0052
0053
0054
0055
0056
0057 acpi_gbl_global_lock_present = FALSE;
0058 if (status == AE_NO_HARDWARE_RESPONSE) {
0059 ACPI_ERROR((AE_INFO,
0060 "No response from Global Lock hardware, disabling lock"));
0061
0062 return_ACPI_STATUS(AE_OK);
0063 }
0064
0065 status = acpi_os_create_lock(&acpi_gbl_global_lock_pending_lock);
0066 if (ACPI_FAILURE(status)) {
0067 return_ACPI_STATUS(status);
0068 }
0069
0070 acpi_gbl_global_lock_pending = FALSE;
0071 acpi_gbl_global_lock_present = TRUE;
0072 return_ACPI_STATUS(status);
0073 }
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087 acpi_status acpi_ev_remove_global_lock_handler(void)
0088 {
0089 acpi_status status;
0090
0091 ACPI_FUNCTION_TRACE(ev_remove_global_lock_handler);
0092
0093 acpi_gbl_global_lock_present = FALSE;
0094 status = acpi_remove_fixed_event_handler(ACPI_EVENT_GLOBAL,
0095 acpi_ev_global_lock_handler);
0096
0097 acpi_os_delete_lock(acpi_gbl_global_lock_pending_lock);
0098 return_ACPI_STATUS(status);
0099 }
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115 static u32 acpi_ev_global_lock_handler(void *context)
0116 {
0117 acpi_status status;
0118 acpi_cpu_flags flags;
0119
0120 flags = acpi_os_acquire_lock(acpi_gbl_global_lock_pending_lock);
0121
0122
0123
0124
0125
0126
0127 if (!acpi_gbl_global_lock_pending) {
0128 goto cleanup_and_exit;
0129 }
0130
0131
0132
0133
0134
0135 status = acpi_os_signal_semaphore(acpi_gbl_global_lock_semaphore, 1);
0136 if (ACPI_FAILURE(status)) {
0137 ACPI_ERROR((AE_INFO, "Could not signal Global Lock semaphore"));
0138 }
0139
0140 acpi_gbl_global_lock_pending = FALSE;
0141
0142 cleanup_and_exit:
0143
0144 acpi_os_release_lock(acpi_gbl_global_lock_pending_lock, flags);
0145 return (ACPI_INTERRUPT_HANDLED);
0146 }
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170 acpi_status acpi_ev_acquire_global_lock(u16 timeout)
0171 {
0172 acpi_cpu_flags flags;
0173 acpi_status status;
0174 u8 acquired = FALSE;
0175
0176 ACPI_FUNCTION_TRACE(ev_acquire_global_lock);
0177
0178
0179
0180
0181
0182 status =
0183 acpi_ex_system_wait_mutex(acpi_gbl_global_lock_mutex->mutex.
0184 os_mutex, timeout);
0185 if (ACPI_FAILURE(status)) {
0186 return_ACPI_STATUS(status);
0187 }
0188
0189
0190
0191
0192
0193
0194
0195
0196
0197 acpi_gbl_global_lock_handle++;
0198 if (acpi_gbl_global_lock_handle == 0) {
0199 acpi_gbl_global_lock_handle = 1;
0200 }
0201
0202
0203
0204
0205
0206 if (!acpi_gbl_global_lock_present) {
0207 acpi_gbl_global_lock_acquired = TRUE;
0208 return_ACPI_STATUS(AE_OK);
0209 }
0210
0211 flags = acpi_os_acquire_lock(acpi_gbl_global_lock_pending_lock);
0212
0213 do {
0214
0215
0216
0217 ACPI_ACQUIRE_GLOBAL_LOCK(acpi_gbl_FACS, acquired);
0218 if (acquired) {
0219 acpi_gbl_global_lock_acquired = TRUE;
0220 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
0221 "Acquired hardware Global Lock\n"));
0222 break;
0223 }
0224
0225
0226
0227
0228
0229
0230 acpi_gbl_global_lock_pending = TRUE;
0231 acpi_os_release_lock(acpi_gbl_global_lock_pending_lock, flags);
0232
0233 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
0234 "Waiting for hardware Global Lock\n"));
0235
0236
0237
0238
0239
0240 status =
0241 acpi_ex_system_wait_semaphore
0242 (acpi_gbl_global_lock_semaphore, ACPI_WAIT_FOREVER);
0243
0244 flags = acpi_os_acquire_lock(acpi_gbl_global_lock_pending_lock);
0245
0246 } while (ACPI_SUCCESS(status));
0247
0248 acpi_gbl_global_lock_pending = FALSE;
0249 acpi_os_release_lock(acpi_gbl_global_lock_pending_lock, flags);
0250
0251 return_ACPI_STATUS(status);
0252 }
0253
0254
0255
0256
0257
0258
0259
0260
0261
0262
0263
0264
0265
0266 acpi_status acpi_ev_release_global_lock(void)
0267 {
0268 u8 pending = FALSE;
0269 acpi_status status = AE_OK;
0270
0271 ACPI_FUNCTION_TRACE(ev_release_global_lock);
0272
0273
0274
0275 if (!acpi_gbl_global_lock_acquired) {
0276 ACPI_WARNING((AE_INFO,
0277 "Cannot release the ACPI Global Lock, it has not been acquired"));
0278 return_ACPI_STATUS(AE_NOT_ACQUIRED);
0279 }
0280
0281 if (acpi_gbl_global_lock_present) {
0282
0283
0284
0285 ACPI_RELEASE_GLOBAL_LOCK(acpi_gbl_FACS, pending);
0286
0287
0288
0289
0290
0291 if (pending) {
0292 status =
0293 acpi_write_bit_register
0294 (ACPI_BITREG_GLOBAL_LOCK_RELEASE,
0295 ACPI_ENABLE_EVENT);
0296 }
0297
0298 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
0299 "Released hardware Global Lock\n"));
0300 }
0301
0302 acpi_gbl_global_lock_acquired = FALSE;
0303
0304
0305
0306 acpi_os_release_mutex(acpi_gbl_global_lock_mutex->mutex.os_mutex);
0307 return_ACPI_STATUS(status);
0308 }
0309
0310 #endif