Make selection of mode automatic.
If EC sends confirmation interrupts -- switch to interrupt mode, otherwise
poll it.
If EC fails to send confirmation interrupt within a timeout, 
switch back to poll mode.

Signed-off-by: Alexey Starikovskiy <[EMAIL PROTECTED]>
---

 drivers/acpi/ec.c |   42 +++++++++++++++---------------------------
 1 files changed, 15 insertions(+), 27 deletions(-)

diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index e9a8805..5183769 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -72,9 +72,9 @@ enum ec_event {
 #define ACPI_EC_UDELAY_GLK     1000    /* Wait 1ms max. to get global lock */
 
 static enum ec_mode {
-       EC_INTR = 1,            /* Output buffer full */
-       EC_POLL,                /* Input buffer empty */
-} acpi_ec_mode = EC_INTR;
+       EC_INTR = 1,            /* EC sends GPE to complete transaction */
+       EC_POLL,                /* EC does not send anything */
+} acpi_ec_mode = EC_POLL;      /* start with safer assumptions */
 
 static int acpi_ec_remove(struct acpi_device *device, int type);
 static int acpi_ec_start(struct acpi_device *device);
@@ -177,16 +177,18 @@ static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event 
event,
        } else {
                if (wait_event_timeout(ec->wait,
                                       acpi_ec_check_status(ec, event, count),
-                                      msecs_to_jiffies(ACPI_EC_DELAY)) ||
-                   acpi_ec_check_status(ec, event, 0)) {
+                                      msecs_to_jiffies(ACPI_EC_DELAY)))
+                       return 0;
+               if (acpi_ec_check_status(ec, event, 0)) {
+                       printk(KERN_WARNING PREFIX "EC did not send confirm "
+                               "interrupt, switch to poll mode\n");
+                       acpi_ec_mode = EC_POLL;
                        return 0;
-               } else {
-                       printk(KERN_ERR PREFIX "acpi_ec_wait timeout,"
-                              " status = %d, expect_event = %d\n",
-                              acpi_ec_read_status(ec), event);
                }
        }
-
+       printk(KERN_ERR PREFIX "acpi_ec_wait timeout,"
+               " status = %d, expect_event = %d\n",
+               acpi_ec_read_status(ec), event);
        return -ETIME;
 }
 
@@ -490,8 +492,10 @@ static u32 acpi_ec_gpe_handler(void *data)
                atomic_set(&ec->query_pending, 1);
                status =
                    acpi_os_execute(OSL_EC_BURST_HANDLER, acpi_ec_gpe_query, 
ec);
+       } else {
+               /* Non-query intterrupt from EC, must be confirmation */
+               acpi_ec_mode = EC_INTR;
        }
-
        return status == AE_OK ?
            ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED;
 }
@@ -925,19 +929,3 @@ static void __exit acpi_ec_exit(void)
        return;
 }
 #endif                         /* 0 */
-
-static int __init acpi_ec_set_intr_mode(char *str)
-{
-       int intr;
-
-       if (!get_option(&str, &intr))
-               return 0;
-
-       acpi_ec_mode = (intr) ? EC_INTR : EC_POLL;
-
-       printk(KERN_NOTICE PREFIX "%s mode.\n", intr ? "interrupt" : "polling");
-
-       return 1;
-}
-
-__setup("ec_intr=", acpi_ec_set_intr_mode);

-
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to