xref: /openbmc/linux/drivers/acpi/acpica/evregion.c (revision 275876e2)
1 /******************************************************************************
2  *
3  * Module Name: evregion - Operation Region support
4  *
5  *****************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2014, 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 "accommon.h"
46 #include "acevents.h"
47 #include "acnamesp.h"
48 #include "acinterp.h"
49 
50 #define _COMPONENT          ACPI_EVENTS
51 ACPI_MODULE_NAME("evregion")
52 
53 extern u8 acpi_gbl_default_address_spaces[];
54 
55 /* Local prototypes */
56 
57 static void
58 acpi_ev_orphan_ec_reg_method(struct acpi_namespace_node *ec_device_node);
59 
60 static acpi_status
61 acpi_ev_reg_run(acpi_handle obj_handle,
62 		u32 level, void *context, void **return_value);
63 
64 /*******************************************************************************
65  *
66  * FUNCTION:    acpi_ev_initialize_op_regions
67  *
68  * PARAMETERS:  None
69  *
70  * RETURN:      Status
71  *
72  * DESCRIPTION: Execute _REG methods for all Operation Regions that have
73  *              an installed default region handler.
74  *
75  ******************************************************************************/
76 
77 acpi_status acpi_ev_initialize_op_regions(void)
78 {
79 	acpi_status status;
80 	u32 i;
81 
82 	ACPI_FUNCTION_TRACE(ev_initialize_op_regions);
83 
84 	status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
85 	if (ACPI_FAILURE(status)) {
86 		return_ACPI_STATUS(status);
87 	}
88 
89 	/* Run the _REG methods for op_regions in each default address space */
90 
91 	for (i = 0; i < ACPI_NUM_DEFAULT_SPACES; i++) {
92 		/*
93 		 * Make sure the installed handler is the DEFAULT handler. If not the
94 		 * default, the _REG methods will have already been run (when the
95 		 * handler was installed)
96 		 */
97 		if (acpi_ev_has_default_handler(acpi_gbl_root_node,
98 						acpi_gbl_default_address_spaces
99 						[i])) {
100 			status =
101 			    acpi_ev_execute_reg_methods(acpi_gbl_root_node,
102 							acpi_gbl_default_address_spaces
103 							[i]);
104 		}
105 	}
106 
107 	acpi_gbl_reg_methods_executed = TRUE;
108 
109 	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
110 	return_ACPI_STATUS(status);
111 }
112 
113 /*******************************************************************************
114  *
115  * FUNCTION:    acpi_ev_address_space_dispatch
116  *
117  * PARAMETERS:  region_obj          - Internal region object
118  *              field_obj           - Corresponding field. Can be NULL.
119  *              function            - Read or Write operation
120  *              region_offset       - Where in the region to read or write
121  *              bit_width           - Field width in bits (8, 16, 32, or 64)
122  *              value               - Pointer to in or out value, must be
123  *                                    a full 64-bit integer
124  *
125  * RETURN:      Status
126  *
127  * DESCRIPTION: Dispatch an address space or operation region access to
128  *              a previously installed handler.
129  *
130  ******************************************************************************/
131 
132 acpi_status
133 acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj,
134 			       union acpi_operand_object *field_obj,
135 			       u32 function,
136 			       u32 region_offset, u32 bit_width, u64 *value)
137 {
138 	acpi_status status;
139 	acpi_adr_space_handler handler;
140 	acpi_adr_space_setup region_setup;
141 	union acpi_operand_object *handler_desc;
142 	union acpi_operand_object *region_obj2;
143 	void *region_context = NULL;
144 	struct acpi_connection_info *context;
145 
146 	ACPI_FUNCTION_TRACE(ev_address_space_dispatch);
147 
148 	region_obj2 = acpi_ns_get_secondary_object(region_obj);
149 	if (!region_obj2) {
150 		return_ACPI_STATUS(AE_NOT_EXIST);
151 	}
152 
153 	/* Ensure that there is a handler associated with this region */
154 
155 	handler_desc = region_obj->region.handler;
156 	if (!handler_desc) {
157 		ACPI_ERROR((AE_INFO,
158 			    "No handler for Region [%4.4s] (%p) [%s]",
159 			    acpi_ut_get_node_name(region_obj->region.node),
160 			    region_obj,
161 			    acpi_ut_get_region_name(region_obj->region.
162 						    space_id)));
163 
164 		return_ACPI_STATUS(AE_NOT_EXIST);
165 	}
166 
167 	context = handler_desc->address_space.context;
168 
169 	/*
170 	 * It may be the case that the region has never been initialized.
171 	 * Some types of regions require special init code
172 	 */
173 	if (!(region_obj->region.flags & AOPOBJ_SETUP_COMPLETE)) {
174 
175 		/* This region has not been initialized yet, do it */
176 
177 		region_setup = handler_desc->address_space.setup;
178 		if (!region_setup) {
179 
180 			/* No initialization routine, exit with error */
181 
182 			ACPI_ERROR((AE_INFO,
183 				    "No init routine for region(%p) [%s]",
184 				    region_obj,
185 				    acpi_ut_get_region_name(region_obj->region.
186 							    space_id)));
187 			return_ACPI_STATUS(AE_NOT_EXIST);
188 		}
189 
190 		/*
191 		 * We must exit the interpreter because the region setup will
192 		 * potentially execute control methods (for example, the _REG method
193 		 * for this region)
194 		 */
195 		acpi_ex_exit_interpreter();
196 
197 		status = region_setup(region_obj, ACPI_REGION_ACTIVATE,
198 				      context, &region_context);
199 
200 		/* Re-enter the interpreter */
201 
202 		acpi_ex_enter_interpreter();
203 
204 		/* Check for failure of the Region Setup */
205 
206 		if (ACPI_FAILURE(status)) {
207 			ACPI_EXCEPTION((AE_INFO, status,
208 					"During region initialization: [%s]",
209 					acpi_ut_get_region_name(region_obj->
210 								region.
211 								space_id)));
212 			return_ACPI_STATUS(status);
213 		}
214 
215 		/* Region initialization may have been completed by region_setup */
216 
217 		if (!(region_obj->region.flags & AOPOBJ_SETUP_COMPLETE)) {
218 			region_obj->region.flags |= AOPOBJ_SETUP_COMPLETE;
219 
220 			/*
221 			 * Save the returned context for use in all accesses to
222 			 * the handler for this particular region
223 			 */
224 			if (!(region_obj2->extra.region_context)) {
225 				region_obj2->extra.region_context =
226 				    region_context;
227 			}
228 		}
229 	}
230 
231 	/* We have everything we need, we can invoke the address space handler */
232 
233 	handler = handler_desc->address_space.handler;
234 
235 	ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
236 			  "Handler %p (@%p) Address %8.8X%8.8X [%s]\n",
237 			  &region_obj->region.handler->address_space, handler,
238 			  ACPI_FORMAT_NATIVE_UINT(region_obj->region.address +
239 						  region_offset),
240 			  acpi_ut_get_region_name(region_obj->region.
241 						  space_id)));
242 
243 	/*
244 	 * Special handling for generic_serial_bus and general_purpose_io:
245 	 * There are three extra parameters that must be passed to the
246 	 * handler via the context:
247 	 *   1) Connection buffer, a resource template from Connection() op.
248 	 *   2) Length of the above buffer.
249 	 *   3) Actual access length from the access_as() op.
250 	 */
251 	if (((region_obj->region.space_id == ACPI_ADR_SPACE_GSBUS) ||
252 	     (region_obj->region.space_id == ACPI_ADR_SPACE_GPIO)) &&
253 	    context && field_obj) {
254 
255 		/* Get the Connection (resource_template) buffer */
256 
257 		context->connection = field_obj->field.resource_buffer;
258 		context->length = field_obj->field.resource_length;
259 		context->access_length = field_obj->field.access_length;
260 	}
261 
262 	if (!(handler_desc->address_space.handler_flags &
263 	      ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) {
264 		/*
265 		 * For handlers other than the default (supplied) handlers, we must
266 		 * exit the interpreter because the handler *might* block -- we don't
267 		 * know what it will do, so we can't hold the lock on the intepreter.
268 		 */
269 		acpi_ex_exit_interpreter();
270 	}
271 
272 	/* Call the handler */
273 
274 	status = handler(function,
275 			 (region_obj->region.address + region_offset),
276 			 bit_width, value, context,
277 			 region_obj2->extra.region_context);
278 
279 	if (ACPI_FAILURE(status)) {
280 		ACPI_EXCEPTION((AE_INFO, status, "Returned by Handler for [%s]",
281 				acpi_ut_get_region_name(region_obj->region.
282 							space_id)));
283 	}
284 
285 	if (!(handler_desc->address_space.handler_flags &
286 	      ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) {
287 		/*
288 		 * We just returned from a non-default handler, we must re-enter the
289 		 * interpreter
290 		 */
291 		acpi_ex_enter_interpreter();
292 	}
293 
294 	return_ACPI_STATUS(status);
295 }
296 
297 /*******************************************************************************
298  *
299  * FUNCTION:    acpi_ev_detach_region
300  *
301  * PARAMETERS:  region_obj          - Region Object
302  *              acpi_ns_is_locked   - Namespace Region Already Locked?
303  *
304  * RETURN:      None
305  *
306  * DESCRIPTION: Break the association between the handler and the region
307  *              this is a two way association.
308  *
309  ******************************************************************************/
310 
311 void
312 acpi_ev_detach_region(union acpi_operand_object *region_obj,
313 		      u8 acpi_ns_is_locked)
314 {
315 	union acpi_operand_object *handler_obj;
316 	union acpi_operand_object *obj_desc;
317 	union acpi_operand_object *start_desc;
318 	union acpi_operand_object **last_obj_ptr;
319 	acpi_adr_space_setup region_setup;
320 	void **region_context;
321 	union acpi_operand_object *region_obj2;
322 	acpi_status status;
323 
324 	ACPI_FUNCTION_TRACE(ev_detach_region);
325 
326 	region_obj2 = acpi_ns_get_secondary_object(region_obj);
327 	if (!region_obj2) {
328 		return_VOID;
329 	}
330 	region_context = &region_obj2->extra.region_context;
331 
332 	/* Get the address handler from the region object */
333 
334 	handler_obj = region_obj->region.handler;
335 	if (!handler_obj) {
336 
337 		/* This region has no handler, all done */
338 
339 		return_VOID;
340 	}
341 
342 	/* Find this region in the handler's list */
343 
344 	obj_desc = handler_obj->address_space.region_list;
345 	start_desc = obj_desc;
346 	last_obj_ptr = &handler_obj->address_space.region_list;
347 
348 	while (obj_desc) {
349 
350 		/* Is this the correct Region? */
351 
352 		if (obj_desc == region_obj) {
353 			ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
354 					  "Removing Region %p from address handler %p\n",
355 					  region_obj, handler_obj));
356 
357 			/* This is it, remove it from the handler's list */
358 
359 			*last_obj_ptr = obj_desc->region.next;
360 			obj_desc->region.next = NULL;	/* Must clear field */
361 
362 			if (acpi_ns_is_locked) {
363 				status =
364 				    acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
365 				if (ACPI_FAILURE(status)) {
366 					return_VOID;
367 				}
368 			}
369 
370 			/* Now stop region accesses by executing the _REG method */
371 
372 			status =
373 			    acpi_ev_execute_reg_method(region_obj,
374 						       ACPI_REG_DISCONNECT);
375 			if (ACPI_FAILURE(status)) {
376 				ACPI_EXCEPTION((AE_INFO, status,
377 						"from region _REG, [%s]",
378 						acpi_ut_get_region_name
379 						(region_obj->region.space_id)));
380 			}
381 
382 			if (acpi_ns_is_locked) {
383 				status =
384 				    acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
385 				if (ACPI_FAILURE(status)) {
386 					return_VOID;
387 				}
388 			}
389 
390 			/*
391 			 * If the region has been activated, call the setup handler with
392 			 * the deactivate notification
393 			 */
394 			if (region_obj->region.flags & AOPOBJ_SETUP_COMPLETE) {
395 				region_setup = handler_obj->address_space.setup;
396 				status =
397 				    region_setup(region_obj,
398 						 ACPI_REGION_DEACTIVATE,
399 						 handler_obj->address_space.
400 						 context, region_context);
401 
402 				/*
403 				 * region_context should have been released by the deactivate
404 				 * operation. We don't need access to it anymore here.
405 				 */
406 				if (region_context) {
407 					*region_context = NULL;
408 				}
409 
410 				/* Init routine may fail, Just ignore errors */
411 
412 				if (ACPI_FAILURE(status)) {
413 					ACPI_EXCEPTION((AE_INFO, status,
414 							"from region handler - deactivate, [%s]",
415 							acpi_ut_get_region_name
416 							(region_obj->region.
417 							 space_id)));
418 				}
419 
420 				region_obj->region.flags &=
421 				    ~(AOPOBJ_SETUP_COMPLETE);
422 			}
423 
424 			/*
425 			 * Remove handler reference in the region
426 			 *
427 			 * NOTE: this doesn't mean that the region goes away, the region
428 			 * is just inaccessible as indicated to the _REG method
429 			 *
430 			 * If the region is on the handler's list, this must be the
431 			 * region's handler
432 			 */
433 			region_obj->region.handler = NULL;
434 			acpi_ut_remove_reference(handler_obj);
435 
436 			return_VOID;
437 		}
438 
439 		/* Walk the linked list of handlers */
440 
441 		last_obj_ptr = &obj_desc->region.next;
442 		obj_desc = obj_desc->region.next;
443 
444 		/* Prevent infinite loop if list is corrupted */
445 
446 		if (obj_desc == start_desc) {
447 			ACPI_ERROR((AE_INFO,
448 				    "Circular handler list in region object %p",
449 				    region_obj));
450 			return_VOID;
451 		}
452 	}
453 
454 	/* If we get here, the region was not in the handler's region list */
455 
456 	ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
457 			  "Cannot remove region %p from address handler %p\n",
458 			  region_obj, handler_obj));
459 
460 	return_VOID;
461 }
462 
463 /*******************************************************************************
464  *
465  * FUNCTION:    acpi_ev_attach_region
466  *
467  * PARAMETERS:  handler_obj         - Handler Object
468  *              region_obj          - Region Object
469  *              acpi_ns_is_locked   - Namespace Region Already Locked?
470  *
471  * RETURN:      None
472  *
473  * DESCRIPTION: Create the association between the handler and the region
474  *              this is a two way association.
475  *
476  ******************************************************************************/
477 
478 acpi_status
479 acpi_ev_attach_region(union acpi_operand_object *handler_obj,
480 		      union acpi_operand_object *region_obj,
481 		      u8 acpi_ns_is_locked)
482 {
483 
484 	ACPI_FUNCTION_TRACE(ev_attach_region);
485 
486 	ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
487 			  "Adding Region [%4.4s] %p to address handler %p [%s]\n",
488 			  acpi_ut_get_node_name(region_obj->region.node),
489 			  region_obj, handler_obj,
490 			  acpi_ut_get_region_name(region_obj->region.
491 						  space_id)));
492 
493 	/* Link this region to the front of the handler's list */
494 
495 	region_obj->region.next = handler_obj->address_space.region_list;
496 	handler_obj->address_space.region_list = region_obj;
497 
498 	/* Install the region's handler */
499 
500 	if (region_obj->region.handler) {
501 		return_ACPI_STATUS(AE_ALREADY_EXISTS);
502 	}
503 
504 	region_obj->region.handler = handler_obj;
505 	acpi_ut_add_reference(handler_obj);
506 
507 	return_ACPI_STATUS(AE_OK);
508 }
509 
510 /*******************************************************************************
511  *
512  * FUNCTION:    acpi_ev_execute_reg_method
513  *
514  * PARAMETERS:  region_obj          - Region object
515  *              function            - Passed to _REG: On (1) or Off (0)
516  *
517  * RETURN:      Status
518  *
519  * DESCRIPTION: Execute _REG method for a region
520  *
521  ******************************************************************************/
522 
523 acpi_status
524 acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function)
525 {
526 	struct acpi_evaluate_info *info;
527 	union acpi_operand_object *args[3];
528 	union acpi_operand_object *region_obj2;
529 	acpi_status status;
530 
531 	ACPI_FUNCTION_TRACE(ev_execute_reg_method);
532 
533 	region_obj2 = acpi_ns_get_secondary_object(region_obj);
534 	if (!region_obj2) {
535 		return_ACPI_STATUS(AE_NOT_EXIST);
536 	}
537 
538 	if (region_obj2->extra.method_REG == NULL) {
539 		return_ACPI_STATUS(AE_OK);
540 	}
541 
542 	/* Allocate and initialize the evaluation information block */
543 
544 	info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
545 	if (!info) {
546 		return_ACPI_STATUS(AE_NO_MEMORY);
547 	}
548 
549 	info->prefix_node = region_obj2->extra.method_REG;
550 	info->relative_pathname = NULL;
551 	info->parameters = args;
552 	info->flags = ACPI_IGNORE_RETURN_VALUE;
553 
554 	/*
555 	 * The _REG method has two arguments:
556 	 *
557 	 * arg0 - Integer:
558 	 *  Operation region space ID Same value as region_obj->Region.space_id
559 	 *
560 	 * arg1 - Integer:
561 	 *  connection status 1 for connecting the handler, 0 for disconnecting
562 	 *  the handler (Passed as a parameter)
563 	 */
564 	args[0] =
565 	    acpi_ut_create_integer_object((u64)region_obj->region.space_id);
566 	if (!args[0]) {
567 		status = AE_NO_MEMORY;
568 		goto cleanup1;
569 	}
570 
571 	args[1] = acpi_ut_create_integer_object((u64)function);
572 	if (!args[1]) {
573 		status = AE_NO_MEMORY;
574 		goto cleanup2;
575 	}
576 
577 	args[2] = NULL;		/* Terminate list */
578 
579 	/* Execute the method, no return value */
580 
581 	ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname
582 			(ACPI_TYPE_METHOD, info->prefix_node, NULL));
583 
584 	status = acpi_ns_evaluate(info);
585 	acpi_ut_remove_reference(args[1]);
586 
587 cleanup2:
588 	acpi_ut_remove_reference(args[0]);
589 
590 cleanup1:
591 	ACPI_FREE(info);
592 	return_ACPI_STATUS(status);
593 }
594 
595 /*******************************************************************************
596  *
597  * FUNCTION:    acpi_ev_execute_reg_methods
598  *
599  * PARAMETERS:  node            - Namespace node for the device
600  *              space_id        - The address space ID
601  *
602  * RETURN:      Status
603  *
604  * DESCRIPTION: Run all _REG methods for the input Space ID;
605  *              Note: assumes namespace is locked, or system init time.
606  *
607  ******************************************************************************/
608 
609 acpi_status
610 acpi_ev_execute_reg_methods(struct acpi_namespace_node *node,
611 			    acpi_adr_space_type space_id)
612 {
613 	acpi_status status;
614 
615 	ACPI_FUNCTION_TRACE(ev_execute_reg_methods);
616 
617 	/*
618 	 * Run all _REG methods for all Operation Regions for this space ID. This
619 	 * is a separate walk in order to handle any interdependencies between
620 	 * regions and _REG methods. (i.e. handlers must be installed for all
621 	 * regions of this Space ID before we can run any _REG methods)
622 	 */
623 	status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, node, ACPI_UINT32_MAX,
624 					ACPI_NS_WALK_UNLOCK, acpi_ev_reg_run,
625 					NULL, &space_id, NULL);
626 
627 	/* Special case for EC: handle "orphan" _REG methods with no region */
628 
629 	if (space_id == ACPI_ADR_SPACE_EC) {
630 		acpi_ev_orphan_ec_reg_method(node);
631 	}
632 
633 	return_ACPI_STATUS(status);
634 }
635 
636 /*******************************************************************************
637  *
638  * FUNCTION:    acpi_ev_reg_run
639  *
640  * PARAMETERS:  walk_namespace callback
641  *
642  * DESCRIPTION: Run _REG method for region objects of the requested spaceID
643  *
644  ******************************************************************************/
645 
646 static acpi_status
647 acpi_ev_reg_run(acpi_handle obj_handle,
648 		u32 level, void *context, void **return_value)
649 {
650 	union acpi_operand_object *obj_desc;
651 	struct acpi_namespace_node *node;
652 	acpi_adr_space_type space_id;
653 	acpi_status status;
654 
655 	space_id = *ACPI_CAST_PTR(acpi_adr_space_type, context);
656 
657 	/* Convert and validate the device handle */
658 
659 	node = acpi_ns_validate_handle(obj_handle);
660 	if (!node) {
661 		return (AE_BAD_PARAMETER);
662 	}
663 
664 	/*
665 	 * We only care about regions.and objects that are allowed to have address
666 	 * space handlers
667 	 */
668 	if ((node->type != ACPI_TYPE_REGION) && (node != acpi_gbl_root_node)) {
669 		return (AE_OK);
670 	}
671 
672 	/* Check for an existing internal object */
673 
674 	obj_desc = acpi_ns_get_attached_object(node);
675 	if (!obj_desc) {
676 
677 		/* No object, just exit */
678 
679 		return (AE_OK);
680 	}
681 
682 	/* Object is a Region */
683 
684 	if (obj_desc->region.space_id != space_id) {
685 
686 		/* This region is for a different address space, just ignore it */
687 
688 		return (AE_OK);
689 	}
690 
691 	status = acpi_ev_execute_reg_method(obj_desc, ACPI_REG_CONNECT);
692 	return (status);
693 }
694 
695 /*******************************************************************************
696  *
697  * FUNCTION:    acpi_ev_orphan_ec_reg_method
698  *
699  * PARAMETERS:  ec_device_node      - Namespace node for an EC device
700  *
701  * RETURN:      None
702  *
703  * DESCRIPTION: Execute an "orphan" _REG method that appears under the EC
704  *              device. This is a _REG method that has no corresponding region
705  *              within the EC device scope. The orphan _REG method appears to
706  *              have been enabled by the description of the ECDT in the ACPI
707  *              specification: "The availability of the region space can be
708  *              detected by providing a _REG method object underneath the
709  *              Embedded Controller device."
710  *
711  *              To quickly access the EC device, we use the ec_device_node used
712  *              during EC handler installation. Otherwise, we would need to
713  *              perform a time consuming namespace walk, executing _HID
714  *              methods to find the EC device.
715  *
716  *  MUTEX:      Assumes the namespace is locked
717  *
718  ******************************************************************************/
719 
720 static void
721 acpi_ev_orphan_ec_reg_method(struct acpi_namespace_node *ec_device_node)
722 {
723 	acpi_handle reg_method;
724 	struct acpi_namespace_node *next_node;
725 	acpi_status status;
726 	struct acpi_object_list args;
727 	union acpi_object objects[2];
728 
729 	ACPI_FUNCTION_TRACE(ev_orphan_ec_reg_method);
730 
731 	if (!ec_device_node) {
732 		return_VOID;
733 	}
734 
735 	/* Namespace is currently locked, must release */
736 
737 	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
738 
739 	/* Get a handle to a _REG method immediately under the EC device */
740 
741 	status = acpi_get_handle(ec_device_node, METHOD_NAME__REG, &reg_method);
742 	if (ACPI_FAILURE(status)) {
743 		goto exit;	/* There is no _REG method present */
744 	}
745 
746 	/*
747 	 * Execute the _REG method only if there is no Operation Region in
748 	 * this scope with the Embedded Controller space ID. Otherwise, it
749 	 * will already have been executed. Note, this allows for Regions
750 	 * with other space IDs to be present; but the code below will then
751 	 * execute the _REG method with the embedded_control space_ID argument.
752 	 */
753 	next_node = acpi_ns_get_next_node(ec_device_node, NULL);
754 	while (next_node) {
755 		if ((next_node->type == ACPI_TYPE_REGION) &&
756 		    (next_node->object) &&
757 		    (next_node->object->region.space_id == ACPI_ADR_SPACE_EC)) {
758 			goto exit;	/* Do not execute the _REG */
759 		}
760 
761 		next_node = acpi_ns_get_next_node(ec_device_node, next_node);
762 	}
763 
764 	/* Evaluate the _REG(embedded_control,Connect) method */
765 
766 	args.count = 2;
767 	args.pointer = objects;
768 	objects[0].type = ACPI_TYPE_INTEGER;
769 	objects[0].integer.value = ACPI_ADR_SPACE_EC;
770 	objects[1].type = ACPI_TYPE_INTEGER;
771 	objects[1].integer.value = ACPI_REG_CONNECT;
772 
773 	status = acpi_evaluate_object(reg_method, NULL, &args, NULL);
774 
775 exit:
776 	/* We ignore all errors from above, don't care */
777 
778 	status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
779 	return_VOID;
780 }
781