--- /dev/null
+From 8517934ef6aaa28d6e055b98df65b31cedbd1372 Mon Sep 17 00:00:00 2001
+From: Alexey Starikovskiy <astarikovskiy@suse.de>
+Date: Tue, 11 Nov 2008 12:54:11 +0300
+Subject: ACPI: EC: Don't do transaction from GPE handler in poll mode.
+
+From: Alexey Starikovskiy <astarikovskiy@suse.de>
+
+commit 8517934ef6aaa28d6e055b98df65b31cedbd1372 upstream.
+
+Referencies: http://bugzilla.kernel.org/show_bug.cgi?id=12004
+
+Signed-off-by: Alexey Starikovskiy <astarikovskiy@suse.de>
+Signed-off-by: Len Brown <len.brown@intel.com>
+Cc: Rafael J. Wysocki <rjw@sisk.pl>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/acpi/ec.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+--- a/drivers/acpi/ec.c
++++ b/drivers/acpi/ec.c
+@@ -581,9 +581,12 @@ static u32 acpi_ec_gpe_handler(void *dat
+ pr_debug(PREFIX "~~~> interrupt\n");
+ status = acpi_ec_read_status(ec);
+
+- gpe_transaction(ec, status);
+- if (ec_transaction_done(ec) && (status & ACPI_EC_FLAG_IBF) == 0)
+- wake_up(&ec->wait);
++ if (test_bit(EC_FLAGS_GPE_MODE, &ec->flags)) {
++ gpe_transaction(ec, status);
++ if (ec_transaction_done(ec) &&
++ (status & ACPI_EC_FLAG_IBF) == 0)
++ wake_up(&ec->wait);
++ }
+
+ ec_check_sci(ec, status);
+ if (!test_bit(EC_FLAGS_GPE_MODE, &ec->flags) &&
--- /dev/null
+From 06cf7d3c7af902939cd1754abcafb2464060cba8 Mon Sep 17 00:00:00 2001
+From: Alexey Starikovskiy <astarikovskiy@suse.de>
+Date: Sun, 9 Nov 2008 19:01:06 +0300
+Subject: ACPI: EC: lower interrupt storm treshold
+
+From: Alexey Starikovskiy <astarikovskiy@suse.de>
+
+commit 06cf7d3c7af902939cd1754abcafb2464060cba8 upstream.
+
+http://bugzilla.kernel.org/show_bug.cgi?id=11892
+
+Signed-off-by: Alexey Starikovskiy <astarikovskiy@suse.de>
+Signed-off-by: Len Brown <len.brown@intel.com>
+Cc: Rafael J. Wysocki <rjw@sisk.pl>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/acpi/ec.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/acpi/ec.c
++++ b/drivers/acpi/ec.c
+@@ -70,7 +70,7 @@ enum ec_command {
+ #define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */
+ #define ACPI_EC_UDELAY 100 /* Wait 100us before polling EC again */
+
+-#define ACPI_EC_STORM_THRESHOLD 20 /* number of false interrupts
++#define ACPI_EC_STORM_THRESHOLD 8 /* number of false interrupts
+ per one transaction */
+
+ enum {
--- /dev/null
+From a2f93aeadf97e870ff385030633a73e21146815d Mon Sep 17 00:00:00 2001
+From: Alexey Starikovskiy <astarikovskiy@suse.de>
+Date: Wed, 12 Nov 2008 01:40:19 +0300
+Subject: ACPI: EC: restart failed command
+
+From: Alexey Starikovskiy <astarikovskiy@suse.de>
+
+commit a2f93aeadf97e870ff385030633a73e21146815d upstream.
+
+Restart current transaction if we recieved unexpected GPEs instead
+of needed ones.
+
+http://bugzilla.kernel.org/show_bug.cgi?id=11896
+
+Signed-off-by: Alexey Starikovskiy <astarikovskiy@suse.de>
+Signed-off-by: Len Brown <len.brown@intel.com>
+Cc: Rafael J. Wysocki <rjw@sisk.pl>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/acpi/ec.c | 41 +++++++++++++++++++++++++++++------------
+ 1 file changed, 29 insertions(+), 12 deletions(-)
+
+--- a/drivers/acpi/ec.c
++++ b/drivers/acpi/ec.c
+@@ -100,6 +100,8 @@ struct transaction {
+ u8 *rdata;
+ unsigned short irq_count;
+ u8 command;
++ u8 wi;
++ u8 ri;
+ u8 wlen;
+ u8 rlen;
+ bool done;
+@@ -185,26 +187,34 @@ static int ec_transaction_done(struct ac
+ return ret;
+ }
+
++static void start_transaction(struct acpi_ec *ec)
++{
++ ec->curr->irq_count = ec->curr->wi = ec->curr->ri = 0;
++ ec->curr->done = false;
++ acpi_ec_write_cmd(ec, ec->curr->command);
++}
++
+ static void gpe_transaction(struct acpi_ec *ec, u8 status)
+ {
+ unsigned long flags;
+ spin_lock_irqsave(&ec->curr_lock, flags);
+ if (!ec->curr)
+ goto unlock;
+- if (ec->curr->wlen > 0) {
+- if ((status & ACPI_EC_FLAG_IBF) == 0) {
+- acpi_ec_write_data(ec, *(ec->curr->wdata++));
+- --ec->curr->wlen;
+- } else
++ if (ec->curr->wlen > ec->curr->wi) {
++ if ((status & ACPI_EC_FLAG_IBF) == 0)
++ acpi_ec_write_data(ec,
++ ec->curr->wdata[ec->curr->wi++]);
++ else
+ goto err;
+- } else if (ec->curr->rlen > 0) {
++ } else if (ec->curr->rlen > ec->curr->ri) {
+ if ((status & ACPI_EC_FLAG_OBF) == 1) {
+- *(ec->curr->rdata++) = acpi_ec_read_data(ec);
+- if (--ec->curr->rlen == 0)
++ ec->curr->rdata[ec->curr->ri++] = acpi_ec_read_data(ec);
++ if (ec->curr->rlen == ec->curr->ri)
+ ec->curr->done = true;
+ } else
+ goto err;
+- } else if (ec->curr->wlen == 0 && (status & ACPI_EC_FLAG_IBF) == 0)
++ } else if (ec->curr->wlen == ec->curr->wi &&
++ (status & ACPI_EC_FLAG_IBF) == 0)
+ ec->curr->done = true;
+ goto unlock;
+ err:
+@@ -219,6 +229,15 @@ static int acpi_ec_wait(struct acpi_ec *
+ if (wait_event_timeout(ec->wait, ec_transaction_done(ec),
+ msecs_to_jiffies(ACPI_EC_DELAY)))
+ return 0;
++ /* try restart command if we get any false interrupts */
++ if (ec->curr->irq_count &&
++ (acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF) == 0) {
++ pr_debug(PREFIX "controller reset, restart transaction\n");
++ start_transaction(ec);
++ if (wait_event_timeout(ec->wait, ec_transaction_done(ec),
++ msecs_to_jiffies(ACPI_EC_DELAY)))
++ return 0;
++ }
+ /* missing GPEs, switch back to poll mode */
+ if (printk_ratelimit())
+ pr_info(PREFIX "missing confirmations, "
+@@ -268,10 +287,8 @@ static int acpi_ec_transaction_unlocked(
+ /* start transaction */
+ spin_lock_irqsave(&ec->curr_lock, tmp);
+ /* following two actions should be kept atomic */
+- t->irq_count = 0;
+- t->done = false;
+ ec->curr = t;
+- acpi_ec_write_cmd(ec, ec->curr->command);
++ start_transaction(ec);
+ if (ec->curr->command == ACPI_EC_COMMAND_QUERY)
+ clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags);
+ spin_unlock_irqrestore(&ec->curr_lock, tmp);