|
@@ -112,8 +112,7 @@ enum {
|
|
|
EC_FLAGS_EVT_HANDLER_INSTALLED, /* _Qxx handlers installed */
|
|
|
EC_FLAGS_STARTED, /* Driver is started */
|
|
|
EC_FLAGS_STOPPED, /* Driver is stopped */
|
|
|
- EC_FLAGS_COMMAND_STORM, /* GPE storms occurred to the
|
|
|
- * current command processing */
|
|
|
+ EC_FLAGS_GPE_MASKED, /* GPE masked */
|
|
|
};
|
|
|
|
|
|
#define ACPI_EC_COMMAND_POLL 0x01 /* Available for command byte */
|
|
@@ -425,19 +424,19 @@ static void acpi_ec_complete_request(struct acpi_ec *ec)
|
|
|
wake_up(&ec->wait);
|
|
|
}
|
|
|
|
|
|
-static void acpi_ec_set_storm(struct acpi_ec *ec, u8 flag)
|
|
|
+static void acpi_ec_mask_gpe(struct acpi_ec *ec)
|
|
|
{
|
|
|
- if (!test_bit(flag, &ec->flags)) {
|
|
|
+ if (!test_bit(EC_FLAGS_GPE_MASKED, &ec->flags)) {
|
|
|
acpi_ec_disable_gpe(ec, false);
|
|
|
ec_dbg_drv("Polling enabled");
|
|
|
- set_bit(flag, &ec->flags);
|
|
|
+ set_bit(EC_FLAGS_GPE_MASKED, &ec->flags);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-static void acpi_ec_clear_storm(struct acpi_ec *ec, u8 flag)
|
|
|
+static void acpi_ec_unmask_gpe(struct acpi_ec *ec)
|
|
|
{
|
|
|
- if (test_bit(flag, &ec->flags)) {
|
|
|
- clear_bit(flag, &ec->flags);
|
|
|
+ if (test_bit(EC_FLAGS_GPE_MASKED, &ec->flags)) {
|
|
|
+ clear_bit(EC_FLAGS_GPE_MASKED, &ec->flags);
|
|
|
acpi_ec_enable_gpe(ec, false);
|
|
|
ec_dbg_drv("Polling disabled");
|
|
|
}
|
|
@@ -464,7 +463,7 @@ static bool acpi_ec_submit_flushable_request(struct acpi_ec *ec)
|
|
|
|
|
|
static void acpi_ec_submit_query(struct acpi_ec *ec)
|
|
|
{
|
|
|
- acpi_ec_set_storm(ec, EC_FLAGS_COMMAND_STORM);
|
|
|
+ acpi_ec_mask_gpe(ec);
|
|
|
if (!acpi_ec_event_enabled(ec))
|
|
|
return;
|
|
|
if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags)) {
|
|
@@ -480,7 +479,7 @@ static void acpi_ec_complete_query(struct acpi_ec *ec)
|
|
|
if (test_and_clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags))
|
|
|
ec_dbg_evt("Command(%s) unblocked",
|
|
|
acpi_ec_cmd_string(ACPI_EC_COMMAND_QUERY));
|
|
|
- acpi_ec_clear_storm(ec, EC_FLAGS_COMMAND_STORM);
|
|
|
+ acpi_ec_unmask_gpe(ec);
|
|
|
}
|
|
|
|
|
|
static inline void __acpi_ec_enable_event(struct acpi_ec *ec)
|
|
@@ -700,7 +699,7 @@ err:
|
|
|
++t->irq_count;
|
|
|
/* Allow triggering on 0 threshold */
|
|
|
if (t->irq_count == ec_storm_threshold)
|
|
|
- acpi_ec_set_storm(ec, EC_FLAGS_COMMAND_STORM);
|
|
|
+ acpi_ec_mask_gpe(ec);
|
|
|
}
|
|
|
}
|
|
|
out:
|
|
@@ -798,7 +797,7 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec,
|
|
|
|
|
|
spin_lock_irqsave(&ec->lock, tmp);
|
|
|
if (t->irq_count == ec_storm_threshold)
|
|
|
- acpi_ec_clear_storm(ec, EC_FLAGS_COMMAND_STORM);
|
|
|
+ acpi_ec_unmask_gpe(ec);
|
|
|
ec_dbg_req("Command(%s) stopped", acpi_ec_cmd_string(t->command));
|
|
|
ec->curr = NULL;
|
|
|
/* Disable GPE for command processing (IBF=0/OBF=1) */
|
|
@@ -1586,9 +1585,7 @@ static bool acpi_is_boot_ec(struct acpi_ec *ec)
|
|
|
{
|
|
|
if (!boot_ec)
|
|
|
return false;
|
|
|
- if (ec->handle == boot_ec->handle &&
|
|
|
- ec->gpe == boot_ec->gpe &&
|
|
|
- ec->command_addr == boot_ec->command_addr &&
|
|
|
+ if (ec->command_addr == boot_ec->command_addr &&
|
|
|
ec->data_addr == boot_ec->data_addr)
|
|
|
return true;
|
|
|
return false;
|
|
@@ -1613,6 +1610,13 @@ static int acpi_ec_add(struct acpi_device *device)
|
|
|
|
|
|
if (acpi_is_boot_ec(ec)) {
|
|
|
boot_ec_is_ecdt = false;
|
|
|
+ /*
|
|
|
+ * Trust PNP0C09 namespace location rather than ECDT ID.
|
|
|
+ *
|
|
|
+ * But trust ECDT GPE rather than _GPE because of ASUS quirks,
|
|
|
+ * so do not change boot_ec->gpe to ec->gpe.
|
|
|
+ */
|
|
|
+ boot_ec->handle = ec->handle;
|
|
|
acpi_handle_debug(ec->handle, "duplicated.\n");
|
|
|
acpi_ec_free(ec);
|
|
|
ec = boot_ec;
|
|
@@ -1747,18 +1751,20 @@ static int __init acpi_ec_ecdt_start(void)
|
|
|
|
|
|
if (!boot_ec)
|
|
|
return -ENODEV;
|
|
|
- /*
|
|
|
- * The DSDT EC should have already been started in
|
|
|
- * acpi_ec_add().
|
|
|
- */
|
|
|
+ /* In case acpi_ec_ecdt_start() is called after acpi_ec_add() */
|
|
|
if (!boot_ec_is_ecdt)
|
|
|
return -ENODEV;
|
|
|
|
|
|
/*
|
|
|
* At this point, the namespace and the GPE is initialized, so
|
|
|
* start to find the namespace objects and handle the events.
|
|
|
+ *
|
|
|
+ * Note: ec->handle can be valid if this function is called after
|
|
|
+ * acpi_ec_add(), hence the fast path.
|
|
|
*/
|
|
|
- if (!acpi_ec_ecdt_get_handle(&handle))
|
|
|
+ if (boot_ec->handle != ACPI_ROOT_OBJECT)
|
|
|
+ handle = boot_ec->handle;
|
|
|
+ else if (!acpi_ec_ecdt_get_handle(&handle))
|
|
|
return -ENODEV;
|
|
|
return acpi_config_boot_ec(boot_ec, handle, true, true);
|
|
|
}
|
|
@@ -2011,8 +2017,8 @@ int __init acpi_ec_init(void)
|
|
|
return result;
|
|
|
|
|
|
/* Drivers must be started after acpi_ec_query_init() */
|
|
|
- ecdt_fail = acpi_ec_ecdt_start();
|
|
|
dsdt_fail = acpi_bus_register_driver(&acpi_ec_driver);
|
|
|
+ ecdt_fail = acpi_ec_ecdt_start();
|
|
|
return ecdt_fail && dsdt_fail ? -ENODEV : 0;
|
|
|
}
|
|
|
|