Alan Jenkins wrote:
Rafael J. Wysocki wrote:
On Saturday, 11 of October 2008, Alexey Starikovskiy wrote:
Rafael J. Wysocki wrote:
No, we discussed this before -- we are outside of the transaction, thus
no GPE
activity could interfere with ec_check_ibf0.
Ok, this is in the process context and we don't really expect to get an
interrupt at this point, but what happens if the EC generates an event that's
not related to any transiaction. Is that guaranteed to never happen?
Interrupt handler in this case can't cause a change to status register, thus our
read of it will not be affected by interrupt.
Ok, thanks.
Alan, does the patch work for you?
Rafael
Yes. Two reboot cycles, three suspend/resume cycles each, and no error
message.
I hope we have a better fix in mind though :-P. The patch doesn't solve
the unnecessary 500ms delay when this thing happens.
Something like this?
Regards,
Alex.
ACPI: EC: Check for IBF=0 once again after timeout
From: Alexey Starikovskiy <astarikovskiy@xxxxxxx>
Signed-off-by: Alexey Starikovskiy <astarikovskiy@xxxxxxx>
---
drivers/acpi/ec.c | 14 ++++++++++++--
1 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 69f5f78..5e7c9c5 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -300,6 +300,17 @@ static int ec_check_ibf0(struct acpi_ec *ec)
return (status & ACPI_EC_FLAG_IBF) == 0;
}
+static int ec_wait_ibf0(struct acpi_ec *ec)
+{
+ unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY);
+ while (time_before(jiffies, delay)) {
+ 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)
{
@@ -317,8 +328,7 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t,
goto unlock;
}
}
- if (!wait_event_timeout(ec->wait, ec_check_ibf0(ec),
- msecs_to_jiffies(ACPI_EC_DELAY))) {
+ if (ec_wait_ibf0(ec)) {
pr_err(PREFIX "input buffer is not empty, "
"aborting transaction\n");
status = -ETIME;