|
@@ -126,6 +126,7 @@ static int EC_FLAGS_MSI; /* Out-of-spec MSI controller */
|
|
static int EC_FLAGS_VALIDATE_ECDT; /* ASUStec ECDTs need to be validated */
|
|
static int EC_FLAGS_VALIDATE_ECDT; /* ASUStec ECDTs need to be validated */
|
|
static int EC_FLAGS_SKIP_DSDT_SCAN; /* Not all BIOS survive early DSDT scan */
|
|
static int EC_FLAGS_SKIP_DSDT_SCAN; /* Not all BIOS survive early DSDT scan */
|
|
static int EC_FLAGS_CLEAR_ON_RESUME; /* Needs acpi_ec_clear() on boot/resume */
|
|
static int EC_FLAGS_CLEAR_ON_RESUME; /* Needs acpi_ec_clear() on boot/resume */
|
|
|
|
+static int EC_FLAGS_QUERY_HANDSHAKE; /* Needs QR_EC issued when SCI_EVT set */
|
|
|
|
|
|
/* --------------------------------------------------------------------------
|
|
/* --------------------------------------------------------------------------
|
|
* Transaction Management
|
|
* Transaction Management
|
|
@@ -236,13 +237,8 @@ static bool advance_transaction(struct acpi_ec *ec)
|
|
}
|
|
}
|
|
return wakeup;
|
|
return wakeup;
|
|
} else {
|
|
} else {
|
|
- /*
|
|
|
|
- * There is firmware refusing to respond QR_EC when SCI_EVT
|
|
|
|
- * is not set, for which case, we complete the QR_EC
|
|
|
|
- * without issuing it to the firmware.
|
|
|
|
- * https://bugzilla.kernel.org/show_bug.cgi?id=86211
|
|
|
|
- */
|
|
|
|
- if (!(status & ACPI_EC_FLAG_SCI) &&
|
|
|
|
|
|
+ if (EC_FLAGS_QUERY_HANDSHAKE &&
|
|
|
|
+ !(status & ACPI_EC_FLAG_SCI) &&
|
|
(t->command == ACPI_EC_COMMAND_QUERY)) {
|
|
(t->command == ACPI_EC_COMMAND_QUERY)) {
|
|
t->flags |= ACPI_EC_COMMAND_POLL;
|
|
t->flags |= ACPI_EC_COMMAND_POLL;
|
|
t->rdata[t->ri++] = 0x00;
|
|
t->rdata[t->ri++] = 0x00;
|
|
@@ -334,13 +330,13 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec,
|
|
pr_debug("***** Command(%s) started *****\n",
|
|
pr_debug("***** Command(%s) started *****\n",
|
|
acpi_ec_cmd_string(t->command));
|
|
acpi_ec_cmd_string(t->command));
|
|
start_transaction(ec);
|
|
start_transaction(ec);
|
|
- spin_unlock_irqrestore(&ec->lock, tmp);
|
|
|
|
- ret = ec_poll(ec);
|
|
|
|
- spin_lock_irqsave(&ec->lock, tmp);
|
|
|
|
if (ec->curr->command == ACPI_EC_COMMAND_QUERY) {
|
|
if (ec->curr->command == ACPI_EC_COMMAND_QUERY) {
|
|
clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags);
|
|
clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags);
|
|
pr_debug("***** Event stopped *****\n");
|
|
pr_debug("***** Event stopped *****\n");
|
|
}
|
|
}
|
|
|
|
+ spin_unlock_irqrestore(&ec->lock, tmp);
|
|
|
|
+ ret = ec_poll(ec);
|
|
|
|
+ spin_lock_irqsave(&ec->lock, tmp);
|
|
pr_debug("***** Command(%s) stopped *****\n",
|
|
pr_debug("***** Command(%s) stopped *****\n",
|
|
acpi_ec_cmd_string(t->command));
|
|
acpi_ec_cmd_string(t->command));
|
|
ec->curr = NULL;
|
|
ec->curr = NULL;
|
|
@@ -1011,6 +1007,18 @@ static int ec_enlarge_storm_threshold(const struct dmi_system_id *id)
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+/*
|
|
|
|
+ * Acer EC firmware refuses to respond QR_EC when SCI_EVT is not set, for
|
|
|
|
+ * which case, we complete the QR_EC without issuing it to the firmware.
|
|
|
|
+ * https://bugzilla.kernel.org/show_bug.cgi?id=86211
|
|
|
|
+ */
|
|
|
|
+static int ec_flag_query_handshake(const struct dmi_system_id *id)
|
|
|
|
+{
|
|
|
|
+ pr_debug("Detected the EC firmware requiring QR_EC issued when SCI_EVT set\n");
|
|
|
|
+ EC_FLAGS_QUERY_HANDSHAKE = 1;
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* On some hardware it is necessary to clear events accumulated by the EC during
|
|
* On some hardware it is necessary to clear events accumulated by the EC during
|
|
* sleep. These ECs stop reporting GPEs until they are manually polled, if too
|
|
* sleep. These ECs stop reporting GPEs until they are manually polled, if too
|
|
@@ -1085,6 +1093,9 @@ static struct dmi_system_id ec_dmi_table[] __initdata = {
|
|
{
|
|
{
|
|
ec_clear_on_resume, "Samsung hardware", {
|
|
ec_clear_on_resume, "Samsung hardware", {
|
|
DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD.")}, NULL},
|
|
DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD.")}, NULL},
|
|
|
|
+ {
|
|
|
|
+ ec_flag_query_handshake, "Acer hardware", {
|
|
|
|
+ DMI_MATCH(DMI_SYS_VENDOR, "Acer"), }, NULL},
|
|
{},
|
|
{},
|
|
};
|
|
};
|
|
|
|
|