提交 1312b7e0 编写于 作者: R Rafael J. Wysocki

ACPICA: Make it possible to enable runtime GPEs earlier

Runtime GPEs have corresponding _Lxx/_Exx methods and are enabled
automatically during the initialization of the ACPI subsystem through
acpi_update_all_gpes() with the assumption that acpi_setup_gpe_for_wake()
will be called in advance for all of the GPEs pointed to by _PRW
objects in the namespace that may be affected by acpi_update_all_gpes().
That is, acpi_ev_initialize_gpe_block() can only be called for a GPE
block after acpi_setup_gpe_for_wake() has been called for all of the
_PRW (wakeup) GPEs in it.

The platform firmware on some systems, however, expects GPEs to be
enabled before the enumeration of devices which is when
acpi_setup_gpe_for_wake() is called and that goes against the above
assumption.

For this reason, introduce a new flag to be set by
acpi_ev_initialize_gpe_block() when automatically enabling a GPE
to indicate to acpi_setup_gpe_for_wake() that it needs to drop the
reference to the GPE coming from acpi_ev_initialize_gpe_block()
and modify acpi_setup_gpe_for_wake() accordingly.  These changes
allow acpi_setup_gpe_for_wake() and acpi_ev_initialize_gpe_block()
to be invoked in any order.
Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
Tested-by: NMika Westerberg <mika.westerberg@linux.intel.com>
上级 ecc1165b
...@@ -496,6 +496,8 @@ acpi_ev_initialize_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, ...@@ -496,6 +496,8 @@ acpi_ev_initialize_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
continue; continue;
} }
gpe_event_info->flags |= ACPI_GPE_AUTO_ENABLED;
if (event_status & ACPI_EVENT_FLAG_STATUS_SET) { if (event_status & ACPI_EVENT_FLAG_STATUS_SET) {
ACPI_INFO(("GPE 0x%02X active on init", ACPI_INFO(("GPE 0x%02X active on init",
gpe_number)); gpe_number));
......
...@@ -435,6 +435,14 @@ acpi_setup_gpe_for_wake(acpi_handle wake_device, ...@@ -435,6 +435,14 @@ acpi_setup_gpe_for_wake(acpi_handle wake_device,
*/ */
gpe_event_info->flags = gpe_event_info->flags =
(ACPI_GPE_DISPATCH_NOTIFY | ACPI_GPE_LEVEL_TRIGGERED); (ACPI_GPE_DISPATCH_NOTIFY | ACPI_GPE_LEVEL_TRIGGERED);
} else if (gpe_event_info->flags & ACPI_GPE_AUTO_ENABLED) {
/*
* A reference to this GPE has been added during the GPE block
* initialization, so drop it now to prevent the GPE from being
* permanently enabled and clear its ACPI_GPE_AUTO_ENABLED flag.
*/
(void)acpi_ev_remove_gpe_reference(gpe_event_info);
gpe_event_info->flags &= ~ACPI_GPE_AUTO_ENABLED;
} }
/* /*
......
...@@ -775,7 +775,7 @@ typedef u32 acpi_event_status; ...@@ -775,7 +775,7 @@ typedef u32 acpi_event_status;
* | | | | +-- Type of dispatch:to method, handler, notify, or none * | | | | +-- Type of dispatch:to method, handler, notify, or none
* | | | +----- Interrupt type: edge or level triggered * | | | +----- Interrupt type: edge or level triggered
* | | +------- Is a Wake GPE * | | +------- Is a Wake GPE
* | +--------- Is GPE masked by the software GPE masking mechanism * | +--------- Has been enabled automatically at init time
* +------------ <Reserved> * +------------ <Reserved>
*/ */
#define ACPI_GPE_DISPATCH_NONE (u8) 0x00 #define ACPI_GPE_DISPATCH_NONE (u8) 0x00
...@@ -791,6 +791,7 @@ typedef u32 acpi_event_status; ...@@ -791,6 +791,7 @@ typedef u32 acpi_event_status;
#define ACPI_GPE_XRUPT_TYPE_MASK (u8) 0x08 #define ACPI_GPE_XRUPT_TYPE_MASK (u8) 0x08
#define ACPI_GPE_CAN_WAKE (u8) 0x10 #define ACPI_GPE_CAN_WAKE (u8) 0x10
#define ACPI_GPE_AUTO_ENABLED (u8) 0x20
/* /*
* Flags for GPE and Lock interfaces * Flags for GPE and Lock interfaces
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册