diff options
author | Rafael J. Wysocki <rjw@sisk.pl> | 2010-02-23 18:52:08 -0500 |
---|---|---|
committer | Jesse Barnes <jbarnes@virtuousgeek.org> | 2010-02-24 17:25:23 -0500 |
commit | cbbc0de700e61d0cdc854d435dbc2ef148de0e00 (patch) | |
tree | 9a645bbdab91e1a00446680a95f2b86e741e0de4 /drivers/acpi/ec.c | |
parent | 7bc5e3f2be32ae6fb0c74cd0f707f986b3a01a26 (diff) |
ACPI: Use GPE reference counting to support shared GPEs
To fix a bug and address the reviewers' comments regarding the ACPI
GPE refcounting patch, do the following additional changes:
o Remove the second argument of acpi_ev_enable_gpe(),
'write_to_hardware', because it is not necessary any more.
o Add the "bad parameter" test against 'type' in
acpi_enable_gpe() and acpi_disable_gpe().
o Make acpi_enable_gpe() only check 'status' for runtime GPEs if
acpi_ev_enable_gpe() was actually called.
o Make acpi_disable_gpe() return 'status' returned by
acpi_ev_disable_gpe() and fix a bug where ACPI_GPE_TYPE_WAKE
and ACPI_GPE_TYPE_RUNTIME were exchanged by mistake.
o Add comments explaining why acpi_set_gpe() is used by the ACPI EC
driver.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Diffstat (limited to 'drivers/acpi/ec.c')
-rw-r--r-- | drivers/acpi/ec.c | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 0fa65a8210da..27e0b92b2e39 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
@@ -307,6 +307,10 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t) | |||
307 | pr_debug(PREFIX "transaction start\n"); | 307 | pr_debug(PREFIX "transaction start\n"); |
308 | /* disable GPE during transaction if storm is detected */ | 308 | /* disable GPE during transaction if storm is detected */ |
309 | if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) { | 309 | if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) { |
310 | /* | ||
311 | * It has to be disabled at the hardware level regardless of the | ||
312 | * GPE reference counting, so that it doesn't trigger. | ||
313 | */ | ||
310 | acpi_set_gpe(NULL, ec->gpe, ACPI_GPE_DISABLE); | 314 | acpi_set_gpe(NULL, ec->gpe, ACPI_GPE_DISABLE); |
311 | } | 315 | } |
312 | 316 | ||
@@ -316,7 +320,11 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t) | |||
316 | ec_check_sci_sync(ec, acpi_ec_read_status(ec)); | 320 | ec_check_sci_sync(ec, acpi_ec_read_status(ec)); |
317 | if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) { | 321 | if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) { |
318 | msleep(1); | 322 | msleep(1); |
319 | /* it is safe to enable GPE outside of transaction */ | 323 | /* |
324 | * It is safe to enable the GPE outside of the transaction. Use | ||
325 | * acpi_set_gpe() for that, since we used it to disable the GPE | ||
326 | * above. | ||
327 | */ | ||
320 | acpi_set_gpe(NULL, ec->gpe, ACPI_GPE_ENABLE); | 328 | acpi_set_gpe(NULL, ec->gpe, ACPI_GPE_ENABLE); |
321 | } else if (t->irq_count > ACPI_EC_STORM_THRESHOLD) { | 329 | } else if (t->irq_count > ACPI_EC_STORM_THRESHOLD) { |
322 | pr_info(PREFIX "GPE storm detected, " | 330 | pr_info(PREFIX "GPE storm detected, " |
@@ -1059,7 +1067,7 @@ error: | |||
1059 | static int acpi_ec_suspend(struct acpi_device *device, pm_message_t state) | 1067 | static int acpi_ec_suspend(struct acpi_device *device, pm_message_t state) |
1060 | { | 1068 | { |
1061 | struct acpi_ec *ec = acpi_driver_data(device); | 1069 | struct acpi_ec *ec = acpi_driver_data(device); |
1062 | /* Stop using GPE */ | 1070 | /* Stop using the GPE, but keep it reference counted. */ |
1063 | acpi_set_gpe(NULL, ec->gpe, ACPI_GPE_DISABLE); | 1071 | acpi_set_gpe(NULL, ec->gpe, ACPI_GPE_DISABLE); |
1064 | return 0; | 1072 | return 0; |
1065 | } | 1073 | } |
@@ -1067,7 +1075,7 @@ static int acpi_ec_suspend(struct acpi_device *device, pm_message_t state) | |||
1067 | static int acpi_ec_resume(struct acpi_device *device) | 1075 | static int acpi_ec_resume(struct acpi_device *device) |
1068 | { | 1076 | { |
1069 | struct acpi_ec *ec = acpi_driver_data(device); | 1077 | struct acpi_ec *ec = acpi_driver_data(device); |
1070 | /* Enable use of GPE back */ | 1078 | /* Enable the GPE again, but don't reference count it once more. */ |
1071 | acpi_set_gpe(NULL, ec->gpe, ACPI_GPE_ENABLE); | 1079 | acpi_set_gpe(NULL, ec->gpe, ACPI_GPE_ENABLE); |
1072 | return 0; | 1080 | return 0; |
1073 | } | 1081 | } |