diff options
author | Bob Moore <robert.moore@intel.com> | 2011-02-14 16:13:25 +0800 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2011-03-02 19:38:06 -0500 |
commit | ef09c4f578147464524041cbe3205bb25f900598 (patch) | |
tree | c4270c7cf7f257fad6d8e8e7f5107c54f9d9b8d6 /drivers | |
parent | 47863b9cbec29f137b3a7718ec851be879b41137 (diff) |
ACPICA: Add mechanism to defer _REG methods for some installed handlers
The memory/io/pci/dataTable regions must always be available. For
any user installed handlers for these spaces, defer execution
of _REG methods until acpi_enable_subsystem. This prevents any
chicken/egg problems and ensures that no methods are executed
until all of these regions are ready and available.
Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Lin Ming <ming.m.lin@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/acpi/acpica/acglobal.h | 4 | ||||
-rw-r--r-- | drivers/acpi/acpica/evregion.c | 2 | ||||
-rw-r--r-- | drivers/acpi/acpica/evxfregn.c | 34 | ||||
-rw-r--r-- | drivers/acpi/acpica/utglobal.c | 1 |
4 files changed, 39 insertions, 2 deletions
diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index 82a1bd283db..d69750b83b3 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h @@ -273,6 +273,10 @@ ACPI_EXTERN u32 acpi_gbl_owner_id_mask[ACPI_NUM_OWNERID_MASKS]; ACPI_EXTERN u8 acpi_gbl_last_owner_id_index; ACPI_EXTERN u8 acpi_gbl_next_owner_id_offset; +/* Initialization sequencing */ + +ACPI_EXTERN u8 acpi_gbl_reg_methods_executed; + /* Misc */ ACPI_EXTERN u32 acpi_gbl_original_mode; diff --git a/drivers/acpi/acpica/evregion.c b/drivers/acpi/acpica/evregion.c index 785a5ee6458..bea7223d7a7 100644 --- a/drivers/acpi/acpica/evregion.c +++ b/drivers/acpi/acpica/evregion.c @@ -231,6 +231,8 @@ acpi_status acpi_ev_initialize_op_regions(void) } } + acpi_gbl_reg_methods_executed = TRUE; + (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); return_ACPI_STATUS(status); } diff --git a/drivers/acpi/acpica/evxfregn.c b/drivers/acpi/acpica/evxfregn.c index eb738676371..c85c8c45599 100644 --- a/drivers/acpi/acpica/evxfregn.c +++ b/drivers/acpi/acpica/evxfregn.c @@ -110,9 +110,39 @@ acpi_install_address_space_handler(acpi_handle device, goto unlock_and_exit; } - /* Run all _REG methods for this address space */ + /* + * For the default space_iDs, (the IDs for which there are default region handlers + * installed) Only execute the _REG methods if the global initialization _REG + * methods have already been run (via acpi_initialize_objects). In other words, + * we will defer the execution of the _REG methods for these space_iDs until + * execution of acpi_initialize_objects. This is done because we need the handlers + * for the default spaces (mem/io/pci/table) to be installed before we can run + * any control methods (or _REG methods). There is known BIOS code that depends + * on this. + * + * For all other space_iDs, we can safely execute the _REG methods immediately. + * This means that for IDs like embedded_controller, this function should be called + * only after acpi_enable_subsystem has been called. + */ + switch (space_id) { + case ACPI_ADR_SPACE_SYSTEM_MEMORY: + case ACPI_ADR_SPACE_SYSTEM_IO: + case ACPI_ADR_SPACE_PCI_CONFIG: + case ACPI_ADR_SPACE_DATA_TABLE: + + if (acpi_gbl_reg_methods_executed) { + + /* Run all _REG methods for this address space */ + + status = acpi_ev_execute_reg_methods(node, space_id); + } + break; + + default: - status = acpi_ev_execute_reg_methods(node, space_id); + status = acpi_ev_execute_reg_methods(node, space_id); + break; + } unlock_and_exit: (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); diff --git a/drivers/acpi/acpica/utglobal.c b/drivers/acpi/acpica/utglobal.c index fc909782151..833a38a9c90 100644 --- a/drivers/acpi/acpica/utglobal.c +++ b/drivers/acpi/acpica/utglobal.c @@ -323,6 +323,7 @@ acpi_status acpi_ut_init_globals(void) acpi_gbl_db_output_flags = ACPI_DB_CONSOLE_OUTPUT; acpi_gbl_osi_data = 0; acpi_gbl_osi_mutex = NULL; + acpi_gbl_reg_methods_executed = FALSE; /* Hardware oriented */ |