rpms/kernel/F-11 acpi-ec-merge-irq-and-poll-modes.patch, NONE, 1.1 acpi-ec-restart-command-even-if-no-interrupts-from-ec.patch, NONE, 1.1 acpi-ec-use-burst-mode-only-for-msi-notebooks.patch, NONE, 1.1 TODO, 1.71, 1.72 kernel.spec, 1.1752, 1.1753

Chuck Ebbert cebbert at fedoraproject.org
Tue Oct 6 07:33:23 UTC 2009


Author: cebbert

Update of /cvs/pkgs/rpms/kernel/F-11
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv21707

Modified Files:
	TODO kernel.spec 
Added Files:
	acpi-ec-merge-irq-and-poll-modes.patch 
	acpi-ec-restart-command-even-if-no-interrupts-from-ec.patch 
	acpi-ec-use-burst-mode-only-for-msi-notebooks.patch 
Log Message:
ACPI EC bug fixes taken from kernel 2.6.32 (#492699, #525681)

acpi-ec-merge-irq-and-poll-modes.patch:
 ec.c |  140 ++++++++++++++++++++++---------------------------------------------
 1 file changed, 46 insertions(+), 94 deletions(-)

--- NEW FILE acpi-ec-merge-irq-and-poll-modes.patch ---
From: Alexey Starikovskiy <astarikovskiy at suse.de>
Date: Sat, 29 Aug 2009 23:06:14 +0000 (+0400)
Subject: ACPI: EC: Merge IRQ and POLL modes
X-Git-Tag: v2.6.32-rc1~171^2~11^2~2
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=2a84cb9852f52c0cd1c48bca41a8792d44ad06cc

ACPI: EC: Merge IRQ and POLL modes

In general, EC transaction should complete in less than 1ms, thus it is possible to merge wait for
1ms in poll mode and 1ms of interrupt transaction timeout.
Still, driver will wait 500ms for EC to complete transaction.

This significantly simplifies driver and makes it immune to problematic EC interrupt
implementations.

It also may lessen kernel start-up time by 500ms.

References: http://bugzilla.kernel.org/show_bug.cgi?id=12949

Signed-off-by: Alexey Starikovskiy <astarikovskiy at suse.de>
Signed-off-by: Len Brown <len.brown at intel.com>
---

diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 391f331..839b542 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -68,15 +68,13 @@ enum ec_command {
 #define ACPI_EC_DELAY		500	/* Wait 500ms max. during EC ops */
 #define ACPI_EC_UDELAY_GLK	1000	/* Wait 1ms max. to get global lock */
 #define ACPI_EC_CDELAY		10	/* Wait 10us before polling EC */
+#define ACPI_EC_MSI_UDELAY	550	/* Wait 550us for MSI EC */
 
 #define ACPI_EC_STORM_THRESHOLD 8	/* number of false interrupts
 					   per one transaction */
 
 enum {
 	EC_FLAGS_QUERY_PENDING,		/* Query is pending */
-	EC_FLAGS_GPE_MODE,		/* Expect GPE to be sent
-					 * for status change */
-	EC_FLAGS_NO_GPE,		/* Don't use GPE mode */
 	EC_FLAGS_GPE_STORM,		/* GPE storm detected */
 	EC_FLAGS_HANDLERS_INSTALLED	/* Handlers for GPE and
 					 * OpReg are installed */
@@ -170,7 +168,7 @@ static void start_transaction(struct acpi_ec *ec)
 	acpi_ec_write_cmd(ec, ec->curr->command);
 }
 
-static void gpe_transaction(struct acpi_ec *ec, u8 status)
+static void advance_transaction(struct acpi_ec *ec, u8 status)
 {
 	unsigned long flags;
 	spin_lock_irqsave(&ec->curr_lock, flags);
@@ -201,29 +199,6 @@ unlock:
 	spin_unlock_irqrestore(&ec->curr_lock, flags);
 }
 
-static int acpi_ec_wait(struct acpi_ec *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, "
-				"switch off interrupt mode.\n");
-	set_bit(EC_FLAGS_NO_GPE, &ec->flags);
-	clear_bit(EC_FLAGS_GPE_MODE, &ec->flags);
-	return 1;
-}
-
 static void acpi_ec_gpe_query(void *ec_cxt);
 
 static int ec_check_sci(struct acpi_ec *ec, u8 state)
@@ -236,43 +211,51 @@ static int ec_check_sci(struct acpi_ec *ec, u8 state)
 	return 0;
 }
 
-static void ec_delay(void)
-{
-	/* EC in MSI notebooks don't tolerate delays other than 550 usec */
-	if (EC_FLAGS_MSI)
-		udelay(ACPI_EC_DELAY);
-	else
-		/* Use shortest sleep available */
-		msleep(1);
-}
-
 static int ec_poll(struct acpi_ec *ec)
 {
-	unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY);
-	udelay(ACPI_EC_CDELAY);
-	while (time_before(jiffies, delay)) {
-		gpe_transaction(ec, acpi_ec_read_status(ec));
-		ec_delay();
-		if (ec_transaction_done(ec))
-			return 0;
+	unsigned long flags;
+	int repeat = 2; /* number of command restarts */
+	while (repeat--) {
+		unsigned long delay = jiffies +
+			msecs_to_jiffies(ACPI_EC_DELAY);
+		do {
+			/* don't sleep with disabled interrupts */
+			if (EC_FLAGS_MSI || irqs_disabled()) {
+				udelay(ACPI_EC_MSI_UDELAY);
+				if (ec_transaction_done(ec))
+					return 0;
+			} else {
+				if (wait_event_timeout(ec->wait,
+						ec_transaction_done(ec),
+						msecs_to_jiffies(1)))
+					return 0;
+			}
+			advance_transaction(ec, acpi_ec_read_status(ec));
+		} while (time_before(jiffies, delay));
+		if (!ec->curr->irq_count ||
+		    (acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF))
+			break;
+		/* try restart command if we get any false interrupts */
+		pr_debug(PREFIX "controller reset, restart transaction\n");
+		spin_lock_irqsave(&ec->curr_lock, flags);
+		start_transaction(ec);
+		spin_unlock_irqrestore(&ec->curr_lock, flags);
 	}
 	return -ETIME;
 }
 
 static int acpi_ec_transaction_unlocked(struct acpi_ec *ec,
-					struct transaction *t,
-					int force_poll)
+					struct transaction *t)
 {
 	unsigned long tmp;
 	int ret = 0;
 	pr_debug(PREFIX "transaction start\n");
 	/* disable GPE during transaction if storm is detected */
 	if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) {
-		clear_bit(EC_FLAGS_GPE_MODE, &ec->flags);
 		acpi_disable_gpe(NULL, ec->gpe);
 	}
 	if (EC_FLAGS_MSI)
-		udelay(ACPI_EC_DELAY);
+		udelay(ACPI_EC_MSI_UDELAY);
 	/* start transaction */
 	spin_lock_irqsave(&ec->curr_lock, tmp);
 	/* following two actions should be kept atomic */
@@ -281,11 +264,7 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec,
 	if (ec->curr->command == ACPI_EC_COMMAND_QUERY)
 		clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags);
 	spin_unlock_irqrestore(&ec->curr_lock, tmp);
-	/* if we selected poll mode or failed in GPE-mode do a poll loop */
-	if (force_poll ||
-	    !test_bit(EC_FLAGS_GPE_MODE, &ec->flags) ||
-	    acpi_ec_wait(ec))
-		ret = ec_poll(ec);
+	ret = ec_poll(ec);
 	pr_debug(PREFIX "transaction end\n");
 	spin_lock_irqsave(&ec->curr_lock, tmp);
 	ec->curr = NULL;
@@ -295,8 +274,7 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec,
 		ec_check_sci(ec, acpi_ec_read_status(ec));
 		/* it is safe to enable GPE outside of transaction */
 		acpi_enable_gpe(NULL, ec->gpe);
-	} else if (test_bit(EC_FLAGS_GPE_MODE, &ec->flags) &&
-		   t->irq_count > ACPI_EC_STORM_THRESHOLD) {
+	} else if (t->irq_count > ACPI_EC_STORM_THRESHOLD) {
 		pr_info(PREFIX "GPE storm detected, "
 			"transactions will use polling mode\n");
 		set_bit(EC_FLAGS_GPE_STORM, &ec->flags);
@@ -314,16 +292,14 @@ static int ec_wait_ibf0(struct acpi_ec *ec)
 {
 	unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY);
 	/* interrupt wait manually if GPE mode is not active */
-	unsigned long timeout = test_bit(EC_FLAGS_GPE_MODE, &ec->flags) ?
-		msecs_to_jiffies(ACPI_EC_DELAY) : msecs_to_jiffies(1);
 	while (time_before(jiffies, delay))
-		if (wait_event_timeout(ec->wait, ec_check_ibf0(ec), timeout))
+		if (wait_event_timeout(ec->wait, ec_check_ibf0(ec),
+					msecs_to_jiffies(1)))
 			return 0;
 	return -ETIME;
 }
 
-static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t,
-			       int force_poll)
+static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t)
 {
 	int status;
 	u32 glk;
@@ -345,7 +321,7 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t,
 		status = -ETIME;
 		goto end;
 	}
-	status = acpi_ec_transaction_unlocked(ec, t, force_poll);
+	status = acpi_ec_transaction_unlocked(ec, t);
 end:
 	if (ec->global_lock)
 		acpi_release_global_lock(glk);
@@ -365,7 +341,7 @@ static int acpi_ec_burst_enable(struct acpi_ec *ec)
 				.wdata = NULL, .rdata = &d,
 				.wlen = 0, .rlen = 1};
 
-	return acpi_ec_transaction(ec, &t, 0);
+	return acpi_ec_transaction(ec, &t);
 }
 
 static int acpi_ec_burst_disable(struct acpi_ec *ec)
@@ -375,7 +351,7 @@ static int acpi_ec_burst_disable(struct acpi_ec *ec)
 				.wlen = 0, .rlen = 0};
 
 	return (acpi_ec_read_status(ec) & ACPI_EC_FLAG_BURST) ?
-				acpi_ec_transaction(ec, &t, 0) : 0;
+				acpi_ec_transaction(ec, &t) : 0;
 }
 
 static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 * data)
@@ -386,7 +362,7 @@ static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 * data)
 				.wdata = &address, .rdata = &d,
 				.wlen = 1, .rlen = 1};
 
-	result = acpi_ec_transaction(ec, &t, 0);
+	result = acpi_ec_transaction(ec, &t);
 	*data = d;
 	return result;
 }
@@ -398,7 +374,7 @@ static int acpi_ec_write(struct acpi_ec *ec, u8 address, u8 data)
 				.wdata = wdata, .rdata = NULL,
 				.wlen = 2, .rlen = 0};
 
-	return acpi_ec_transaction(ec, &t, 0);
+	return acpi_ec_transaction(ec, &t);
 }
 
 /*
@@ -466,7 +442,7 @@ int ec_transaction(u8 command,
 	if (!first_ec)
 		return -ENODEV;
 
-	return acpi_ec_transaction(first_ec, &t, force_poll);
+	return acpi_ec_transaction(first_ec, &t);
 }
 
 EXPORT_SYMBOL(ec_transaction);
@@ -487,7 +463,7 @@ static int acpi_ec_query(struct acpi_ec *ec, u8 * data)
 	 * bit to be cleared (and thus clearing the interrupt source).
 	 */
 
-	result = acpi_ec_transaction(ec, &t, 0);
+	result = acpi_ec_transaction(ec, &t);
 	if (result)
 		return result;
 
@@ -570,28 +546,10 @@ static u32 acpi_ec_gpe_handler(void *data)
 	pr_debug(PREFIX "~~~> interrupt\n");
 	status = acpi_ec_read_status(ec);
 
-	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);
-	}
-
+	advance_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) &&
-	    !test_bit(EC_FLAGS_NO_GPE, &ec->flags)) {
-		/* this is non-query, must be confirmation */
-		if (!test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) {
-			if (printk_ratelimit())
-				pr_info(PREFIX "non-query interrupt received,"
-					" switching to interrupt mode\n");
-		} else {
-			/* hush, STORM switches the mode every transaction */
-			pr_debug(PREFIX "non-query interrupt received,"
-				" switching to interrupt mode\n");
-		}
-		set_bit(EC_FLAGS_GPE_MODE, &ec->flags);
-	}
 	return ACPI_INTERRUPT_HANDLED;
 }
 
@@ -837,8 +795,6 @@ static int acpi_ec_add(struct acpi_device *device)
 	acpi_ec_add_fs(device);
 	pr_info(PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n",
 			  ec->gpe, ec->command_addr, ec->data_addr);
-	pr_info(PREFIX "driver started in %s mode\n",
-		(test_bit(EC_FLAGS_GPE_MODE, &ec->flags))?"interrupt":"poll");
 	return 0;
 }
 
@@ -1054,8 +1010,6 @@ static int acpi_ec_suspend(struct acpi_device *device, pm_message_t state)
 {
 	struct acpi_ec *ec = acpi_driver_data(device);
 	/* Stop using GPE */
-	set_bit(EC_FLAGS_NO_GPE, &ec->flags);
-	clear_bit(EC_FLAGS_GPE_MODE, &ec->flags);
 	acpi_disable_gpe(NULL, ec->gpe);
 	return 0;
 }
@@ -1064,8 +1018,6 @@ static int acpi_ec_resume(struct acpi_device *device)
 {
 	struct acpi_ec *ec = acpi_driver_data(device);
 	/* Enable use of GPE back */
-	clear_bit(EC_FLAGS_NO_GPE, &ec->flags);
-	set_bit(EC_FLAGS_GPE_MODE, &ec->flags);
 	acpi_enable_gpe(NULL, ec->gpe);
 	return 0;
 }

acpi-ec-restart-command-even-if-no-interrupts-from-ec.patch:
 ec.c |    4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

--- NEW FILE acpi-ec-restart-command-even-if-no-interrupts-from-ec.patch ---
From: Alexey Starikovskiy <astarikovskiy at suse.de>
Date: Thu, 1 Oct 2009 22:53:15 +0000 (+0400)
Subject: ACPI: EC: Restart command even if no interrupts from EC
X-Git-Tag: v2.6.32-rc3~4^2~2^2
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=e12ac3d018dd8f20a075f552020

ACPI: EC: Restart command even if no interrupts from EC

EC may forget a command without sending any "reset" interrupt,
thus we need to lessen the requirement for transaction restart.

Reference: http://bugzilla.kernel.org/show_bug.cgi?id=14247
Signed-off-by: Alexey Starikovskiy <astarikovskiy at suse.de>
Signed-off-by: Len Brown <len.brown at intel.com>
---

diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index f707960..8a4897d 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -232,10 +232,8 @@ static int ec_poll(struct acpi_ec *ec)
 			}
 			advance_transaction(ec, acpi_ec_read_status(ec));
 		} while (time_before(jiffies, delay));
-		if (!ec->curr->irq_count ||
-		    (acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF))
+		if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF)
 			break;
-		/* try restart command if we get any false interrupts */
 		pr_debug(PREFIX "controller reset, restart transaction\n");
 		spin_lock_irqsave(&ec->curr_lock, flags);
 		start_transaction(ec);

acpi-ec-use-burst-mode-only-for-msi-notebooks.patch:
 ec.c |    6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

--- NEW FILE acpi-ec-use-burst-mode-only-for-msi-notebooks.patch ---
From: Alexey Starikovskiy <astarikovskiy at suse.de>
Date: Fri, 28 Aug 2009 19:29:44 +0000 (+0400)
Subject: ACPI: EC: use BURST mode only for MSI notebooks
X-Git-Tag: v2.6.32-rc1~171^2~11^2~1
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=6a63b06f3c494cc87eade97f081300bda60acec7

ACPI: EC: use BURST mode only for MSI notebooks

Signed-off-by: Alexey Starikovskiy <astarikovskiy at suse.de>
Signed-off-by: Len Brown <len.brown at intel.com>
---

diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 839b542..788db78 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -575,7 +575,8 @@ acpi_ec_space_handler(u32 function, acpi_physical_address address,
 	if (bits != 8 && acpi_strict)
 		return AE_BAD_PARAMETER;
 
-	acpi_ec_burst_enable(ec);
+	if (EC_FLAGS_MSI)
+		acpi_ec_burst_enable(ec);
 
 	if (function == ACPI_READ) {
 		result = acpi_ec_read(ec, address, &temp);
@@ -596,7 +597,8 @@ acpi_ec_space_handler(u32 function, acpi_physical_address address,
 		}
 	}
 
-	acpi_ec_burst_disable(ec);
+	if (EC_FLAGS_MSI)
+		acpi_ec_burst_disable(ec);
 
 	switch (result) {
 	case -EINVAL:


Index: TODO
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/F-11/TODO,v
retrieving revision 1.71
retrieving revision 1.72
diff -u -p -r1.71 -r1.72
--- TODO	1 Jul 2009 19:22:18 -0000	1.71
+++ TODO	6 Oct 2009 07:33:21 -0000	1.72
@@ -89,17 +89,8 @@
 	https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=126403
 	http://lkml.org/lkml/2006/8/2/208
 
-* linux-2.6-net-tulip-interrupt.patch
-	Queued by DaveM for next release.
-
-* linux-2.6-pci-sysfs-remove-id.patch
-        In 2.6.30-rc1. Needed for KVM PCI device assignment
-        https://bugzilla.redhat.com/487103
-
-* linux-2.6-kvm-skip-pit-check.patch:
-	Waiting to be pushed upstream from kvm git.
-
-* linux-2.6-xen-check-for-nx-support.patch
-	https://bugzilla.redhat.com/492523
-	Needed for xen domU to boot on some machines. Upstream since
-	2.6.30-rc2.
+* acpi-ec-merge-irq-and-poll-modes.patch
+* acpi-ec-restart-command-even-if-no-interrupts-from-ec.patch
+* acpi-ec-use-burst-mode-only-for-msi-notebooks.patch
+	ACPI EC fixes from 2.6.32 (#492699, #525681)
+	Should go in F-12 and 2.6.31-stable too, once they're tested.


Index: kernel.spec
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/F-11/kernel.spec,v
retrieving revision 1.1752
retrieving revision 1.1753
diff -u -p -r1.1752 -r1.1753
--- kernel.spec	5 Oct 2009 23:14:06 -0000	1.1752
+++ kernel.spec	6 Oct 2009 07:33:21 -0000	1.1753
@@ -704,6 +704,10 @@ Patch3000: linux-2.6-fs-cifs-fix-port-nu
 
 # ACPI
 Patch4000: linux-2.6.30-cpuidle-faster-io.patch
+# EC fixes from 2.6.32 (#492699, #525681)
+Patch4010: acpi-ec-merge-irq-and-poll-modes.patch
+Patch4020: acpi-ec-use-burst-mode-only-for-msi-notebooks.patch
+Patch4030: acpi-ec-restart-command-even-if-no-interrupts-from-ec.patch
 
 #snmp fixes
 Patch10000: linux-2.6-missing-rfc2465-stats.patch
@@ -1249,6 +1253,10 @@ ApplyPatch linux-2.6-fs-cifs-fix-port-nu
 ApplyPatch linux-2.6-defaults-acpi-video.patch
 ApplyPatch linux-2.6-acpi-video-dos.patch
 ApplyPatch linux-2.6.30-cpuidle-faster-io.patch
+# EC fixes from 2.6.32 (#492699, #525681)
+ApplyPatch acpi-ec-merge-irq-and-poll-modes.patch
+ApplyPatch acpi-ec-use-burst-mode-only-for-msi-notebooks.patch
+ApplyPatch acpi-ec-restart-command-even-if-no-interrupts-from-ec.patch
 
 # Various low-impact patches to aid debugging.
 ApplyPatch linux-2.6-debug-sizeof-structs.patch
@@ -2012,6 +2020,9 @@ fi
 # and build.
 
 %changelog
+* Tue Oct 06 2009  Chuck Ebbert <cebbert at redhat.com>  2.6.30.9-74
+- ACPI EC bug fixes taken from kernel 2.6.32 (#492699, #525681)
+
 * Mon Oct 05 2009  Chuck Ebbert <cebbert at redhat.com>  2.6.30.9-73
 - Linux 2.6.30.9
 




More information about the fedora-extras-commits mailing list