123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440 |
- From be8bb5f93d32d3ac7f918cdbfb04b412673ff80b Mon Sep 17 00:00:00 2001
- From: Maximilian Luz <luzmaximilian@gmail.com>
- Date: Sat, 27 Jul 2019 17:51:37 +0200
- Subject: [PATCH] platform/x86: surfacepro3_button: Fix device check
- Do not use the surfacepro3_button driver on newer Microsoft Surface
- models, only use it on the Surface Pro 3 and 4. Newer models (5th, 6th
- and possibly future generations) use the same device as the Surface Pro
- 4 to represent their volume and power buttons (MSHW0040), but their
- actual implementation is significantly different. This patch ensures
- that the surfacepro3_button driver is only used on the Pro 3 and 4
- models, allowing a different driver to bind on other models.
- Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com>
- Patchset: surface-buttons
- ---
- drivers/platform/x86/surfacepro3_button.c | 47 +++++++++++++++++++++++
- 1 file changed, 47 insertions(+)
- diff --git a/drivers/platform/x86/surfacepro3_button.c b/drivers/platform/x86/surfacepro3_button.c
- index 1b491690ce07..96627627060e 100644
- --- a/drivers/platform/x86/surfacepro3_button.c
- +++ b/drivers/platform/x86/surfacepro3_button.c
- @@ -24,6 +24,12 @@
- #define SURFACE_BUTTON_OBJ_NAME "VGBI"
- #define SURFACE_BUTTON_DEVICE_NAME "Surface Pro 3/4 Buttons"
-
- +#define MSHW0040_DSM_REVISION 0x01
- +#define MSHW0040_DSM_GET_OMPR 0x02 // get OEM Platform Revision
- +static const guid_t MSHW0040_DSM_UUID =
- + GUID_INIT(0x6fd05c69, 0xcde3, 0x49f4, 0x95, 0xed, 0xab, 0x16, 0x65,
- + 0x49, 0x80, 0x35);
- +
- #define SURFACE_BUTTON_NOTIFY_TABLET_MODE 0xc8
-
- #define SURFACE_BUTTON_NOTIFY_PRESS_POWER 0xc6
- @@ -146,6 +152,44 @@ static int surface_button_resume(struct device *dev)
- }
- #endif
-
- +/*
- + * Surface Pro 4 and Surface Book 2 / Surface Pro 2017 use the same device
- + * ID (MSHW0040) for the power/volume buttons. Make sure this is the right
- + * device by checking for the _DSM method and OEM Platform Revision.
- + *
- + * Returns true if the driver should bind to this device, i.e. the device is
- + * either MSWH0028 (Pro 3) or MSHW0040 on a Pro 4 or Book 1.
- + */
- +static bool surface_button_check_MSHW0040(struct acpi_device *dev)
- +{
- + acpi_handle handle = dev->handle;
- + union acpi_object *result;
- + u64 oem_platform_rev = 0; // valid revisions are nonzero
- +
- + // get OEM platform revision
- + result = acpi_evaluate_dsm_typed(handle, &MSHW0040_DSM_UUID,
- + MSHW0040_DSM_REVISION,
- + MSHW0040_DSM_GET_OMPR,
- + NULL, ACPI_TYPE_INTEGER);
- +
- + /*
- + * If evaluating the _DSM fails, the method is not present. This means
- + * that we have either MSHW0028 or MSHW0040 on Pro 4 or Book 1, so we
- + * should use this driver. We use revision 0 indicating it is
- + * unavailable.
- + */
- +
- + if (result) {
- + oem_platform_rev = result->integer.value;
- + ACPI_FREE(result);
- + }
- +
- + dev_dbg(&dev->dev, "OEM Platform Revision %llu\n", oem_platform_rev);
- +
- + return oem_platform_rev == 0;
- +}
- +
- +
- static int surface_button_add(struct acpi_device *device)
- {
- struct surface_button *button;
- @@ -158,6 +202,9 @@ static int surface_button_add(struct acpi_device *device)
- strlen(SURFACE_BUTTON_OBJ_NAME)))
- return -ENODEV;
-
- + if (!surface_button_check_MSHW0040(device))
- + return -ENODEV;
- +
- button = kzalloc(sizeof(struct surface_button), GFP_KERNEL);
- if (!button)
- return -ENOMEM;
- --
- 2.33.0
- From dc6c755a5867401c03cb7ca17396f8d9b05df58d Mon Sep 17 00:00:00 2001
- From: Maximilian Luz <luzmaximilian@gmail.com>
- Date: Sat, 27 Jul 2019 17:52:01 +0200
- Subject: [PATCH] Input: soc_button_array - Add support for newer surface
- devices
- Power and volume button support for 5th and 6th generation Microsoft
- Surface devices via soc_button_array.
- Note that these devices use the same MSHW0040 device as on the Surface
- Pro 4, however the implementation is different (GPIOs vs. ACPI
- notifications). Thus some checking is required to ensure we only load
- this driver on the correct devices.
- Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com>
- Patchset: surface-buttons
- ---
- drivers/input/misc/Kconfig | 6 +-
- drivers/input/misc/soc_button_array.c | 105 +++++++++++++++++++++++---
- 2 files changed, 96 insertions(+), 15 deletions(-)
- diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
- index ca59a2be9bc5..ea69610370e8 100644
- --- a/drivers/input/misc/Kconfig
- +++ b/drivers/input/misc/Kconfig
- @@ -781,10 +781,10 @@ config INPUT_IDEAPAD_SLIDEBAR
-
- config INPUT_SOC_BUTTON_ARRAY
- tristate "Windows-compatible SoC Button Array"
- - depends on KEYBOARD_GPIO
- + depends on KEYBOARD_GPIO && ACPI
- help
- - Say Y here if you have a SoC-based tablet that originally
- - runs Windows 8.
- + Say Y here if you have a SoC-based tablet that originally runs
- + Windows 8 or a Microsoft Surface Book 2, Pro 5, Laptop 1 or later.
-
- To compile this driver as a module, choose M here: the
- module will be called soc_button_array.
- diff --git a/drivers/input/misc/soc_button_array.c b/drivers/input/misc/soc_button_array.c
- index 55cd6e0b409c..8f21c062c85d 100644
- --- a/drivers/input/misc/soc_button_array.c
- +++ b/drivers/input/misc/soc_button_array.c
- @@ -29,6 +29,11 @@ struct soc_button_info {
- bool wakeup;
- };
-
- +struct soc_device_data {
- + const struct soc_button_info *button_info;
- + int (*check)(struct device *dev);
- +};
- +
- /*
- * Some of the buttons like volume up/down are auto repeat, while others
- * are not. To support both, we register two platform devices, and put
- @@ -91,8 +96,13 @@ soc_button_device_create(struct platform_device *pdev,
- continue;
-
- gpio = soc_button_lookup_gpio(&pdev->dev, info->acpi_index);
- - if (!gpio_is_valid(gpio))
- + if (gpio < 0 && gpio != -ENOENT) {
- + error = gpio;
- + goto err_free_mem;
- + } else if (!gpio_is_valid(gpio)) {
- + /* Skip GPIO if not present */
- continue;
- + }
-
- gpio_keys[n_buttons].type = info->event_type;
- gpio_keys[n_buttons].code = info->event_code;
- @@ -309,23 +319,26 @@ static int soc_button_remove(struct platform_device *pdev)
- static int soc_button_probe(struct platform_device *pdev)
- {
- struct device *dev = &pdev->dev;
- - const struct acpi_device_id *id;
- - struct soc_button_info *button_info;
- + const struct soc_device_data *device_data;
- + const struct soc_button_info *button_info;
- struct soc_button_data *priv;
- struct platform_device *pd;
- int i;
- int error;
-
- - id = acpi_match_device(dev->driver->acpi_match_table, dev);
- - if (!id)
- - return -ENODEV;
- + device_data = acpi_device_get_match_data(dev);
- + if (device_data && device_data->check) {
- + error = device_data->check(dev);
- + if (error)
- + return error;
- + }
-
- - if (!id->driver_data) {
- + if (device_data && device_data->button_info) {
- + button_info = device_data->button_info;
- + } else {
- button_info = soc_button_get_button_info(dev);
- if (IS_ERR(button_info))
- return PTR_ERR(button_info);
- - } else {
- - button_info = (struct soc_button_info *)id->driver_data;
- }
-
- error = gpiod_count(dev, NULL);
- @@ -357,7 +370,7 @@ static int soc_button_probe(struct platform_device *pdev)
- if (!priv->children[0] && !priv->children[1])
- return -ENODEV;
-
- - if (!id->driver_data)
- + if (!device_data || !device_data->button_info)
- devm_kfree(dev, button_info);
-
- return 0;
- @@ -368,7 +381,7 @@ static int soc_button_probe(struct platform_device *pdev)
- * is defined in section 2.8.7.2 of "Windows ACPI Design Guide for SoC
- * Platforms"
- */
- -static struct soc_button_info soc_button_PNP0C40[] = {
- +static const struct soc_button_info soc_button_PNP0C40[] = {
- { "power", 0, EV_KEY, KEY_POWER, false, true },
- { "home", 1, EV_KEY, KEY_LEFTMETA, false, true },
- { "volume_up", 2, EV_KEY, KEY_VOLUMEUP, true, false },
- @@ -377,9 +390,77 @@ static struct soc_button_info soc_button_PNP0C40[] = {
- { }
- };
-
- +static const struct soc_device_data soc_device_PNP0C40 = {
- + .button_info = soc_button_PNP0C40,
- +};
- +
- +/*
- + * Special device check for Surface Book 2 and Surface Pro (2017).
- + * Both, the Surface Pro 4 (surfacepro3_button.c) and the above mentioned
- + * devices use MSHW0040 for power and volume buttons, however the way they
- + * have to be addressed differs. Make sure that we only load this drivers
- + * for the correct devices by checking the OEM Platform Revision provided by
- + * the _DSM method.
- + */
- +#define MSHW0040_DSM_REVISION 0x01
- +#define MSHW0040_DSM_GET_OMPR 0x02 // get OEM Platform Revision
- +static const guid_t MSHW0040_DSM_UUID =
- + GUID_INIT(0x6fd05c69, 0xcde3, 0x49f4, 0x95, 0xed, 0xab, 0x16, 0x65,
- + 0x49, 0x80, 0x35);
- +
- +static int soc_device_check_MSHW0040(struct device *dev)
- +{
- + acpi_handle handle = ACPI_HANDLE(dev);
- + union acpi_object *result;
- + u64 oem_platform_rev = 0; // valid revisions are nonzero
- +
- + // get OEM platform revision
- + result = acpi_evaluate_dsm_typed(handle, &MSHW0040_DSM_UUID,
- + MSHW0040_DSM_REVISION,
- + MSHW0040_DSM_GET_OMPR, NULL,
- + ACPI_TYPE_INTEGER);
- +
- + if (result) {
- + oem_platform_rev = result->integer.value;
- + ACPI_FREE(result);
- + }
- +
- + /*
- + * If the revision is zero here, the _DSM evaluation has failed. This
- + * indicates that we have a Pro 4 or Book 1 and this driver should not
- + * be used.
- + */
- + if (oem_platform_rev == 0)
- + return -ENODEV;
- +
- + dev_dbg(dev, "OEM Platform Revision %llu\n", oem_platform_rev);
- +
- + return 0;
- +}
- +
- +/*
- + * Button infos for Microsoft Surface Book 2 and Surface Pro (2017).
- + * Obtained from DSDT/testing.
- + */
- +static const struct soc_button_info soc_button_MSHW0040[] = {
- + { "power", 0, EV_KEY, KEY_POWER, false, true },
- + { "volume_up", 2, EV_KEY, KEY_VOLUMEUP, true, false },
- + { "volume_down", 4, EV_KEY, KEY_VOLUMEDOWN, true, false },
- + { }
- +};
- +
- +static const struct soc_device_data soc_device_MSHW0040 = {
- + .button_info = soc_button_MSHW0040,
- + .check = soc_device_check_MSHW0040,
- +};
- +
- static const struct acpi_device_id soc_button_acpi_match[] = {
- - { "PNP0C40", (unsigned long)soc_button_PNP0C40 },
- + { "PNP0C40", (unsigned long)&soc_device_PNP0C40 },
- { "ACPI0011", 0 },
- +
- + /* Microsoft Surface Devices (5th and 6th generation) */
- + { "MSHW0040", (unsigned long)&soc_device_MSHW0040 },
- +
- { }
- };
-
- --
- 2.33.0
- From 3495e149d8dc07d035fc87d0820b2e0938ed097b Mon Sep 17 00:00:00 2001
- From: Hans de Goede <hdegoide@redhat.com>
- Date: Sat, 5 Oct 2019 14:11:58 +0200
- Subject: [PATCH] Input: soc_button_array - partial revert of support for newer
- surface devices
- Commit c394159310d0 ("Input: soc_button_array - add support for newer
- surface devices") not only added support for the MSHW0040 ACPI HID,
- but for some reason it also makes changes to the error handling of the
- soc_button_lookup_gpio() call in soc_button_device_create(). Note ideally
- this seamingly unrelated change would have been made in a separate commit,
- with a message explaining the what and why of this change.
- I guess this change may have been added to deal with -EPROBE_DEFER errors,
- but in case of the existing support for PNP0C40 devices, treating
- -EPROBE_DEFER as any other error is deliberate, see the comment this
- commit adds for why.
- The actual returning of -EPROBE_DEFER to the caller of soc_button_probe()
- introduced by the new error checking causes a serious regression:
- On devices with so called virtual GPIOs soc_button_lookup_gpio() will
- always return -EPROBE_DEFER for these fake GPIOs, when this happens
- during the second call of soc_button_device_create() we already have
- successfully registered our first child. This causes the kernel to think
- we are making progress with probing things even though we unregister the
- child before again before we return the -EPROBE_DEFER. Since we are making
- progress the kernel will retry deferred-probes again immediately ending
- up stuck in a loop with the following showing in dmesg:
- [ 124.022697] input: gpio-keys as /devices/platform/INTCFD9:00/gpio-keys.0.auto/input/input6537
- [ 124.040764] input: gpio-keys as /devices/platform/INTCFD9:00/gpio-keys.0.auto/input/input6538
- [ 124.056967] input: gpio-keys as /devices/platform/INTCFD9:00/gpio-keys.0.auto/input/input6539
- [ 124.072143] input: gpio-keys as /devices/platform/INTCFD9:00/gpio-keys.0.auto/input/input6540
- [ 124.092373] input: gpio-keys as /devices/platform/INTCFD9:00/gpio-keys.0.auto/input/input6541
- [ 124.108065] input: gpio-keys as /devices/platform/INTCFD9:00/gpio-keys.0.auto/input/input6542
- [ 124.128483] input: gpio-keys as /devices/platform/INTCFD9:00/gpio-keys.0.auto/input/input6543
- [ 124.147141] input: gpio-keys as /devices/platform/INTCFD9:00/gpio-keys.0.auto/input/input6544
- [ 124.165070] input: gpio-keys as /devices/platform/INTCFD9:00/gpio-keys.0.auto/input/input6545
- [ 124.179775] input: gpio-keys as /devices/platform/INTCFD9:00/gpio-keys.0.auto/input/input6546
- [ 124.202726] input: gpio-keys as /devices/platform/INTCFD9:00/gpio-keys.0.auto/input/input6547
- <continues on and on and on>
- And 1 CPU core being stuck at 100% and udev hanging since it is waiting
- for the modprobe of soc_button_array to return.
- This patch reverts the soc_button_lookup_gpio() error handling changes,
- fixing this regression.
- Fixes: c394159310d0 ("Input: soc_button_array - add support for newer surface devices")
- BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=205031
- Cc: Maximilian Luz <luzmaximilian@gmail.com>
- Signed-off-by: Hans de Goede <hdegoede@redhat.com>
- Patchset: surface-buttons
- ---
- drivers/input/misc/soc_button_array.c | 17 ++++++++++++-----
- 1 file changed, 12 insertions(+), 5 deletions(-)
- diff --git a/drivers/input/misc/soc_button_array.c b/drivers/input/misc/soc_button_array.c
- index 8f21c062c85d..5983733d78dd 100644
- --- a/drivers/input/misc/soc_button_array.c
- +++ b/drivers/input/misc/soc_button_array.c
- @@ -96,11 +96,18 @@ soc_button_device_create(struct platform_device *pdev,
- continue;
-
- gpio = soc_button_lookup_gpio(&pdev->dev, info->acpi_index);
- - if (gpio < 0 && gpio != -ENOENT) {
- - error = gpio;
- - goto err_free_mem;
- - } else if (!gpio_is_valid(gpio)) {
- - /* Skip GPIO if not present */
- + if (!gpio_is_valid(gpio)) {
- + /*
- + * Skip GPIO if not present. Note we deliberately
- + * ignore -EPROBE_DEFER errors here. On some devices
- + * Intel is using so called virtual GPIOs which are not
- + * GPIOs at all but some way for AML code to check some
- + * random status bits without need a custom opregion.
- + * In some cases the resources table we parse points to
- + * such a virtual GPIO, since these are not real GPIOs
- + * we do not have a driver for these so they will never
- + * show up, therefor we ignore -EPROBE_DEFER.
- + */
- continue;
- }
-
- --
- 2.33.0
- From 97852be9f07614c8f49c9aaa7308d550d952207d Mon Sep 17 00:00:00 2001
- From: "Tsuchiya Yuto (kitakar5525)" <kitakar@gmail.com>
- Date: Mon, 11 May 2020 17:40:21 +0900
- Subject: [PATCH] Input: soc_button_array - fix Wdiscarded-qualifiers for
- kernels below 4.20
- MIME-Version: 1.0
- Content-Type: text/plain; charset=UTF-8
- Content-Transfer-Encoding: 8bit
- There is a warning from compiler when building v4.19-surface kernel that
- backported button patches from newer kernels.
- drivers/input/misc/soc_button_array.c: In function ‘soc_button_probe’:
- drivers/input/misc/soc_button_array.c:381:19: warning: passing argument 2 of ‘devm_kfree’ discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers]
- 381 | devm_kfree(dev, button_info);
- | ^~~~~~~~~~~
- In file included from ./include/linux/input.h:22,
- from drivers/input/misc/soc_button_array.c:14:
- ./include/linux/device.h:695:50: note: expected ‘void *’ but argument is of type ‘const struct soc_button_info *’
- 695 | extern void devm_kfree(struct device *dev, void *p);
- | ~~~~~~^
- This warning happens bacause commit 0571967dfb5d25 ("devres: constify p
- in devm_kfree()") has not been applied to v4.19 series (available after
- v4.20-rc1).
- This commit casts button_info to (void *) when calling devm_kfree() to
- avoid compiler warning.
- Fixes: b892fc124285ba ("Input: soc_button_array - Add support for newer surface devices")
- Signed-off-by: Tsuchiya Yuto (kitakar5525) <kitakar@gmail.com>
- Patchset: surface-buttons
- ---
- drivers/input/misc/soc_button_array.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
- diff --git a/drivers/input/misc/soc_button_array.c b/drivers/input/misc/soc_button_array.c
- index 5983733d78dd..c564ea99f47d 100644
- --- a/drivers/input/misc/soc_button_array.c
- +++ b/drivers/input/misc/soc_button_array.c
- @@ -378,7 +378,7 @@ static int soc_button_probe(struct platform_device *pdev)
- return -ENODEV;
-
- if (!device_data || !device_data->button_info)
- - devm_kfree(dev, button_info);
- + devm_kfree(dev, (void *)button_info);
-
- return 0;
- }
- --
- 2.33.0
|