diff options
Diffstat (limited to 'drivers/acpi/ec.c')
-rw-r--r-- | drivers/acpi/ec.c | 31 |
1 files changed, 21 insertions, 10 deletions
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 3d304ff7f095..5f9b74b9b71f 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
@@ -126,6 +126,7 @@ static int EC_FLAGS_MSI; /* Out-of-spec MSI controller */ | |||
126 | static int EC_FLAGS_VALIDATE_ECDT; /* ASUStec ECDTs need to be validated */ | 126 | static int EC_FLAGS_VALIDATE_ECDT; /* ASUStec ECDTs need to be validated */ |
127 | static int EC_FLAGS_SKIP_DSDT_SCAN; /* Not all BIOS survive early DSDT scan */ | 127 | static int EC_FLAGS_SKIP_DSDT_SCAN; /* Not all BIOS survive early DSDT scan */ |
128 | static int EC_FLAGS_CLEAR_ON_RESUME; /* Needs acpi_ec_clear() on boot/resume */ | 128 | static int EC_FLAGS_CLEAR_ON_RESUME; /* Needs acpi_ec_clear() on boot/resume */ |
129 | static int EC_FLAGS_QUERY_HANDSHAKE; /* Needs QR_EC issued when SCI_EVT set */ | ||
129 | 130 | ||
130 | /* -------------------------------------------------------------------------- | 131 | /* -------------------------------------------------------------------------- |
131 | * Transaction Management | 132 | * Transaction Management |
@@ -236,13 +237,8 @@ static bool advance_transaction(struct acpi_ec *ec) | |||
236 | } | 237 | } |
237 | return wakeup; | 238 | return wakeup; |
238 | } else { | 239 | } else { |
239 | /* | 240 | if (EC_FLAGS_QUERY_HANDSHAKE && |
240 | * There is firmware refusing to respond QR_EC when SCI_EVT | 241 | !(status & ACPI_EC_FLAG_SCI) && |
241 | * is not set, for which case, we complete the QR_EC | ||
242 | * without issuing it to the firmware. | ||
243 | * https://bugzilla.kernel.org/show_bug.cgi?id=86211 | ||
244 | */ | ||
245 | if (!(status & ACPI_EC_FLAG_SCI) && | ||
246 | (t->command == ACPI_EC_COMMAND_QUERY)) { | 242 | (t->command == ACPI_EC_COMMAND_QUERY)) { |
247 | t->flags |= ACPI_EC_COMMAND_POLL; | 243 | t->flags |= ACPI_EC_COMMAND_POLL; |
248 | t->rdata[t->ri++] = 0x00; | 244 | t->rdata[t->ri++] = 0x00; |
@@ -334,13 +330,13 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, | |||
334 | pr_debug("***** Command(%s) started *****\n", | 330 | pr_debug("***** Command(%s) started *****\n", |
335 | acpi_ec_cmd_string(t->command)); | 331 | acpi_ec_cmd_string(t->command)); |
336 | start_transaction(ec); | 332 | start_transaction(ec); |
337 | spin_unlock_irqrestore(&ec->lock, tmp); | ||
338 | ret = ec_poll(ec); | ||
339 | spin_lock_irqsave(&ec->lock, tmp); | ||
340 | if (ec->curr->command == ACPI_EC_COMMAND_QUERY) { | 333 | if (ec->curr->command == ACPI_EC_COMMAND_QUERY) { |
341 | clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); | 334 | clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); |
342 | pr_debug("***** Event stopped *****\n"); | 335 | pr_debug("***** Event stopped *****\n"); |
343 | } | 336 | } |
337 | spin_unlock_irqrestore(&ec->lock, tmp); | ||
338 | ret = ec_poll(ec); | ||
339 | spin_lock_irqsave(&ec->lock, tmp); | ||
344 | pr_debug("***** Command(%s) stopped *****\n", | 340 | pr_debug("***** Command(%s) stopped *****\n", |
345 | acpi_ec_cmd_string(t->command)); | 341 | acpi_ec_cmd_string(t->command)); |
346 | ec->curr = NULL; | 342 | ec->curr = NULL; |
@@ -1012,6 +1008,18 @@ static int ec_enlarge_storm_threshold(const struct dmi_system_id *id) | |||
1012 | } | 1008 | } |
1013 | 1009 | ||
1014 | /* | 1010 | /* |
1011 | * Acer EC firmware refuses to respond QR_EC when SCI_EVT is not set, for | ||
1012 | * which case, we complete the QR_EC without issuing it to the firmware. | ||
1013 | * https://bugzilla.kernel.org/show_bug.cgi?id=86211 | ||
1014 | */ | ||
1015 | static int ec_flag_query_handshake(const struct dmi_system_id *id) | ||
1016 | { | ||
1017 | pr_debug("Detected the EC firmware requiring QR_EC issued when SCI_EVT set\n"); | ||
1018 | EC_FLAGS_QUERY_HANDSHAKE = 1; | ||
1019 | return 0; | ||
1020 | } | ||
1021 | |||
1022 | /* | ||
1015 | * On some hardware it is necessary to clear events accumulated by the EC during | 1023 | * On some hardware it is necessary to clear events accumulated by the EC during |
1016 | * sleep. These ECs stop reporting GPEs until they are manually polled, if too | 1024 | * sleep. These ECs stop reporting GPEs until they are manually polled, if too |
1017 | * many events are accumulated. (e.g. Samsung Series 5/9 notebooks) | 1025 | * many events are accumulated. (e.g. Samsung Series 5/9 notebooks) |
@@ -1085,6 +1093,9 @@ static struct dmi_system_id ec_dmi_table[] __initdata = { | |||
1085 | { | 1093 | { |
1086 | ec_clear_on_resume, "Samsung hardware", { | 1094 | ec_clear_on_resume, "Samsung hardware", { |
1087 | DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD.")}, NULL}, | 1095 | DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD.")}, NULL}, |
1096 | { | ||
1097 | ec_flag_query_handshake, "Acer hardware", { | ||
1098 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), }, NULL}, | ||
1088 | {}, | 1099 | {}, |
1089 | }; | 1100 | }; |
1090 | 1101 | ||