Commit 7c6db5e5 authored by Denis M. Sadykov's avatar Denis M. Sadykov Committed by Len Brown

ACPI: EC: Remove unnecessary delay added by previous transation patch.

Remove unnecessary delay (50 ms) while reading data from EC in interrupt mode.
Signed-off-by: default avatarAlexey Y. Starikovskiy <alexey.y.starikovskiy@intel.com>
Signed-off-by: default avatarLen Brown <len.brown@intel.com>
parent d7a76e4c
...@@ -100,7 +100,7 @@ union acpi_ec { ...@@ -100,7 +100,7 @@ union acpi_ec {
struct acpi_generic_address command_addr; struct acpi_generic_address command_addr;
struct acpi_generic_address data_addr; struct acpi_generic_address data_addr;
unsigned long global_lock; unsigned long global_lock;
unsigned int expect_event; u8 expect_event;
atomic_t leaving_burst; /* 0 : No, 1 : Yes, 2: abort */ atomic_t leaving_burst; /* 0 : No, 1 : Yes, 2: abort */
atomic_t pending_gpe; atomic_t pending_gpe;
struct semaphore sem; struct semaphore sem;
...@@ -121,7 +121,7 @@ union acpi_ec { ...@@ -121,7 +121,7 @@ union acpi_ec {
}; };
static int acpi_ec_poll_wait(union acpi_ec *ec, u8 event); static int acpi_ec_poll_wait(union acpi_ec *ec, u8 event);
static int acpi_ec_intr_wait(union acpi_ec *ec, unsigned int event); static int acpi_ec_intr_wait(union acpi_ec *ec, u8 event);
static int acpi_ec_poll_transaction(union acpi_ec *ec, u8 command, static int acpi_ec_poll_transaction(union acpi_ec *ec, u8 command,
const u8 *wdata, unsigned wdata_len, const u8 *wdata, unsigned wdata_len,
u8 *rdata, unsigned rdata_len); u8 *rdata, unsigned rdata_len);
...@@ -161,6 +161,22 @@ static u32 acpi_ec_read_status(union acpi_ec *ec) ...@@ -161,6 +161,22 @@ static u32 acpi_ec_read_status(union acpi_ec *ec)
return status; return status;
} }
static int acpi_ec_check_status(u32 status, u8 event) {
switch (event) {
case ACPI_EC_EVENT_OBF:
if (status & ACPI_EC_FLAG_OBF)
return 1;
case ACPI_EC_EVENT_IBE:
if (!(status & ACPI_EC_FLAG_IBF))
return 1;
default:
break;
}
return 0;
}
static int acpi_ec_wait(union acpi_ec *ec, u8 event) static int acpi_ec_wait(union acpi_ec *ec, u8 event)
{ {
if (acpi_ec_poll_mode) if (acpi_ec_poll_mode)
...@@ -203,47 +219,28 @@ static int acpi_ec_poll_wait(union acpi_ec *ec, u8 event) ...@@ -203,47 +219,28 @@ static int acpi_ec_poll_wait(union acpi_ec *ec, u8 event)
return -ETIME; return -ETIME;
} }
static int acpi_ec_intr_wait(union acpi_ec *ec, unsigned int event)
{
int result = 0;
static int acpi_ec_intr_wait(union acpi_ec *ec, u8 event)
{
long time_left;
ec->intr.expect_event = event; ec->intr.expect_event = event;
smp_mb();
switch (event) { if (acpi_ec_check_status(acpi_ec_read_status(ec), event)) {
case ACPI_EC_EVENT_IBE:
if (~acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF) {
ec->intr.expect_event = 0; ec->intr.expect_event = 0;
return 0; return 0;
}
break;
default:
break;
} }
result = wait_event_timeout(ec->intr.wait, time_left = wait_event_timeout(ec->intr.wait, !ec->intr.expect_event,
!ec->intr.expect_event, msecs_to_jiffies(ACPI_EC_DELAY));
msecs_to_jiffies(ACPI_EC_DELAY));
ec->intr.expect_event = 0; ec->intr.expect_event = 0;
smp_mb(); if (time_left <= 0) {
if (acpi_ec_check_status(acpi_ec_read_status(ec), event)) {
/* return 0;
* Verify that the event in question has actually happened by }
* querying EC status. Do the check even if operation timed-out } else {
* to make sure that we did not miss interrupt. return 0;
*/
switch (event) {
case ACPI_EC_EVENT_OBF:
if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_OBF)
return 0;
break;
case ACPI_EC_EVENT_IBE:
if (~acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF)
return 0;
break;
} }
return -ETIME; return -ETIME;
...@@ -293,7 +290,7 @@ int acpi_ec_leave_burst_mode(union acpi_ec *ec) ...@@ -293,7 +290,7 @@ int acpi_ec_leave_burst_mode(union acpi_ec *ec)
goto end; goto end;
acpi_hw_low_level_write(8, ACPI_EC_BURST_DISABLE, &ec->common.command_addr); acpi_hw_low_level_write(8, ACPI_EC_BURST_DISABLE, &ec->common.command_addr);
acpi_ec_wait(ec, ACPI_EC_FLAG_IBF); acpi_ec_wait(ec, ACPI_EC_FLAG_IBF);
} }
atomic_set(&ec->intr.leaving_burst, 1); atomic_set(&ec->intr.leaving_burst, 1);
return 0; return 0;
end: end:
...@@ -333,32 +330,32 @@ static int acpi_ec_transaction_unlocked(union acpi_ec *ec, u8 command, ...@@ -333,32 +330,32 @@ static int acpi_ec_transaction_unlocked(union acpi_ec *ec, u8 command,
acpi_hw_low_level_write(8, command, &ec->common.command_addr); acpi_hw_low_level_write(8, command, &ec->common.command_addr);
result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); for (; wdata_len > 0; wdata_len --) {
if (result) result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
return result; if (result)
return result;
for (; wdata_len > 0; wdata_len --) {
acpi_hw_low_level_write(8, *(wdata++), &ec->common.data_addr);
result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); acpi_hw_low_level_write(8, *(wdata++), &ec->common.data_addr);
if (result)
return result;
} }
if (command == ACPI_EC_COMMAND_WRITE) {
result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
if (result)
return result;
}
for (; rdata_len > 0; rdata_len --) { for (; rdata_len > 0; rdata_len --) {
u32 d; u32 d;
result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF); result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
if (result) if (result)
return result; return result;
acpi_hw_low_level_read(8, &d, &ec->common.data_addr); acpi_hw_low_level_read(8, &d, &ec->common.data_addr);
*(rdata++) = (u8) d; *(rdata++) = (u8) d;
} }
return 0; return 0;
} }
static int acpi_ec_poll_transaction(union acpi_ec *ec, u8 command, static int acpi_ec_poll_transaction(union acpi_ec *ec, u8 command,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment