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; |