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