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 */  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_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 @@ -236,13 +237,8 @@ static bool advance_transaction(struct acpi_ec *ec)  		}  		return wakeup;  	} 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->flags |= ACPI_EC_COMMAND_POLL;  			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",  		 acpi_ec_cmd_string(t->command));  	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) {  		clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags);  		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",  		 acpi_ec_cmd_string(t->command));  	ec->curr = NULL; @@ -1012,6 +1008,18 @@ static int ec_enlarge_storm_threshold(const struct dmi_system_id *id)  }  /* + * 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   * sleep. These ECs stop reporting GPEs until they are manually polled, if too   * many events are accumulated. (e.g. Samsung Series 5/9 notebooks) @@ -1085,6 +1093,9 @@ static struct dmi_system_id ec_dmi_table[] __initdata = {  	{  	ec_clear_on_resume, "Samsung hardware", {  	DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD.")}, NULL}, +	{ +	ec_flag_query_handshake, "Acer hardware", { +	DMI_MATCH(DMI_SYS_VENDOR, "Acer"), }, NULL},  	{},  };  | 
