Input: soc_button_array - add invalid acpi_index DMI quirk handling
authorHans de Goede <hdegoede@redhat.com>
Thu, 11 May 2023 18:57:04 +0000 (11:57 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 28 Jun 2023 09:12:37 +0000 (11:12 +0200)
[ Upstream commit 20a99a291d564a559cc2fd013b4824a3bb3f1db7 ]

Some devices have a wrong entry in their button array which points to
a GPIO which is required in another driver, so soc_button_array must
not claim it.

A specific example of this is the Lenovo Yoga Book X90F / X90L,
where the PNP0C40 home button entry points to a GPIO which is not
a home button and which is required by the lenovo-yogabook driver.

Add a DMI quirk table which can specify an ACPI GPIO resource index which
should be skipped; and add an entry for the Lenovo Yoga Book X90F / X90L
to this new DMI quirk table.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Link: https://lore.kernel.org/r/20230414072116.4497-1-hdegoede@redhat.com
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/input/misc/soc_button_array.c

index 0948938..e79f549 100644 (file)
@@ -109,6 +109,27 @@ static const struct dmi_system_id dmi_use_low_level_irq[] = {
 };
 
 /*
+ * Some devices have a wrong entry which points to a GPIO which is
+ * required in another driver, so this driver must not claim it.
+ */
+static const struct dmi_system_id dmi_invalid_acpi_index[] = {
+       {
+               /*
+                * Lenovo Yoga Book X90F / X90L, the PNP0C40 home button entry
+                * points to a GPIO which is not a home button and which is
+                * required by the lenovo-yogabook driver.
+                */
+               .matches = {
+                       DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
+                       DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "CHERRYVIEW D1 PLATFORM"),
+                       DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "YETI-11"),
+               },
+               .driver_data = (void *)1l,
+       },
+       {} /* Terminating entry */
+};
+
+/*
  * Get the Nth GPIO number from the ACPI object.
  */
 static int soc_button_lookup_gpio(struct device *dev, int acpi_index,
@@ -137,6 +158,8 @@ soc_button_device_create(struct platform_device *pdev,
        struct platform_device *pd;
        struct gpio_keys_button *gpio_keys;
        struct gpio_keys_platform_data *gpio_keys_pdata;
+       const struct dmi_system_id *dmi_id;
+       int invalid_acpi_index = -1;
        int error, gpio, irq;
        int n_buttons = 0;
 
@@ -154,10 +177,17 @@ soc_button_device_create(struct platform_device *pdev,
        gpio_keys = (void *)(gpio_keys_pdata + 1);
        n_buttons = 0;
 
+       dmi_id = dmi_first_match(dmi_invalid_acpi_index);
+       if (dmi_id)
+               invalid_acpi_index = (long)dmi_id->driver_data;
+
        for (info = button_info; info->name; info++) {
                if (info->autorepeat != autorepeat)
                        continue;
 
+               if (info->acpi_index == invalid_acpi_index)
+                       continue;
+
                error = soc_button_lookup_gpio(&pdev->dev, info->acpi_index, &gpio, &irq);
                if (error || irq < 0) {
                        /*