[PATCH] ACPI: EC: switch to poll mode automatically

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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 <astarikovskiy@xxxxxxx>
---

 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 majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux IBM ACPI]     [Linux Power Management]     [Linux Kernel]     [Linux Laptop]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Device Mapper]     [Linux Resources]

  Powered by Linux