acpi_status
acpi_ev_update_gpe_enable_masks(struct acpi_gpe_event_info *gpe_event_info);
-acpi_status
-acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info,
- u8 write_to_hardware);
+acpi_status acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info);
acpi_status acpi_ev_disable_gpe(struct acpi_gpe_event_info *gpe_event_info);
* FUNCTION: acpi_ev_enable_gpe
*
* PARAMETERS: gpe_event_info - GPE to enable
- * write_to_hardware - Enable now, or just mark data structs
- * (WAKE GPEs should be deferred)
*
* RETURN: Status
*
*
******************************************************************************/
-acpi_status
-acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info,
- u8 write_to_hardware)
+acpi_status acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info)
{
acpi_status status;
/* Mark wake-enabled or HW enable, or both */
- if (gpe_event_info->runtime_count && write_to_hardware) {
+ if (gpe_event_info->runtime_count) {
/* Clear the GPE (of stale events), then enable it */
status = acpi_hw_clear_gpe(gpe_event_info);
if (ACPI_FAILURE(status))
/* Set the GPE flags for return to enabled state */
- (void)acpi_ev_enable_gpe(gpe_event_info, FALSE);
+ (void)acpi_ev_update_gpe_enable_masks(gpe_event_info);
/*
* Take a snapshot of the GPE info for this level - we copy the info to
switch (action) {
case ACPI_GPE_ENABLE:
- status = acpi_ev_enable_gpe(gpe_event_info, TRUE);
+ status = acpi_ev_enable_gpe(gpe_event_info);
break;
case ACPI_GPE_DISABLE:
ACPI_FUNCTION_TRACE(acpi_enable_gpe);
+ if (type & ~ACPI_GPE_TYPE_WAKE_RUN)
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
+
flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
/* Ensure that we have a valid GPE number */
}
if (type & ACPI_GPE_TYPE_RUNTIME) {
- if (++gpe_event_info->runtime_count == 1)
- status = acpi_ev_enable_gpe(gpe_event_info, TRUE);
-
- if (ACPI_FAILURE(status))
- gpe_event_info->runtime_count--;
+ if (++gpe_event_info->runtime_count == 1) {
+ status = acpi_ev_enable_gpe(gpe_event_info);
+ if (ACPI_FAILURE(status))
+ gpe_event_info->runtime_count--;
+ }
}
if (type & ACPI_GPE_TYPE_WAKE) {
ACPI_FUNCTION_TRACE(acpi_disable_gpe);
+ if (type & ~ACPI_GPE_TYPE_WAKE_RUN)
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
+
flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
/* Ensure that we have a valid GPE number */
goto unlock_and_exit;
}
- if ((type & ACPI_GPE_TYPE_WAKE) && gpe_event_info->runtime_count) {
+ if ((type & ACPI_GPE_TYPE_RUNTIME) && gpe_event_info->runtime_count) {
if (--gpe_event_info->runtime_count == 0)
- acpi_ev_disable_gpe(gpe_event_info);
+ status = acpi_ev_disable_gpe(gpe_event_info);
}
- if ((type & ACPI_GPE_TYPE_RUNTIME) && gpe_event_info->wakeup_count) {
+ if ((type & ACPI_GPE_TYPE_WAKE) && gpe_event_info->wakeup_count) {
/*
* Wake-up GPEs are not enabled after leaving system sleep
* states, so we don't need to disable them here.
pr_debug(PREFIX "transaction start\n");
/* disable GPE during transaction if storm is detected */
if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) {
+ /*
+ * It has to be disabled at the hardware level regardless of the
+ * GPE reference counting, so that it doesn't trigger.
+ */
acpi_set_gpe(NULL, ec->gpe, ACPI_GPE_DISABLE);
}
ec_check_sci_sync(ec, acpi_ec_read_status(ec));
if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) {
msleep(1);
- /* it is safe to enable GPE outside of transaction */
+ /*
+ * It is safe to enable the GPE outside of the transaction. Use
+ * acpi_set_gpe() for that, since we used it to disable the GPE
+ * above.
+ */
acpi_set_gpe(NULL, ec->gpe, ACPI_GPE_ENABLE);
} else if (t->irq_count > ACPI_EC_STORM_THRESHOLD) {
pr_info(PREFIX "GPE storm detected, "
static int acpi_ec_suspend(struct acpi_device *device, pm_message_t state)
{
struct acpi_ec *ec = acpi_driver_data(device);
- /* Stop using GPE */
+ /* Stop using the GPE, but keep it reference counted. */
acpi_set_gpe(NULL, ec->gpe, ACPI_GPE_DISABLE);
return 0;
}
static int acpi_ec_resume(struct acpi_device *device)
{
struct acpi_ec *ec = acpi_driver_data(device);
- /* Enable use of GPE back */
+ /* Enable the GPE again, but don't reference count it once more. */
acpi_set_gpe(NULL, ec->gpe, ACPI_GPE_ENABLE);
return 0;
}