Merge branches 'acpi-ec' and 'acpi-video'
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>
Mon, 3 Jul 2017 12:26:43 +0000 (14:26 +0200)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Mon, 3 Jul 2017 12:26:43 +0000 (14:26 +0200)
* acpi-ec:
  ACPI / EC: Add quirk for GL720VMK
  ACPI / EC: Fix media keys not working problem on some Asus laptops
  ACPI / EC: Add support to skip boot stage DSDT probe
  ACPI / EC: Enhance boot EC sanity check
  ACPI: EC: Fix EC command visibility for dynamic debug
  ACPI: EC: Fix an EC event IRQ storming issue

* acpi-video:
  ACPI / video: Add quirks for the Dell Precision 7510

1  2  3 
drivers/acpi/ec.c

diff --combined drivers/acpi/ec.c
   
   /* Uncomment next line to get verbose printout */
   /* #define DEBUG */
 --#define pr_fmt(fmt) "ACPI : EC: " fmt
 ++#define pr_fmt(fmt) "ACPI: EC: " fmt
   
   #include <linux/kernel.h>
   #include <linux/module.h>
@@@@ -190,6 -190,7 -190,6 +190,7 @@@@ static struct workqueue_struct *ec_quer
   
   static int EC_FLAGS_QUERY_HANDSHAKE; /* Needs QR_EC issued when SCI_EVT set */
   static int EC_FLAGS_CORRECT_ECDT; /* Needs ECDT port address correction */
+ +static int EC_FLAGS_IGNORE_DSDT_GPE; /* Needs ECDT GPE as correction setting */
   
   /* --------------------------------------------------------------------------
    *                           Logging/Debugging
@@@@ -316,7 -317,7 -316,7 +317,7 @@@@ static inline void acpi_ec_write_data(s
        ec->timestamp = jiffies;
   }
   
- -#ifdef DEBUG
+ +#if defined(DEBUG) || defined(CONFIG_DYNAMIC_DEBUG)
   static const char *acpi_ec_cmd_string(u8 cmd)
   {
        switch (cmd) {
@@@@ -459,8 -460,10 -459,8 +460,10 @@@@ static bool acpi_ec_submit_flushable_re
   
   static void acpi_ec_submit_query(struct acpi_ec *ec)
   {
- -     if (acpi_ec_event_enabled(ec) &&
- -         !test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags)) {
+ +     acpi_ec_set_storm(ec, EC_FLAGS_COMMAND_STORM);
+ +     if (!acpi_ec_event_enabled(ec))
+ +             return;
+ +     if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags)) {
                ec_dbg_evt("Command(%s) submitted/blocked",
                           acpi_ec_cmd_string(ACPI_EC_COMMAND_QUERY));
                ec->nr_pending_queries++;
   
   static void acpi_ec_complete_query(struct acpi_ec *ec)
   {
- -     if (test_bit(EC_FLAGS_QUERY_PENDING, &ec->flags)) {
- -             clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags);
+ +     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);
   }
   
   static inline void __acpi_ec_enable_event(struct acpi_ec *ec)
@@@@ -1362,13 -1364,23 -1362,13 +1364,23 @@@@ ec_parse_device(acpi_handle handle, u3
                                     ec_parse_io_ports, ec);
        if (ACPI_FAILURE(status))
                return status;
+ +     if (ec->data_addr == 0 || ec->command_addr == 0)
+ +             return AE_OK;
   
- -     /* Get GPE bit assignment (EC events). */
- -     /* TODO: Add support for _GPE returning a package */
- -     status = acpi_evaluate_integer(handle, "_GPE", NULL, &tmp);
- -     if (ACPI_FAILURE(status))
- -             return status;
- -     ec->gpe = tmp;
+ +     if (boot_ec && boot_ec_is_ecdt && EC_FLAGS_IGNORE_DSDT_GPE) {
+ +             /*
+ +              * Always inherit the GPE number setting from the ECDT
+ +              * EC.
+ +              */
+ +             ec->gpe = boot_ec->gpe;
+ +     } else {
+ +             /* Get GPE bit assignment (EC events). */
+ +             /* TODO: Add support for _GPE returning a package */
+ +             status = acpi_evaluate_integer(handle, "_GPE", NULL, &tmp);
+ +             if (ACPI_FAILURE(status))
+ +                     return status;
+ +             ec->gpe = tmp;
+ +     }
        /* Use the global lock for all EC transactions? */
        tmp = 0;
        acpi_evaluate_integer(handle, "_GLK", NULL, &tmp);
@@@@ -1665,12 -1677,26 -1665,12 +1677,26 @@@@ static const struct acpi_device_id ec_d
        {"", 0},
   };
   
+ +/*
+ + * This function is not Windows-compatible as Windows never enumerates the
+ + * namespace EC before the main ACPI device enumeration process. It is
+ + * retained for historical reason and will be deprecated in the future.
+ + */
   int __init acpi_ec_dsdt_probe(void)
   {
        acpi_status status;
        struct acpi_ec *ec;
        int ret;
   
+ +     /*
+ +      * If a platform has ECDT, there is no need to proceed as the
+ +      * following probe is not a part of the ACPI device enumeration,
+ +      * executing _STA is not safe, and thus this probe may risk of
+ +      * picking up an invalid EC device.
+ +      */
+ +     if (boot_ec)
+ +             return -ENODEV;
+ +
        ec = acpi_ec_alloc();
        if (!ec)
                return -ENOMEM;
@@@@ -1753,11 -1779,43 -1753,11 +1779,43 @@@@ static int ec_correct_ecdt(const struc
        return 0;
   }
   
+ +/*
+ + * Some DSDTs contain wrong GPE setting.
+ + * Asus FX502VD/VE, GL702VMK, X550VXK, X580VD
+ + * https://bugzilla.kernel.org/show_bug.cgi?id=195651
+ + */
+ +static int ec_honor_ecdt_gpe(const struct dmi_system_id *id)
+ +{
+ +     pr_debug("Detected system needing ignore DSDT GPE setting.\n");
+ +     EC_FLAGS_IGNORE_DSDT_GPE = 1;
+ +     return 0;
+ +}
+ +
   static struct dmi_system_id ec_dmi_table[] __initdata = {
        {
        ec_correct_ecdt, "MSI MS-171F", {
        DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star"),
        DMI_MATCH(DMI_PRODUCT_NAME, "MS-171F"),}, NULL},
+ +     {
+ +     ec_honor_ecdt_gpe, "ASUS FX502VD", {
+ +     DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+ +     DMI_MATCH(DMI_PRODUCT_NAME, "FX502VD"),}, NULL},
+ +     {
+ +     ec_honor_ecdt_gpe, "ASUS FX502VE", {
+ +     DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+ +     DMI_MATCH(DMI_PRODUCT_NAME, "FX502VE"),}, NULL},
+ +     {
+ +     ec_honor_ecdt_gpe, "ASUS GL702VMK", {
+ +     DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+ +     DMI_MATCH(DMI_PRODUCT_NAME, "GL702VMK"),}, NULL},
+ +     {
+ +     ec_honor_ecdt_gpe, "ASUS X550VXK", {
+ +     DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+ +     DMI_MATCH(DMI_PRODUCT_NAME, "X550VXK"),}, NULL},
+ +     {
+ +     ec_honor_ecdt_gpe, "ASUS X580VD", {
+ +     DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+ +     DMI_MATCH(DMI_PRODUCT_NAME, "X580VD"),}, NULL},
        {},
   };