11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/******************************************************************************
21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Module Name: evrgnini- ACPI address_space (op_region) init
41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *****************************************************************************/
61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
8fbb7a2dc2be493c87399550bdc2ddaa510cdf450Bob Moore * Copyright (C) 2000 - 2014, Intel Corp.
91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * All rights reserved.
101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Redistribution and use in source and binary forms, with or without
121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * modification, are permitted provided that the following conditions
131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * are met:
141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1. Redistributions of source code must retain the above copyright
151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    notice, this list of conditions, and the following disclaimer,
161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    without modification.
171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2. Redistributions in binary form must reproduce at minimum a disclaimer
181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    substantially similar to the "NO WARRANTY" disclaimer below
191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    ("Disclaimer") and any redistribution must be conditioned upon
201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    including a substantially similar Disclaimer requirement for further
211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    binary redistribution.
221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 3. Neither the names of the above-listed copyright holders nor the names
231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    of any contributors may be used to endorse or promote products derived
241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    from this software without specific prior written permission.
251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Alternatively, this software may be distributed under the terms of the
271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * GNU General Public License ("GPL") version 2 as published by the Free
281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Software Foundation.
291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * NO WARRANTY
311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * POSSIBILITY OF SUCH DAMAGES.
421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <acpi/acpi.h>
45e2f7a7772880458edff1b1cc5a988947229fac26Len Brown#include "accommon.h"
46e2f7a7772880458edff1b1cc5a988947229fac26Len Brown#include "acevents.h"
47e2f7a7772880458edff1b1cc5a988947229fac26Len Brown#include "acnamesp.h"
481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define _COMPONENT          ACPI_EVENTS
504be44fcd3bf648b782f4460fd06dfae6c42ded4bLen BrownACPI_MODULE_NAME("evrgnini")
511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
52b7a69806308600711589e4ca306d18dd029ef0cfBob Moore/* Local prototypes */
53b7a69806308600711589e4ca306d18dd029ef0cfBob Moorestatic u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node);
54b7a69806308600711589e4ca306d18dd029ef0cfBob Moore
551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*******************************************************************************
561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * FUNCTION:    acpi_ev_system_memory_region_setup
581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
59ba494beeaa69bc0fb01eb89464ad5d57d26e3901Bob Moore * PARAMETERS:  handle              - Region we are interested in
60ba494beeaa69bc0fb01eb89464ad5d57d26e3901Bob Moore *              function            - Start or stop
611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              handler_context     - Address space handler context
621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              region_context      - Region specific context
631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * RETURN:      Status
651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
6644f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore * DESCRIPTION: Setup a system_memory operation region
671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ******************************************************************************/
69b7a69806308600711589e4ca306d18dd029ef0cfBob Moore
701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsacpi_status
714be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brownacpi_ev_system_memory_region_setup(acpi_handle handle,
724be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown				   u32 function,
734be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown				   void *handler_context, void **region_context)
741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
754be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	union acpi_operand_object *region_desc =
764be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	    (union acpi_operand_object *)handle;
774be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	struct acpi_mem_space_context *local_region_context;
781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
79b229cf92eee616c7cb5ad8cdb35a19b119f00bc8Bob Moore	ACPI_FUNCTION_TRACE(ev_system_memory_region_setup);
801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (function == ACPI_REGION_DEACTIVATE) {
821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (*region_context) {
83793c2388cae3fd023b3b5166354931752d42353cBob Moore			local_region_context =
84793c2388cae3fd023b3b5166354931752d42353cBob Moore			    (struct acpi_mem_space_context *)*region_context;
85793c2388cae3fd023b3b5166354931752d42353cBob Moore
86793c2388cae3fd023b3b5166354931752d42353cBob Moore			/* Delete a cached mapping if present */
87793c2388cae3fd023b3b5166354931752d42353cBob Moore
88793c2388cae3fd023b3b5166354931752d42353cBob Moore			if (local_region_context->mapped_length) {
89793c2388cae3fd023b3b5166354931752d42353cBob Moore				acpi_os_unmap_memory(local_region_context->
90793c2388cae3fd023b3b5166354931752d42353cBob Moore						     mapped_logical_address,
91793c2388cae3fd023b3b5166354931752d42353cBob Moore						     local_region_context->
92793c2388cae3fd023b3b5166354931752d42353cBob Moore						     mapped_length);
93793c2388cae3fd023b3b5166354931752d42353cBob Moore			}
94793c2388cae3fd023b3b5166354931752d42353cBob Moore			ACPI_FREE(local_region_context);
951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			*region_context = NULL;
961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
974be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		return_ACPI_STATUS(AE_OK);
981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Create a new context */
1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1024be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	local_region_context =
1038313524a0d466f451a62709aaedf988d8257b21cBob Moore	    ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_mem_space_context));
1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!(local_region_context)) {
1054be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		return_ACPI_STATUS(AE_NO_MEMORY);
1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Save the region length and address for use in the handler */
1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	local_region_context->length = region_desc->region.length;
1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	local_region_context->address = region_desc->region.address;
1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*region_context = local_region_context;
1144be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	return_ACPI_STATUS(AE_OK);
1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*******************************************************************************
1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * FUNCTION:    acpi_ev_io_space_region_setup
1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
121ba494beeaa69bc0fb01eb89464ad5d57d26e3901Bob Moore * PARAMETERS:  handle              - Region we are interested in
122ba494beeaa69bc0fb01eb89464ad5d57d26e3901Bob Moore *              function            - Start or stop
1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              handler_context     - Address space handler context
1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              region_context      - Region specific context
1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * RETURN:      Status
1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
12844f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore * DESCRIPTION: Setup a IO operation region
1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ******************************************************************************/
1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsacpi_status
1334be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brownacpi_ev_io_space_region_setup(acpi_handle handle,
1344be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown			      u32 function,
1354be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown			      void *handler_context, void **region_context)
1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
137b229cf92eee616c7cb5ad8cdb35a19b119f00bc8Bob Moore	ACPI_FUNCTION_TRACE(ev_io_space_region_setup);
1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (function == ACPI_REGION_DEACTIVATE) {
1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		*region_context = NULL;
1414be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	} else {
1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		*region_context = handler_context;
1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1454be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	return_ACPI_STATUS(AE_OK);
1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*******************************************************************************
1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * FUNCTION:    acpi_ev_pci_config_region_setup
1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
152ba494beeaa69bc0fb01eb89464ad5d57d26e3901Bob Moore * PARAMETERS:  handle              - Region we are interested in
153ba494beeaa69bc0fb01eb89464ad5d57d26e3901Bob Moore *              function            - Start or stop
1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              handler_context     - Address space handler context
1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              region_context      - Region specific context
1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * RETURN:      Status
1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
15944f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore * DESCRIPTION: Setup a PCI_Config operation region
1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * MUTEX:       Assumes namespace is not locked
1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ******************************************************************************/
1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsacpi_status
1664be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brownacpi_ev_pci_config_region_setup(acpi_handle handle,
1674be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown				u32 function,
1684be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown				void *handler_context, void **region_context)
1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1704be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	acpi_status status = AE_OK;
1715df7e6cb42da36c7d878239bebc81907b15f3943Bob Moore	u64 pci_value;
1724be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	struct acpi_pci_id *pci_id = *region_context;
1734be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	union acpi_operand_object *handler_obj;
1744be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	struct acpi_namespace_node *parent_node;
1754be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	struct acpi_namespace_node *pci_root_node;
176b7a69806308600711589e4ca306d18dd029ef0cfBob Moore	struct acpi_namespace_node *pci_device_node;
1774be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	union acpi_operand_object *region_obj =
1784be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	    (union acpi_operand_object *)handle;
1794be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown
180b229cf92eee616c7cb5ad8cdb35a19b119f00bc8Bob Moore	ACPI_FUNCTION_TRACE(ev_pci_config_region_setup);
1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	handler_obj = region_obj->region.handler;
1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!handler_obj) {
1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/*
1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * No installed handler. This shouldn't happen because the dispatch
1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * routine checks before we get here, but we check again just in case.
1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 */
1884be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
1894be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown				  "Attempting to init a region %p, with no handler\n",
1904be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown				  region_obj));
1914be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		return_ACPI_STATUS(AE_NOT_EXIST);
1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*region_context = NULL;
1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (function == ACPI_REGION_DEACTIVATE) {
1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (pci_id) {
1978313524a0d466f451a62709aaedf988d8257b21cBob Moore			ACPI_FREE(pci_id);
1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
1994be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		return_ACPI_STATUS(status);
2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
202c45b5c097001480e66d4c523eb715ad317a4ef77Alexey Starikovskiy	parent_node = region_obj->region.node->parent;
2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * Get the _SEG and _BBN values from the device upon which the handler
2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * is installed.
2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 *
2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * We need to get the _SEG and _BBN objects relative to the PCI BUS device.
2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * This is the device the handler has been registered to handle.
2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * If the address_space.Node is still pointing to the root, we need
2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * to scan upward for a PCI Root bridge and re-associate the op_region
2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * handlers with that device.
2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (handler_obj->address_space.node == acpi_gbl_root_node) {
21852fc0b026e99b5d5d585095148d997d5634bbc25Bob Moore
2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* Start search from the parent object */
2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		pci_root_node = parent_node;
2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		while (pci_root_node != acpi_gbl_root_node) {
223b7a69806308600711589e4ca306d18dd029ef0cfBob Moore
224b7a69806308600711589e4ca306d18dd029ef0cfBob Moore			/* Get the _HID/_CID in order to detect a root_bridge */
225b7a69806308600711589e4ca306d18dd029ef0cfBob Moore
226b7a69806308600711589e4ca306d18dd029ef0cfBob Moore			if (acpi_ev_is_pci_root_bridge(pci_root_node)) {
227b7a69806308600711589e4ca306d18dd029ef0cfBob Moore
228b7a69806308600711589e4ca306d18dd029ef0cfBob Moore				/* Install a handler for this PCI root bridge */
229b7a69806308600711589e4ca306d18dd029ef0cfBob Moore
2301f86e8c1c9f129d450fd75e42d25ddba69a522acLv Zheng				status = acpi_install_address_space_handler((acpi_handle) pci_root_node, ACPI_ADR_SPACE_PCI_CONFIG, ACPI_DEFAULT_HANDLER, NULL, NULL);
231b7a69806308600711589e4ca306d18dd029ef0cfBob Moore				if (ACPI_FAILURE(status)) {
232b7a69806308600711589e4ca306d18dd029ef0cfBob Moore					if (status == AE_SAME_HANDLER) {
233b7a69806308600711589e4ca306d18dd029ef0cfBob Moore						/*
2349f15fc666ef54afc7aff31dfa31edecf00e0d81aBob Moore						 * It is OK if the handler is already installed on the
2359f15fc666ef54afc7aff31dfa31edecf00e0d81aBob Moore						 * root bridge. Still need to return a context object
2369f15fc666ef54afc7aff31dfa31edecf00e0d81aBob Moore						 * for the new PCI_Config operation region, however.
237b7a69806308600711589e4ca306d18dd029ef0cfBob Moore						 */
238b7a69806308600711589e4ca306d18dd029ef0cfBob Moore						status = AE_OK;
239b7a69806308600711589e4ca306d18dd029ef0cfBob Moore					} else {
240b7a69806308600711589e4ca306d18dd029ef0cfBob Moore						ACPI_EXCEPTION((AE_INFO, status,
241d4913dc6d0c680aa106d1d80b5ad2a9325367afdBob Moore								"Could not install PciConfig handler "
242d4913dc6d0c680aa106d1d80b5ad2a9325367afdBob Moore								"for Root Bridge %4.4s",
243b7a69806308600711589e4ca306d18dd029ef0cfBob Moore								acpi_ut_get_node_name
244b7a69806308600711589e4ca306d18dd029ef0cfBob Moore								(pci_root_node)));
2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					}
2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				}
247b7a69806308600711589e4ca306d18dd029ef0cfBob Moore				break;
2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
250c45b5c097001480e66d4c523eb715ad317a4ef77Alexey Starikovskiy			pci_root_node = pci_root_node->parent;
2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* PCI root bridge not found, use namespace root node */
2544be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	} else {
2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		pci_root_node = handler_obj->address_space.node;
2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * If this region is now initialized, we are done.
2601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * (install_address_space_handler could have initialized it)
2611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (region_obj->region.flags & AOPOBJ_SETUP_COMPLETE) {
2634be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		return_ACPI_STATUS(AE_OK);
2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Region is still not initialized. Create a new context */
2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2688313524a0d466f451a62709aaedf988d8257b21cBob Moore	pci_id = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_pci_id));
2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!pci_id) {
2704be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		return_ACPI_STATUS(AE_NO_MEMORY);
2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
2749f15fc666ef54afc7aff31dfa31edecf00e0d81aBob Moore	 * For PCI_Config space access, we need the segment, bus, device and
2759f15fc666ef54afc7aff31dfa31edecf00e0d81aBob Moore	 * function numbers. Acquire them here.
276b7a69806308600711589e4ca306d18dd029ef0cfBob Moore	 *
277b7a69806308600711589e4ca306d18dd029ef0cfBob Moore	 * Find the parent device object. (This allows the operation region to be
278b7a69806308600711589e4ca306d18dd029ef0cfBob Moore	 * within a subscope under the device, such as a control method.)
2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
280b7a69806308600711589e4ca306d18dd029ef0cfBob Moore	pci_device_node = region_obj->region.node;
281b7a69806308600711589e4ca306d18dd029ef0cfBob Moore	while (pci_device_node && (pci_device_node->type != ACPI_TYPE_DEVICE)) {
282c45b5c097001480e66d4c523eb715ad317a4ef77Alexey Starikovskiy		pci_device_node = pci_device_node->parent;
283b7a69806308600711589e4ca306d18dd029ef0cfBob Moore	}
284b7a69806308600711589e4ca306d18dd029ef0cfBob Moore
285b7a69806308600711589e4ca306d18dd029ef0cfBob Moore	if (!pci_device_node) {
286e6917317c0f6a930442c40dc38a6f21710adf961Jesper Juhl		ACPI_FREE(pci_id);
287b7a69806308600711589e4ca306d18dd029ef0cfBob Moore		return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
288b7a69806308600711589e4ca306d18dd029ef0cfBob Moore	}
2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
29195abccb576c44bc593e05fa1245d0ad26ce6107bBob Moore	 * Get the PCI device and function numbers from the _ADR object
29295abccb576c44bc593e05fa1245d0ad26ce6107bBob Moore	 * contained in the parent's scope.
2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
294d4913dc6d0c680aa106d1d80b5ad2a9325367afdBob Moore	status = acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR,
295d4913dc6d0c680aa106d1d80b5ad2a9325367afdBob Moore						 pci_device_node, &pci_value);
2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
2989f15fc666ef54afc7aff31dfa31edecf00e0d81aBob Moore	 * The default is zero, and since the allocation above zeroed the data,
2999f15fc666ef54afc7aff31dfa31edecf00e0d81aBob Moore	 * just do nothing on failure.
3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
3014be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	if (ACPI_SUCCESS(status)) {
3024be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		pci_id->device = ACPI_HIWORD(ACPI_LODWORD(pci_value));
3034be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		pci_id->function = ACPI_LOWORD(ACPI_LODWORD(pci_value));
3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* The PCI segment number comes from the _SEG method */
3071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
308d4913dc6d0c680aa106d1d80b5ad2a9325367afdBob Moore	status = acpi_ut_evaluate_numeric_object(METHOD_NAME__SEG,
309d4913dc6d0c680aa106d1d80b5ad2a9325367afdBob Moore						 pci_root_node, &pci_value);
3104be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	if (ACPI_SUCCESS(status)) {
3114be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		pci_id->segment = ACPI_LOWORD(pci_value);
3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* The PCI bus number comes from the _BBN method */
3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
316d4913dc6d0c680aa106d1d80b5ad2a9325367afdBob Moore	status = acpi_ut_evaluate_numeric_object(METHOD_NAME__BBN,
317d4913dc6d0c680aa106d1d80b5ad2a9325367afdBob Moore						 pci_root_node, &pci_value);
3184be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	if (ACPI_SUCCESS(status)) {
3194be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		pci_id->bus = ACPI_LOWORD(pci_value);
3201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
32295abccb576c44bc593e05fa1245d0ad26ce6107bBob Moore	/* Complete/update the PCI ID for this device */
3231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
32495abccb576c44bc593e05fa1245d0ad26ce6107bBob Moore	status =
32595abccb576c44bc593e05fa1245d0ad26ce6107bBob Moore	    acpi_hw_derive_pci_id(pci_id, pci_root_node,
32695abccb576c44bc593e05fa1245d0ad26ce6107bBob Moore				  region_obj->region.node);
32795abccb576c44bc593e05fa1245d0ad26ce6107bBob Moore	if (ACPI_FAILURE(status)) {
32895abccb576c44bc593e05fa1245d0ad26ce6107bBob Moore		ACPI_FREE(pci_id);
32995abccb576c44bc593e05fa1245d0ad26ce6107bBob Moore		return_ACPI_STATUS(status);
33095abccb576c44bc593e05fa1245d0ad26ce6107bBob Moore	}
3311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*region_context = pci_id;
3334be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	return_ACPI_STATUS(AE_OK);
3341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*******************************************************************************
337b7a69806308600711589e4ca306d18dd029ef0cfBob Moore *
338b7a69806308600711589e4ca306d18dd029ef0cfBob Moore * FUNCTION:    acpi_ev_is_pci_root_bridge
339b7a69806308600711589e4ca306d18dd029ef0cfBob Moore *
340ba494beeaa69bc0fb01eb89464ad5d57d26e3901Bob Moore * PARAMETERS:  node            - Device node being examined
341b7a69806308600711589e4ca306d18dd029ef0cfBob Moore *
342b7a69806308600711589e4ca306d18dd029ef0cfBob Moore * RETURN:      TRUE if device is a PCI/PCI-Express Root Bridge
343b7a69806308600711589e4ca306d18dd029ef0cfBob Moore *
344b7a69806308600711589e4ca306d18dd029ef0cfBob Moore * DESCRIPTION: Determine if the input device represents a PCI Root Bridge by
345b7a69806308600711589e4ca306d18dd029ef0cfBob Moore *              examining the _HID and _CID for the device.
346b7a69806308600711589e4ca306d18dd029ef0cfBob Moore *
347b7a69806308600711589e4ca306d18dd029ef0cfBob Moore ******************************************************************************/
348b7a69806308600711589e4ca306d18dd029ef0cfBob Moore
349b7a69806308600711589e4ca306d18dd029ef0cfBob Moorestatic u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node)
350b7a69806308600711589e4ca306d18dd029ef0cfBob Moore{
351b7a69806308600711589e4ca306d18dd029ef0cfBob Moore	acpi_status status;
35278e25fef2751434f38c7f711ecbf8762f79f7318Lv Zheng	struct acpi_pnp_device_id *hid;
35378e25fef2751434f38c7f711ecbf8762f79f7318Lv Zheng	struct acpi_pnp_device_id_list *cid;
35467a119f990063f5662574f6d6414fe9bc5ece86aBob Moore	u32 i;
35515b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	u8 match;
356b7a69806308600711589e4ca306d18dd029ef0cfBob Moore
3579f15fc666ef54afc7aff31dfa31edecf00e0d81aBob Moore	/* Get the _HID and check for a PCI Root Bridge */
3589f15fc666ef54afc7aff31dfa31edecf00e0d81aBob Moore
359b7a69806308600711589e4ca306d18dd029ef0cfBob Moore	status = acpi_ut_execute_HID(node, &hid);
360b7a69806308600711589e4ca306d18dd029ef0cfBob Moore	if (ACPI_FAILURE(status)) {
361b7a69806308600711589e4ca306d18dd029ef0cfBob Moore		return (FALSE);
362b7a69806308600711589e4ca306d18dd029ef0cfBob Moore	}
363b7a69806308600711589e4ca306d18dd029ef0cfBob Moore
36415b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	match = acpi_ut_is_pci_root_bridge(hid->string);
36515b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	ACPI_FREE(hid);
36615b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore
36715b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	if (match) {
368b7a69806308600711589e4ca306d18dd029ef0cfBob Moore		return (TRUE);
369b7a69806308600711589e4ca306d18dd029ef0cfBob Moore	}
370b7a69806308600711589e4ca306d18dd029ef0cfBob Moore
3719f15fc666ef54afc7aff31dfa31edecf00e0d81aBob Moore	/* The _HID did not match. Get the _CID and check for a PCI Root Bridge */
3729f15fc666ef54afc7aff31dfa31edecf00e0d81aBob Moore
373b7a69806308600711589e4ca306d18dd029ef0cfBob Moore	status = acpi_ut_execute_CID(node, &cid);
374b7a69806308600711589e4ca306d18dd029ef0cfBob Moore	if (ACPI_FAILURE(status)) {
375b7a69806308600711589e4ca306d18dd029ef0cfBob Moore		return (FALSE);
376b7a69806308600711589e4ca306d18dd029ef0cfBob Moore	}
377b7a69806308600711589e4ca306d18dd029ef0cfBob Moore
378b7a69806308600711589e4ca306d18dd029ef0cfBob Moore	/* Check all _CIDs in the returned list */
379b7a69806308600711589e4ca306d18dd029ef0cfBob Moore
380b7a69806308600711589e4ca306d18dd029ef0cfBob Moore	for (i = 0; i < cid->count; i++) {
38115b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore		if (acpi_ut_is_pci_root_bridge(cid->ids[i].string)) {
382b7a69806308600711589e4ca306d18dd029ef0cfBob Moore			ACPI_FREE(cid);
383b7a69806308600711589e4ca306d18dd029ef0cfBob Moore			return (TRUE);
384b7a69806308600711589e4ca306d18dd029ef0cfBob Moore		}
385b7a69806308600711589e4ca306d18dd029ef0cfBob Moore	}
386b7a69806308600711589e4ca306d18dd029ef0cfBob Moore
387b7a69806308600711589e4ca306d18dd029ef0cfBob Moore	ACPI_FREE(cid);
388b7a69806308600711589e4ca306d18dd029ef0cfBob Moore	return (FALSE);
389b7a69806308600711589e4ca306d18dd029ef0cfBob Moore}
390b7a69806308600711589e4ca306d18dd029ef0cfBob Moore
391b7a69806308600711589e4ca306d18dd029ef0cfBob Moore/*******************************************************************************
3921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
3931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * FUNCTION:    acpi_ev_pci_bar_region_setup
3941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
395ba494beeaa69bc0fb01eb89464ad5d57d26e3901Bob Moore * PARAMETERS:  handle              - Region we are interested in
396ba494beeaa69bc0fb01eb89464ad5d57d26e3901Bob Moore *              function            - Start or stop
3971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              handler_context     - Address space handler context
3981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              region_context      - Region specific context
3991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
4001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * RETURN:      Status
4011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
402ba494beeaa69bc0fb01eb89464ad5d57d26e3901Bob Moore * DESCRIPTION: Setup a pci_BAR operation region
4031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
4041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * MUTEX:       Assumes namespace is not locked
4051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
4061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ******************************************************************************/
4071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsacpi_status
4094be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brownacpi_ev_pci_bar_region_setup(acpi_handle handle,
4104be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown			     u32 function,
4114be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown			     void *handler_context, void **region_context)
4121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
413b229cf92eee616c7cb5ad8cdb35a19b119f00bc8Bob Moore	ACPI_FUNCTION_TRACE(ev_pci_bar_region_setup);
4141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4154be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	return_ACPI_STATUS(AE_OK);
4161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
4171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*******************************************************************************
4191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
4201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * FUNCTION:    acpi_ev_cmos_region_setup
4211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
422ba494beeaa69bc0fb01eb89464ad5d57d26e3901Bob Moore * PARAMETERS:  handle              - Region we are interested in
423ba494beeaa69bc0fb01eb89464ad5d57d26e3901Bob Moore *              function            - Start or stop
4241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              handler_context     - Address space handler context
4251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              region_context      - Region specific context
4261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
4271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * RETURN:      Status
4281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
42944f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore * DESCRIPTION: Setup a CMOS operation region
4301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
4311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * MUTEX:       Assumes namespace is not locked
4321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
4331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ******************************************************************************/
4341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsacpi_status
4364be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brownacpi_ev_cmos_region_setup(acpi_handle handle,
4374be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown			  u32 function,
4384be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown			  void *handler_context, void **region_context)
4391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
440b229cf92eee616c7cb5ad8cdb35a19b119f00bc8Bob Moore	ACPI_FUNCTION_TRACE(ev_cmos_region_setup);
4411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4424be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	return_ACPI_STATUS(AE_OK);
4431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
4441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*******************************************************************************
4461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
4471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * FUNCTION:    acpi_ev_default_region_setup
4481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
449ba494beeaa69bc0fb01eb89464ad5d57d26e3901Bob Moore * PARAMETERS:  handle              - Region we are interested in
450ba494beeaa69bc0fb01eb89464ad5d57d26e3901Bob Moore *              function            - Start or stop
4511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              handler_context     - Address space handler context
4521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              region_context      - Region specific context
4531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
4541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * RETURN:      Status
4551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
45644f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore * DESCRIPTION: Default region initialization
4571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
4581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ******************************************************************************/
4591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsacpi_status
4614be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brownacpi_ev_default_region_setup(acpi_handle handle,
4624be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown			     u32 function,
4634be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown			     void *handler_context, void **region_context)
4641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
465b229cf92eee616c7cb5ad8cdb35a19b119f00bc8Bob Moore	ACPI_FUNCTION_TRACE(ev_default_region_setup);
4661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (function == ACPI_REGION_DEACTIVATE) {
4681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		*region_context = NULL;
4694be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	} else {
4701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		*region_context = handler_context;
4711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
4721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4734be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	return_ACPI_STATUS(AE_OK);
4741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
4751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*******************************************************************************
4771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
4781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * FUNCTION:    acpi_ev_initialize_region
4791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
4801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * PARAMETERS:  region_obj      - Region we are initializing
4811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              acpi_ns_locked  - Is namespace locked?
4821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
4831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * RETURN:      Status
4841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
4851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * DESCRIPTION: Initializes the region, finds any _REG methods and saves them
4861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              for execution at a later time
4871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
4881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              Get the appropriate address space handler for a newly
4891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              created region.
4901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
4919f15fc666ef54afc7aff31dfa31edecf00e0d81aBob Moore *              This also performs address space specific initialization. For
4921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              example, PCI regions must have an _ADR object that contains
4939f15fc666ef54afc7aff31dfa31edecf00e0d81aBob Moore *              a PCI address in the scope of the definition. This address is
4941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              required to perform an access to PCI config space.
4951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
496c9e3ba2c1d178195e17bb4f1d49c32e0be8dbb16Bob Moore * MUTEX:       Interpreter should be unlocked, because we may run the _REG
497c9e3ba2c1d178195e17bb4f1d49c32e0be8dbb16Bob Moore *              method for this region.
498c9e3ba2c1d178195e17bb4f1d49c32e0be8dbb16Bob Moore *
4991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ******************************************************************************/
5001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsacpi_status
5024be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brownacpi_ev_initialize_region(union acpi_operand_object *region_obj,
5034be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown			  u8 acpi_ns_locked)
5041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
5054be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	union acpi_operand_object *handler_obj;
5064be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	union acpi_operand_object *obj_desc;
5074be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	acpi_adr_space_type space_id;
5084be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	struct acpi_namespace_node *node;
5094be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	acpi_status status;
5104be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	struct acpi_namespace_node *method_node;
5114be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	acpi_name *reg_name_ptr = (acpi_name *) METHOD_NAME__REG;
5124be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	union acpi_operand_object *region_obj2;
5131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
514b229cf92eee616c7cb5ad8cdb35a19b119f00bc8Bob Moore	ACPI_FUNCTION_TRACE_U32(ev_initialize_region, acpi_ns_locked);
5151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!region_obj) {
5174be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		return_ACPI_STATUS(AE_BAD_PARAMETER);
5181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
5191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (region_obj->common.flags & AOPOBJ_OBJECT_INITIALIZED) {
5214be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		return_ACPI_STATUS(AE_OK);
5221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
5231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5244be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	region_obj2 = acpi_ns_get_secondary_object(region_obj);
5251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!region_obj2) {
5264be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		return_ACPI_STATUS(AE_NOT_EXIST);
5271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
5281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
529c45b5c097001480e66d4c523eb715ad317a4ef77Alexey Starikovskiy	node = region_obj->region.node->parent;
5301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	space_id = region_obj->region.space_id;
5311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Setup defaults */
5331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	region_obj->region.handler = NULL;
5351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	region_obj2->extra.method_REG = NULL;
5361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	region_obj->common.flags &= ~(AOPOBJ_SETUP_COMPLETE);
5371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	region_obj->common.flags |= AOPOBJ_OBJECT_INITIALIZED;
5381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Find any "_REG" method associated with this region definition */
5401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5414119532c95547821dbe72d6916dfa1b2148475b3Bob Moore	status =
5424119532c95547821dbe72d6916dfa1b2148475b3Bob Moore	    acpi_ns_search_one_scope(*reg_name_ptr, node, ACPI_TYPE_METHOD,
5434119532c95547821dbe72d6916dfa1b2148475b3Bob Moore				     &method_node);
5444be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	if (ACPI_SUCCESS(status)) {
5451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/*
5461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * The _REG method is optional and there can be only one per region
5479f15fc666ef54afc7aff31dfa31edecf00e0d81aBob Moore		 * definition. This will be executed when the handler is attached
5481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * or removed
5491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 */
5501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		region_obj2->extra.method_REG = method_node;
5511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
5521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
5541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * The following loop depends upon the root Node having no parent
5551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * ie: acpi_gbl_root_node->parent_entry being set to NULL
5561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
5571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	while (node) {
55852fc0b026e99b5d5d585095148d997d5634bbc25Bob Moore
5591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* Check to see if a handler exists */
5601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		handler_obj = NULL;
5624be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		obj_desc = acpi_ns_get_attached_object(node);
5631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (obj_desc) {
56452fc0b026e99b5d5d585095148d997d5634bbc25Bob Moore
5651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/* Can only be a handler if the object exists */
5661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			switch (node->type) {
5681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			case ACPI_TYPE_DEVICE:
5691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				handler_obj = obj_desc->device.handler;
5711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				break;
5721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			case ACPI_TYPE_PROCESSOR:
5741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				handler_obj = obj_desc->processor.handler;
5761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				break;
5771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			case ACPI_TYPE_THERMAL:
5791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				handler_obj = obj_desc->thermal_zone.handler;
5811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				break;
5821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
583e31c32cfe52e98344dad28853c3331879f72c4b0Lin Ming			case ACPI_TYPE_METHOD:
584e31c32cfe52e98344dad28853c3331879f72c4b0Lin Ming				/*
585e31c32cfe52e98344dad28853c3331879f72c4b0Lin Ming				 * If we are executing module level code, the original
586e31c32cfe52e98344dad28853c3331879f72c4b0Lin Ming				 * Node's object was replaced by this Method object and we
587e31c32cfe52e98344dad28853c3331879f72c4b0Lin Ming				 * saved the handler in the method object.
588e31c32cfe52e98344dad28853c3331879f72c4b0Lin Ming				 *
589e31c32cfe52e98344dad28853c3331879f72c4b0Lin Ming				 * See acpi_ns_exec_module_code
590e31c32cfe52e98344dad28853c3331879f72c4b0Lin Ming				 */
591e31c32cfe52e98344dad28853c3331879f72c4b0Lin Ming				if (obj_desc->method.
592262948428878fb340127faca1791acb17146122eLin Ming				    info_flags & ACPI_METHOD_MODULE_LEVEL) {
593e31c32cfe52e98344dad28853c3331879f72c4b0Lin Ming					handler_obj =
594262948428878fb340127faca1791acb17146122eLin Ming					    obj_desc->method.dispatch.handler;
595e31c32cfe52e98344dad28853c3331879f72c4b0Lin Ming				}
596e31c32cfe52e98344dad28853c3331879f72c4b0Lin Ming				break;
597e31c32cfe52e98344dad28853c3331879f72c4b0Lin Ming
5981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			default:
5991d1ea1b723d9f239f736b8cf284327cbbf9d15d1Chao Guan
6001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				/* Ignore other objects */
6011d1ea1b723d9f239f736b8cf284327cbbf9d15d1Chao Guan
6021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				break;
6031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
6041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			while (handler_obj) {
60652fc0b026e99b5d5d585095148d997d5634bbc25Bob Moore
6071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				/* Is this handler of the correct type? */
6081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6094be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown				if (handler_obj->address_space.space_id ==
6104be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown				    space_id) {
61152fc0b026e99b5d5d585095148d997d5634bbc25Bob Moore
6121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					/* Found correct handler */
6131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6144be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown					ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
6154be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown							  "Found handler %p for region %p in obj %p\n",
6164be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown							  handler_obj,
6174be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown							  region_obj,
6184be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown							  obj_desc));
6191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6204be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown					status =
6214be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown					    acpi_ev_attach_region(handler_obj,
6224be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown								  region_obj,
6234be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown								  acpi_ns_locked);
6241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					/*
626d4913dc6d0c680aa106d1d80b5ad2a9325367afdBob Moore					 * Tell all users that this region is usable by
627d4913dc6d0c680aa106d1d80b5ad2a9325367afdBob Moore					 * running the _REG method
6281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					 */
6291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					if (acpi_ns_locked) {
6304be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown						status =
6314be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown						    acpi_ut_release_mutex
6324be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown						    (ACPI_MTX_NAMESPACE);
6334be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown						if (ACPI_FAILURE(status)) {
6344be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown							return_ACPI_STATUS
6354be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown							    (status);
6361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds						}
6371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					}
6381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6394be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown					status =
6404be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown					    acpi_ev_execute_reg_method
641e2066ca1b211ff08325c98be9fb8ad95affbaba8Bob Moore					    (region_obj, ACPI_REG_CONNECT);
6421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					if (acpi_ns_locked) {
6444be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown						status =
6454be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown						    acpi_ut_acquire_mutex
6464be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown						    (ACPI_MTX_NAMESPACE);
6474be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown						if (ACPI_FAILURE(status)) {
6484be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown							return_ACPI_STATUS
6494be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown							    (status);
6501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds						}
6511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					}
6521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6534be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown					return_ACPI_STATUS(AE_OK);
6541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				}
6551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				/* Try next handler in the list */
6571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				handler_obj = handler_obj->address_space.next;
6591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
6601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
6611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6629f15fc666ef54afc7aff31dfa31edecf00e0d81aBob Moore		/* This node does not have the handler we need; Pop up one level */
6639f15fc666ef54afc7aff31dfa31edecf00e0d81aBob Moore
664c45b5c097001480e66d4c523eb715ad317a4ef77Alexey Starikovskiy		node = node->parent;
6651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
6661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* If we get here, there is no handler for this region */
6681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6694be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
670b229cf92eee616c7cb5ad8cdb35a19b119f00bc8Bob Moore			  "No handler for RegionType %s(%X) (RegionObj %p)\n",
6714be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown			  acpi_ut_get_region_name(space_id), space_id,
6724be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown			  region_obj));
6731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6744be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	return_ACPI_STATUS(AE_NOT_EXIST);
6751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
676