/*******************************************************************************
*
- * FUNCTION: acpi_enable_gpe
+ * FUNCTION: acpi_enable_gpe_cond
*
* PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
* gpe_number - GPE level within the GPE block
+ * dispatch_type - GPE dispatch type to match
*
* RETURN: Status
*
- * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is
- * hardware-enabled.
+ * DESCRIPTION: Add a reference to a GPE so long as its dispatch type matches
+ * the supplied one, or it is different from ACPI_GPE_DISPATCH_NONE
+ * if the supplied one is ACPI_GPE_DISPATCH_MASK. On the first
+ * reference, the GPE is hardware-enabled.
*
******************************************************************************/
-acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number)
+acpi_status acpi_enable_gpe_cond(acpi_handle gpe_device, u32 gpe_number,
+ u8 dispatch_type)
{
acpi_status status = AE_BAD_PARAMETER;
struct acpi_gpe_event_info *gpe_event_info;
flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
/*
- * Ensure that we have a valid GPE number and that there is some way
- * of handling the GPE (handler or a GPE method). In other words, we
- * won't allow a valid GPE to be enabled if there is no way to handle it.
+ * Ensure that we have a valid GPE number and that the dispatch type of
+ * the GPE matches the supplied one (or it is not ACPI_GPE_DISPATCH_NONE
+ * if the supplied one is ACPI_GPE_DISPATCH_MASK).
*/
gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
if (gpe_event_info) {
- if (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) !=
- ACPI_GPE_DISPATCH_NONE) {
+ if (dispatch_type == ACPI_GPE_DISPATCH_MASK)
+ dispatch_type = ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags);
+ else if (dispatch_type != ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags))
+ dispatch_type = ACPI_GPE_DISPATCH_NONE;
+
+ if (dispatch_type != ACPI_GPE_DISPATCH_NONE) {
status = acpi_ev_add_gpe_reference(gpe_event_info, TRUE);
if (ACPI_SUCCESS(status) &&
ACPI_GPE_IS_POLLING_NEEDED(gpe_event_info)) {
acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
return_ACPI_STATUS(status);
}
+ACPI_EXPORT_SYMBOL(acpi_enable_gpe_cond)
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_enable_gpe
+ *
+ * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
+ * gpe_number - GPE level within the GPE block
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is
+ * hardware-enabled.
+ *
+ ******************************************************************************/
+acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number)
+{
+ /*
+ * Ensure that there is some way of handling the GPE (handler or a GPE
+ * method). In other words, we won't allow a valid GPE to be enabled if
+ * there is no way to handle it.
+ */
+ return acpi_enable_gpe_cond(gpe_device, gpe_number, ACPI_GPE_DISPATCH_MASK);
+}
ACPI_EXPORT_SYMBOL(acpi_enable_gpe)
/*******************************************************************************
ktime_t last_time;
bool suspended;
bool lid_state_initialized;
+ bool gpe_enabled;
};
static struct acpi_device *lid_device;
status = acpi_install_notify_handler(device->handle,
ACPI_ALL_NOTIFY, handler,
button);
+ if (ACPI_SUCCESS(status) && device->wakeup.flags.valid) {
+ acpi_status st;
+
+ /*
+ * If the wakeup GPE has a handler method, enable it in
+ * case it is also used for signaling runtime events.
+ */
+ st = acpi_enable_gpe_cond(device->wakeup.gpe_device,
+ device->wakeup.gpe_number,
+ ACPI_GPE_DISPATCH_METHOD);
+ button->gpe_enabled = ACPI_SUCCESS(st);
+ if (button->gpe_enabled)
+ dev_dbg(button->dev, "Enabled ACPI GPE%02llx\n",
+ device->wakeup.gpe_number);
+ }
break;
}
if (ACPI_FAILURE(status)) {
acpi_button_event);
break;
default:
+ if (button->gpe_enabled) {
+ dev_dbg(button->dev, "Disabling ACPI GPE%02llx\n",
+ adev->wakeup.gpe_number);
+ acpi_disable_gpe(adev->wakeup.gpe_device,
+ adev->wakeup.gpe_number);
+ }
acpi_remove_notify_handler(adev->handle, ACPI_ALL_NOTIFY,
button->type == ACPI_BUTTON_TYPE_LID ?
acpi_lid_notify :