mirror of
https://github.com/rd-stuffs/msm-4.14.git
synced 2025-02-20 11:45:48 +08:00
ACPI: EC: Unify poll and interrupt gpe handlers
Signed-off-by: Alexey Y. Starikovskiy <alexey.y.starikovskiy@intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
This commit is contained in:
parent
3576cf619b
commit
8e0341ba79
@ -112,11 +112,6 @@ static struct acpi_ec *ec_ecdt;
|
|||||||
static struct acpi_device *first_ec;
|
static struct acpi_device *first_ec;
|
||||||
static int acpi_ec_mode = EC_INTR;
|
static int acpi_ec_mode = EC_INTR;
|
||||||
|
|
||||||
static void acpi_ec_gpe_poll_query(void *ec_cxt);
|
|
||||||
static void acpi_ec_gpe_intr_query(void *ec_cxt);
|
|
||||||
static u32 acpi_ec_gpe_poll_handler(void *data);
|
|
||||||
static u32 acpi_ec_gpe_intr_handler(void *data);
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------
|
||||||
Transaction Management
|
Transaction Management
|
||||||
-------------------------------------------------------------------------- */
|
-------------------------------------------------------------------------- */
|
||||||
@ -428,20 +423,12 @@ static int acpi_ec_query(struct acpi_ec *ec, u32 * data)
|
|||||||
Event Management
|
Event Management
|
||||||
-------------------------------------------------------------------------- */
|
-------------------------------------------------------------------------- */
|
||||||
|
|
||||||
union acpi_ec_query_data {
|
struct acpi_ec_query_data {
|
||||||
acpi_handle handle;
|
acpi_handle handle;
|
||||||
u8 data;
|
u8 data;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void acpi_ec_gpe_query(void *ec_cxt)
|
static void acpi_ec_gpe_query(void *ec_cxt)
|
||||||
{
|
|
||||||
if (acpi_ec_mode == EC_POLL)
|
|
||||||
acpi_ec_gpe_poll_query(ec_cxt);
|
|
||||||
else
|
|
||||||
acpi_ec_gpe_intr_query(ec_cxt);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void acpi_ec_gpe_poll_query(void *ec_cxt)
|
|
||||||
{
|
{
|
||||||
struct acpi_ec *ec = (struct acpi_ec *)ec_cxt;
|
struct acpi_ec *ec = (struct acpi_ec *)ec_cxt;
|
||||||
u32 value = 0;
|
u32 value = 0;
|
||||||
@ -454,18 +441,8 @@ static void acpi_ec_gpe_poll_query(void *ec_cxt)
|
|||||||
if (!ec_cxt)
|
if (!ec_cxt)
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
if (down_interruptible (&ec->sem)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
value = acpi_ec_read_status(ec);
|
value = acpi_ec_read_status(ec);
|
||||||
up(&ec->sem);
|
|
||||||
|
|
||||||
/* TBD: Implement asynch events!
|
|
||||||
* NOTE: All we care about are EC-SCI's. Other EC events are
|
|
||||||
* handled via polling (yuck!). This is because some systems
|
|
||||||
* treat EC-SCIs as level (versus EDGE!) triggered, preventing
|
|
||||||
* a purely interrupt-driven approach (grumble, grumble).
|
|
||||||
*/
|
|
||||||
if (!(value & ACPI_EC_FLAG_SCI))
|
if (!(value & ACPI_EC_FLAG_SCI))
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
@ -475,96 +452,36 @@ static void acpi_ec_gpe_poll_query(void *ec_cxt)
|
|||||||
object_name[2] = hex[((value >> 4) & 0x0F)];
|
object_name[2] = hex[((value >> 4) & 0x0F)];
|
||||||
object_name[3] = hex[(value & 0x0F)];
|
object_name[3] = hex[(value & 0x0F)];
|
||||||
|
|
||||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluating %s\n", object_name));
|
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluating %s", object_name));
|
||||||
|
|
||||||
acpi_evaluate_object(ec->handle, object_name, NULL, NULL);
|
acpi_evaluate_object(ec->handle, object_name, NULL, NULL);
|
||||||
|
|
||||||
end:
|
end:
|
||||||
acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
|
acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
|
||||||
}
|
}
|
||||||
static void acpi_ec_gpe_intr_query(void *ec_cxt)
|
|
||||||
{
|
|
||||||
struct acpi_ec *ec = (struct acpi_ec *)ec_cxt;
|
|
||||||
u32 value;
|
|
||||||
int result = -ENODATA;
|
|
||||||
static char object_name[5] = { '_', 'Q', '0', '0', '\0' };
|
|
||||||
const char hex[] = { '0', '1', '2', '3', '4', '5', '6', '7',
|
|
||||||
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_SCI)
|
|
||||||
result = acpi_ec_query(ec, &value);
|
|
||||||
|
|
||||||
if (result)
|
|
||||||
goto end;
|
|
||||||
|
|
||||||
object_name[2] = hex[((value >> 4) & 0x0F)];
|
|
||||||
object_name[3] = hex[(value & 0x0F)];
|
|
||||||
|
|
||||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluating %s\n", object_name));
|
|
||||||
|
|
||||||
acpi_evaluate_object(ec->handle, object_name, NULL, NULL);
|
|
||||||
end:
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
static u32 acpi_ec_gpe_handler(void *data)
|
static u32 acpi_ec_gpe_handler(void *data)
|
||||||
{
|
|
||||||
if (acpi_ec_mode == EC_POLL)
|
|
||||||
return acpi_ec_gpe_poll_handler(data);
|
|
||||||
else
|
|
||||||
return acpi_ec_gpe_intr_handler(data);
|
|
||||||
}
|
|
||||||
static u32 acpi_ec_gpe_poll_handler(void *data)
|
|
||||||
{
|
|
||||||
acpi_status status = AE_OK;
|
|
||||||
struct acpi_ec *ec = (struct acpi_ec *)data;
|
|
||||||
|
|
||||||
if (!ec)
|
|
||||||
return ACPI_INTERRUPT_NOT_HANDLED;
|
|
||||||
|
|
||||||
acpi_disable_gpe(NULL, ec->gpe_bit, ACPI_ISR);
|
|
||||||
|
|
||||||
status = acpi_os_execute(OSL_EC_POLL_HANDLER, acpi_ec_gpe_query, ec);
|
|
||||||
|
|
||||||
if (status == AE_OK)
|
|
||||||
return ACPI_INTERRUPT_HANDLED;
|
|
||||||
else
|
|
||||||
return ACPI_INTERRUPT_NOT_HANDLED;
|
|
||||||
}
|
|
||||||
static u32 acpi_ec_gpe_intr_handler(void *data)
|
|
||||||
{
|
{
|
||||||
acpi_status status = AE_OK;
|
acpi_status status = AE_OK;
|
||||||
u32 value;
|
u32 value;
|
||||||
|
u8 exec_mode;
|
||||||
struct acpi_ec *ec = (struct acpi_ec *)data;
|
struct acpi_ec *ec = (struct acpi_ec *)data;
|
||||||
|
|
||||||
if (!ec)
|
|
||||||
return ACPI_INTERRUPT_NOT_HANDLED;
|
|
||||||
|
|
||||||
acpi_clear_gpe(NULL, ec->gpe_bit, ACPI_ISR);
|
acpi_clear_gpe(NULL, ec->gpe_bit, ACPI_ISR);
|
||||||
value = acpi_ec_read_status(ec);
|
value = acpi_ec_read_status(ec);
|
||||||
|
|
||||||
switch (ec->expect_event) {
|
if (acpi_ec_mode == EC_INTR) {
|
||||||
case ACPI_EC_EVENT_OBF_1:
|
if (acpi_ec_check_status(value, ec->expect_event)) {
|
||||||
if (!(value & ACPI_EC_FLAG_OBF))
|
ec->expect_event = 0;
|
||||||
break;
|
wake_up(&ec->wait);
|
||||||
ec->expect_event = 0;
|
}
|
||||||
wake_up(&ec->wait);
|
exec_mode = OSL_EC_BURST_HANDLER;
|
||||||
break;
|
} else {
|
||||||
case ACPI_EC_EVENT_IBF_0:
|
exec_mode = OSL_EC_POLL_HANDLER;
|
||||||
if ((value & ACPI_EC_FLAG_IBF))
|
|
||||||
break;
|
|
||||||
ec->expect_event = 0;
|
|
||||||
wake_up(&ec->wait);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value & ACPI_EC_FLAG_SCI) {
|
if (value & ACPI_EC_FLAG_SCI) {
|
||||||
status = acpi_os_execute(OSL_EC_BURST_HANDLER,
|
status = acpi_os_execute(exec_mode, acpi_ec_gpe_query, ec);
|
||||||
acpi_ec_gpe_query, ec);
|
|
||||||
return status == AE_OK ?
|
return status == AE_OK ?
|
||||||
ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED;
|
ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user