0004-surface-buttons.patch 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440
  1. From be8bb5f93d32d3ac7f918cdbfb04b412673ff80b Mon Sep 17 00:00:00 2001
  2. From: Maximilian Luz <luzmaximilian@gmail.com>
  3. Date: Sat, 27 Jul 2019 17:51:37 +0200
  4. Subject: [PATCH] platform/x86: surfacepro3_button: Fix device check
  5. Do not use the surfacepro3_button driver on newer Microsoft Surface
  6. models, only use it on the Surface Pro 3 and 4. Newer models (5th, 6th
  7. and possibly future generations) use the same device as the Surface Pro
  8. 4 to represent their volume and power buttons (MSHW0040), but their
  9. actual implementation is significantly different. This patch ensures
  10. that the surfacepro3_button driver is only used on the Pro 3 and 4
  11. models, allowing a different driver to bind on other models.
  12. Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com>
  13. Patchset: surface-buttons
  14. ---
  15. drivers/platform/x86/surfacepro3_button.c | 47 +++++++++++++++++++++++
  16. 1 file changed, 47 insertions(+)
  17. diff --git a/drivers/platform/x86/surfacepro3_button.c b/drivers/platform/x86/surfacepro3_button.c
  18. index 1b491690ce07..96627627060e 100644
  19. --- a/drivers/platform/x86/surfacepro3_button.c
  20. +++ b/drivers/platform/x86/surfacepro3_button.c
  21. @@ -24,6 +24,12 @@
  22. #define SURFACE_BUTTON_OBJ_NAME "VGBI"
  23. #define SURFACE_BUTTON_DEVICE_NAME "Surface Pro 3/4 Buttons"
  24. +#define MSHW0040_DSM_REVISION 0x01
  25. +#define MSHW0040_DSM_GET_OMPR 0x02 // get OEM Platform Revision
  26. +static const guid_t MSHW0040_DSM_UUID =
  27. + GUID_INIT(0x6fd05c69, 0xcde3, 0x49f4, 0x95, 0xed, 0xab, 0x16, 0x65,
  28. + 0x49, 0x80, 0x35);
  29. +
  30. #define SURFACE_BUTTON_NOTIFY_TABLET_MODE 0xc8
  31. #define SURFACE_BUTTON_NOTIFY_PRESS_POWER 0xc6
  32. @@ -146,6 +152,44 @@ static int surface_button_resume(struct device *dev)
  33. }
  34. #endif
  35. +/*
  36. + * Surface Pro 4 and Surface Book 2 / Surface Pro 2017 use the same device
  37. + * ID (MSHW0040) for the power/volume buttons. Make sure this is the right
  38. + * device by checking for the _DSM method and OEM Platform Revision.
  39. + *
  40. + * Returns true if the driver should bind to this device, i.e. the device is
  41. + * either MSWH0028 (Pro 3) or MSHW0040 on a Pro 4 or Book 1.
  42. + */
  43. +static bool surface_button_check_MSHW0040(struct acpi_device *dev)
  44. +{
  45. + acpi_handle handle = dev->handle;
  46. + union acpi_object *result;
  47. + u64 oem_platform_rev = 0; // valid revisions are nonzero
  48. +
  49. + // get OEM platform revision
  50. + result = acpi_evaluate_dsm_typed(handle, &MSHW0040_DSM_UUID,
  51. + MSHW0040_DSM_REVISION,
  52. + MSHW0040_DSM_GET_OMPR,
  53. + NULL, ACPI_TYPE_INTEGER);
  54. +
  55. + /*
  56. + * If evaluating the _DSM fails, the method is not present. This means
  57. + * that we have either MSHW0028 or MSHW0040 on Pro 4 or Book 1, so we
  58. + * should use this driver. We use revision 0 indicating it is
  59. + * unavailable.
  60. + */
  61. +
  62. + if (result) {
  63. + oem_platform_rev = result->integer.value;
  64. + ACPI_FREE(result);
  65. + }
  66. +
  67. + dev_dbg(&dev->dev, "OEM Platform Revision %llu\n", oem_platform_rev);
  68. +
  69. + return oem_platform_rev == 0;
  70. +}
  71. +
  72. +
  73. static int surface_button_add(struct acpi_device *device)
  74. {
  75. struct surface_button *button;
  76. @@ -158,6 +202,9 @@ static int surface_button_add(struct acpi_device *device)
  77. strlen(SURFACE_BUTTON_OBJ_NAME)))
  78. return -ENODEV;
  79. + if (!surface_button_check_MSHW0040(device))
  80. + return -ENODEV;
  81. +
  82. button = kzalloc(sizeof(struct surface_button), GFP_KERNEL);
  83. if (!button)
  84. return -ENOMEM;
  85. --
  86. 2.33.0
  87. From dc6c755a5867401c03cb7ca17396f8d9b05df58d Mon Sep 17 00:00:00 2001
  88. From: Maximilian Luz <luzmaximilian@gmail.com>
  89. Date: Sat, 27 Jul 2019 17:52:01 +0200
  90. Subject: [PATCH] Input: soc_button_array - Add support for newer surface
  91. devices
  92. Power and volume button support for 5th and 6th generation Microsoft
  93. Surface devices via soc_button_array.
  94. Note that these devices use the same MSHW0040 device as on the Surface
  95. Pro 4, however the implementation is different (GPIOs vs. ACPI
  96. notifications). Thus some checking is required to ensure we only load
  97. this driver on the correct devices.
  98. Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com>
  99. Patchset: surface-buttons
  100. ---
  101. drivers/input/misc/Kconfig | 6 +-
  102. drivers/input/misc/soc_button_array.c | 105 +++++++++++++++++++++++---
  103. 2 files changed, 96 insertions(+), 15 deletions(-)
  104. diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
  105. index ca59a2be9bc5..ea69610370e8 100644
  106. --- a/drivers/input/misc/Kconfig
  107. +++ b/drivers/input/misc/Kconfig
  108. @@ -781,10 +781,10 @@ config INPUT_IDEAPAD_SLIDEBAR
  109. config INPUT_SOC_BUTTON_ARRAY
  110. tristate "Windows-compatible SoC Button Array"
  111. - depends on KEYBOARD_GPIO
  112. + depends on KEYBOARD_GPIO && ACPI
  113. help
  114. - Say Y here if you have a SoC-based tablet that originally
  115. - runs Windows 8.
  116. + Say Y here if you have a SoC-based tablet that originally runs
  117. + Windows 8 or a Microsoft Surface Book 2, Pro 5, Laptop 1 or later.
  118. To compile this driver as a module, choose M here: the
  119. module will be called soc_button_array.
  120. diff --git a/drivers/input/misc/soc_button_array.c b/drivers/input/misc/soc_button_array.c
  121. index 55cd6e0b409c..8f21c062c85d 100644
  122. --- a/drivers/input/misc/soc_button_array.c
  123. +++ b/drivers/input/misc/soc_button_array.c
  124. @@ -29,6 +29,11 @@ struct soc_button_info {
  125. bool wakeup;
  126. };
  127. +struct soc_device_data {
  128. + const struct soc_button_info *button_info;
  129. + int (*check)(struct device *dev);
  130. +};
  131. +
  132. /*
  133. * Some of the buttons like volume up/down are auto repeat, while others
  134. * are not. To support both, we register two platform devices, and put
  135. @@ -91,8 +96,13 @@ soc_button_device_create(struct platform_device *pdev,
  136. continue;
  137. gpio = soc_button_lookup_gpio(&pdev->dev, info->acpi_index);
  138. - if (!gpio_is_valid(gpio))
  139. + if (gpio < 0 && gpio != -ENOENT) {
  140. + error = gpio;
  141. + goto err_free_mem;
  142. + } else if (!gpio_is_valid(gpio)) {
  143. + /* Skip GPIO if not present */
  144. continue;
  145. + }
  146. gpio_keys[n_buttons].type = info->event_type;
  147. gpio_keys[n_buttons].code = info->event_code;
  148. @@ -309,23 +319,26 @@ static int soc_button_remove(struct platform_device *pdev)
  149. static int soc_button_probe(struct platform_device *pdev)
  150. {
  151. struct device *dev = &pdev->dev;
  152. - const struct acpi_device_id *id;
  153. - struct soc_button_info *button_info;
  154. + const struct soc_device_data *device_data;
  155. + const struct soc_button_info *button_info;
  156. struct soc_button_data *priv;
  157. struct platform_device *pd;
  158. int i;
  159. int error;
  160. - id = acpi_match_device(dev->driver->acpi_match_table, dev);
  161. - if (!id)
  162. - return -ENODEV;
  163. + device_data = acpi_device_get_match_data(dev);
  164. + if (device_data && device_data->check) {
  165. + error = device_data->check(dev);
  166. + if (error)
  167. + return error;
  168. + }
  169. - if (!id->driver_data) {
  170. + if (device_data && device_data->button_info) {
  171. + button_info = device_data->button_info;
  172. + } else {
  173. button_info = soc_button_get_button_info(dev);
  174. if (IS_ERR(button_info))
  175. return PTR_ERR(button_info);
  176. - } else {
  177. - button_info = (struct soc_button_info *)id->driver_data;
  178. }
  179. error = gpiod_count(dev, NULL);
  180. @@ -357,7 +370,7 @@ static int soc_button_probe(struct platform_device *pdev)
  181. if (!priv->children[0] && !priv->children[1])
  182. return -ENODEV;
  183. - if (!id->driver_data)
  184. + if (!device_data || !device_data->button_info)
  185. devm_kfree(dev, button_info);
  186. return 0;
  187. @@ -368,7 +381,7 @@ static int soc_button_probe(struct platform_device *pdev)
  188. * is defined in section 2.8.7.2 of "Windows ACPI Design Guide for SoC
  189. * Platforms"
  190. */
  191. -static struct soc_button_info soc_button_PNP0C40[] = {
  192. +static const struct soc_button_info soc_button_PNP0C40[] = {
  193. { "power", 0, EV_KEY, KEY_POWER, false, true },
  194. { "home", 1, EV_KEY, KEY_LEFTMETA, false, true },
  195. { "volume_up", 2, EV_KEY, KEY_VOLUMEUP, true, false },
  196. @@ -377,9 +390,77 @@ static struct soc_button_info soc_button_PNP0C40[] = {
  197. { }
  198. };
  199. +static const struct soc_device_data soc_device_PNP0C40 = {
  200. + .button_info = soc_button_PNP0C40,
  201. +};
  202. +
  203. +/*
  204. + * Special device check for Surface Book 2 and Surface Pro (2017).
  205. + * Both, the Surface Pro 4 (surfacepro3_button.c) and the above mentioned
  206. + * devices use MSHW0040 for power and volume buttons, however the way they
  207. + * have to be addressed differs. Make sure that we only load this drivers
  208. + * for the correct devices by checking the OEM Platform Revision provided by
  209. + * the _DSM method.
  210. + */
  211. +#define MSHW0040_DSM_REVISION 0x01
  212. +#define MSHW0040_DSM_GET_OMPR 0x02 // get OEM Platform Revision
  213. +static const guid_t MSHW0040_DSM_UUID =
  214. + GUID_INIT(0x6fd05c69, 0xcde3, 0x49f4, 0x95, 0xed, 0xab, 0x16, 0x65,
  215. + 0x49, 0x80, 0x35);
  216. +
  217. +static int soc_device_check_MSHW0040(struct device *dev)
  218. +{
  219. + acpi_handle handle = ACPI_HANDLE(dev);
  220. + union acpi_object *result;
  221. + u64 oem_platform_rev = 0; // valid revisions are nonzero
  222. +
  223. + // get OEM platform revision
  224. + result = acpi_evaluate_dsm_typed(handle, &MSHW0040_DSM_UUID,
  225. + MSHW0040_DSM_REVISION,
  226. + MSHW0040_DSM_GET_OMPR, NULL,
  227. + ACPI_TYPE_INTEGER);
  228. +
  229. + if (result) {
  230. + oem_platform_rev = result->integer.value;
  231. + ACPI_FREE(result);
  232. + }
  233. +
  234. + /*
  235. + * If the revision is zero here, the _DSM evaluation has failed. This
  236. + * indicates that we have a Pro 4 or Book 1 and this driver should not
  237. + * be used.
  238. + */
  239. + if (oem_platform_rev == 0)
  240. + return -ENODEV;
  241. +
  242. + dev_dbg(dev, "OEM Platform Revision %llu\n", oem_platform_rev);
  243. +
  244. + return 0;
  245. +}
  246. +
  247. +/*
  248. + * Button infos for Microsoft Surface Book 2 and Surface Pro (2017).
  249. + * Obtained from DSDT/testing.
  250. + */
  251. +static const struct soc_button_info soc_button_MSHW0040[] = {
  252. + { "power", 0, EV_KEY, KEY_POWER, false, true },
  253. + { "volume_up", 2, EV_KEY, KEY_VOLUMEUP, true, false },
  254. + { "volume_down", 4, EV_KEY, KEY_VOLUMEDOWN, true, false },
  255. + { }
  256. +};
  257. +
  258. +static const struct soc_device_data soc_device_MSHW0040 = {
  259. + .button_info = soc_button_MSHW0040,
  260. + .check = soc_device_check_MSHW0040,
  261. +};
  262. +
  263. static const struct acpi_device_id soc_button_acpi_match[] = {
  264. - { "PNP0C40", (unsigned long)soc_button_PNP0C40 },
  265. + { "PNP0C40", (unsigned long)&soc_device_PNP0C40 },
  266. { "ACPI0011", 0 },
  267. +
  268. + /* Microsoft Surface Devices (5th and 6th generation) */
  269. + { "MSHW0040", (unsigned long)&soc_device_MSHW0040 },
  270. +
  271. { }
  272. };
  273. --
  274. 2.33.0
  275. From 3495e149d8dc07d035fc87d0820b2e0938ed097b Mon Sep 17 00:00:00 2001
  276. From: Hans de Goede <hdegoide@redhat.com>
  277. Date: Sat, 5 Oct 2019 14:11:58 +0200
  278. Subject: [PATCH] Input: soc_button_array - partial revert of support for newer
  279. surface devices
  280. Commit c394159310d0 ("Input: soc_button_array - add support for newer
  281. surface devices") not only added support for the MSHW0040 ACPI HID,
  282. but for some reason it also makes changes to the error handling of the
  283. soc_button_lookup_gpio() call in soc_button_device_create(). Note ideally
  284. this seamingly unrelated change would have been made in a separate commit,
  285. with a message explaining the what and why of this change.
  286. I guess this change may have been added to deal with -EPROBE_DEFER errors,
  287. but in case of the existing support for PNP0C40 devices, treating
  288. -EPROBE_DEFER as any other error is deliberate, see the comment this
  289. commit adds for why.
  290. The actual returning of -EPROBE_DEFER to the caller of soc_button_probe()
  291. introduced by the new error checking causes a serious regression:
  292. On devices with so called virtual GPIOs soc_button_lookup_gpio() will
  293. always return -EPROBE_DEFER for these fake GPIOs, when this happens
  294. during the second call of soc_button_device_create() we already have
  295. successfully registered our first child. This causes the kernel to think
  296. we are making progress with probing things even though we unregister the
  297. child before again before we return the -EPROBE_DEFER. Since we are making
  298. progress the kernel will retry deferred-probes again immediately ending
  299. up stuck in a loop with the following showing in dmesg:
  300. [ 124.022697] input: gpio-keys as /devices/platform/INTCFD9:00/gpio-keys.0.auto/input/input6537
  301. [ 124.040764] input: gpio-keys as /devices/platform/INTCFD9:00/gpio-keys.0.auto/input/input6538
  302. [ 124.056967] input: gpio-keys as /devices/platform/INTCFD9:00/gpio-keys.0.auto/input/input6539
  303. [ 124.072143] input: gpio-keys as /devices/platform/INTCFD9:00/gpio-keys.0.auto/input/input6540
  304. [ 124.092373] input: gpio-keys as /devices/platform/INTCFD9:00/gpio-keys.0.auto/input/input6541
  305. [ 124.108065] input: gpio-keys as /devices/platform/INTCFD9:00/gpio-keys.0.auto/input/input6542
  306. [ 124.128483] input: gpio-keys as /devices/platform/INTCFD9:00/gpio-keys.0.auto/input/input6543
  307. [ 124.147141] input: gpio-keys as /devices/platform/INTCFD9:00/gpio-keys.0.auto/input/input6544
  308. [ 124.165070] input: gpio-keys as /devices/platform/INTCFD9:00/gpio-keys.0.auto/input/input6545
  309. [ 124.179775] input: gpio-keys as /devices/platform/INTCFD9:00/gpio-keys.0.auto/input/input6546
  310. [ 124.202726] input: gpio-keys as /devices/platform/INTCFD9:00/gpio-keys.0.auto/input/input6547
  311. <continues on and on and on>
  312. And 1 CPU core being stuck at 100% and udev hanging since it is waiting
  313. for the modprobe of soc_button_array to return.
  314. This patch reverts the soc_button_lookup_gpio() error handling changes,
  315. fixing this regression.
  316. Fixes: c394159310d0 ("Input: soc_button_array - add support for newer surface devices")
  317. BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=205031
  318. Cc: Maximilian Luz <luzmaximilian@gmail.com>
  319. Signed-off-by: Hans de Goede <hdegoede@redhat.com>
  320. Patchset: surface-buttons
  321. ---
  322. drivers/input/misc/soc_button_array.c | 17 ++++++++++++-----
  323. 1 file changed, 12 insertions(+), 5 deletions(-)
  324. diff --git a/drivers/input/misc/soc_button_array.c b/drivers/input/misc/soc_button_array.c
  325. index 8f21c062c85d..5983733d78dd 100644
  326. --- a/drivers/input/misc/soc_button_array.c
  327. +++ b/drivers/input/misc/soc_button_array.c
  328. @@ -96,11 +96,18 @@ soc_button_device_create(struct platform_device *pdev,
  329. continue;
  330. gpio = soc_button_lookup_gpio(&pdev->dev, info->acpi_index);
  331. - if (gpio < 0 && gpio != -ENOENT) {
  332. - error = gpio;
  333. - goto err_free_mem;
  334. - } else if (!gpio_is_valid(gpio)) {
  335. - /* Skip GPIO if not present */
  336. + if (!gpio_is_valid(gpio)) {
  337. + /*
  338. + * Skip GPIO if not present. Note we deliberately
  339. + * ignore -EPROBE_DEFER errors here. On some devices
  340. + * Intel is using so called virtual GPIOs which are not
  341. + * GPIOs at all but some way for AML code to check some
  342. + * random status bits without need a custom opregion.
  343. + * In some cases the resources table we parse points to
  344. + * such a virtual GPIO, since these are not real GPIOs
  345. + * we do not have a driver for these so they will never
  346. + * show up, therefor we ignore -EPROBE_DEFER.
  347. + */
  348. continue;
  349. }
  350. --
  351. 2.33.0
  352. From 97852be9f07614c8f49c9aaa7308d550d952207d Mon Sep 17 00:00:00 2001
  353. From: "Tsuchiya Yuto (kitakar5525)" <kitakar@gmail.com>
  354. Date: Mon, 11 May 2020 17:40:21 +0900
  355. Subject: [PATCH] Input: soc_button_array - fix Wdiscarded-qualifiers for
  356. kernels below 4.20
  357. MIME-Version: 1.0
  358. Content-Type: text/plain; charset=UTF-8
  359. Content-Transfer-Encoding: 8bit
  360. There is a warning from compiler when building v4.19-surface kernel that
  361. backported button patches from newer kernels.
  362. drivers/input/misc/soc_button_array.c: In function ‘soc_button_probe’:
  363. 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]
  364. 381 | devm_kfree(dev, button_info);
  365. | ^~~~~~~~~~~
  366. In file included from ./include/linux/input.h:22,
  367. from drivers/input/misc/soc_button_array.c:14:
  368. ./include/linux/device.h:695:50: note: expected ‘void *’ but argument is of type ‘const struct soc_button_info *’
  369. 695 | extern void devm_kfree(struct device *dev, void *p);
  370. | ~~~~~~^
  371. This warning happens bacause commit 0571967dfb5d25 ("devres: constify p
  372. in devm_kfree()") has not been applied to v4.19 series (available after
  373. v4.20-rc1).
  374. This commit casts button_info to (void *) when calling devm_kfree() to
  375. avoid compiler warning.
  376. Fixes: b892fc124285ba ("Input: soc_button_array - Add support for newer surface devices")
  377. Signed-off-by: Tsuchiya Yuto (kitakar5525) <kitakar@gmail.com>
  378. Patchset: surface-buttons
  379. ---
  380. drivers/input/misc/soc_button_array.c | 2 +-
  381. 1 file changed, 1 insertion(+), 1 deletion(-)
  382. diff --git a/drivers/input/misc/soc_button_array.c b/drivers/input/misc/soc_button_array.c
  383. index 5983733d78dd..c564ea99f47d 100644
  384. --- a/drivers/input/misc/soc_button_array.c
  385. +++ b/drivers/input/misc/soc_button_array.c
  386. @@ -378,7 +378,7 @@ static int soc_button_probe(struct platform_device *pdev)
  387. return -ENODEV;
  388. if (!device_data || !device_data->button_info)
  389. - devm_kfree(dev, button_info);
  390. + devm_kfree(dev, (void *)button_info);
  391. return 0;
  392. }
  393. --
  394. 2.33.0