ACPI / PM: Move ACPI video resume to a PM notifier
[cascardo/linux.git] / drivers / acpi / ec.c
index d7a6bbb..35ba254 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/interrupt.h>
 #include <linux/list.h>
 #include <linux/spinlock.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
@@ -76,8 +77,9 @@ enum ec_command {
 enum {
        EC_FLAGS_QUERY_PENDING,         /* Query is pending */
        EC_FLAGS_GPE_STORM,             /* GPE storm detected */
-       EC_FLAGS_HANDLERS_INSTALLED     /* Handlers for GPE and
+       EC_FLAGS_HANDLERS_INSTALLED,    /* Handlers for GPE and
                                         * OpReg are installed */
+       EC_FLAGS_FROZEN,                /* Transactions are suspended */
 };
 
 /* If we find an EC via the ECDT, we need to keep a ptr to its context */
@@ -291,6 +293,10 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t)
        if (t->rdata)
                memset(t->rdata, 0, t->rlen);
        mutex_lock(&ec->lock);
+       if (test_bit(EC_FLAGS_FROZEN, &ec->flags)) {
+               status = -EINVAL;
+               goto unlock;
+       }
        if (ec->global_lock) {
                status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
                if (ACPI_FAILURE(status)) {
@@ -453,6 +459,32 @@ int ec_transaction(u8 command,
 
 EXPORT_SYMBOL(ec_transaction);
 
+void acpi_ec_suspend_transactions(void)
+{
+       struct acpi_ec *ec = first_ec;
+
+       if (!ec)
+               return;
+
+       mutex_lock(&ec->lock);
+       /* Prevent transactions from being carried out */
+       set_bit(EC_FLAGS_FROZEN, &ec->flags);
+       mutex_unlock(&ec->lock);
+}
+
+void acpi_ec_resume_transactions(void)
+{
+       struct acpi_ec *ec = first_ec;
+
+       if (!ec)
+               return;
+
+       mutex_lock(&ec->lock);
+       /* Allow transactions to be carried out again */
+       clear_bit(EC_FLAGS_FROZEN, &ec->flags);
+       mutex_unlock(&ec->lock);
+}
+
 static int acpi_ec_query_unlocked(struct acpi_ec *ec, u8 * data)
 {
        int result;