diff options
Diffstat (limited to 'drivers/acpi/acpica/nseval.c')
-rw-r--r-- | drivers/acpi/acpica/nseval.c | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/drivers/acpi/acpica/nseval.c b/drivers/acpi/acpica/nseval.c index 8e7dec1176c9..846d1132feb1 100644 --- a/drivers/acpi/acpica/nseval.c +++ b/drivers/acpi/acpica/nseval.c | |||
@@ -50,6 +50,11 @@ | |||
50 | #define _COMPONENT ACPI_NAMESPACE | 50 | #define _COMPONENT ACPI_NAMESPACE |
51 | ACPI_MODULE_NAME("nseval") | 51 | ACPI_MODULE_NAME("nseval") |
52 | 52 | ||
53 | /* Local prototypes */ | ||
54 | static void | ||
55 | acpi_ns_exec_module_code(union acpi_operand_object *method_obj, | ||
56 | struct acpi_evaluate_info *info); | ||
57 | |||
53 | /******************************************************************************* | 58 | /******************************************************************************* |
54 | * | 59 | * |
55 | * FUNCTION: acpi_ns_evaluate | 60 | * FUNCTION: acpi_ns_evaluate |
@@ -76,6 +81,7 @@ ACPI_MODULE_NAME("nseval") | |||
76 | * MUTEX: Locks interpreter | 81 | * MUTEX: Locks interpreter |
77 | * | 82 | * |
78 | ******************************************************************************/ | 83 | ******************************************************************************/ |
84 | |||
79 | acpi_status acpi_ns_evaluate(struct acpi_evaluate_info * info) | 85 | acpi_status acpi_ns_evaluate(struct acpi_evaluate_info * info) |
80 | { | 86 | { |
81 | acpi_status status; | 87 | acpi_status status; |
@@ -276,3 +282,134 @@ acpi_status acpi_ns_evaluate(struct acpi_evaluate_info * info) | |||
276 | */ | 282 | */ |
277 | return_ACPI_STATUS(status); | 283 | return_ACPI_STATUS(status); |
278 | } | 284 | } |
285 | |||
286 | /******************************************************************************* | ||
287 | * | ||
288 | * FUNCTION: acpi_ns_exec_module_code_list | ||
289 | * | ||
290 | * PARAMETERS: None | ||
291 | * | ||
292 | * RETURN: None. Exceptions during method execution are ignored, since | ||
293 | * we cannot abort a table load. | ||
294 | * | ||
295 | * DESCRIPTION: Execute all elements of the global module-level code list. | ||
296 | * Each element is executed as a single control method. | ||
297 | * | ||
298 | ******************************************************************************/ | ||
299 | |||
300 | void acpi_ns_exec_module_code_list(void) | ||
301 | { | ||
302 | union acpi_operand_object *prev; | ||
303 | union acpi_operand_object *next; | ||
304 | struct acpi_evaluate_info *info; | ||
305 | u32 method_count = 0; | ||
306 | |||
307 | ACPI_FUNCTION_TRACE(ns_exec_module_code_list); | ||
308 | |||
309 | /* Exit now if the list is empty */ | ||
310 | |||
311 | next = acpi_gbl_module_code_list; | ||
312 | if (!next) { | ||
313 | return_VOID; | ||
314 | } | ||
315 | |||
316 | /* Allocate the evaluation information block */ | ||
317 | |||
318 | info = ACPI_ALLOCATE(sizeof(struct acpi_evaluate_info)); | ||
319 | if (!info) { | ||
320 | return_VOID; | ||
321 | } | ||
322 | |||
323 | /* Walk the list, executing each "method" */ | ||
324 | |||
325 | while (next) { | ||
326 | prev = next; | ||
327 | next = next->method.mutex; | ||
328 | |||
329 | /* Clear the link field and execute the method */ | ||
330 | |||
331 | prev->method.mutex = NULL; | ||
332 | acpi_ns_exec_module_code(prev, info); | ||
333 | method_count++; | ||
334 | |||
335 | /* Delete the (temporary) method object */ | ||
336 | |||
337 | acpi_ut_remove_reference(prev); | ||
338 | } | ||
339 | |||
340 | ACPI_INFO((AE_INFO, | ||
341 | "Executed %u blocks of module-level executable AML code", | ||
342 | method_count)); | ||
343 | |||
344 | ACPI_FREE(info); | ||
345 | acpi_gbl_module_code_list = NULL; | ||
346 | return_VOID; | ||
347 | } | ||
348 | |||
349 | /******************************************************************************* | ||
350 | * | ||
351 | * FUNCTION: acpi_ns_exec_module_code | ||
352 | * | ||
353 | * PARAMETERS: method_obj - Object container for the module-level code | ||
354 | * Info - Info block for method evaluation | ||
355 | * | ||
356 | * RETURN: None. Exceptions during method execution are ignored, since | ||
357 | * we cannot abort a table load. | ||
358 | * | ||
359 | * DESCRIPTION: Execute a control method containing a block of module-level | ||
360 | * executable AML code. The control method is temporarily | ||
361 | * installed to the root node, then evaluated. | ||
362 | * | ||
363 | ******************************************************************************/ | ||
364 | |||
365 | static void | ||
366 | acpi_ns_exec_module_code(union acpi_operand_object *method_obj, | ||
367 | struct acpi_evaluate_info *info) | ||
368 | { | ||
369 | union acpi_operand_object *root_obj; | ||
370 | acpi_status status; | ||
371 | |||
372 | ACPI_FUNCTION_TRACE(ns_exec_module_code); | ||
373 | |||
374 | /* Initialize the evaluation information block */ | ||
375 | |||
376 | ACPI_MEMSET(info, 0, sizeof(struct acpi_evaluate_info)); | ||
377 | info->prefix_node = acpi_gbl_root_node; | ||
378 | |||
379 | /* | ||
380 | * Get the currently attached root object. Add a reference, because the | ||
381 | * ref count will be decreased when the method object is installed to | ||
382 | * the root node. | ||
383 | */ | ||
384 | root_obj = acpi_ns_get_attached_object(acpi_gbl_root_node); | ||
385 | acpi_ut_add_reference(root_obj); | ||
386 | |||
387 | /* Install the method (module-level code) in the root node */ | ||
388 | |||
389 | status = acpi_ns_attach_object(acpi_gbl_root_node, method_obj, | ||
390 | ACPI_TYPE_METHOD); | ||
391 | if (ACPI_FAILURE(status)) { | ||
392 | goto exit; | ||
393 | } | ||
394 | |||
395 | /* Execute the root node as a control method */ | ||
396 | |||
397 | status = acpi_ns_evaluate(info); | ||
398 | |||
399 | ACPI_DEBUG_PRINT((ACPI_DB_INIT, "Executed module-level code at %p\n", | ||
400 | method_obj->method.aml_start)); | ||
401 | |||
402 | /* Detach the temporary method object */ | ||
403 | |||
404 | acpi_ns_detach_object(acpi_gbl_root_node); | ||
405 | |||
406 | /* Restore the original root object */ | ||
407 | |||
408 | status = | ||
409 | acpi_ns_attach_object(acpi_gbl_root_node, root_obj, | ||
410 | ACPI_TYPE_DEVICE); | ||
411 | |||
412 | exit: | ||
413 | acpi_ut_remove_reference(root_obj); | ||
414 | return_VOID; | ||
415 | } | ||