Subject: [PATCH] [acpi ec] ADd interrupt-driven ->e_wait() method - Set in ec_intr_init() - Based on acpi_ec_intr_wait() from old school driver Signed-off-by: Patrick Mochel --- drivers/acpi/drivers/ec/intr.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 files changed, 40 insertions(+), 0 deletions(-) applies-to: 34187976ab1e5ce3a71527afd2bc62b85f9d889d da19508a1659e9a6cc47bcad262d9e8529b3fa00 diff --git a/drivers/acpi/drivers/ec/intr.c b/drivers/acpi/drivers/ec/intr.c index a4bf075..9b2dd89 100644 --- a/drivers/acpi/drivers/ec/intr.c +++ b/drivers/acpi/drivers/ec/intr.c @@ -15,7 +15,47 @@ #include "ec.h" +static int wait_intr(struct acpi_ec * ec, u32 event) +{ + u32 status; + int ret; + + ec->e_expect = event; + smp_mb(); + + if (event == ACPI_EC_EVENT_IBE) { + status = ec_read_status(ec); + if (~status & event) { + ec->e_expect = 0; + return 0; + } + } + + ret = wait_event_timeout(ec->e_waitq, !ec->e_expect, + msecs_to_jiffies(ACPI_EC_DELAY)); + ec->e_expect = 0; + smp_mb(); + + /* + * Verify the event in question has actually happened by + * querying the EC status. Do the check even if the operation + * timed-out to make sure that we didn't miss the interrupt. + */ + status = ec_read_status(ec); + + if (event == ACPI_EC_EVENT_OBF) { + if (status & ACPI_EC_FLAG_OBF) + return 0; + } else if (event == ACPI_EC_EVENT_IBE) { + if (~status & ACPI_EC_FLAG_IBF) + return 0; + } + return -ETIME; +} + int ec_intr_init(struct acpi_ec * ec) { + ec->e_wait = wait_intr; + return 0; } --- 0.99.9.GIT