forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-11 072de836f53be56a70cecf70b43ae43b7ce17376
kernel/drivers/acpi/acpica/evregion.c
....@@ -3,7 +3,7 @@
33 *
44 * Module Name: evregion - Operation Region support
55 *
6
- * Copyright (C) 2000 - 2018, Intel Corp.
6
+ * Copyright (C) 2000 - 2020, Intel Corp.
77 *
88 *****************************************************************************/
99
....@@ -111,6 +111,8 @@
111111 union acpi_operand_object *region_obj2;
112112 void *region_context = NULL;
113113 struct acpi_connection_info *context;
114
+ acpi_mutex context_mutex;
115
+ u8 context_locked;
114116 acpi_physical_address address;
115117
116118 ACPI_FUNCTION_TRACE(ev_address_space_dispatch);
....@@ -135,6 +137,8 @@
135137 }
136138
137139 context = handler_desc->address_space.context;
140
+ context_mutex = handler_desc->address_space.context_mutex;
141
+ context_locked = FALSE;
138142
139143 /*
140144 * It may be the case that the region has never been initialized.
....@@ -203,41 +207,6 @@
203207 handler = handler_desc->address_space.handler;
204208 address = (region_obj->region.address + region_offset);
205209
206
- /*
207
- * Special handling for generic_serial_bus and general_purpose_io:
208
- * There are three extra parameters that must be passed to the
209
- * handler via the context:
210
- * 1) Connection buffer, a resource template from Connection() op
211
- * 2) Length of the above buffer
212
- * 3) Actual access length from the access_as() op
213
- *
214
- * In addition, for general_purpose_io, the Address and bit_width fields
215
- * are defined as follows:
216
- * 1) Address is the pin number index of the field (bit offset from
217
- * the previous Connection)
218
- * 2) bit_width is the actual bit length of the field (number of pins)
219
- */
220
- if ((region_obj->region.space_id == ACPI_ADR_SPACE_GSBUS) &&
221
- context && field_obj) {
222
-
223
- /* Get the Connection (resource_template) buffer */
224
-
225
- context->connection = field_obj->field.resource_buffer;
226
- context->length = field_obj->field.resource_length;
227
- context->access_length = field_obj->field.access_length;
228
- }
229
- if ((region_obj->region.space_id == ACPI_ADR_SPACE_GPIO) &&
230
- context && field_obj) {
231
-
232
- /* Get the Connection (resource_template) buffer */
233
-
234
- context->connection = field_obj->field.resource_buffer;
235
- context->length = field_obj->field.resource_length;
236
- context->access_length = field_obj->field.access_length;
237
- address = field_obj->field.pin_number_index;
238
- bit_width = field_obj->field.bit_length;
239
- }
240
-
241210 ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
242211 "Handler %p (@%p) Address %8.8X%8.8X [%s]\n",
243212 &region_obj->region.handler->address_space, handler,
....@@ -250,15 +219,75 @@
250219 /*
251220 * For handlers other than the default (supplied) handlers, we must
252221 * exit the interpreter because the handler *might* block -- we don't
253
- * know what it will do, so we can't hold the lock on the intepreter.
222
+ * know what it will do, so we can't hold the lock on the interpreter.
254223 */
255224 acpi_ex_exit_interpreter();
225
+ }
226
+
227
+ /*
228
+ * Special handling for generic_serial_bus and general_purpose_io:
229
+ * There are three extra parameters that must be passed to the
230
+ * handler via the context:
231
+ * 1) Connection buffer, a resource template from Connection() op
232
+ * 2) Length of the above buffer
233
+ * 3) Actual access length from the access_as() op
234
+ *
235
+ * Since we pass these extra parameters via the context, which is
236
+ * shared between threads, we must lock the context to avoid these
237
+ * parameters being changed from another thread before the handler
238
+ * has completed running.
239
+ *
240
+ * In addition, for general_purpose_io, the Address and bit_width fields
241
+ * are defined as follows:
242
+ * 1) Address is the pin number index of the field (bit offset from
243
+ * the previous Connection)
244
+ * 2) bit_width is the actual bit length of the field (number of pins)
245
+ */
246
+ if ((region_obj->region.space_id == ACPI_ADR_SPACE_GSBUS) &&
247
+ context && field_obj) {
248
+
249
+ status =
250
+ acpi_os_acquire_mutex(context_mutex, ACPI_WAIT_FOREVER);
251
+ if (ACPI_FAILURE(status)) {
252
+ goto re_enter_interpreter;
253
+ }
254
+
255
+ context_locked = TRUE;
256
+
257
+ /* Get the Connection (resource_template) buffer */
258
+
259
+ context->connection = field_obj->field.resource_buffer;
260
+ context->length = field_obj->field.resource_length;
261
+ context->access_length = field_obj->field.access_length;
262
+ }
263
+ if ((region_obj->region.space_id == ACPI_ADR_SPACE_GPIO) &&
264
+ context && field_obj) {
265
+
266
+ status =
267
+ acpi_os_acquire_mutex(context_mutex, ACPI_WAIT_FOREVER);
268
+ if (ACPI_FAILURE(status)) {
269
+ goto re_enter_interpreter;
270
+ }
271
+
272
+ context_locked = TRUE;
273
+
274
+ /* Get the Connection (resource_template) buffer */
275
+
276
+ context->connection = field_obj->field.resource_buffer;
277
+ context->length = field_obj->field.resource_length;
278
+ context->access_length = field_obj->field.access_length;
279
+ address = field_obj->field.pin_number_index;
280
+ bit_width = field_obj->field.bit_length;
256281 }
257282
258283 /* Call the handler */
259284
260285 status = handler(function, address, bit_width, value, context,
261286 region_obj2->extra.region_context);
287
+
288
+ if (context_locked) {
289
+ acpi_os_release_mutex(context_mutex);
290
+ }
262291
263292 if (ACPI_FAILURE(status)) {
264293 ACPI_EXCEPTION((AE_INFO, status, "Returned by Handler for [%s]",
....@@ -276,6 +305,7 @@
276305 }
277306 }
278307
308
+re_enter_interpreter:
279309 if (!(handler_desc->address_space.handler_flags &
280310 ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) {
281311 /*
....@@ -836,11 +866,11 @@
836866 objects[1].type = ACPI_TYPE_INTEGER;
837867 objects[1].integer.value = ACPI_REG_CONNECT;
838868
839
- status = acpi_evaluate_object(reg_method, NULL, &args, NULL);
869
+ (void)acpi_evaluate_object(reg_method, NULL, &args, NULL);
840870
841871 exit:
842872 /* We ignore all errors from above, don't care */
843873
844
- status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
874
+ (void)acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
845875 return_VOID;
846876 }