| From 28fe5c825f8e15744d04c7c1b8df197950923ecd Mon Sep 17 00:00:00 2001 |
| From: Lan Tianyu <tianyu.lan@intel.com> |
| Date: Mon, 6 May 2013 03:23:40 +0000 |
| Subject: ACPI / EC: Restart transaction even when the IBF flag set |
| |
| From: Lan Tianyu <tianyu.lan@intel.com> |
| |
| commit 28fe5c825f8e15744d04c7c1b8df197950923ecd upstream. |
| |
| The EC driver works abnormally with IBF flag always set. |
| IBF means "The host has written a byte of data to the command |
| or data port, but the embedded controller has not yet read it". |
| If IBF is set in the EC status and not cleared, this will cause |
| all subsequent EC requests to fail with a timeout error. |
| |
| Change the EC driver so that it doesn't refuse to restart a |
| transaction if IBF is set in the status. Also increase the |
| number of transaction restarts to 5, as it turns out that 2 |
| is not sufficient in some cases. |
| |
| This bug happens on several different machines (Asus V1S, |
| Dell Latitude E6530, Samsung R719, Acer Aspire 5930G, |
| Sony Vaio SR19VN and others). |
| |
| [rjw: Changelog] |
| References: https://bugzilla.kernel.org/show_bug.cgi?id=14733 |
| References: https://bugzilla.kernel.org/show_bug.cgi?id=15560 |
| References: https://bugzilla.kernel.org/show_bug.cgi?id=15946 |
| References: https://bugzilla.kernel.org/show_bug.cgi?id=42945 |
| References: https://bugzilla.kernel.org/show_bug.cgi?id=48221 |
| Signed-off-by: Lan Tianyu <tianyu.lan@intel.com> |
| Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/acpi/ec.c | 4 +--- |
| 1 file changed, 1 insertion(+), 3 deletions(-) |
| |
| --- a/drivers/acpi/ec.c |
| +++ b/drivers/acpi/ec.c |
| @@ -223,7 +223,7 @@ static int ec_check_sci_sync(struct acpi |
| static int ec_poll(struct acpi_ec *ec) |
| { |
| unsigned long flags; |
| - int repeat = 2; /* number of command restarts */ |
| + int repeat = 5; /* number of command restarts */ |
| while (repeat--) { |
| unsigned long delay = jiffies + |
| msecs_to_jiffies(ec_delay); |
| @@ -241,8 +241,6 @@ static int ec_poll(struct acpi_ec *ec) |
| } |
| advance_transaction(ec, acpi_ec_read_status(ec)); |
| } while (time_before(jiffies, delay)); |
| - if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF) |
| - break; |
| pr_debug(PREFIX "controller reset, restart transaction\n"); |
| spin_lock_irqsave(&ec->lock, flags); |
| start_transaction(ec); |