|
@@ -307,6 +307,10 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t)
|
|
pr_debug(PREFIX "transaction start\n");
|
|
pr_debug(PREFIX "transaction start\n");
|
|
/* disable GPE during transaction if storm is detected */
|
|
/* disable GPE during transaction if storm is detected */
|
|
if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) {
|
|
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);
|
|
acpi_set_gpe(NULL, ec->gpe, ACPI_GPE_DISABLE);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -316,7 +320,11 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t)
|
|
ec_check_sci_sync(ec, acpi_ec_read_status(ec));
|
|
ec_check_sci_sync(ec, acpi_ec_read_status(ec));
|
|
if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) {
|
|
if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) {
|
|
msleep(1);
|
|
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);
|
|
acpi_set_gpe(NULL, ec->gpe, ACPI_GPE_ENABLE);
|
|
} else if (t->irq_count > ACPI_EC_STORM_THRESHOLD) {
|
|
} else if (t->irq_count > ACPI_EC_STORM_THRESHOLD) {
|
|
pr_info(PREFIX "GPE storm detected, "
|
|
pr_info(PREFIX "GPE storm detected, "
|
|
@@ -1059,7 +1067,7 @@ error:
|
|
static int acpi_ec_suspend(struct acpi_device *device, pm_message_t state)
|
|
static int acpi_ec_suspend(struct acpi_device *device, pm_message_t state)
|
|
{
|
|
{
|
|
struct acpi_ec *ec = acpi_driver_data(device);
|
|
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);
|
|
acpi_set_gpe(NULL, ec->gpe, ACPI_GPE_DISABLE);
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
@@ -1067,7 +1075,7 @@ static int acpi_ec_suspend(struct acpi_device *device, pm_message_t state)
|
|
static int acpi_ec_resume(struct acpi_device *device)
|
|
static int acpi_ec_resume(struct acpi_device *device)
|
|
{
|
|
{
|
|
struct acpi_ec *ec = acpi_driver_data(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);
|
|
acpi_set_gpe(NULL, ec->gpe, ACPI_GPE_ENABLE);
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|