diff options
Diffstat (limited to 'drivers/acpi/ec.c')
| -rw-r--r-- | drivers/acpi/ec.c | 33 |
1 files changed, 32 insertions, 1 deletions
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index d7a6bbbb834c..1ac28c6a672e 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
| @@ -76,8 +76,9 @@ enum ec_command { | |||
| 76 | enum { | 76 | enum { |
| 77 | EC_FLAGS_QUERY_PENDING, /* Query is pending */ | 77 | EC_FLAGS_QUERY_PENDING, /* Query is pending */ |
| 78 | EC_FLAGS_GPE_STORM, /* GPE storm detected */ | 78 | EC_FLAGS_GPE_STORM, /* GPE storm detected */ |
| 79 | EC_FLAGS_HANDLERS_INSTALLED /* Handlers for GPE and | 79 | EC_FLAGS_HANDLERS_INSTALLED, /* Handlers for GPE and |
| 80 | * OpReg are installed */ | 80 | * OpReg are installed */ |
| 81 | EC_FLAGS_FROZEN, /* Transactions are suspended */ | ||
| 81 | }; | 82 | }; |
| 82 | 83 | ||
| 83 | /* If we find an EC via the ECDT, we need to keep a ptr to its context */ | 84 | /* If we find an EC via the ECDT, we need to keep a ptr to its context */ |
| @@ -291,6 +292,10 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t) | |||
| 291 | if (t->rdata) | 292 | if (t->rdata) |
| 292 | memset(t->rdata, 0, t->rlen); | 293 | memset(t->rdata, 0, t->rlen); |
| 293 | mutex_lock(&ec->lock); | 294 | mutex_lock(&ec->lock); |
| 295 | if (test_bit(EC_FLAGS_FROZEN, &ec->flags)) { | ||
| 296 | status = -EINVAL; | ||
| 297 | goto unlock; | ||
| 298 | } | ||
| 294 | if (ec->global_lock) { | 299 | if (ec->global_lock) { |
| 295 | status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk); | 300 | status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk); |
| 296 | if (ACPI_FAILURE(status)) { | 301 | if (ACPI_FAILURE(status)) { |
| @@ -453,6 +458,32 @@ int ec_transaction(u8 command, | |||
| 453 | 458 | ||
| 454 | EXPORT_SYMBOL(ec_transaction); | 459 | EXPORT_SYMBOL(ec_transaction); |
| 455 | 460 | ||
| 461 | void acpi_ec_suspend_transactions(void) | ||
| 462 | { | ||
| 463 | struct acpi_ec *ec = first_ec; | ||
| 464 | |||
| 465 | if (!ec) | ||
| 466 | return; | ||
| 467 | |||
| 468 | mutex_lock(&ec->lock); | ||
| 469 | /* Prevent transactions from being carried out */ | ||
| 470 | set_bit(EC_FLAGS_FROZEN, &ec->flags); | ||
| 471 | mutex_unlock(&ec->lock); | ||
| 472 | } | ||
| 473 | |||
| 474 | void acpi_ec_resume_transactions(void) | ||
| 475 | { | ||
| 476 | struct acpi_ec *ec = first_ec; | ||
| 477 | |||
| 478 | if (!ec) | ||
| 479 | return; | ||
| 480 | |||
| 481 | mutex_lock(&ec->lock); | ||
| 482 | /* Allow transactions to be carried out again */ | ||
| 483 | clear_bit(EC_FLAGS_FROZEN, &ec->flags); | ||
| 484 | mutex_unlock(&ec->lock); | ||
| 485 | } | ||
| 486 | |||
| 456 | static int acpi_ec_query_unlocked(struct acpi_ec *ec, u8 * data) | 487 | static int acpi_ec_query_unlocked(struct acpi_ec *ec, u8 * data) |
| 457 | { | 488 | { |
| 458 | int result; | 489 | int result; |
