diff options
Diffstat (limited to 'drivers/acpi/acpica/nsinit.c')
-rw-r--r-- | drivers/acpi/acpica/nsinit.c | 593 |
1 files changed, 593 insertions, 0 deletions
diff --git a/drivers/acpi/acpica/nsinit.c b/drivers/acpi/acpica/nsinit.c new file mode 100644 index 00000000000..fe470c4b38f --- /dev/null +++ b/drivers/acpi/acpica/nsinit.c | |||
@@ -0,0 +1,593 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Module Name: nsinit - namespace initialization | ||
4 | * | ||
5 | *****************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2008, Intel Corp. | ||
9 | * All rights reserved. | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * 1. Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions, and the following disclaimer, | ||
16 | * without modification. | ||
17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
18 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
19 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
20 | * including a substantially similar Disclaimer requirement for further | ||
21 | * binary redistribution. | ||
22 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
23 | * of any contributors may be used to endorse or promote products derived | ||
24 | * from this software without specific prior written permission. | ||
25 | * | ||
26 | * Alternatively, this software may be distributed under the terms of the | ||
27 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
28 | * Software Foundation. | ||
29 | * | ||
30 | * NO WARRANTY | ||
31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
41 | * POSSIBILITY OF SUCH DAMAGES. | ||
42 | */ | ||
43 | |||
44 | #include <acpi/acpi.h> | ||
45 | #include <acpi/accommon.h> | ||
46 | #include <acpi/acnamesp.h> | ||
47 | #include <acpi/acdispat.h> | ||
48 | #include <acpi/acinterp.h> | ||
49 | #include <linux/nmi.h> | ||
50 | |||
51 | #define _COMPONENT ACPI_NAMESPACE | ||
52 | ACPI_MODULE_NAME("nsinit") | ||
53 | |||
54 | /* Local prototypes */ | ||
55 | static acpi_status | ||
56 | acpi_ns_init_one_object(acpi_handle obj_handle, | ||
57 | u32 level, void *context, void **return_value); | ||
58 | |||
59 | static acpi_status | ||
60 | acpi_ns_init_one_device(acpi_handle obj_handle, | ||
61 | u32 nesting_level, void *context, void **return_value); | ||
62 | |||
63 | static acpi_status | ||
64 | acpi_ns_find_ini_methods(acpi_handle obj_handle, | ||
65 | u32 nesting_level, void *context, void **return_value); | ||
66 | |||
67 | /******************************************************************************* | ||
68 | * | ||
69 | * FUNCTION: acpi_ns_initialize_objects | ||
70 | * | ||
71 | * PARAMETERS: None | ||
72 | * | ||
73 | * RETURN: Status | ||
74 | * | ||
75 | * DESCRIPTION: Walk the entire namespace and perform any necessary | ||
76 | * initialization on the objects found therein | ||
77 | * | ||
78 | ******************************************************************************/ | ||
79 | |||
80 | acpi_status acpi_ns_initialize_objects(void) | ||
81 | { | ||
82 | acpi_status status; | ||
83 | struct acpi_init_walk_info info; | ||
84 | |||
85 | ACPI_FUNCTION_TRACE(ns_initialize_objects); | ||
86 | |||
87 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, | ||
88 | "**** Starting initialization of namespace objects ****\n")); | ||
89 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, | ||
90 | "Completing Region/Field/Buffer/Package initialization:")); | ||
91 | |||
92 | /* Set all init info to zero */ | ||
93 | |||
94 | ACPI_MEMSET(&info, 0, sizeof(struct acpi_init_walk_info)); | ||
95 | |||
96 | /* Walk entire namespace from the supplied root */ | ||
97 | |||
98 | status = acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, | ||
99 | ACPI_UINT32_MAX, acpi_ns_init_one_object, | ||
100 | &info, NULL); | ||
101 | if (ACPI_FAILURE(status)) { | ||
102 | ACPI_EXCEPTION((AE_INFO, status, "During WalkNamespace")); | ||
103 | } | ||
104 | |||
105 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, | ||
106 | "\nInitialized %hd/%hd Regions %hd/%hd Fields %hd/%hd Buffers %hd/%hd Packages (%hd nodes)\n", | ||
107 | info.op_region_init, info.op_region_count, | ||
108 | info.field_init, info.field_count, | ||
109 | info.buffer_init, info.buffer_count, | ||
110 | info.package_init, info.package_count, | ||
111 | info.object_count)); | ||
112 | |||
113 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, | ||
114 | "%hd Control Methods found\n", info.method_count)); | ||
115 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, | ||
116 | "%hd Op Regions found\n", info.op_region_count)); | ||
117 | |||
118 | return_ACPI_STATUS(AE_OK); | ||
119 | } | ||
120 | |||
121 | /******************************************************************************* | ||
122 | * | ||
123 | * FUNCTION: acpi_ns_initialize_devices | ||
124 | * | ||
125 | * PARAMETERS: None | ||
126 | * | ||
127 | * RETURN: acpi_status | ||
128 | * | ||
129 | * DESCRIPTION: Walk the entire namespace and initialize all ACPI devices. | ||
130 | * This means running _INI on all present devices. | ||
131 | * | ||
132 | * Note: We install PCI config space handler on region access, | ||
133 | * not here. | ||
134 | * | ||
135 | ******************************************************************************/ | ||
136 | |||
137 | acpi_status acpi_ns_initialize_devices(void) | ||
138 | { | ||
139 | acpi_status status; | ||
140 | struct acpi_device_walk_info info; | ||
141 | |||
142 | ACPI_FUNCTION_TRACE(ns_initialize_devices); | ||
143 | |||
144 | /* Init counters */ | ||
145 | |||
146 | info.device_count = 0; | ||
147 | info.num_STA = 0; | ||
148 | info.num_INI = 0; | ||
149 | |||
150 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, | ||
151 | "Initializing Device/Processor/Thermal objects by executing _INI methods:")); | ||
152 | |||
153 | /* Tree analysis: find all subtrees that contain _INI methods */ | ||
154 | |||
155 | status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, | ||
156 | ACPI_UINT32_MAX, FALSE, | ||
157 | acpi_ns_find_ini_methods, &info, NULL); | ||
158 | if (ACPI_FAILURE(status)) { | ||
159 | goto error_exit; | ||
160 | } | ||
161 | |||
162 | /* Allocate the evaluation information block */ | ||
163 | |||
164 | info.evaluate_info = | ||
165 | ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info)); | ||
166 | if (!info.evaluate_info) { | ||
167 | status = AE_NO_MEMORY; | ||
168 | goto error_exit; | ||
169 | } | ||
170 | |||
171 | /* Walk namespace to execute all _INIs on present devices */ | ||
172 | |||
173 | status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, | ||
174 | ACPI_UINT32_MAX, FALSE, | ||
175 | acpi_ns_init_one_device, &info, NULL); | ||
176 | |||
177 | ACPI_FREE(info.evaluate_info); | ||
178 | if (ACPI_FAILURE(status)) { | ||
179 | goto error_exit; | ||
180 | } | ||
181 | |||
182 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, | ||
183 | "\nExecuted %hd _INI methods requiring %hd _STA executions (examined %hd objects)\n", | ||
184 | info.num_INI, info.num_STA, info.device_count)); | ||
185 | |||
186 | return_ACPI_STATUS(status); | ||
187 | |||
188 | error_exit: | ||
189 | ACPI_EXCEPTION((AE_INFO, status, "During device initialization")); | ||
190 | return_ACPI_STATUS(status); | ||
191 | } | ||
192 | |||
193 | /******************************************************************************* | ||
194 | * | ||
195 | * FUNCTION: acpi_ns_init_one_object | ||
196 | * | ||
197 | * PARAMETERS: obj_handle - Node | ||
198 | * Level - Current nesting level | ||
199 | * Context - Points to a init info struct | ||
200 | * return_value - Not used | ||
201 | * | ||
202 | * RETURN: Status | ||
203 | * | ||
204 | * DESCRIPTION: Callback from acpi_walk_namespace. Invoked for every object | ||
205 | * within the namespace. | ||
206 | * | ||
207 | * Currently, the only objects that require initialization are: | ||
208 | * 1) Methods | ||
209 | * 2) Op Regions | ||
210 | * | ||
211 | ******************************************************************************/ | ||
212 | |||
213 | static acpi_status | ||
214 | acpi_ns_init_one_object(acpi_handle obj_handle, | ||
215 | u32 level, void *context, void **return_value) | ||
216 | { | ||
217 | acpi_object_type type; | ||
218 | acpi_status status = AE_OK; | ||
219 | struct acpi_init_walk_info *info = | ||
220 | (struct acpi_init_walk_info *)context; | ||
221 | struct acpi_namespace_node *node = | ||
222 | (struct acpi_namespace_node *)obj_handle; | ||
223 | union acpi_operand_object *obj_desc; | ||
224 | |||
225 | ACPI_FUNCTION_NAME(ns_init_one_object); | ||
226 | |||
227 | info->object_count++; | ||
228 | |||
229 | /* And even then, we are only interested in a few object types */ | ||
230 | |||
231 | type = acpi_ns_get_type(obj_handle); | ||
232 | obj_desc = acpi_ns_get_attached_object(node); | ||
233 | if (!obj_desc) { | ||
234 | return (AE_OK); | ||
235 | } | ||
236 | |||
237 | /* Increment counters for object types we are looking for */ | ||
238 | |||
239 | switch (type) { | ||
240 | case ACPI_TYPE_REGION: | ||
241 | info->op_region_count++; | ||
242 | break; | ||
243 | |||
244 | case ACPI_TYPE_BUFFER_FIELD: | ||
245 | info->field_count++; | ||
246 | break; | ||
247 | |||
248 | case ACPI_TYPE_LOCAL_BANK_FIELD: | ||
249 | info->field_count++; | ||
250 | break; | ||
251 | |||
252 | case ACPI_TYPE_BUFFER: | ||
253 | info->buffer_count++; | ||
254 | break; | ||
255 | |||
256 | case ACPI_TYPE_PACKAGE: | ||
257 | info->package_count++; | ||
258 | break; | ||
259 | |||
260 | default: | ||
261 | |||
262 | /* No init required, just exit now */ | ||
263 | return (AE_OK); | ||
264 | } | ||
265 | |||
266 | /* | ||
267 | * If the object is already initialized, nothing else to do | ||
268 | */ | ||
269 | if (obj_desc->common.flags & AOPOBJ_DATA_VALID) { | ||
270 | return (AE_OK); | ||
271 | } | ||
272 | |||
273 | /* | ||
274 | * Must lock the interpreter before executing AML code | ||
275 | */ | ||
276 | acpi_ex_enter_interpreter(); | ||
277 | |||
278 | /* | ||
279 | * Each of these types can contain executable AML code within the | ||
280 | * declaration. | ||
281 | */ | ||
282 | switch (type) { | ||
283 | case ACPI_TYPE_REGION: | ||
284 | |||
285 | info->op_region_init++; | ||
286 | status = acpi_ds_get_region_arguments(obj_desc); | ||
287 | break; | ||
288 | |||
289 | case ACPI_TYPE_BUFFER_FIELD: | ||
290 | |||
291 | info->field_init++; | ||
292 | status = acpi_ds_get_buffer_field_arguments(obj_desc); | ||
293 | break; | ||
294 | |||
295 | case ACPI_TYPE_LOCAL_BANK_FIELD: | ||
296 | |||
297 | info->field_init++; | ||
298 | status = acpi_ds_get_bank_field_arguments(obj_desc); | ||
299 | break; | ||
300 | |||
301 | case ACPI_TYPE_BUFFER: | ||
302 | |||
303 | info->buffer_init++; | ||
304 | status = acpi_ds_get_buffer_arguments(obj_desc); | ||
305 | break; | ||
306 | |||
307 | case ACPI_TYPE_PACKAGE: | ||
308 | |||
309 | info->package_init++; | ||
310 | status = acpi_ds_get_package_arguments(obj_desc); | ||
311 | break; | ||
312 | |||
313 | default: | ||
314 | /* No other types can get here */ | ||
315 | break; | ||
316 | } | ||
317 | |||
318 | if (ACPI_FAILURE(status)) { | ||
319 | ACPI_EXCEPTION((AE_INFO, status, | ||
320 | "Could not execute arguments for [%4.4s] (%s)", | ||
321 | acpi_ut_get_node_name(node), | ||
322 | acpi_ut_get_type_name(type))); | ||
323 | } | ||
324 | |||
325 | /* | ||
326 | * Print a dot for each object unless we are going to print the entire | ||
327 | * pathname | ||
328 | */ | ||
329 | if (!(acpi_dbg_level & ACPI_LV_INIT_NAMES)) { | ||
330 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, ".")); | ||
331 | } | ||
332 | |||
333 | /* | ||
334 | * We ignore errors from above, and always return OK, since we don't want | ||
335 | * to abort the walk on any single error. | ||
336 | */ | ||
337 | acpi_ex_exit_interpreter(); | ||
338 | return (AE_OK); | ||
339 | } | ||
340 | |||
341 | /******************************************************************************* | ||
342 | * | ||
343 | * FUNCTION: acpi_ns_find_ini_methods | ||
344 | * | ||
345 | * PARAMETERS: acpi_walk_callback | ||
346 | * | ||
347 | * RETURN: acpi_status | ||
348 | * | ||
349 | * DESCRIPTION: Called during namespace walk. Finds objects named _INI under | ||
350 | * device/processor/thermal objects, and marks the entire subtree | ||
351 | * with a SUBTREE_HAS_INI flag. This flag is used during the | ||
352 | * subsequent device initialization walk to avoid entire subtrees | ||
353 | * that do not contain an _INI. | ||
354 | * | ||
355 | ******************************************************************************/ | ||
356 | |||
357 | static acpi_status | ||
358 | acpi_ns_find_ini_methods(acpi_handle obj_handle, | ||
359 | u32 nesting_level, void *context, void **return_value) | ||
360 | { | ||
361 | struct acpi_device_walk_info *info = | ||
362 | ACPI_CAST_PTR(struct acpi_device_walk_info, context); | ||
363 | struct acpi_namespace_node *node; | ||
364 | struct acpi_namespace_node *parent_node; | ||
365 | |||
366 | /* Keep count of device/processor/thermal objects */ | ||
367 | |||
368 | node = ACPI_CAST_PTR(struct acpi_namespace_node, obj_handle); | ||
369 | if ((node->type == ACPI_TYPE_DEVICE) || | ||
370 | (node->type == ACPI_TYPE_PROCESSOR) || | ||
371 | (node->type == ACPI_TYPE_THERMAL)) { | ||
372 | info->device_count++; | ||
373 | return (AE_OK); | ||
374 | } | ||
375 | |||
376 | /* We are only looking for methods named _INI */ | ||
377 | |||
378 | if (!ACPI_COMPARE_NAME(node->name.ascii, METHOD_NAME__INI)) { | ||
379 | return (AE_OK); | ||
380 | } | ||
381 | |||
382 | /* | ||
383 | * The only _INI methods that we care about are those that are | ||
384 | * present under Device, Processor, and Thermal objects. | ||
385 | */ | ||
386 | parent_node = acpi_ns_get_parent_node(node); | ||
387 | switch (parent_node->type) { | ||
388 | case ACPI_TYPE_DEVICE: | ||
389 | case ACPI_TYPE_PROCESSOR: | ||
390 | case ACPI_TYPE_THERMAL: | ||
391 | |||
392 | /* Mark parent and bubble up the INI present flag to the root */ | ||
393 | |||
394 | while (parent_node) { | ||
395 | parent_node->flags |= ANOBJ_SUBTREE_HAS_INI; | ||
396 | parent_node = acpi_ns_get_parent_node(parent_node); | ||
397 | } | ||
398 | break; | ||
399 | |||
400 | default: | ||
401 | break; | ||
402 | } | ||
403 | |||
404 | return (AE_OK); | ||
405 | } | ||
406 | |||
407 | /******************************************************************************* | ||
408 | * | ||
409 | * FUNCTION: acpi_ns_init_one_device | ||
410 | * | ||
411 | * PARAMETERS: acpi_walk_callback | ||
412 | * | ||
413 | * RETURN: acpi_status | ||
414 | * | ||
415 | * DESCRIPTION: This is called once per device soon after ACPI is enabled | ||
416 | * to initialize each device. It determines if the device is | ||
417 | * present, and if so, calls _INI. | ||
418 | * | ||
419 | ******************************************************************************/ | ||
420 | |||
421 | static acpi_status | ||
422 | acpi_ns_init_one_device(acpi_handle obj_handle, | ||
423 | u32 nesting_level, void *context, void **return_value) | ||
424 | { | ||
425 | struct acpi_device_walk_info *walk_info = | ||
426 | ACPI_CAST_PTR(struct acpi_device_walk_info, context); | ||
427 | struct acpi_evaluate_info *info = walk_info->evaluate_info; | ||
428 | u32 flags; | ||
429 | acpi_status status; | ||
430 | struct acpi_namespace_node *device_node; | ||
431 | |||
432 | ACPI_FUNCTION_TRACE(ns_init_one_device); | ||
433 | |||
434 | /* We are interested in Devices, Processors and thermal_zones only */ | ||
435 | |||
436 | device_node = ACPI_CAST_PTR(struct acpi_namespace_node, obj_handle); | ||
437 | if ((device_node->type != ACPI_TYPE_DEVICE) && | ||
438 | (device_node->type != ACPI_TYPE_PROCESSOR) && | ||
439 | (device_node->type != ACPI_TYPE_THERMAL)) { | ||
440 | return_ACPI_STATUS(AE_OK); | ||
441 | } | ||
442 | |||
443 | /* | ||
444 | * Because of an earlier namespace analysis, all subtrees that contain an | ||
445 | * _INI method are tagged. | ||
446 | * | ||
447 | * If this device subtree does not contain any _INI methods, we | ||
448 | * can exit now and stop traversing this entire subtree. | ||
449 | */ | ||
450 | if (!(device_node->flags & ANOBJ_SUBTREE_HAS_INI)) { | ||
451 | return_ACPI_STATUS(AE_CTRL_DEPTH); | ||
452 | } | ||
453 | |||
454 | /* | ||
455 | * Run _STA to determine if this device is present and functioning. We | ||
456 | * must know this information for two important reasons (from ACPI spec): | ||
457 | * | ||
458 | * 1) We can only run _INI if the device is present. | ||
459 | * 2) We must abort the device tree walk on this subtree if the device is | ||
460 | * not present and is not functional (we will not examine the children) | ||
461 | * | ||
462 | * The _STA method is not required to be present under the device, we | ||
463 | * assume the device is present if _STA does not exist. | ||
464 | */ | ||
465 | ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname | ||
466 | (ACPI_TYPE_METHOD, device_node, METHOD_NAME__STA)); | ||
467 | |||
468 | status = acpi_ut_execute_STA(device_node, &flags); | ||
469 | if (ACPI_FAILURE(status)) { | ||
470 | |||
471 | /* Ignore error and move on to next device */ | ||
472 | |||
473 | return_ACPI_STATUS(AE_OK); | ||
474 | } | ||
475 | |||
476 | /* | ||
477 | * Flags == -1 means that _STA was not found. In this case, we assume that | ||
478 | * the device is both present and functional. | ||
479 | * | ||
480 | * From the ACPI spec, description of _STA: | ||
481 | * | ||
482 | * "If a device object (including the processor object) does not have an | ||
483 | * _STA object, then OSPM assumes that all of the above bits are set (in | ||
484 | * other words, the device is present, ..., and functioning)" | ||
485 | */ | ||
486 | if (flags != ACPI_UINT32_MAX) { | ||
487 | walk_info->num_STA++; | ||
488 | } | ||
489 | |||
490 | /* | ||
491 | * Examine the PRESENT and FUNCTIONING status bits | ||
492 | * | ||
493 | * Note: ACPI spec does not seem to specify behavior for the present but | ||
494 | * not functioning case, so we assume functioning if present. | ||
495 | */ | ||
496 | if (!(flags & ACPI_STA_DEVICE_PRESENT)) { | ||
497 | |||
498 | /* Device is not present, we must examine the Functioning bit */ | ||
499 | |||
500 | if (flags & ACPI_STA_DEVICE_FUNCTIONING) { | ||
501 | /* | ||
502 | * Device is not present but is "functioning". In this case, | ||
503 | * we will not run _INI, but we continue to examine the children | ||
504 | * of this device. | ||
505 | * | ||
506 | * From the ACPI spec, description of _STA: (Note - no mention | ||
507 | * of whether to run _INI or not on the device in question) | ||
508 | * | ||
509 | * "_STA may return bit 0 clear (not present) with bit 3 set | ||
510 | * (device is functional). This case is used to indicate a valid | ||
511 | * device for which no device driver should be loaded (for example, | ||
512 | * a bridge device.) Children of this device may be present and | ||
513 | * valid. OSPM should continue enumeration below a device whose | ||
514 | * _STA returns this bit combination" | ||
515 | */ | ||
516 | return_ACPI_STATUS(AE_OK); | ||
517 | } else { | ||
518 | /* | ||
519 | * Device is not present and is not functioning. We must abort the | ||
520 | * walk of this subtree immediately -- don't look at the children | ||
521 | * of such a device. | ||
522 | * | ||
523 | * From the ACPI spec, description of _INI: | ||
524 | * | ||
525 | * "If the _STA method indicates that the device is not present, | ||
526 | * OSPM will not run the _INI and will not examine the children | ||
527 | * of the device for _INI methods" | ||
528 | */ | ||
529 | return_ACPI_STATUS(AE_CTRL_DEPTH); | ||
530 | } | ||
531 | } | ||
532 | |||
533 | /* | ||
534 | * The device is present or is assumed present if no _STA exists. | ||
535 | * Run the _INI if it exists (not required to exist) | ||
536 | * | ||
537 | * Note: We know there is an _INI within this subtree, but it may not be | ||
538 | * under this particular device, it may be lower in the branch. | ||
539 | */ | ||
540 | ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname | ||
541 | (ACPI_TYPE_METHOD, device_node, METHOD_NAME__INI)); | ||
542 | |||
543 | info->prefix_node = device_node; | ||
544 | info->pathname = METHOD_NAME__INI; | ||
545 | info->parameters = NULL; | ||
546 | info->flags = ACPI_IGNORE_RETURN_VALUE; | ||
547 | |||
548 | /* | ||
549 | * Some hardware relies on this being executed as atomically | ||
550 | * as possible (without an NMI being received in the middle of | ||
551 | * this) - so disable NMIs and initialize the device: | ||
552 | */ | ||
553 | acpi_nmi_disable(); | ||
554 | status = acpi_ns_evaluate(info); | ||
555 | acpi_nmi_enable(); | ||
556 | |||
557 | if (ACPI_SUCCESS(status)) { | ||
558 | walk_info->num_INI++; | ||
559 | |||
560 | if ((acpi_dbg_level <= ACPI_LV_ALL_EXCEPTIONS) && | ||
561 | (!(acpi_dbg_level & ACPI_LV_INFO))) { | ||
562 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, ".")); | ||
563 | } | ||
564 | } | ||
565 | #ifdef ACPI_DEBUG_OUTPUT | ||
566 | else if (status != AE_NOT_FOUND) { | ||
567 | |||
568 | /* Ignore error and move on to next device */ | ||
569 | |||
570 | char *scope_name = | ||
571 | acpi_ns_get_external_pathname(info->resolved_node); | ||
572 | |||
573 | ACPI_EXCEPTION((AE_INFO, status, "during %s._INI execution", | ||
574 | scope_name)); | ||
575 | ACPI_FREE(scope_name); | ||
576 | } | ||
577 | #endif | ||
578 | |||
579 | /* Ignore errors from above */ | ||
580 | |||
581 | status = AE_OK; | ||
582 | |||
583 | /* | ||
584 | * The _INI method has been run if present; call the Global Initialization | ||
585 | * Handler for this device. | ||
586 | */ | ||
587 | if (acpi_gbl_init_handler) { | ||
588 | status = | ||
589 | acpi_gbl_init_handler(device_node, ACPI_INIT_DEVICE_INI); | ||
590 | } | ||
591 | |||
592 | return_ACPI_STATUS(status); | ||
593 | } | ||