From 239f75d22d99a12c31dd269823bf503980ca0990 Mon Sep 17 00:00:00 2001 From: Maximilian Luz Date: Tue, 17 Mar 2020 02:16:47 +0100 Subject: [PATCH] Update patches --- patches/4.19/0001-surface3-power.patch | 4 +- patches/4.19/0002-surface3-spi.patch | 4 +- patches/4.19/0003-surface3-oemb.patch | 4 +- patches/4.19/0004-surface-buttons.patch | 4 +- patches/4.19/0005-surface-sam.patch | 849 ++++++++++---------- patches/4.19/0006-suspend.patch | 8 +- patches/4.19/0007-ipts.patch | 36 +- patches/4.19/0008-surface-lte.patch | 4 +- patches/4.19/0009-ioremap_uc.patch | 4 +- patches/4.19/0010-wifi.patch | 75 +- patches/5.5/0001-surface3-power.patch | 4 +- patches/5.5/0002-surface3-spi.patch | 4 +- patches/5.5/0003-surface3-oemb.patch | 4 +- patches/5.5/0004-surface-sam.patch | 840 +++++++++----------- patches/5.5/0005-surface-lte.patch | 4 +- patches/5.5/0006-wifi.patch | 75 +- patches/5.5/0007-ipts.patch | 999 ++++++++++++++---------- 17 files changed, 1546 insertions(+), 1376 deletions(-) diff --git a/patches/4.19/0001-surface3-power.patch b/patches/4.19/0001-surface3-power.patch index 870cf696e..0115d20f8 100644 --- a/patches/4.19/0001-surface3-power.patch +++ b/patches/4.19/0001-surface3-power.patch @@ -1,4 +1,4 @@ -From 173ad7941bfc2f1231e1210218fecd8416269487 Mon Sep 17 00:00:00 2001 +From b932081d4a4690f34c928abf1beaa784a50fa3fe Mon Sep 17 00:00:00 2001 From: Maximilian Luz Date: Sat, 28 Sep 2019 18:00:43 +0200 Subject: [PATCH 01/10] surface3-power @@ -651,5 +651,5 @@ index 000000000000..e0af01a60302 +MODULE_DESCRIPTION("mshw0011 driver"); +MODULE_LICENSE("GPL v2"); -- -2.25.0 +2.25.1 diff --git a/patches/4.19/0002-surface3-spi.patch b/patches/4.19/0002-surface3-spi.patch index bc6f77b30..0bdc252a8 100644 --- a/patches/4.19/0002-surface3-spi.patch +++ b/patches/4.19/0002-surface3-spi.patch @@ -1,4 +1,4 @@ -From 453ea3f94fd2c3d7f944864d55196d1f9577bb8e Mon Sep 17 00:00:00 2001 +From 8255cdea04cc9c59a5e702f0e5acadd2f258eab6 Mon Sep 17 00:00:00 2001 From: kitakar5525 <34676735+kitakar5525@users.noreply.github.com> Date: Fri, 6 Dec 2019 23:10:30 +0900 Subject: [PATCH 02/10] surface3-spi @@ -59,5 +59,5 @@ index 5db0f1c4ef38..8935ddbc2357 100644 } -- -2.25.0 +2.25.1 diff --git a/patches/4.19/0003-surface3-oemb.patch b/patches/4.19/0003-surface3-oemb.patch index ab9bea8b9..400120114 100644 --- a/patches/4.19/0003-surface3-oemb.patch +++ b/patches/4.19/0003-surface3-oemb.patch @@ -1,4 +1,4 @@ -From dbe15026e61130dbbf2f44039bfabed548b4efd2 Mon Sep 17 00:00:00 2001 +From 000864916c307c9f6b7a1af544f241a8927cd732 Mon Sep 17 00:00:00 2001 From: Chih-Wei Huang Date: Tue, 18 Sep 2018 11:01:37 +0800 Subject: [PATCH 03/10] surface3-oemb @@ -65,5 +65,5 @@ index 91bb99b69601..c9f966bacfc1 100644 { } }; -- -2.25.0 +2.25.1 diff --git a/patches/4.19/0004-surface-buttons.patch b/patches/4.19/0004-surface-buttons.patch index 8ae2b0957..763badbe3 100644 --- a/patches/4.19/0004-surface-buttons.patch +++ b/patches/4.19/0004-surface-buttons.patch @@ -1,4 +1,4 @@ -From 40baf1bc4739c49334e9b6dc7badc44771c5ee4a Mon Sep 17 00:00:00 2001 +From 29532061e18b218be50e52966d52a3ab1c1dbd85 Mon Sep 17 00:00:00 2001 From: Maximilian Luz Date: Sat, 27 Jul 2019 17:51:37 +0200 Subject: [PATCH 04/10] surface-buttons @@ -270,5 +270,5 @@ index 1b491690ce07..96627627060e 100644 if (!button) return -ENOMEM; -- -2.25.0 +2.25.1 diff --git a/patches/4.19/0005-surface-sam.patch b/patches/4.19/0005-surface-sam.patch index 03d9b22b2..10b9ab9aa 100644 --- a/patches/4.19/0005-surface-sam.patch +++ b/patches/4.19/0005-surface-sam.patch @@ -1,4 +1,4 @@ -From 4c686fa01f273b247473bdf2399ab3886aab8831 Mon Sep 17 00:00:00 2001 +From b52e4b39f0a890c467bb5616b010dbe2f93a6e3e Mon Sep 17 00:00:00 2001 From: qzed Date: Mon, 26 Aug 2019 01:15:40 +0200 Subject: [PATCH 05/10] surface-sam @@ -8,22 +8,22 @@ Subject: [PATCH 05/10] surface-sam drivers/acpi/acpica/exfield.c | 26 +- drivers/platform/x86/Kconfig | 2 + drivers/platform/x86/Makefile | 1 + - drivers/platform/x86/surface_sam/Kconfig | 163 ++ + drivers/platform/x86/surface_sam/Kconfig | 164 ++ drivers/platform/x86/surface_sam/Makefile | 10 + - .../x86/surface_sam/surface_sam_dtx.c | 623 ++++++ + .../x86/surface_sam/surface_sam_dtx.c | 604 ++++++ .../x86/surface_sam/surface_sam_hps.c | 1110 +++++++++++ - .../x86/surface_sam/surface_sam_san.c | 901 +++++++++ - .../x86/surface_sam/surface_sam_san.h | 29 + - .../x86/surface_sam/surface_sam_sid.c | 117 ++ - .../x86/surface_sam/surface_sam_sid_gpelid.c | 219 ++ - .../surface_sam/surface_sam_sid_perfmode.c | 225 +++ - .../x86/surface_sam/surface_sam_sid_power.c | 1259 ++++++++++++ - .../x86/surface_sam/surface_sam_sid_vhf.c | 440 ++++ - .../x86/surface_sam/surface_sam_ssh.c | 1773 +++++++++++++++++ - .../x86/surface_sam/surface_sam_ssh.h | 97 + - .../x86/surface_sam/surface_sam_vhf.c | 276 +++ - drivers/tty/serdev/core.c | 111 +- - 19 files changed, 7355 insertions(+), 29 deletions(-) + .../x86/surface_sam/surface_sam_san.c | 883 +++++++++ + .../x86/surface_sam/surface_sam_san.h | 30 + + .../x86/surface_sam/surface_sam_sid.c | 137 ++ + .../x86/surface_sam/surface_sam_sid_gpelid.c | 224 +++ + .../surface_sam/surface_sam_sid_perfmode.c | 216 ++ + .../x86/surface_sam/surface_sam_sid_power.c | 1264 ++++++++++++ + .../x86/surface_sam/surface_sam_sid_vhf.c | 428 ++++ + .../x86/surface_sam/surface_sam_ssh.c | 1744 +++++++++++++++++ + .../x86/surface_sam/surface_sam_ssh.h | 98 + + .../x86/surface_sam/surface_sam_vhf.c | 270 +++ + drivers/tty/serdev/core.c | 110 +- + 19 files changed, 7294 insertions(+), 29 deletions(-) create mode 100644 drivers/platform/x86/surface_sam/Kconfig create mode 100644 drivers/platform/x86/surface_sam/Makefile create mode 100644 drivers/platform/x86/surface_sam/surface_sam_dtx.c @@ -129,23 +129,23 @@ index 2ea90039a3e4..cbea9579c1d2 100644 +obj-$(CONFIG_SURFACE_SAM) += surface_sam/ diff --git a/drivers/platform/x86/surface_sam/Kconfig b/drivers/platform/x86/surface_sam/Kconfig new file mode 100644 -index 000000000000..b4513c234c4d +index 000000000000..c4556e58b9a5 --- /dev/null +++ b/drivers/platform/x86/surface_sam/Kconfig -@@ -0,0 +1,163 @@ +@@ -0,0 +1,164 @@ +menuconfig SURFACE_SAM -+ depends on ACPI -+ tristate "Microsoft Surface/System Aggregator Module and Platform Drivers" -+ ---help--- -+ Drivers for the Surface/System Aggregator Module (SAM) of Microsoft -+ Surface devices. ++ depends on ACPI ++ tristate "Microsoft Surface/System Aggregator Module and Platform Drivers" ++ help ++ Drivers for the Surface/System Aggregator Module (SAM) of Microsoft ++ Surface devices. + -+ SAM is an embedded controller that provides access to various -+ functionalities on these devices, including battery status, keyboard -+ events (on the Laptops) and many more. ++ SAM is an embedded controller that provides access to various ++ functionalities on these devices, including battery status, keyboard ++ events (on the Laptops) and many more. + -+ Say M/Y here if you have a Microsoft Surface device with a SAM device -+ (i.e. 5th generation or later). ++ Say M/Y here if you have a Microsoft Surface device with a SAM device ++ (i.e. 5th generation or later). + +config SURFACE_SAM_SSH + tristate "Surface Serial Hub Driver" @@ -153,7 +153,7 @@ index 000000000000..b4513c234c4d + depends on SERIAL_DEV_CTRL_TTYPORT + select CRC_CCITT + default m -+ ---help--- ++ help + Surface Serial Hub driver for 5th generation (or later) Microsoft + Surface devices. + @@ -171,7 +171,7 @@ index 000000000000..b4513c234c4d + depends on SURFACE_SAM_SSH + depends on SYSFS + default n -+ ---help--- ++ help + Debug device for direct communication with the embedded controller + found on 5th generation (and later) Microsoft Surface devices (e.g. + Book 2, Laptop, Laptop 2, Pro 2017, Pro 6, ...) via sysfs. @@ -182,7 +182,7 @@ index 000000000000..b4513c234c4d + tristate "Surface ACPI Notify Driver" + depends on SURFACE_SAM_SSH + default m -+ ---help--- ++ help + Surface ACPI Notify driver for 5th generation (or later) Microsoft + Surface devices. + @@ -197,7 +197,7 @@ index 000000000000..b4513c234c4d + depends on SURFACE_SAM_SSH + depends on HID + default m -+ ---help--- ++ help + Surface Virtual HID Framework driver for 5th generation (or later) + Microsoft Surface devices. + @@ -211,7 +211,7 @@ index 000000000000..b4513c234c4d + depends on SURFACE_SAM_SSH + depends on INPUT + default m -+ ---help--- ++ help + Surface Detachment System (DTX) driver for the Microsoft Surface Book + 2. This driver provides support for proper detachment handling in + user-space, status-events relating to the base and support for @@ -227,8 +227,9 @@ index 000000000000..b4513c234c4d + tristate "Surface dGPU Hot-Plug System (dGPU-HPS) Driver" + depends on SURFACE_SAM_SSH + depends on SURFACE_SAM_SAN ++ depends on GPIO_SYSFS + default m -+ ---help--- ++ help + Driver to properly handle hot-plugging and explicit power-on/power-off + of the discrete GPU (dGPU) on the Surface Book 2. + @@ -238,7 +239,7 @@ index 000000000000..b4513c234c4d + tristate "Surface Platform Integration Driver" + depends on SURFACE_SAM_SSH + default m -+ ---help--- ++ help + Surface Platform Integration Driver for the Microsoft Surface Devices. + This driver loads various model-specific sub-drivers, including + battery and keyboard support on 7th generation Surface devices, proper @@ -252,7 +253,7 @@ index 000000000000..b4513c234c4d + tristate "Surface Lid Wakeup Driver" + depends on SURFACE_SAM_SID + default m -+ ---help--- ++ help + Driver to set up device wake-up via lid on Intel-based Microsoft + Surface devices. These devices do not wake up from sleep as their GPE + interrupt is not configured automatically. This driver solves that @@ -265,8 +266,8 @@ index 000000000000..b4513c234c4d + depends on SURFACE_SAM_SID + depends on SYSFS + default m -+ ---help--- -+ This driver provides suport for setting performance-modes on Surface ++ help ++ This driver provides support for setting performance-modes on Surface + devices via the perf_mode sysfs attribute. Currently only supports the + Surface Book 2. Performance-modes directly influence the fan-profile + of the device, allowing to choose between higher performance or @@ -279,7 +280,7 @@ index 000000000000..b4513c234c4d + depends on SURFACE_SAM_SID + depends on HID + default m -+ ---help--- ++ help + This driver provides support for HID devices connected via the Surface + SAM embedded controller. It provides support for keyboard and touchpad + on the Surface Laptop 3 models. @@ -291,7 +292,7 @@ index 000000000000..b4513c234c4d + depends on SURFACE_SAM_SID + select POWER_SUPPLY + default m -+ ---help--- ++ help + This driver provides support for the battery and AC on 7th generation + Surface devices. + @@ -314,10 +315,11 @@ index 000000000000..188975ccde5c +obj-$(CONFIG_SURFACE_SAM_SID_VHF) += surface_sam_sid_vhf.o diff --git a/drivers/platform/x86/surface_sam/surface_sam_dtx.c b/drivers/platform/x86/surface_sam/surface_sam_dtx.c new file mode 100644 -index 000000000000..4b924de6ab09 +index 000000000000..1e772fd5b0be --- /dev/null +++ b/drivers/platform/x86/surface_sam/surface_sam_dtx.c -@@ -0,0 +1,623 @@ +@@ -0,0 +1,604 @@ ++// SPDX-License-Identifier: GPL-2.0 +/* + * Detachment system (DTX) driver for Microsoft Surface Book 2. + */ @@ -437,13 +439,11 @@ index 000000000000..4b924de6ab09 + }; + + status = surface_sam_ssh_rqst(&rqst, &result); -+ if (status) { ++ if (status) + return status; -+ } + -+ if (result.len != 1) { ++ if (result.len != 1) + return -EFAULT; -+ } + + return result.data[0]; +} @@ -466,14 +466,14 @@ index 000000000000..4b924de6ab09 + +static int dtx_cmd_get_opmode(int __user *buf) +{ -+ int opmode = surface_sam_query_opmpde(); -+ if (opmode < 0) { -+ return opmode; -+ } ++ int opmode; + -+ if (put_user(opmode, buf)) { ++ opmode = surface_sam_query_opmpde(); ++ if (opmode < 0) ++ return opmode; ++ ++ if (put_user(opmode, buf)) + return -EACCES; -+ } + + return 0; +} @@ -486,9 +486,8 @@ index 000000000000..4b924de6ab09 + + // initialize client + client = kzalloc(sizeof(struct surface_dtx_client), GFP_KERNEL); -+ if (!client) { ++ if (!client) + return -ENOMEM; -+ } + + spin_lock_init(&client->buffer_lock); + client->buffer_head = 0; @@ -530,37 +529,32 @@ index 000000000000..4b924de6ab09 + size_t read = 0; + int status = 0; + -+ if (count != 0 && count < sizeof(struct surface_dtx_event)) { ++ if (count != 0 && count < sizeof(struct surface_dtx_event)) + return -EINVAL; -+ } + -+ if (!ddev->active) { ++ if (!ddev->active) + return -ENODEV; -+ } + + // check availability -+ if (client->buffer_head == client->buffer_tail){ -+ if (file->f_flags & O_NONBLOCK) { ++ if (client->buffer_head == client->buffer_tail) { ++ if (file->f_flags & O_NONBLOCK) + return -EAGAIN; -+ } + + status = wait_event_interruptible(ddev->waitq, + client->buffer_head != client->buffer_tail || + !ddev->active); -+ if (status) { ++ if (status) + return status; -+ } + -+ if (!ddev->active) { ++ if (!ddev->active) + return -ENODEV; -+ } + } + + // copy events one by one + while (read + sizeof(struct surface_dtx_event) <= count) { + spin_lock_irq(&client->buffer_lock); + -+ if(client->buffer_head == client->buffer_tail) { ++ if (client->buffer_head == client->buffer_tail) { + spin_unlock_irq(&client->buffer_lock); + break; + } @@ -571,9 +565,8 @@ index 000000000000..4b924de6ab09 + spin_unlock_irq(&client->buffer_lock); + + // copy to userspace -+ if(copy_to_user(buf, &event, sizeof(struct surface_dtx_event))) { ++ if (copy_to_user(buf, &event, sizeof(struct surface_dtx_event))) + return -EFAULT; -+ } + + read += sizeof(struct surface_dtx_event); + } @@ -588,15 +581,13 @@ index 000000000000..4b924de6ab09 + + poll_wait(file, &client->ddev->waitq, pt); + -+ if (client->ddev->active) { ++ if (client->ddev->active) + mask = EPOLLOUT | EPOLLWRNORM; -+ } else { ++ else + mask = EPOLLHUP | EPOLLERR; -+ } + -+ if (client->buffer_head != client->buffer_tail) { ++ if (client->buffer_head != client->buffer_tail) + mask |= EPOLLIN | EPOLLRDNORM; -+ } + + return mask; +} @@ -615,9 +606,8 @@ index 000000000000..4b924de6ab09 + int status; + + status = mutex_lock_interruptible(&ddev->mutex); -+ if (status) { ++ if (status) + return status; -+ } + + if (!ddev->active) { + mutex_unlock(&ddev->mutex); @@ -711,9 +701,8 @@ index 000000000000..4b924de6ab09 + + // get operation mode + opmode = surface_sam_query_opmpde(); -+ if (opmode < 0) { ++ if (opmode < 0) + printk(DTX_ERR "EC request failed with error %d\n", opmode); -+ } + + // send DTX event + event.type = 0x11; @@ -725,7 +714,7 @@ index 000000000000..4b924de6ab09 + + // send SW_TABLET_MODE event + spin_lock(&ddev->input_lock); -+ input_report_switch(ddev->input_dev, SW_TABLET_MODE, opmode == 0x00); ++ input_report_switch(ddev->input_dev, SW_TABLET_MODE, opmode != DTX_OPMODE_LAPTOP); + input_sync(ddev->input_dev); + spin_unlock(&ddev->input_lock); +} @@ -775,14 +764,12 @@ index 000000000000..4b924de6ab09 + int status; + + status = surface_sam_ssh_set_event_handler(SAM_EVENT_DTX_RQID, surface_dtx_evt_dtx, ddev); -+ if (status) { ++ if (status) + goto err_handler; -+ } + + status = surface_sam_ssh_enable_event_source(SAM_EVENT_DTX_TC, 0x01, SAM_EVENT_DTX_RQID); -+ if (status) { ++ if (status) + goto err_source; -+ } + + return 0; + @@ -805,9 +792,8 @@ index 000000000000..4b924de6ab09 + int status; + + input_dev = input_allocate_device(); -+ if (!input_dev) { ++ if (!input_dev) + return ERR_PTR(-ENOMEM); -+ } + + input_dev->name = DTX_INPUT_NAME; + input_dev->dev.parent = &pdev->dev; @@ -823,7 +809,7 @@ index 000000000000..4b924de6ab09 + return ERR_PTR(status); + } + -+ input_report_switch(input_dev, SW_TABLET_MODE, status == 0x00); ++ input_report_switch(input_dev, SW_TABLET_MODE, status != DTX_OPMODE_LAPTOP); + + status = input_register_device(input_dev); + if (status) { @@ -843,14 +829,12 @@ index 000000000000..4b924de6ab09 + + // link to ec + status = surface_sam_ssh_consumer_register(&pdev->dev); -+ if (status) { ++ if (status) + return status == -ENXIO ? -EPROBE_DEFER : status; -+ } + + input_dev = surface_dtx_register_inputdev(pdev); -+ if (IS_ERR(input_dev)) { ++ if (IS_ERR(input_dev)) + return PTR_ERR(input_dev); -+ } + + // initialize device + mutex_lock(&ddev->mutex); @@ -867,15 +851,13 @@ index 000000000000..4b924de6ab09 + mutex_unlock(&ddev->mutex); + + status = misc_register(&ddev->mdev); -+ if (status) { ++ if (status) + goto err_register; -+ } + + // enable events + status = surface_dtx_events_setup(ddev); -+ if (status) { ++ if (status) + goto err_events_setup; -+ } + + return 0; + @@ -943,10 +925,11 @@ index 000000000000..4b924de6ab09 +MODULE_LICENSE("GPL v2"); diff --git a/drivers/platform/x86/surface_sam/surface_sam_hps.c b/drivers/platform/x86/surface_sam/surface_sam_hps.c new file mode 100644 -index 000000000000..3b123bd3dcfe +index 000000000000..4fba5ee75a66 --- /dev/null +++ b/drivers/platform/x86/surface_sam/surface_sam_hps.c @@ -0,0 +1,1110 @@ ++// SPDX-License-Identifier: GPL-2.0 +/* + * Surface dGPU hot-plug system driver. + * Supports explicit setting of the dGPU power-state on the Surface Book 2 and @@ -1016,7 +999,8 @@ index 000000000000..3b123bd3dcfe + SHPS_DGPU_POWER_UNKNOWN = 2, +}; + -+static const char* shps_dgpu_power_str(enum shps_dgpu_power power) { ++static const char *shps_dgpu_power_str(enum shps_dgpu_power power) ++{ + if (power == SHPS_DGPU_POWER_OFF) + return "off"; + else if (power == SHPS_DGPU_POWER_ON) @@ -1045,7 +1029,7 @@ index 000000000000..3b123bd3dcfe +#define SHPS_STATE_BIT_WAKE_ENABLED 2 /* wakeup via base-presence GPIO enabled */ + + -+#define SHPS_DGPU_PARAM_PERM (S_IRUGO | S_IWUSR) ++#define SHPS_DGPU_PARAM_PERM 0644 + +enum shps_dgpu_power_mp { + SHPS_DGPU_MP_POWER_OFF = SHPS_DGPU_POWER_OFF, @@ -1062,13 +1046,11 @@ index 000000000000..3b123bd3dcfe + int status; + + status = kstrtoint(val, 0, &power); -+ if (status) { ++ if (status) + return status; -+ } + -+ if (power < __SHPS_DGPU_MP_POWER_START || power > __SHPS_DGPU_MP_POWER_END) { ++ if (power < __SHPS_DGPU_MP_POWER_START || power > __SHPS_DGPU_MP_POWER_END) + return -EINVAL; -+ } + + return param_set_int(val, kp); +} @@ -1109,18 +1091,18 @@ index 000000000000..3b123bd3dcfe + return surface_sam_ssh_rqst(&rqst, NULL); +} + -+inline static int shps_dtx_latch_lock(void) ++static inline int shps_dtx_latch_lock(void) +{ + return dtx_cmd_simple(SAM_DTX_CID_LATCH_LOCK); +} + -+inline static int shps_dtx_latch_unlock(void) ++static inline int shps_dtx_latch_unlock(void) +{ + return dtx_cmd_simple(SAM_DTX_CID_LATCH_UNLOCK); +} + + -+static int shps_dgpu_dsm_get_pci_addr(struct platform_device *pdev, const char* entry) ++static int shps_dgpu_dsm_get_pci_addr(struct platform_device *pdev, const char *entry) +{ + acpi_handle handle = ACPI_HANDLE(&pdev->dev); + union acpi_object *result; @@ -1174,7 +1156,7 @@ index 000000000000..3b123bd3dcfe + return bus << 8 | PCI_DEVFN(dev, fun); +} + -+static struct pci_dev *shps_dgpu_dsm_get_pci_dev(struct platform_device *pdev, const char* entry) ++static struct pci_dev *shps_dgpu_dsm_get_pci_dev(struct platform_device *pdev, const char *entry) +{ + struct pci_dev *dev; + int addr; @@ -1225,7 +1207,7 @@ index 000000000000..3b123bd3dcfe + param.integer.value = power == SHPS_DGPU_POWER_ON; + + result = acpi_evaluate_dsm_typed(handle, &SHPS_DSM_UUID, SHPS_DSM_REVISION, -+ SHPS_DSM_GPU_POWER, ¶m, ACPI_TYPE_BUFFER); ++ SHPS_DSM_GPU_POWER, ¶m, ACPI_TYPE_BUFFER); + + if (IS_ERR_OR_NULL(result)) + return result ? PTR_ERR(result) : -EIO; @@ -1410,20 +1392,23 @@ index 000000000000..3b123bd3dcfe + if (status) + shps_dtx_latch_unlock(); + -+ return status; + } else { + status = shps_dgpu_rp_set_power(pdev, power); + if (status) + return status; + -+ return shps_dtx_latch_unlock(); ++ status = shps_dtx_latch_unlock(); + } ++ ++ return status; +} + + +static int shps_dgpu_is_present(struct platform_device *pdev) +{ -+ struct shps_driver_data *drvdata = platform_get_drvdata(pdev); ++ struct shps_driver_data *drvdata; ++ ++ drvdata = platform_get_drvdata(pdev); + return gpiod_get_value_cansleep(drvdata->gpio_dgpu_presence); +} + @@ -1651,9 +1636,8 @@ index 000000000000..3b123bd3dcfe + struct shps_driver_data *drvdata = platform_get_drvdata(pdev); + int status = 0; + -+ if (test_and_clear_bit(SHPS_STATE_BIT_WAKE_ENABLED, &drvdata->state)) { ++ if (test_and_clear_bit(SHPS_STATE_BIT_WAKE_ENABLED, &drvdata->state)) + status = disable_irq_wake(drvdata->irq_base_presence); -+ } + + return status; +} @@ -1925,15 +1909,13 @@ index 000000000000..3b123bd3dcfe + + // link to SSH + status = surface_sam_ssh_consumer_register(&pdev->dev); -+ if (status) { ++ if (status) + return status == -ENXIO ? -EPROBE_DEFER : status; -+ } + + // link to SAN + status = surface_sam_san_consumer_register(&pdev->dev, 0); -+ if (status) { ++ if (status) + return status == -ENXIO ? -EPROBE_DEFER : status; -+ } + + status = acpi_dev_add_driver_gpios(shps_dev, shps_acpi_gpios); + if (status) @@ -2042,7 +2024,7 @@ index 000000000000..3b123bd3dcfe +}; +MODULE_DEVICE_TABLE(acpi, shps_acpi_match); + -+struct platform_driver surface_sam_hps = { ++static struct platform_driver surface_sam_hps = { + .probe = shps_probe, + .remove = shps_remove, + .shutdown = shps_shutdown, @@ -2059,10 +2041,11 @@ index 000000000000..3b123bd3dcfe +MODULE_LICENSE("GPL v2"); diff --git a/drivers/platform/x86/surface_sam/surface_sam_san.c b/drivers/platform/x86/surface_sam/surface_sam_san.c new file mode 100644 -index 000000000000..aa0cfc4262be +index 000000000000..63478945e6b2 --- /dev/null +++ b/drivers/platform/x86/surface_sam/surface_sam_san.c -@@ -0,0 +1,901 @@ +@@ -0,0 +1,883 @@ ++// SPDX-License-Identifier: GPL-2.0 +/* + * Surface ACPI Notify (SAN) and ACPI integration driver for SAM. + * Translates communication from ACPI to SSH and back. @@ -2085,7 +2068,7 @@ index 000000000000..aa0cfc4262be + +static const guid_t SAN_DSM_UUID = + GUID_INIT(0x93b666c5, 0x70c6, 0x469f, 0xa2, 0x15, 0x3d, -+ 0x48, 0x7c, 0x91, 0xab, 0x3c); ++ 0x48, 0x7c, 0x91, 0xab, 0x3c); + +#define SAM_EVENT_DELAY_PWR_ADAPTER msecs_to_jiffies(5000) +#define SAM_EVENT_DELAY_PWR_BST msecs_to_jiffies(2500) @@ -2267,11 +2250,10 @@ index 000000000000..aa0cfc4262be + + dev_dbg(dev, "notify power event 0x%02x\n", event); + obj = acpi_evaluate_dsm_typed(san, &SAN_DSM_UUID, SAN_DSM_REVISION, -+ (u8) event, NULL, ACPI_TYPE_BUFFER); ++ (u8) event, NULL, ACPI_TYPE_BUFFER); + -+ if (IS_ERR_OR_NULL(obj)) { ++ if (IS_ERR_OR_NULL(obj)) + return obj ? PTR_ERR(obj) : -ENXIO; -+ } + + if (obj->buffer.length != 1 || obj->buffer.pointer[0] != 0) { + dev_err(dev, "got unexpected result from _DSM\n"); @@ -2292,12 +2274,11 @@ index 000000000000..aa0cfc4262be + param.integer.value = iid; + + obj = acpi_evaluate_dsm_typed(san, &SAN_DSM_UUID, SAN_DSM_REVISION, -+ SAN_DSM_FN_NOTIFY_SENSOR_TRIP_POINT, ++ SAN_DSM_FN_NOTIFY_SENSOR_TRIP_POINT, + ¶m, ACPI_TYPE_BUFFER); + -+ if (IS_ERR_OR_NULL(obj)) { ++ if (IS_ERR_OR_NULL(obj)) + return obj ? PTR_ERR(obj) : -ENXIO; -+ } + + if (obj->buffer.length != 1 || obj->buffer.pointer[0] != 0) { + dev_err(dev, "got unexpected result from _DSM\n"); @@ -2309,7 +2290,7 @@ index 000000000000..aa0cfc4262be +} + + -+inline static int san_evt_power_adapter(struct device *dev, struct surface_sam_ssh_event *event) ++static inline int san_evt_power_adapter(struct device *dev, struct surface_sam_ssh_event *event) +{ + int status; + @@ -2341,16 +2322,15 @@ index 000000000000..aa0cfc4262be + return 0; +} + -+inline static int san_evt_power_bix(struct device *dev, struct surface_sam_ssh_event *event) ++static inline int san_evt_power_bix(struct device *dev, struct surface_sam_ssh_event *event) +{ + enum san_pwr_event evcode; + int status; + -+ if (event->iid == 0x02) { ++ if (event->iid == 0x02) + evcode = SAN_PWR_EVENT_BAT2_INFO; -+ } else { ++ else + evcode = SAN_PWR_EVENT_BAT1_INFO; -+ } + + status = san_acpi_notify_power_event(dev, evcode); + if (status) { @@ -2361,16 +2341,15 @@ index 000000000000..aa0cfc4262be + return 0; +} + -+inline static int san_evt_power_bst(struct device *dev, struct surface_sam_ssh_event *event) ++static inline int san_evt_power_bst(struct device *dev, struct surface_sam_ssh_event *event) +{ + enum san_pwr_event evcode; + int status; + -+ if (event->iid == 0x02) { ++ if (event->iid == 0x02) + evcode = SAN_PWR_EVENT_BAT2_STAT; -+ } else { ++ else + evcode = SAN_PWR_EVENT_BAT1_STAT; -+ } + + status = san_acpi_notify_power_event(dev, evcode); + if (status) { @@ -2436,7 +2415,7 @@ index 000000000000..aa0cfc4262be +} + + -+inline static int san_evt_thermal_notify(struct device *dev, struct surface_sam_ssh_event *event) ++static inline int san_evt_thermal_notify(struct device *dev, struct surface_sam_ssh_event *event) +{ + int status; + @@ -2521,9 +2500,8 @@ index 000000000000..aa0cfc4262be + int status = 0; + int try; + -+ if (!gsb_rqst) { ++ if (!gsb_rqst) + return AE_OK; -+ } + + rqst.tc = gsb_rqst->tc; + rqst.cid = gsb_rqst->cid; @@ -2537,17 +2515,16 @@ index 000000000000..aa0cfc4262be + result.len = 0; + result.data = kzalloc(result.cap, GFP_KERNEL); + -+ if (!result.data) { ++ if (!result.data) + return AE_NO_MEMORY; -+ } + + for (try = 0; try < SAN_RQST_RETRY; try++) { -+ if (try) { -+ dev_warn(ctx->dev, SAN_RQST_TAG "IO error occured, trying again\n"); -+ } ++ if (try) ++ dev_warn(ctx->dev, SAN_RQST_TAG "IO error occurred, trying again\n"); + + status = surface_sam_ssh_rqst(&rqst, &result); -+ if (status != -EIO) break; ++ if (status != -EIO) ++ break; + } + + if (rqst.tc == 0x11 && rqst.cid == 0x0D && status == -EPERM) { @@ -2599,9 +2576,8 @@ index 000000000000..aa0cfc4262be + struct surface_sam_san_rqsg rqsg = {}; + int status; + -+ if (!gsb_rqsg) { ++ if (!gsb_rqsg) + return AE_OK; -+ } + + rqsg.tc = gsb_rqsg->tc; + rqsg.cid = gsb_rqsg->cid; @@ -2762,22 +2738,19 @@ index 000000000000..aa0cfc4262be + u32 max_links = 0; + int status; + -+ if (!cons) { ++ if (!cons) + return 0; -+ } + + // count links -+ for (con = cons; con->path; ++con) { ++ for (con = cons; con->path; ++con) + max_links += 1; -+ } + + // allocate -+ links = kzalloc(max_links * sizeof(struct san_consumer_link), GFP_KERNEL); ++ links = kcalloc(max_links, sizeof(struct san_consumer_link), GFP_KERNEL); + link = &links[0]; + -+ if (!links) { ++ if (!links) + return -ENOMEM; -+ } + + // create links + for (con = cons; con->path; ++con) { @@ -2792,9 +2765,8 @@ index 000000000000..aa0cfc4262be + } + + status = acpi_bus_get_device(handle, &adev); -+ if (status) { ++ if (status) + goto cleanup; -+ } + + link->link = device_link_add(&adev->dev, &pdev->dev, con->flags); + if (!(link->link)) { @@ -2813,25 +2785,23 @@ index 000000000000..aa0cfc4262be + +cleanup: + for (link = link - 1; link >= links; --link) { -+ if (link->properties->flags & DL_FLAG_STATELESS) { ++ if (link->properties->flags & DL_FLAG_STATELESS) + device_link_del(link->link); -+ } + } + + return status; +} + -+static void san_consumers_unlink(struct san_consumers *consumers) { ++static void san_consumers_unlink(struct san_consumers *consumers) ++{ + u32 i; + -+ if (!consumers) { ++ if (!consumers) + return; -+ } + + for (i = 0; i < consumers->num; ++i) { -+ if (consumers->links[i].properties->flags & DL_FLAG_STATELESS) { ++ if (consumers->links[i].properties->flags & DL_FLAG_STATELESS) + device_link_del(consumers->links[i].link); -+ } + } + + kfree(consumers->links); @@ -2854,22 +2824,19 @@ index 000000000000..aa0cfc4262be + * consumer to set up a device_link. + */ + status = surface_sam_ssh_consumer_register(&pdev->dev); -+ if (status) { ++ if (status) + return status == -ENXIO ? -EPROBE_DEFER : status; -+ } + + drvdata = kzalloc(sizeof(struct san_drvdata), GFP_KERNEL); -+ if (!drvdata) { ++ if (!drvdata) + return -ENOMEM; -+ } + + drvdata->opreg_ctx.dev = &pdev->dev; + + cons = acpi_device_get_match_data(&pdev->dev); + status = san_consumers_link(pdev, cons, &drvdata->consumers); -+ if (status) { ++ if (status) + goto err_consumers; -+ } + + platform_set_drvdata(pdev, drvdata); + @@ -2884,21 +2851,18 @@ index 000000000000..aa0cfc4262be + } + + status = san_enable_events(pdev); -+ if (status) { ++ if (status) + goto err_enable_events; -+ } + + mutex_lock(&rqsg_if.lock); -+ if (!rqsg_if.san_dev) { ++ if (!rqsg_if.san_dev) + rqsg_if.san_dev = &pdev->dev; -+ } else { ++ else + status = -EBUSY; -+ } + mutex_unlock(&rqsg_if.lock); + -+ if (status) { ++ if (status) + goto err_install_dev; -+ } + + acpi_walk_dep_device_list(san); + return 0; @@ -2945,7 +2909,7 @@ index 000000000000..aa0cfc4262be +}; + +static const struct acpi_device_id surface_sam_san_match[] = { -+ { "MSHW0091", (long unsigned int) san_mshw0091_consumers }, ++ { "MSHW0091", (unsigned long) san_mshw0091_consumers }, + { }, +}; +MODULE_DEVICE_TABLE(acpi, surface_sam_san_match); @@ -2966,10 +2930,11 @@ index 000000000000..aa0cfc4262be +MODULE_LICENSE("GPL v2"); diff --git a/drivers/platform/x86/surface_sam/surface_sam_san.h b/drivers/platform/x86/surface_sam/surface_sam_san.h new file mode 100644 -index 000000000000..1ea8713db367 +index 000000000000..85b6d6569947 --- /dev/null +++ b/drivers/platform/x86/surface_sam/surface_sam_san.h -@@ -0,0 +1,29 @@ +@@ -0,0 +1,30 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Interface for Surface ACPI/Notify (SAN). + * @@ -2989,7 +2954,7 @@ index 000000000000..1ea8713db367 + u8 tc; // target category + u8 cid; // command ID + u8 iid; // instance ID -+ u8 cdl; // command data length (lenght of payload) ++ u8 cdl; // command data length (length of payload) + u8 *pld; // pointer to payload of length cdl +}; + @@ -3001,10 +2966,11 @@ index 000000000000..1ea8713db367 +#endif /* _SURFACE_SAM_SAN_H */ diff --git a/drivers/platform/x86/surface_sam/surface_sam_sid.c b/drivers/platform/x86/surface_sam/surface_sam_sid.c new file mode 100644 -index 000000000000..f64dcd590494 +index 000000000000..fb49d0e00808 --- /dev/null +++ b/drivers/platform/x86/surface_sam/surface_sam_sid.c -@@ -0,0 +1,117 @@ +@@ -0,0 +1,137 @@ ++// SPDX-License-Identifier: GPL-2.0 +/* + * Surface Integration Driver. + * MFD driver to provide device/model dependent functionality. @@ -3018,14 +2984,16 @@ index 000000000000..f64dcd590494 + + +static const struct mfd_cell sid_devs_sp4[] = { -+ { .name = "surface_sam_sid_gpelid", .id = -1 }, ++ { .name = "surface_sam_sid_gpelid", .id = -1 }, ++ { .name = "surface_sam_sid_perfmode", .id = -1 }, + { }, +}; + +static const struct mfd_cell sid_devs_sp7[] = { -+ { .name = "surface_sam_sid_gpelid", .id = -1 }, -+ { .name = "surface_sam_sid_ac", .id = -1 }, -+ { .name = "surface_sam_sid_battery", .id = -1 }, ++ { .name = "surface_sam_sid_gpelid", .id = -1 }, ++ { .name = "surface_sam_sid_ac", .id = -1 }, ++ { .name = "surface_sam_sid_battery", .id = -1 }, ++ { .name = "surface_sam_sid_perfmode", .id = -1 }, + { }, +}; + @@ -3051,10 +3019,11 @@ index 000000000000..f64dcd590494 +}; + +static const struct mfd_cell sid_devs_sl3_13[] = { -+ { .name = "surface_sam_sid_gpelid", .id = -1 }, -+ { .name = "surface_sam_sid_vhf", .id = -1 }, -+ { .name = "surface_sam_sid_ac", .id = -1 }, -+ { .name = "surface_sam_sid_battery", .id = -1 }, ++ { .name = "surface_sam_sid_gpelid", .id = -1 }, ++ { .name = "surface_sam_sid_vhf", .id = -1 }, ++ { .name = "surface_sam_sid_ac", .id = -1 }, ++ { .name = "surface_sam_sid_battery", .id = -1 }, ++ { .name = "surface_sam_sid_perfmode", .id = -1 }, + { }, +}; + @@ -3066,14 +3035,30 @@ index 000000000000..f64dcd590494 +}; + +static const struct acpi_device_id surface_sam_sid_match[] = { -+ { "MSHW0081", (unsigned long)sid_devs_sp4 }, /* Surface Pro 4, 5, and 6 */ -+ { "MSHW0116", (unsigned long)sid_devs_sp7 }, /* Surface Pro 7 */ -+ { "MSHW0080", (unsigned long)sid_devs_sb1 }, /* Surface Book 1 */ -+ { "MSHW0107", (unsigned long)sid_devs_sb2 }, /* Surface Book 2 */ -+ { "MSHW0086", (unsigned long)sid_devs_sl1 }, /* Surface Laptop 1 */ -+ { "MSHW0112", (unsigned long)sid_devs_sl2 }, /* Surface Laptop 2 */ -+ { "MSHW0114", (unsigned long)sid_devs_sl3_13 }, /* Surface Laptop 3 (13") */ -+ { "MSHW0110", (unsigned long)sid_devs_sl3_15 }, /* Surface Laptop 3 (15") */ ++ /* Surface Pro 4, 5, and 6 */ ++ { "MSHW0081", (unsigned long)sid_devs_sp4 }, ++ ++ /* Surface Pro 7 */ ++ { "MSHW0116", (unsigned long)sid_devs_sp7 }, ++ ++ /* Surface Book 1 */ ++ { "MSHW0080", (unsigned long)sid_devs_sb1 }, ++ ++ /* Surface Book 2 */ ++ { "MSHW0107", (unsigned long)sid_devs_sb2 }, ++ ++ /* Surface Laptop 1 */ ++ { "MSHW0086", (unsigned long)sid_devs_sl1 }, ++ ++ /* Surface Laptop 2 */ ++ { "MSHW0112", (unsigned long)sid_devs_sl2 }, ++ ++ /* Surface Laptop 3 (13") */ ++ { "MSHW0114", (unsigned long)sid_devs_sl3_13 }, ++ ++ /* Surface Laptop 3 (15") */ ++ { "MSHW0110", (unsigned long)sid_devs_sl3_15 }, ++ + { }, +}; +MODULE_DEVICE_TABLE(acpi, surface_sam_sid_match); @@ -3124,10 +3109,11 @@ index 000000000000..f64dcd590494 +MODULE_LICENSE("GPL v2"); diff --git a/drivers/platform/x86/surface_sam/surface_sam_sid_gpelid.c b/drivers/platform/x86/surface_sam/surface_sam_sid_gpelid.c new file mode 100644 -index 000000000000..ce32ebf4d94d +index 000000000000..286411701d36 --- /dev/null +++ b/drivers/platform/x86/surface_sam/surface_sam_sid_gpelid.c -@@ -0,0 +1,219 @@ +@@ -0,0 +1,224 @@ ++// SPDX-License-Identifier: GPL-2.0 +/* + * Surface Lid driver to enable wakeup from suspend via the lid. + */ @@ -3268,25 +3254,29 @@ index 000000000000..ce32ebf4d94d + +static int surface_sam_sid_gpelid_suspend(struct device *dev) +{ -+ const struct sid_lid_device *ldev = dev_get_drvdata(dev); ++ const struct sid_lid_device *ldev; ++ ++ ldev = dev_get_drvdata(dev); + return sid_lid_enable_wakeup(ldev, true); +} + +static int surface_sam_sid_gpelid_resume(struct device *dev) +{ -+ const struct sid_lid_device *ldev = dev_get_drvdata(dev); ++ const struct sid_lid_device *ldev; ++ ++ ldev = dev_get_drvdata(dev); + return sid_lid_enable_wakeup(ldev, false); +} + +static SIMPLE_DEV_PM_OPS(surface_sam_sid_gpelid_pm, -+ surface_sam_sid_gpelid_suspend, -+ surface_sam_sid_gpelid_resume); ++ surface_sam_sid_gpelid_suspend, ++ surface_sam_sid_gpelid_resume); + + +static int surface_sam_sid_gpelid_probe(struct platform_device *pdev) +{ + const struct dmi_system_id *match; -+ struct sid_lid_device *dev; ++ struct sid_lid_device *dev; + acpi_handle lid_handle; + int status; + @@ -3294,9 +3284,9 @@ index 000000000000..ce32ebf4d94d + if (!match) + return -ENODEV; + -+ dev = match->driver_data; -+ if (!dev) -+ return -ENODEV; ++ dev = match->driver_data; ++ if (!dev) ++ return -ENODEV; + + status = acpi_get_handle(NULL, (acpi_string)dev->acpi_path, &lid_handle); + if (status) @@ -3313,11 +3303,11 @@ index 000000000000..ce32ebf4d94d + status = sid_lid_enable_wakeup(dev, false); + if (status) { + acpi_disable_gpe(NULL, dev->gpe_number); -+ return status; -+ } ++ return status; ++ } + -+ platform_set_drvdata(pdev, dev); -+ return 0; ++ platform_set_drvdata(pdev, dev); ++ return 0; +} + +static int surface_sam_sid_gpelid_remove(struct platform_device *pdev) @@ -3326,10 +3316,10 @@ index 000000000000..ce32ebf4d94d + + /* restore default behavior without this module */ + sid_lid_enable_wakeup(dev, false); -+ acpi_disable_gpe(NULL, dev->gpe_number); ++ acpi_disable_gpe(NULL, dev->gpe_number); + -+ platform_set_drvdata(pdev, NULL); -+ return 0; ++ platform_set_drvdata(pdev, NULL); ++ return 0; +} + +static struct platform_driver surface_sam_sid_gpelid = { @@ -3349,10 +3339,11 @@ index 000000000000..ce32ebf4d94d +MODULE_ALIAS("platform:surface_sam_sid_gpelid"); diff --git a/drivers/platform/x86/surface_sam/surface_sam_sid_perfmode.c b/drivers/platform/x86/surface_sam/surface_sam_sid_perfmode.c new file mode 100644 -index 000000000000..880a2567cf1b +index 000000000000..f74e2b51604d --- /dev/null +++ b/drivers/platform/x86/surface_sam/surface_sam_sid_perfmode.c -@@ -0,0 +1,225 @@ +@@ -0,0 +1,216 @@ ++// SPDX-License-Identifier: GPL-2.0 +/* + * Surface Performance Mode Driver. + * Allows to change cooling capabilities based on user preference. @@ -3366,7 +3357,7 @@ index 000000000000..880a2567cf1b +#include "surface_sam_ssh.h" + + -+#define SID_PARAM_PERM (S_IRUGO | S_IWUSR) ++#define SID_PARAM_PERM 0644 + +enum sam_perf_mode { + SAM_PERF_MODE_NORMAL = 1, @@ -3412,13 +3403,11 @@ index 000000000000..880a2567cf1b + }; + + status = surface_sam_ssh_rqst(&rqst, &result); -+ if (status) { ++ if (status) + return status; -+ } + -+ if (result.len != 8) { ++ if (result.len != 8) + return -EFAULT; -+ } + + return get_unaligned_le32(&result.data[0]); +} @@ -3437,9 +3426,8 @@ index 000000000000..880a2567cf1b + .pld = payload, + }; + -+ if (perf_mode < __SAM_PERF_MODE__START || perf_mode > __SAM_PERF_MODE__END) { ++ if (perf_mode < __SAM_PERF_MODE__START || perf_mode > __SAM_PERF_MODE__END) + return -EINVAL; -+ } + + put_unaligned_le32(perf_mode, &rqst.pld[0]); + return surface_sam_ssh_rqst(&rqst, NULL); @@ -3452,13 +3440,11 @@ index 000000000000..880a2567cf1b + int status; + + status = kstrtoint(val, 0, &perf_mode); -+ if (status) { ++ if (status) + return status; -+ } + -+ if (perf_mode < __SID_PARAM_PERF_MODE__START || perf_mode > __SID_PARAM_PERF_MODE__END) { ++ if (perf_mode < __SID_PARAM_PERF_MODE__START || perf_mode > __SID_PARAM_PERF_MODE__END) + return -EINVAL; -+ } + + return param_set_int(val, kp); +} @@ -3492,20 +3478,18 @@ index 000000000000..880a2567cf1b +} + +static ssize_t perf_mode_store(struct device *dev, struct device_attribute *attr, -+ const char *data, size_t count) ++ const char *data, size_t count) +{ + int perf_mode; + int status; + + status = kstrtoint(data, 0, &perf_mode); -+ if (status) { ++ if (status) + return status; -+ } + + status = surface_sam_perf_mode_set(perf_mode); -+ if (status) { ++ if (status) + return status; -+ } + + // TODO: Should we notify ACPI here? + // @@ -3532,23 +3516,20 @@ index 000000000000..880a2567cf1b + + // link to ec + status = surface_sam_ssh_consumer_register(&pdev->dev); -+ if (status) { ++ if (status) + return status == -ENXIO ? -EPROBE_DEFER : status; -+ } + + // set initial perf_mode + if (param_perf_mode_init != SID_PARAM_PERF_MODE_AS_IS) { + status = surface_sam_perf_mode_set(param_perf_mode_init); -+ if (status) { ++ if (status) + return status; -+ } + } + + // register perf_mode attribute + status = sysfs_create_file(&pdev->dev.kobj, &dev_attr_perf_mode.attr); -+ if (status) { ++ if (status) + goto err_sysfs; -+ } + + return 0; + @@ -3580,10 +3561,11 @@ index 000000000000..880a2567cf1b +MODULE_ALIAS("platform:surface_sam_sid_perfmode"); diff --git a/drivers/platform/x86/surface_sam/surface_sam_sid_power.c b/drivers/platform/x86/surface_sam/surface_sam_sid_power.c new file mode 100644 -index 000000000000..1f2c88eda394 +index 000000000000..eb925bdda883 --- /dev/null +++ b/drivers/platform/x86/surface_sam/surface_sam_sid_power.c -@@ -0,0 +1,1259 @@ +@@ -0,0 +1,1264 @@ ++// SPDX-License-Identifier: GPL-2.0 +/* + * Surface SID Battery/AC Driver. + * Provides support for the battery and AC on 7th generation Surface devices. @@ -3917,7 +3899,7 @@ index 000000000000..1f2c88eda394 +struct spwr_subsystem { + struct mutex lock; + -+ unsigned refcount; ++ unsigned int refcount; + struct spwr_ac_device *ac; + struct spwr_battery_device *battery[__SPWR_NUM_BAT]; +}; @@ -3973,18 +3955,18 @@ index 000000000000..1f2c88eda394 +static int spwr_battery_unregister(struct spwr_battery_device *bat); + + -+inline static bool spwr_battery_present(struct spwr_battery_device *bat) ++static inline bool spwr_battery_present(struct spwr_battery_device *bat) +{ + return bat->sta & SAM_BATTERY_STA_PRESENT; +} + + -+inline static int spwr_battery_load_sta(struct spwr_battery_device *bat) ++static inline int spwr_battery_load_sta(struct spwr_battery_device *bat) +{ + return sam_psy_get_sta(bat->id + 1, &bat->sta); +} + -+inline static int spwr_battery_load_bix(struct spwr_battery_device *bat) ++static inline int spwr_battery_load_bix(struct spwr_battery_device *bat) +{ + if (!spwr_battery_present(bat)) + return 0; @@ -3992,7 +3974,7 @@ index 000000000000..1f2c88eda394 + return sam_psy_get_bix(bat->id + 1, &bat->bix); +} + -+inline static int spwr_battery_load_bst(struct spwr_battery_device *bat) ++static inline int spwr_battery_load_bst(struct spwr_battery_device *bat) +{ + if (!spwr_battery_present(bat)) + return 0; @@ -4001,13 +3983,13 @@ index 000000000000..1f2c88eda394 +} + + -+inline static int spwr_battery_set_alarm_unlocked(struct spwr_battery_device *bat, u32 value) ++static inline int spwr_battery_set_alarm_unlocked(struct spwr_battery_device *bat, u32 value) +{ + bat->alarm = value; + return sam_psy_set_btp(bat->id + 1, bat->alarm); +} + -+inline static int spwr_battery_set_alarm(struct spwr_battery_device *bat, u32 value) ++static inline int spwr_battery_set_alarm(struct spwr_battery_device *bat, u32 value) +{ + int status; + @@ -4018,7 +4000,7 @@ index 000000000000..1f2c88eda394 + return status; +} + -+inline static int spwr_battery_update_bst_unlocked(struct spwr_battery_device *bat, bool cached) ++static inline int spwr_battery_update_bst_unlocked(struct spwr_battery_device *bat, bool cached) +{ + unsigned long cache_deadline = bat->timestamp + msecs_to_jiffies(cache_time); + int status; @@ -4049,7 +4031,7 @@ index 000000000000..1f2c88eda394 + return status; +} + -+inline static int spwr_battery_update_bix_unlocked(struct spwr_battery_device *bat) ++static inline int spwr_battery_update_bix_unlocked(struct spwr_battery_device *bat) +{ + int status; + @@ -4080,7 +4062,7 @@ index 000000000000..1f2c88eda394 + return status; +} + -+inline static int spwr_ac_update_unlocked(struct spwr_ac_device *ac) ++static inline int spwr_ac_update_unlocked(struct spwr_ac_device *ac) +{ + return sam_psy_get_psrc(0x00, &ac->state); +} @@ -4258,7 +4240,7 @@ index 000000000000..1f2c88eda394 +} + + -+inline static int spwr_battery_prop_status(struct spwr_battery_device *bat) ++static inline int spwr_battery_prop_status(struct spwr_battery_device *bat) +{ + if (bat->bst.state & SAM_BATTERY_STATE_DISCHARGING) + return POWER_SUPPLY_STATUS_DISCHARGING; @@ -4275,7 +4257,7 @@ index 000000000000..1f2c88eda394 + return POWER_SUPPLY_STATUS_UNKNOWN; +} + -+inline static int spwr_battery_prop_technology(struct spwr_battery_device *bat) ++static inline int spwr_battery_prop_technology(struct spwr_battery_device *bat) +{ + if (!strcasecmp("NiCd", bat->bix.type)) + return POWER_SUPPLY_TECHNOLOGY_NiCd; @@ -4295,7 +4277,7 @@ index 000000000000..1f2c88eda394 + return POWER_SUPPLY_TECHNOLOGY_UNKNOWN; +} + -+inline static int spwr_battery_prop_capacity(struct spwr_battery_device *bat) ++static inline int spwr_battery_prop_capacity(struct spwr_battery_device *bat) +{ + if (bat->bst.remaining_cap && bat->bix.last_full_charge_cap) + return bat->bst.remaining_cap * 100 / bat->bix.last_full_charge_cap; @@ -4303,7 +4285,7 @@ index 000000000000..1f2c88eda394 + return 0; +} + -+inline static int spwr_battery_prop_capacity_level(struct spwr_battery_device *bat) ++static inline int spwr_battery_prop_capacity_level(struct spwr_battery_device *bat) +{ + if (bat->bst.state & SAM_BATTERY_STATE_CRITICAL) + return POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL; @@ -4485,14 +4467,12 @@ index 000000000000..1f2c88eda394 + int status; + + status = surface_sam_ssh_set_event_handler(SAM_PWR_RQID, spwr_handle_event, NULL); -+ if (status) { ++ if (status) + goto err_handler; -+ } + + status = surface_sam_ssh_enable_event_source(SAM_PWR_TC, 0x01, SAM_PWR_RQID); -+ if (status) { ++ if (status) + goto err_source; -+ } + + return 0; + @@ -4697,7 +4677,7 @@ index 000000000000..1f2c88eda394 + int status; + + if (bat->id < 0 || bat->id >= __SPWR_NUM_BAT) -+ return -EINVAL ; ++ return -EINVAL; + + mutex_lock(&spwr_subsystem.lock); + if (spwr_subsystem.battery[bat->id] != bat) { @@ -4726,7 +4706,9 @@ index 000000000000..1f2c88eda394 +#ifdef CONFIG_PM_SLEEP +static int surface_sam_sid_battery_resume(struct device *dev) +{ -+ struct spwr_battery_device *bat = dev_get_drvdata(dev); ++ struct spwr_battery_device *bat; ++ ++ bat = dev_get_drvdata(dev); + return spwr_battery_recheck(bat); +} +#else @@ -4755,7 +4737,9 @@ index 000000000000..1f2c88eda394 + +static int surface_sam_sid_battery_remove(struct platform_device *pdev) +{ -+ struct spwr_battery_device *bat = platform_get_drvdata(pdev); ++ struct spwr_battery_device *bat; ++ ++ bat = platform_get_drvdata(pdev); + return spwr_battery_unregister(bat); +} + @@ -4798,7 +4782,9 @@ index 000000000000..1f2c88eda394 + +static int surface_sam_sid_ac_remove(struct platform_device *pdev) +{ -+ struct spwr_ac_device *ac = platform_get_drvdata(pdev); ++ struct spwr_ac_device *ac; ++ ++ ac = platform_get_drvdata(pdev); + return spwr_ac_unregister(ac); +} + @@ -4845,10 +4831,11 @@ index 000000000000..1f2c88eda394 +MODULE_ALIAS("platform:surface_sam_sid_battery"); diff --git a/drivers/platform/x86/surface_sam/surface_sam_sid_vhf.c b/drivers/platform/x86/surface_sam/surface_sam_sid_vhf.c new file mode 100644 -index 000000000000..dc5be3a14a8c +index 000000000000..9cf912a44171 --- /dev/null +++ b/drivers/platform/x86/surface_sam/surface_sam_sid_vhf.c -@@ -0,0 +1,440 @@ +@@ -0,0 +1,428 @@ ++// SPDX-License-Identifier: GPL-2.0 +/* + * Microsofs Surface HID (VHF) driver for HID input events via SAM. + * Used for keyboard input events on the 7th generation Surface Laptops. @@ -4972,19 +4959,18 @@ index 000000000000..dc5be3a14a8c + .pri = 0x02, + .snc = 0x01, + .cdl = sizeof(struct surface_sam_sid_vhf_meta_rqst), -+ .pld = (u8*)&resp.rqst, ++ .pld = (u8 *)&resp.rqst, + }; + + struct surface_sam_ssh_buf result = { + .cap = sizeof(struct surface_sam_sid_vhf_meta_resp), + .len = 0, -+ .data = (u8*)&resp, ++ .data = (u8 *)&resp, + }; + + status = surface_sam_ssh_rqst(&rqst, &result); -+ if (status) { ++ if (status) + return status; -+ } + + *meta = resp.data.meta; + @@ -5012,20 +4998,19 @@ index 000000000000..dc5be3a14a8c + .pri = 0x02, + .snc = 0x01, + .cdl = sizeof(struct surface_sam_sid_vhf_meta_rqst), -+ .pld = (u8*)&resp.rqst, ++ .pld = (u8 *)&resp.rqst, + }; + + struct surface_sam_ssh_buf result = { + .cap = sizeof(struct surface_sam_sid_vhf_meta_resp), + .len = 0, -+ .data = (u8*)&resp, ++ .data = (u8 *)&resp, + }; + + // first fetch 00 to get the total length + status = surface_sam_ssh_rqst(&rqst, &result); -+ if (status) { ++ if (status) + return status; -+ } + + len = resp.data.info.hid_len; + @@ -5122,8 +5107,8 @@ index 000000000000..dc5be3a14a8c + rqst.pri = SURFACE_SAM_PRIORITY_HIGH; + rqst.iid = 0x00; // windows tends to distinguish iids, but EC will take it + rqst.cid = cid; -+ rqst.snc = HID_REQ_GET_REPORT == reqtype ? 0x01 : 0x00; -+ rqst.cdl = HID_REQ_GET_REPORT == reqtype ? 0x01 : len; ++ rqst.snc = reqtype == HID_REQ_GET_REPORT ? 0x01 : 0x00; ++ rqst.cdl = reqtype == HID_REQ_GET_REPORT ? 0x01 : len; + rqst.pld = buf; + + result.cap = len; @@ -5135,13 +5120,11 @@ index 000000000000..dc5be3a14a8c + status = surface_sam_ssh_rqst(&rqst, &result); + hid_dbg(hid, "%s: status %i\n", __func__, status); + -+ if (status) { ++ if (status) + return status; -+ } + -+ if (result.len > 0) { ++ if (result.len > 0) + print_hex_dump_debug("response:", DUMP_PREFIX_OFFSET, 16, 1, result.data, result.len, false); -+ } + + return result.len; +} @@ -5161,9 +5144,8 @@ index 000000000000..dc5be3a14a8c + struct hid_device *hid; + + hid = hid_allocate_device(); -+ if (IS_ERR(hid)) { ++ if (IS_ERR(hid)) + return hid; -+ } + + hid->dev.parent = &pdev->dev; + @@ -5183,13 +5165,11 @@ index 000000000000..dc5be3a14a8c + struct sid_vhf_evtctx *ctx = (struct sid_vhf_evtctx *)data; + + // skip if HID hasn't started yet -+ if (!test_bit(VHF_HID_STARTED, &ctx->flags)) { ++ if (!test_bit(VHF_HID_STARTED, &ctx->flags)) + return 0; -+ } + -+ if (event->tc == SAM_EVENT_SID_VHF_TC && (event->cid == 0x00 || event->cid == 0x03 || event->cid == 0x04)) { ++ if (event->tc == SAM_EVENT_SID_VHF_TC && (event->cid == 0x00 || event->cid == 0x03 || event->cid == 0x04)) + return hid_input_report(ctx->hid, HID_INPUT_REPORT, event->pld, event->len, 1); -+ } + + dev_warn(ctx->dev, "unsupported event (tc = %d, cid = %d)\n", event->tc, event->cid); + return 0; @@ -5204,19 +5184,16 @@ index 000000000000..dc5be3a14a8c + + // add device link to EC + status = surface_sam_ssh_consumer_register(&pdev->dev); -+ if (status) { ++ if (status) + return status == -ENXIO ? -EPROBE_DEFER : status; -+ } + + drvdata = kzalloc(sizeof(struct sid_vhf_drvdata), GFP_KERNEL); -+ if (!drvdata) { ++ if (!drvdata) + return -ENOMEM; -+ } + + status = vhf_get_metadata(0x00, &meta); -+ if (status) { ++ if (status) + goto err_create_hid; -+ } + + hid = sid_vhf_create_hid_device(pdev, &meta); + if (IS_ERR(hid)) { @@ -5233,19 +5210,16 @@ index 000000000000..dc5be3a14a8c + SAM_EVENT_SID_VHF_RQID, + sid_vhf_event_handler, + &drvdata->event_ctx); -+ if (status) { ++ if (status) + goto err_event_handler; -+ } + + status = surface_sam_ssh_enable_event_source(SAM_EVENT_SID_VHF_TC, 0x01, SAM_EVENT_SID_VHF_RQID); -+ if (status) { ++ if (status) + goto err_event_source; -+ } + + status = hid_add_device(hid); -+ if (status) { ++ if (status) + goto err_add_hid; -+ } + + return 0; + @@ -5291,10 +5265,11 @@ index 000000000000..dc5be3a14a8c +MODULE_ALIAS("platform:surface_sam_sid_vhf"); diff --git a/drivers/platform/x86/surface_sam/surface_sam_ssh.c b/drivers/platform/x86/surface_sam/surface_sam_ssh.c new file mode 100644 -index 000000000000..34905cf29a51 +index 000000000000..988be7c2d286 --- /dev/null +++ b/drivers/platform/x86/surface_sam/surface_sam_ssh.c -@@ -0,0 +1,1773 @@ +@@ -0,0 +1,1744 @@ ++// SPDX-License-Identifier: GPL-2.0 +/* + * Surface Serial Hub (SSH) driver for communication with the Surface/System + * Aggregator Module. @@ -5522,7 +5497,7 @@ index 000000000000..34905cf29a51 +}; + + -+inline static struct sam_ssh_ec *surface_sam_ssh_acquire(void) ++static inline struct sam_ssh_ec *surface_sam_ssh_acquire(void) +{ + struct sam_ssh_ec *ec = &ssh_ec; + @@ -5530,12 +5505,12 @@ index 000000000000..34905cf29a51 + return ec; +} + -+inline static void surface_sam_ssh_release(struct sam_ssh_ec *ec) ++static inline void surface_sam_ssh_release(struct sam_ssh_ec *ec) +{ + mutex_unlock(&ec->lock); +} + -+inline static struct sam_ssh_ec *surface_sam_ssh_acquire_init(void) ++static inline struct sam_ssh_ec *surface_sam_ssh_acquire_init(void) +{ + struct sam_ssh_ec *ec = surface_sam_ssh_acquire(); + @@ -5554,14 +5529,12 @@ index 000000000000..34905cf29a51 + struct device_link *link; + + ec = surface_sam_ssh_acquire_init(); -+ if (!ec) { ++ if (!ec) + return -ENXIO; -+ } + + link = device_link_add(consumer, &ec->serdev->dev, flags); -+ if (!link) { ++ if (!link) + return -EFAULT; -+ } + + surface_sam_ssh_release(ec); + return 0; @@ -5569,12 +5542,15 @@ index 000000000000..34905cf29a51 +EXPORT_SYMBOL_GPL(surface_sam_ssh_consumer_register); + + -+inline static u16 sam_rqid_to_rqst(u16 rqid) { ++static inline u16 sam_rqid_to_rqst(u16 rqid) ++{ + return rqid << SURFACE_SAM_SSH_RQID_EVENT_BITS; +} + -+inline static bool sam_rqid_is_event(u16 rqid) { ++static inline bool sam_rqid_is_event(u16 rqid) ++{ + const u16 mask = (1 << SURFACE_SAM_SSH_RQID_EVENT_BITS) - 1; ++ + return rqid != 0 && (rqid | mask) == mask; +} + @@ -5602,16 +5578,15 @@ index 000000000000..34905cf29a51 + int status; + + // only allow RQIDs that lie within event spectrum -+ if (!sam_rqid_is_event(rqid)) { ++ if (!sam_rqid_is_event(rqid)) + return -EINVAL; -+ } + + status = surface_sam_ssh_rqst(&rqst, &result); + + if (buf[0] != 0x00) { -+ printk(KERN_WARNING SSH_RQST_TAG_FULL -+ "unexpected result while enabling event source: 0x%02x\n", -+ buf[0]); ++ pr_warn(SSH_RQST_TAG_FULL ++ "unexpected result while enabling event source: 0x%02x\n", ++ buf[0]); + } + + return status; @@ -5643,16 +5618,15 @@ index 000000000000..34905cf29a51 + int status; + + // only allow RQIDs that lie within event spectrum -+ if (!sam_rqid_is_event(rqid)) { ++ if (!sam_rqid_is_event(rqid)) + return -EINVAL; -+ } + + status = surface_sam_ssh_rqst(&rqst, &result); + + if (buf[0] != 0x00) { -+ printk(KERN_WARNING SSH_RQST_TAG_FULL -+ "unexpected result while disabling event source: 0x%02x\n", -+ buf[0]); ++ pr_warn(SSH_RQST_TAG_FULL ++ "unexpected result while disabling event source: 0x%02x\n", ++ buf[0]); + } + + return status; @@ -5672,18 +5646,15 @@ index 000000000000..34905cf29a51 + struct sam_ssh_ec *ec; + unsigned long flags; + -+ if (!sam_rqid_is_event(rqid)) { ++ if (!sam_rqid_is_event(rqid)) + return -EINVAL; -+ } + + ec = surface_sam_ssh_acquire_init(); -+ if (!ec) { ++ if (!ec) + return -ENXIO; -+ } + -+ if (!delay) { ++ if (!delay) + delay = sam_event_default_delay; -+ } + + spin_lock_irqsave(&ec->events.lock, flags); + // check if we already have a handler @@ -5709,14 +5680,12 @@ index 000000000000..34905cf29a51 + struct sam_ssh_ec *ec; + unsigned long flags; + -+ if (!sam_rqid_is_event(rqid)) { ++ if (!sam_rqid_is_event(rqid)) + return -EINVAL; -+ } + + ec = surface_sam_ssh_acquire_init(); -+ if (!ec) { ++ if (!ec) + return -ENXIO; -+ } + + spin_lock_irqsave(&ec->events.lock, flags); + @@ -5739,24 +5708,24 @@ index 000000000000..34905cf29a51 +EXPORT_SYMBOL_GPL(surface_sam_ssh_remove_event_handler); + + -+inline static u16 ssh_crc(const u8 *buf, size_t size) ++static inline u16 ssh_crc(const u8 *buf, size_t size) +{ + return crc_ccitt_false(0xffff, buf, size); +} + -+inline static void ssh_write_u16(struct ssh_writer *writer, u16 in) ++static inline void ssh_write_u16(struct ssh_writer *writer, u16 in) +{ + put_unaligned_le16(in, writer->ptr); + writer->ptr += 2; +} + -+inline static void ssh_write_crc(struct ssh_writer *writer, ++static inline void ssh_write_crc(struct ssh_writer *writer, + const u8 *buf, size_t size) +{ + ssh_write_u16(writer, ssh_crc(buf, size)); +} + -+inline static void ssh_write_syn(struct ssh_writer *writer) ++static inline void ssh_write_syn(struct ssh_writer *writer) +{ + u8 *w = writer->ptr; + @@ -5766,7 +5735,7 @@ index 000000000000..34905cf29a51 + writer->ptr = w; +} + -+inline static void ssh_write_ter(struct ssh_writer *writer) ++static inline void ssh_write_ter(struct ssh_writer *writer) +{ + u8 *w = writer->ptr; + @@ -5776,13 +5745,13 @@ index 000000000000..34905cf29a51 + writer->ptr = w; +} + -+inline static void ssh_write_buf(struct ssh_writer *writer, ++static inline void ssh_write_buf(struct ssh_writer *writer, + u8 *in, size_t len) +{ + writer->ptr = memcpy(writer->ptr, in, len) + len; +} + -+inline static void ssh_write_hdr(struct ssh_writer *writer, ++static inline void ssh_write_hdr(struct ssh_writer *writer, + const struct surface_sam_ssh_rqst *rqst, + struct sam_ssh_ec *ec) +{ @@ -5799,7 +5768,7 @@ index 000000000000..34905cf29a51 + ssh_write_crc(writer, begin, writer->ptr - begin); +} + -+inline static void ssh_write_cmd(struct ssh_writer *writer, ++static inline void ssh_write_cmd(struct ssh_writer *writer, + const struct surface_sam_ssh_rqst *rqst, + struct sam_ssh_ec *ec) +{ @@ -5825,7 +5794,7 @@ index 000000000000..34905cf29a51 + ssh_write_crc(writer, begin, writer->ptr - begin); +} + -+inline static void ssh_write_ack(struct ssh_writer *writer, u8 seq) ++static inline void ssh_write_ack(struct ssh_writer *writer, u8 seq) +{ + struct ssh_frame_ctrl *ack = (struct ssh_frame_ctrl *)writer->ptr; + u8 *begin = writer->ptr; @@ -5840,12 +5809,12 @@ index 000000000000..34905cf29a51 + ssh_write_crc(writer, begin, writer->ptr - begin); +} + -+inline static void ssh_writer_reset(struct ssh_writer *writer) ++static inline void ssh_writer_reset(struct ssh_writer *writer) +{ + writer->ptr = writer->data; +} + -+inline static int ssh_writer_flush(struct sam_ssh_ec *ec) ++static inline int ssh_writer_flush(struct sam_ssh_ec *ec) +{ + struct ssh_writer *writer = &ec->writer; + struct serdev_device *serdev = ec->serdev; @@ -5855,13 +5824,13 @@ index 000000000000..34905cf29a51 + + dev_dbg(&ec->serdev->dev, "sending message\n"); + print_hex_dump_debug("send: ", DUMP_PREFIX_OFFSET, 16, 1, -+ writer->data, writer->ptr - writer->data, false); ++ writer->data, writer->ptr - writer->data, false); + + status = serdev_device_write(serdev, writer->data, len, SSH_WRITE_TIMEOUT); + return status >= 0 ? 0 : status; +} + -+inline static void ssh_write_msg_cmd(struct sam_ssh_ec *ec, ++static inline void ssh_write_msg_cmd(struct sam_ssh_ec *ec, + const struct surface_sam_ssh_rqst *rqst) +{ + ssh_writer_reset(&ec->writer); @@ -5870,7 +5839,7 @@ index 000000000000..34905cf29a51 + ssh_write_cmd(&ec->writer, rqst, ec); +} + -+inline static void ssh_write_msg_ack(struct sam_ssh_ec *ec, u8 seq) ++static inline void ssh_write_msg_ack(struct sam_ssh_ec *ec, u8 seq) +{ + ssh_writer_reset(&ec->writer); + ssh_write_syn(&ec->writer); @@ -5878,7 +5847,7 @@ index 000000000000..34905cf29a51 + ssh_write_ter(&ec->writer); +} + -+inline static void ssh_receiver_restart(struct sam_ssh_ec *ec, ++static inline void ssh_receiver_restart(struct sam_ssh_ec *ec, + const struct surface_sam_ssh_rqst *rqst) +{ + unsigned long flags; @@ -5893,7 +5862,7 @@ index 000000000000..34905cf29a51 + spin_unlock_irqrestore(&ec->receiver.lock, flags); +} + -+inline static void ssh_receiver_discard(struct sam_ssh_ec *ec) ++static inline void ssh_receiver_discard(struct sam_ssh_ec *ec) +{ + unsigned long flags; + @@ -5926,18 +5895,16 @@ index 000000000000..34905cf29a51 + // send command, try to get an ack response + for (try = 0; try < SSH_NUM_RETRY; try++) { + status = ssh_writer_flush(ec); -+ if (status) { ++ if (status) + goto out; -+ } + + rem = wait_for_completion_timeout(&ec->receiver.signal, SSH_READ_TIMEOUT); + if (rem) { + // completion assures valid packet, thus ignore returned length + (void) !kfifo_out(&ec->receiver.fifo, &packet, sizeof(packet)); + -+ if (packet.type == SSH_FRAME_TYPE_ACK) { ++ if (packet.type == SSH_FRAME_TYPE_ACK) + break; -+ } + } + } + @@ -5976,9 +5943,8 @@ index 000000000000..34905cf29a51 + if (packet.type == SSH_FRAME_TYPE_CMD) { + ssh_write_msg_ack(ec, packet.seq); + status = ssh_writer_flush(ec); -+ if (status) { ++ if (status) + goto out; -+ } + } + } + @@ -5994,7 +5960,7 @@ index 000000000000..34905cf29a51 + + ec = surface_sam_ssh_acquire_init(); + if (!ec) { -+ printk(KERN_WARNING SSH_RQST_TAG_FULL "embedded controller is uninitialized\n"); ++ pr_warn(SSH_RQST_TAG_FULL "embedded controller is uninitialized\n"); + return -ENXIO; + } + @@ -6033,14 +5999,15 @@ index 000000000000..34905cf29a51 + result.data = buf, + }; + -+ int status = surface_sam_ssh_rqst_unlocked(ec, &rqst, &result); -+ if (status) { ++ int status; ++ ++ status = surface_sam_ssh_rqst_unlocked(ec, &rqst, &result); ++ if (status) + return status; -+ } + + if (buf[0] != 0x00) { + dev_warn(&ec->serdev->dev, -+ "unexpected result while trying to resume EC: 0x%02x\n", ++ "unexpected result while trying to resume EC: 0x%02x\n", + buf[0]); + } + @@ -6067,14 +6034,15 @@ index 000000000000..34905cf29a51 + result.data = buf, + }; + -+ int status = surface_sam_ssh_rqst_unlocked(ec, &rqst, &result); -+ if (status) { ++ int status; ++ ++ status = surface_sam_ssh_rqst_unlocked(ec, &rqst, &result); ++ if (status) + return status; -+ } + + if (buf[0] != 0x00) { + dev_warn(&ec->serdev->dev, -+ "unexpected result while trying to suspend EC: 0x%02x\n", ++ "unexpected result while trying to suspend EC: 0x%02x\n", + buf[0]); + } + @@ -6082,19 +6050,21 @@ index 000000000000..34905cf29a51 +} + + -+inline static bool ssh_is_valid_syn(const u8 *ptr) ++static inline bool ssh_is_valid_syn(const u8 *ptr) +{ + return ptr[0] == 0xaa && ptr[1] == 0x55; +} + -+inline static bool ssh_is_valid_ter(const u8 *ptr) ++static inline bool ssh_is_valid_ter(const u8 *ptr) +{ + return ptr[0] == 0xff && ptr[1] == 0xff; +} + -+inline static bool ssh_is_valid_crc(const u8 *begin, const u8 *end) ++static inline bool ssh_is_valid_crc(const u8 *begin, const u8 *end) +{ -+ u16 crc = ssh_crc(begin, end - begin); ++ u16 crc; ++ ++ crc = ssh_crc(begin, end - begin); + return (end[0] == (crc & 0xff)) && (end[1] == (crc >> 8)); +} + @@ -6121,7 +6091,7 @@ index 000000000000..34905cf29a51 + + dev_dbg(&ec->serdev->dev, "sending message\n"); + print_hex_dump_debug("send: ", DUMP_PREFIX_OFFSET, 16, 1, -+ buf, SSH_MSG_LEN_CTRL, false); ++ buf, SSH_MSG_LEN_CTRL, false); + + status = serdev_device_write(ec->serdev, buf, SSH_MSG_LEN_CTRL, SSH_WRITE_TIMEOUT); + return status >= 0 ? 0 : status; @@ -6140,19 +6110,17 @@ index 000000000000..34905cf29a51 + ec = work->ec; + dev = &ec->serdev->dev; + -+ // make sure we load a fresh ec state ++ /* make sure we load a fresh ec state */ + smp_mb(); + + if (ec->state == SSH_EC_INITIALIZED) { + status = surface_sam_ssh_send_ack(ec, work->seq); -+ if (status) { ++ if (status) + dev_err(dev, SSH_EVENT_TAG "failed to send ACK: %d\n", status); -+ } + } + -+ if (refcount_dec_and_test(&work->refcount)) { ++ if (refcount_dec_and_test(&work->refcount)) + kfree(work); -+ } +} + +static void surface_sam_ssh_event_work_evt_handler(struct work_struct *_work) @@ -6185,24 +6153,20 @@ index 000000000000..34905cf29a51 + * guaranteed to be valid at least until this function returns. + */ + -+ if (handler) { ++ if (handler) + status = handler(event, handler_data); -+ } else { ++ else + dev_warn(dev, SSH_EVENT_TAG "unhandled event (rqid: %04x)\n", event->rqid); -+ } + -+ if (status) { ++ if (status) + dev_err(dev, SSH_EVENT_TAG "error handling event: %d\n", status); -+ } + -+ if (refcount_dec_and_test(&work->refcount)) { ++ if (refcount_dec_and_test(&work->refcount)) + kfree(work); -+ } +} + +static void ssh_handle_event(struct sam_ssh_ec *ec, const u8 *buf) +{ -+ struct device *dev = &ec->serdev->dev; + const struct ssh_frame_ctrl *ctrl; + const struct ssh_frame_cmd *cmd; + struct ssh_event_work *work; @@ -6219,10 +6183,8 @@ index 000000000000..34905cf29a51 + pld_len = ctrl->len - SSH_BYTELEN_CMDFRAME; + + work = kzalloc(sizeof(struct ssh_event_work) + pld_len, GFP_ATOMIC); -+ if (!work) { -+ dev_warn(dev, SSH_EVENT_TAG "failed to allocate memory, dropping event\n"); ++ if (!work) + return; -+ } + + refcount_set(&work->refcount, 1); + work->ec = ec; @@ -6233,7 +6195,7 @@ index 000000000000..34905cf29a51 + work->event.iid = cmd->iid; + work->event.pri = cmd->pri_in; + work->event.len = pld_len; -+ work->event.pld = ((u8*) work) + sizeof(struct ssh_event_work); ++ work->event.pld = ((u8 *)work) + sizeof(struct ssh_event_work); + + memcpy(work->event.pld, buf + SSH_FRAME_OFFS_CMD_PLD, pld_len); + @@ -6277,9 +6239,8 @@ index 000000000000..34905cf29a51 + ctrl = (const struct ssh_frame_ctrl *)(ctrl_begin); + + // actual length check -+ if (size < SSH_MSG_LEN_CTRL) { ++ if (size < SSH_MSG_LEN_CTRL) + return 0; // need more bytes -+ } + + // validate TERM + if (!ssh_is_valid_ter(buf + SSH_FRAME_OFFS_TERM)) { @@ -6354,9 +6315,8 @@ index 000000000000..34905cf29a51 + cmd = (const struct ssh_frame_cmd *)(cmd_begin); + + // we need at least a full control frame -+ if (size < (SSH_BYTELEN_SYNC + SSH_BYTELEN_CTRL + SSH_BYTELEN_CRC)) { ++ if (size < (SSH_BYTELEN_SYNC + SSH_BYTELEN_CTRL + SSH_BYTELEN_CRC)) + return 0; // need more bytes -+ } + + // validate control-frame CRC + if (!ssh_is_valid_crc(ctrl_begin, ctrl_end)) { @@ -6370,9 +6330,8 @@ index 000000000000..34905cf29a51 + + // actual length check (ctrl->len contains command-frame but not crc) + msg_len = SSH_MSG_LEN_CMD_BASE + ctrl->len; -+ if (size < msg_len) { ++ if (size < msg_len) + return 0; // need more bytes -+ } + + cmd_end = cmd_begin + ctrl->len; + @@ -6443,9 +6402,8 @@ index 000000000000..34905cf29a51 + struct ssh_frame_ctrl *ctrl; + + // we need at least a control frame to check what to do -+ if (size < (SSH_BYTELEN_SYNC + SSH_BYTELEN_CTRL)) { ++ if (size < (SSH_BYTELEN_SYNC + SSH_BYTELEN_CTRL)) + return 0; // need more bytes -+ } + + // make sure we're actually at the start of a new message + if (!ssh_is_valid_syn(buf)) { @@ -6453,7 +6411,7 @@ index 000000000000..34905cf29a51 + return size; // discard everything + } + -+ // handle individual message types seperately ++ // handle individual message types separately + ctrl = (struct ssh_frame_ctrl *)(buf + SSH_FRAME_OFFS_CTRL); + + switch (ctrl->type) { @@ -6499,7 +6457,8 @@ index 000000000000..34905cf29a51 + while (offs < rcv->eval_buf.len) { + n = rcv->eval_buf.len - offs; + n = ssh_eval_buf(ec, rcv->eval_buf.ptr + offs, n); -+ if (n <= 0) break; // need more bytes ++ if (n <= 0) ++ break; // need more bytes + + offs += n; + } @@ -6533,11 +6492,10 @@ index 000000000000..34905cf29a51 +} __packed; + +static ssize_t rqst_read(struct file *f, struct kobject *kobj, struct bin_attribute *attr, -+ char *buf, loff_t offs, size_t count) ++ char *buf, loff_t offs, size_t count) +{ -+ if (offs < 0 || count + offs > SURFACE_SAM_SSH_MAX_RQST_RESPONSE) { ++ if (offs < 0 || count + offs > SURFACE_SAM_SSH_MAX_RQST_RESPONSE) + return -EINVAL; -+ } + + memcpy(buf, sam_ssh_debug_rqst_buf_sysfs + offs, count); + return count; @@ -6552,20 +6510,17 @@ index 000000000000..34905cf29a51 + int status; + + // check basic write constriants -+ if (offs != 0 || count > SURFACE_SAM_SSH_MAX_RQST_PAYLOAD + sizeof(struct sysfs_rqst)) { ++ if (offs != 0 || count > SURFACE_SAM_SSH_MAX_RQST_PAYLOAD + sizeof(struct sysfs_rqst)) + return -EINVAL; -+ } + -+ if (count < sizeof(struct sysfs_rqst)) { ++ if (count < sizeof(struct sysfs_rqst)) + return -EINVAL; -+ } + + input = (struct sysfs_rqst *)buf; + + // payload length should be consistent with data provided -+ if (input->cdl + sizeof(struct sysfs_rqst) != count) { ++ if (input->cdl + sizeof(struct sysfs_rqst) != count) + return -EINVAL; -+ } + + rqst.tc = input->tc; + rqst.cid = input->cid; @@ -6581,9 +6536,8 @@ index 000000000000..34905cf29a51 + result.data = sam_ssh_debug_rqst_buf_res; + + status = surface_sam_ssh_rqst(&rqst, &result); -+ if (status) { ++ if (status) + return status; -+ } + + sam_ssh_debug_rqst_buf_sysfs[0] = result.len; + memcpy(sam_ssh_debug_rqst_buf_sysfs + 1, result.data, result.len); @@ -6596,24 +6550,24 @@ index 000000000000..34905cf29a51 +static const BIN_ATTR_RW(rqst, SURFACE_SAM_SSH_MAX_RQST_RESPONSE + 1); + + -+int surface_sam_ssh_sysfs_register(struct device *dev) ++static int surface_sam_ssh_sysfs_register(struct device *dev) +{ + return sysfs_create_bin_file(&dev->kobj, &bin_attr_rqst); +} + -+void surface_sam_ssh_sysfs_unregister(struct device *dev) ++static void surface_sam_ssh_sysfs_unregister(struct device *dev) +{ + sysfs_remove_bin_file(&dev->kobj, &bin_attr_rqst); +} + +#else /* CONFIG_SURFACE_ACPI_SSH_DEBUG_DEVICE */ + -+int surface_sam_ssh_sysfs_register(struct device *dev) ++static int surface_sam_ssh_sysfs_register(struct device *dev) +{ + return 0; +} + -+void surface_sam_ssh_sysfs_unregister(struct device *dev) ++static void surface_sam_ssh_sysfs_unregister(struct device *dev) +{ +} + @@ -6671,14 +6625,12 @@ index 000000000000..34905cf29a51 + struct acpi_resource_uart_serialbus *uart; + int status = 0; + -+ if (resource->type != ACPI_RESOURCE_TYPE_SERIAL_BUS) { ++ if (resource->type != ACPI_RESOURCE_TYPE_SERIAL_BUS) + return AE_OK; -+ } + + serial = &resource->data.common_serial_bus; -+ if (serial->type != ACPI_RESOURCE_SERIAL_TYPE_UART) { ++ if (serial->type != ACPI_RESOURCE_SERIAL_TYPE_UART) + return AE_OK; -+ } + + uart = &resource->data.uart_serial_bus; + @@ -6686,9 +6638,8 @@ index 000000000000..34905cf29a51 + serdev_device_set_baudrate(serdev, uart->default_baud_rate); + + // serdev currently only supports RTSCTS flow control -+ if (uart->flow_control & SSH_SUPPORTED_FLOW_CONTROL_MASK) { ++ if (uart->flow_control & SSH_SUPPORTED_FLOW_CONTROL_MASK) + dev_warn(&serdev->dev, "unsupported flow control (value: 0x%02x)\n", uart->flow_control); -+ } + + // set RTSCTS flow control + serdev_device_set_flow_control(serdev, uart->flow_control & ACPI_UART_FLOW_CONTROL_HW); @@ -6794,8 +6745,8 @@ index 000000000000..34905cf29a51 +}; + + -+int surface_sam_ssh_sysfs_register(struct device *dev); -+void surface_sam_ssh_sysfs_unregister(struct device *dev); ++static int surface_sam_ssh_sysfs_register(struct device *dev); ++static void surface_sam_ssh_sysfs_unregister(struct device *dev); + +static int surface_sam_ssh_probe(struct serdev_device *serdev) +{ @@ -6885,30 +6836,26 @@ index 000000000000..34905cf29a51 + + serdev_device_set_drvdata(serdev, ec); + -+ // ensure everything is properly set-up before we open the device ++ /* ensure everything is properly set-up before we open the device */ + smp_mb(); + + serdev_device_set_client_ops(serdev, &ssh_device_ops); + status = serdev_device_open(serdev); -+ if (status) { ++ if (status) + goto err_open; -+ } + + status = acpi_walk_resources(ssh, METHOD_NAME__CRS, -+ ssh_setup_from_resource, serdev); -+ if (ACPI_FAILURE(status)) { ++ ssh_setup_from_resource, serdev); ++ if (ACPI_FAILURE(status)) + goto err_devinit; -+ } + + status = surface_sam_ssh_ec_resume(ec); -+ if (status) { ++ if (status) + goto err_devinit; -+ } + + status = surface_sam_ssh_sysfs_register(&serdev->dev); -+ if (status) { ++ if (status) + goto err_devinit; -+ } + + surface_sam_ssh_release(ec); + @@ -6954,18 +6901,16 @@ index 000000000000..34905cf29a51 + int status; + + ec = surface_sam_ssh_acquire_init(); -+ if (!ec) { ++ if (!ec) + return; -+ } + + free_irq(ec->irq, serdev); + surface_sam_ssh_sysfs_unregister(&serdev->dev); + + // suspend EC and disable events + status = surface_sam_ssh_ec_suspend(ec); -+ if (status) { ++ if (status) + dev_err(&serdev->dev, "failed to suspend EC: %d\n", status); -+ } + + // make sure all events (received up to now) have been properly handled + flush_workqueue(ec->events.queue_ack); @@ -6975,14 +6920,14 @@ index 000000000000..34905cf29a51 + spin_lock_irqsave(&ec->events.lock, flags); + memset(ec->events.handler, 0, + sizeof(struct ssh_event_handler) -+ * SAM_NUM_EVENT_TYPES); ++ * SAM_NUM_EVENT_TYPES); + spin_unlock_irqrestore(&ec->events.lock, flags); + + // set device to deinitialized state + ec->state = SSH_EC_UNINITIALIZED; + ec->serdev = NULL; + -+ // ensure state and serdev get set before continuing ++ /* ensure state and serdev get set before continuing */ + smp_mb(); + + /* @@ -6995,9 +6940,9 @@ index 000000000000..34905cf29a51 + serdev_device_close(serdev); + + /* -+ * Only at this point, no new events can be received. Destroying the -+ * workqueue here flushes all remaining events. Those events will be -+ * silently ignored and neither ACKed nor any handler gets called. ++ * Only at this point, no new events can be received. Destroying the ++ * workqueue here flushes all remaining events. Those events will be ++ * silently ignored and neither ACKed nor any handler gets called. + */ + destroy_workqueue(ec->events.queue_ack); + destroy_workqueue(ec->events.queue_evt); @@ -7070,10 +7015,11 @@ index 000000000000..34905cf29a51 +MODULE_LICENSE("GPL v2"); diff --git a/drivers/platform/x86/surface_sam/surface_sam_ssh.h b/drivers/platform/x86/surface_sam/surface_sam_ssh.h new file mode 100644 -index 000000000000..714bba6a9457 +index 000000000000..435b5c7bac9a --- /dev/null +++ b/drivers/platform/x86/surface_sam/surface_sam_ssh.h -@@ -0,0 +1,97 @@ +@@ -0,0 +1,98 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Interface for Surface Serial Hub (SSH). + * @@ -7133,7 +7079,7 @@ index 000000000000..714bba6a9457 + u8 iid; // instance ID + u8 pri; // priority + u8 snc; // expect response flag -+ u8 cdl; // command data length (lenght of payload) ++ u8 cdl; // command data length (length of payload) + u8 *pld; // pointer to payload of length cdl +}; + @@ -7173,12 +7119,13 @@ index 000000000000..714bba6a9457 +#endif /* _SURFACE_SAM_SSH_H */ diff --git a/drivers/platform/x86/surface_sam/surface_sam_vhf.c b/drivers/platform/x86/surface_sam/surface_sam_vhf.c new file mode 100644 -index 000000000000..0ed0ebbdb3cb +index 000000000000..a00763805eca --- /dev/null +++ b/drivers/platform/x86/surface_sam/surface_sam_vhf.c -@@ -0,0 +1,276 @@ +@@ -0,0 +1,270 @@ ++// SPDX-License-Identifier: GPL-2.0 +/* -+ * Virtual HID Framwork (VHF) driver for input events via SAM. ++ * Virtual HID Framework (VHF) driver for input events via SAM. + * Used for keyboard input events on the Surface Laptops. + */ + @@ -7331,9 +7278,8 @@ index 000000000000..0ed0ebbdb3cb + struct hid_device *hid; + + hid = hid_allocate_device(); -+ if (IS_ERR(hid)) { ++ if (IS_ERR(hid)) + return hid; -+ } + + hid->dev.parent = &pdev->dev; + @@ -7352,9 +7298,8 @@ index 000000000000..0ed0ebbdb3cb +{ + struct vhf_evtctx *ctx = (struct vhf_evtctx *)data; + -+ if (event->tc == 0x08 && (event->cid == 0x03 || event->cid == 0x04)) { ++ if (event->tc == 0x08 && (event->cid == 0x03 || event->cid == 0x04)) + return hid_input_report(ctx->hid, HID_INPUT_REPORT, event->pld, event->len, 1); -+ } + + dev_warn(ctx->dev, "unsupported event (tc = %d, cid = %d)\n", event->tc, event->cid); + return 0; @@ -7368,14 +7313,12 @@ index 000000000000..0ed0ebbdb3cb + + // add device link to EC + status = surface_sam_ssh_consumer_register(&pdev->dev); -+ if (status) { ++ if (status) + return status == -ENXIO ? -EPROBE_DEFER : status; -+ } + + drvdata = kzalloc(sizeof(struct vhf_drvdata), GFP_KERNEL); -+ if (!drvdata) { ++ if (!drvdata) + return -ENOMEM; -+ } + + hid = vhf_create_hid_device(pdev); + if (IS_ERR(hid)) { @@ -7384,9 +7327,8 @@ index 000000000000..0ed0ebbdb3cb + } + + status = hid_add_device(hid); -+ if (status) { ++ if (status) + goto err_add_hid; -+ } + + drvdata->event_ctx.dev = &pdev->dev; + drvdata->event_ctx.hid = hid; @@ -7395,16 +7337,14 @@ index 000000000000..0ed0ebbdb3cb + + status = surface_sam_ssh_set_event_handler( + SAM_EVENT_VHF_RQID, -+ vhf_event_handler, ++ vhf_event_handler, + &drvdata->event_ctx); -+ if (status) { ++ if (status) + goto err_add_hid; -+ } + + status = surface_sam_ssh_enable_event_source(SAM_EVENT_VHF_TC, 0x01, SAM_EVENT_VHF_RQID); -+ if (status) { ++ if (status) + goto err_event_source; -+ } + + return 0; + @@ -7454,7 +7394,7 @@ index 000000000000..0ed0ebbdb3cb +MODULE_DESCRIPTION("Virtual HID Framework Driver for 5th Generation Surface Devices"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/tty/serdev/core.c b/drivers/tty/serdev/core.c -index c66a04d24f1d..1b18d12d217f 100644 +index c66a04d24f1d..6b48fdfb2005 100644 --- a/drivers/tty/serdev/core.c +++ b/drivers/tty/serdev/core.c @@ -496,16 +496,97 @@ static int of_serdev_register_devices(struct serdev_controller *ctrl) @@ -7503,7 +7443,7 @@ index c66a04d24f1d..1b18d12d217f 100644 +} + +static int acpi_serdev_do_lookup(struct acpi_device *adev, -+ struct acpi_serdev_lookup *lookup) ++ struct acpi_serdev_lookup *lookup) +{ + struct list_head resource_list; + int ret; @@ -7570,7 +7510,7 @@ index c66a04d24f1d..1b18d12d217f 100644 { struct serdev_controller *ctrl = data; struct acpi_device *adev; -@@ -541,26 +622,32 @@ static acpi_status acpi_serdev_add_device(acpi_handle handle, u32 level, +@@ -541,26 +622,31 @@ static acpi_status acpi_serdev_add_device(acpi_handle handle, u32 level, if (acpi_bus_get_device(handle, &adev)) return AE_OK; @@ -7587,7 +7527,6 @@ index c66a04d24f1d..1b18d12d217f 100644 return acpi_serdev_register_device(ctrl, adev); } -+ static int acpi_serdev_register_devices(struct serdev_controller *ctrl) { acpi_status status; @@ -7609,5 +7548,5 @@ index c66a04d24f1d..1b18d12d217f 100644 if (!ctrl->serdev) return -ENODEV; -- -2.25.0 +2.25.1 diff --git a/patches/4.19/0006-suspend.patch b/patches/4.19/0006-suspend.patch index 8695c3801..05443d0dc 100644 --- a/patches/4.19/0006-suspend.patch +++ b/patches/4.19/0006-suspend.patch @@ -1,4 +1,4 @@ -From 56465e5f753dd383417dc9d22532d4b4c7d70e14 Mon Sep 17 00:00:00 2001 +From a770b09614e53afd014b85a7bd79d6c10c90d2f6 Mon Sep 17 00:00:00 2001 From: kitakar5525 <34676735+kitakar5525@users.noreply.github.com> Date: Sat, 28 Sep 2019 17:48:21 +0200 Subject: [PATCH 06/10] suspend @@ -12,7 +12,7 @@ Subject: [PATCH 06/10] suspend 5 files changed, 162 insertions(+), 6 deletions(-) diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c -index b7bd89b3b2f9..a9c689c10d3d 100644 +index a8132e8d72bb..acb0d5bb3a8d 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -1055,15 +1055,15 @@ static struct nvme_id_ns *nvme_identify_ns(struct nvme_ctrl *ctrl, @@ -24,8 +24,8 @@ index b7bd89b3b2f9..a9c689c10d3d 100644 +static int nvme_features(struct nvme_ctrl *dev, u8 op, unsigned int fid, + unsigned int dword11, void *buffer, size_t buflen, u32 *result) { + union nvme_result res = { 0 }; struct nvme_command c; - union nvme_result res; int ret; memset(&c, 0, sizeof(c)); @@ -312,5 +312,5 @@ index b1f297f4b7b0..94ab2fc800d3 100644 #ifdef CONFIG_PCIEAER -- -2.25.0 +2.25.1 diff --git a/patches/4.19/0007-ipts.patch b/patches/4.19/0007-ipts.patch index 0e488889c..4e8bb3a1e 100644 --- a/patches/4.19/0007-ipts.patch +++ b/patches/4.19/0007-ipts.patch @@ -1,4 +1,4 @@ -From 3aa4577c1327da13ed2cece7174da5ee7153d570 Mon Sep 17 00:00:00 2001 +From 9c8623f624d31b18be85f69684c7e5d07102fbb1 Mon Sep 17 00:00:00 2001 From: Maximilian Luz Date: Sat, 28 Sep 2019 17:58:17 +0200 Subject: [PATCH 07/10] ipts @@ -20,7 +20,6 @@ Subject: [PATCH 07/10] ipts drivers/gpu/drm/i915/intel_lrc.c | 12 +- drivers/gpu/drm/i915/intel_lrc.h | 8 + drivers/gpu/drm/i915/intel_panel.c | 7 + - drivers/hid/hid-core.c | 5 +- drivers/misc/Kconfig | 1 + drivers/misc/Makefile | 1 + drivers/misc/ipts/Kconfig | 12 + @@ -33,7 +32,7 @@ Subject: [PATCH 07/10] ipts drivers/misc/ipts/dbgfs.c | 277 +++++ drivers/misc/ipts/gfx.c | 180 ++++ drivers/misc/ipts/gfx.h | 25 + - drivers/misc/ipts/hid.c | 499 +++++++++ + drivers/misc/ipts/hid.c | 502 +++++++++ drivers/misc/ipts/hid.h | 21 + drivers/misc/ipts/ipts.c | 62 ++ drivers/misc/ipts/ipts.h | 172 +++ @@ -55,7 +54,7 @@ Subject: [PATCH 07/10] ipts include/linux/ipts-companion.h | 30 + include/linux/ipts-gfx.h | 86 ++ include/linux/ipts.h | 20 + - 51 files changed, 6802 insertions(+), 24 deletions(-) + 50 files changed, 6802 insertions(+), 22 deletions(-) create mode 100644 drivers/gpu/drm/i915/intel_ipts.c create mode 100644 drivers/gpu/drm/i915/intel_ipts.h create mode 100644 drivers/misc/ipts/Kconfig @@ -1291,22 +1290,6 @@ index 4a9f139e7b73..c137a57f6702 100644 } static void pch_enable_backlight(const struct intel_crtc_state *crtc_state, -diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c -index e723156057a6..11795c7a1662 100644 ---- a/drivers/hid/hid-core.c -+++ b/drivers/hid/hid-core.c -@@ -290,8 +290,9 @@ static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsign - - /* Total size check: Allow for possible report index byte */ - if (report->size > (HID_MAX_BUFFER_SIZE - 1) << 3) { -- hid_err(parser->device, "report is too long\n"); -- return -1; -+ hid_warn(parser->device, "report is too long (%u), skipping\n", -+ report->size); -+ return 0; - } - - if (!parser->local.usage_index) /* Ignore padding fields */ diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 3726eacdf65d..77263b5f5915 100644 --- a/drivers/misc/Kconfig @@ -2396,10 +2379,10 @@ index 000000000000..2880e122e9f9 +#endif // _IPTS_GFX_H_ diff --git a/drivers/misc/ipts/hid.c b/drivers/misc/ipts/hid.c new file mode 100644 -index 000000000000..3652803b5376 +index 000000000000..1a487b633fdd --- /dev/null +++ b/drivers/misc/ipts/hid.c -@@ -0,0 +1,499 @@ +@@ -0,0 +1,502 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * @@ -2705,8 +2688,11 @@ index 000000000000..3652803b5376 + + switch (raw_header->data_type) { + case TOUCH_RAW_DATA_TYPE_HID_REPORT: { -+ if (raw_header->raw_data_size_bytes > HID_MAX_BUFFER_SIZE) -+ raw_header->raw_data_size_bytes = HID_MAX_BUFFER_SIZE; ++ if (raw_header->raw_data_size_bytes > HID_MAX_BUFFER_SIZE) { ++ ipts_err(ipts, "input report too large (%u bytes), skipping", ++ raw_header->raw_data_size_bytes); ++ break; ++ } + + memcpy(ipts->hid_input_report, raw_data, + raw_header->raw_data_size_bytes); @@ -7441,5 +7427,5 @@ index 000000000000..bfa8e1375926 + +#endif // IPTS_H -- -2.25.0 +2.25.1 diff --git a/patches/4.19/0008-surface-lte.patch b/patches/4.19/0008-surface-lte.patch index abacee25b..a6d7ac0b7 100644 --- a/patches/4.19/0008-surface-lte.patch +++ b/patches/4.19/0008-surface-lte.patch @@ -1,4 +1,4 @@ -From 4b4d681cceaa20cf93fd2e6afa93a8fb93f528ad Mon Sep 17 00:00:00 2001 +From 3fdfb22a2d964dc0f89db2ab444b7aaf855b35eb Mon Sep 17 00:00:00 2001 From: Maximilian Luz Date: Sat, 28 Sep 2019 18:02:03 +0200 Subject: [PATCH 08/10] surface-lte @@ -20,5 +20,5 @@ index 613f91add03d..e1428222dd73 100644 /* Huawei devices */ {DEVICE_HWI(0x03f0, 0x581d)}, /* HP lt4112 LTE/HSPA+ Gobi 4G Modem (Huawei me906e) */ -- -2.25.0 +2.25.1 diff --git a/patches/4.19/0009-ioremap_uc.patch b/patches/4.19/0009-ioremap_uc.patch index 6840b141d..29296fc54 100644 --- a/patches/4.19/0009-ioremap_uc.patch +++ b/patches/4.19/0009-ioremap_uc.patch @@ -1,4 +1,4 @@ -From 6405ace9361dabd32a7c47e989de5aa8f005be0d Mon Sep 17 00:00:00 2001 +From dd5b315097f1f0eb3bf3e81f355cd7d7afc4bef5 Mon Sep 17 00:00:00 2001 From: Tuowen Zhao Date: Wed, 16 Oct 2019 15:06:28 -0600 Subject: [PATCH 09/10] ioremap_uc @@ -93,5 +93,5 @@ index aa0f5308ac6b..75ea32d9b661 100644 * devm_ioremap_nocache - Managed ioremap_nocache() * @dev: Generic device to remap IO address for -- -2.25.0 +2.25.1 diff --git a/patches/4.19/0010-wifi.patch b/patches/4.19/0010-wifi.patch index f1d589eab..c1a9ce1f1 100644 --- a/patches/4.19/0010-wifi.patch +++ b/patches/4.19/0010-wifi.patch @@ -1,13 +1,58 @@ -From 0ddca72e89d8d512ec8ba779be709c7be185aca2 Mon Sep 17 00:00:00 2001 +From 2b22581e4dd5184f87f264af7499cc034b543cb6 Mon Sep 17 00:00:00 2001 From: sebanc <22224731+sebanc@users.noreply.github.com> Date: Mon, 4 Nov 2019 09:30:57 +0100 Subject: [PATCH 10/10] wifi --- + .../net/wireless/marvell/mwifiex/cfg80211.c | 26 +++++++ drivers/net/wireless/marvell/mwifiex/pcie.c | 75 ++++++++++--------- - .../net/wireless/marvell/mwifiex/sta_cmd.c | 15 +--- - 2 files changed, 40 insertions(+), 50 deletions(-) + .../net/wireless/marvell/mwifiex/sta_cmd.c | 26 +------ + 3 files changed, 66 insertions(+), 61 deletions(-) +diff --git a/drivers/net/wireless/marvell/mwifiex/cfg80211.c b/drivers/net/wireless/marvell/mwifiex/cfg80211.c +index 7b74ef71bef1..d8e65b733cb3 100644 +--- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c ++++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c +@@ -25,6 +25,11 @@ + static char *reg_alpha2; + module_param(reg_alpha2, charp, 0); + ++static bool allow_ps_mode; ++module_param(allow_ps_mode, bool, 0444); ++MODULE_PARM_DESC(allow_ps_mode, ++ "allow WiFi power management to be enabled. (default: disallowed)"); ++ + static const struct ieee80211_iface_limit mwifiex_ap_sta_limits[] = { + { + .max = 3, .types = BIT(NL80211_IFTYPE_STATION) | +@@ -439,6 +444,27 @@ mwifiex_cfg80211_set_power_mgmt(struct wiphy *wiphy, + + ps_mode = enabled; + ++ /* Allow ps_mode to be enabled only when allow_ps_mode is set ++ * (but always allow ps_mode to be disabled in case it gets enabled ++ * for unknown reason and you want to disable it) */ ++ if (ps_mode && !allow_ps_mode) { ++ dev_info(priv->adapter->dev, ++ "Request to enable ps_mode received but it's disallowed " ++ "by module parameter. Rejecting the request.\n"); ++ ++ /* Return negative value to inform userspace tools that setting ++ * power_save to be enabled is not permitted. */ ++ return -1; ++ } ++ ++ if (ps_mode) ++ dev_warn(priv->adapter->dev, ++ "WARN: Request to enable ps_mode received. Enabling it. " ++ "Disable it if you encounter connection instability.\n"); ++ else ++ dev_info(priv->adapter->dev, ++ "Request to disable ps_mode received. Disabling it.\n"); ++ + return mwifiex_drv_set_power(priv, &ps_mode); + } + diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c index 991b9cc18000..4549359ee19b 100644 --- a/drivers/net/wireless/marvell/mwifiex/pcie.c @@ -128,7 +173,7 @@ index 991b9cc18000..4549359ee19b 100644 } diff --git a/drivers/net/wireless/marvell/mwifiex/sta_cmd.c b/drivers/net/wireless/marvell/mwifiex/sta_cmd.c -index 4ed10cf82f9a..013db4386c39 100644 +index 4ed10cf82f9a..977b57c0908f 100644 --- a/drivers/net/wireless/marvell/mwifiex/sta_cmd.c +++ b/drivers/net/wireless/marvell/mwifiex/sta_cmd.c @@ -2265,14 +2265,13 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no, @@ -147,7 +192,25 @@ index 4ed10cf82f9a..013db4386c39 100644 if (first_sta) { if (priv->adapter->iface_type == MWIFIEX_PCIE) { -@@ -2395,18 +2394,6 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta, bool init) +@@ -2339,17 +2338,6 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta, bool init) + if (ret) + return -1; + +- if (priv->bss_type != MWIFIEX_BSS_TYPE_UAP) { +- /* Enable IEEE PS by default */ +- priv->adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_PSP; +- ret = mwifiex_send_cmd(priv, +- HostCmd_CMD_802_11_PS_MODE_ENH, +- EN_AUTO_PS, BITMAP_STA_PS, NULL, +- true); +- if (ret) +- return -1; +- } +- + if (drcs) { + adapter->drcs_enabled = true; + if (ISSUPP_DRCS_ENABLED(adapter->fw_cap_info)) +@@ -2395,18 +2383,6 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta, bool init) if (ret) return -1; @@ -167,5 +230,5 @@ index 4ed10cf82f9a..013db4386c39 100644 /* Send cmd to FW to enable/disable 11D function */ state_11d = ENABLE_11D; -- -2.25.0 +2.25.1 diff --git a/patches/5.5/0001-surface3-power.patch b/patches/5.5/0001-surface3-power.patch index b56720378..75b6b1fba 100644 --- a/patches/5.5/0001-surface3-power.patch +++ b/patches/5.5/0001-surface3-power.patch @@ -1,4 +1,4 @@ -From 5837cdffdde0776ea3c77378ab2bd8b81d4c6b41 Mon Sep 17 00:00:00 2001 +From fffa55005ebcb790bb06de17dd629fe921849d73 Mon Sep 17 00:00:00 2001 From: qzed Date: Tue, 17 Sep 2019 17:17:56 +0200 Subject: [PATCH 1/7] surface3-power @@ -651,5 +651,5 @@ index 000000000000..e0af01a60302 +MODULE_DESCRIPTION("mshw0011 driver"); +MODULE_LICENSE("GPL v2"); -- -2.25.0 +2.25.1 diff --git a/patches/5.5/0002-surface3-spi.patch b/patches/5.5/0002-surface3-spi.patch index 71ed876d7..8466cefac 100644 --- a/patches/5.5/0002-surface3-spi.patch +++ b/patches/5.5/0002-surface3-spi.patch @@ -1,4 +1,4 @@ -From c36ef21bb796176659ca9edeed13eac751c1f7b4 Mon Sep 17 00:00:00 2001 +From 0196c30f6df1a30ce6edd99c47f44435b0ee2c18 Mon Sep 17 00:00:00 2001 From: kitakar5525 <34676735+kitakar5525@users.noreply.github.com> Date: Fri, 6 Dec 2019 23:10:30 +0900 Subject: [PATCH 2/7] surface3-spi @@ -59,5 +59,5 @@ index ce4828b1415a..63b0b8ddf090 100644 } -- -2.25.0 +2.25.1 diff --git a/patches/5.5/0003-surface3-oemb.patch b/patches/5.5/0003-surface3-oemb.patch index e6723707b..70db36704 100644 --- a/patches/5.5/0003-surface3-oemb.patch +++ b/patches/5.5/0003-surface3-oemb.patch @@ -1,4 +1,4 @@ -From 9807d209ae39183dc4ed805f30f171e96321515f Mon Sep 17 00:00:00 2001 +From 32cf290466d335c1d0f4cd70081900a6bd0e89ab Mon Sep 17 00:00:00 2001 From: Chih-Wei Huang Date: Tue, 18 Sep 2018 11:01:37 +0800 Subject: [PATCH 3/7] surface3-oemb @@ -65,5 +65,5 @@ index d0fb43c2b9f6..de2583918afd 100644 { } }; -- -2.25.0 +2.25.1 diff --git a/patches/5.5/0004-surface-sam.patch b/patches/5.5/0004-surface-sam.patch index c133c15e2..8bbe25a3b 100644 --- a/patches/5.5/0004-surface-sam.patch +++ b/patches/5.5/0004-surface-sam.patch @@ -1,4 +1,4 @@ -From 29136c06b4dfe419a4356c24130075dd21a3dc63 Mon Sep 17 00:00:00 2001 +From d0ed27ff92f5bf9cd70cafc30de03f7051cdaa23 Mon Sep 17 00:00:00 2001 From: qzed Date: Mon, 26 Aug 2019 01:11:08 +0200 Subject: [PATCH 4/7] surface-sam @@ -8,21 +8,21 @@ Subject: [PATCH 4/7] surface-sam drivers/acpi/acpica/exfield.c | 12 +- drivers/platform/x86/Kconfig | 1 + drivers/platform/x86/Makefile | 1 + - drivers/platform/x86/surface_sam/Kconfig | 163 ++ + drivers/platform/x86/surface_sam/Kconfig | 164 ++ drivers/platform/x86/surface_sam/Makefile | 10 + - .../x86/surface_sam/surface_sam_dtx.c | 623 ++++++ + .../x86/surface_sam/surface_sam_dtx.c | 604 ++++++ .../x86/surface_sam/surface_sam_hps.c | 1110 +++++++++++ - .../x86/surface_sam/surface_sam_san.c | 901 +++++++++ - .../x86/surface_sam/surface_sam_san.h | 29 + - .../x86/surface_sam/surface_sam_sid.c | 117 ++ - .../x86/surface_sam/surface_sam_sid_gpelid.c | 219 ++ - .../surface_sam/surface_sam_sid_perfmode.c | 225 +++ - .../x86/surface_sam/surface_sam_sid_power.c | 1259 ++++++++++++ - .../x86/surface_sam/surface_sam_sid_vhf.c | 440 ++++ - .../x86/surface_sam/surface_sam_ssh.c | 1773 +++++++++++++++++ - .../x86/surface_sam/surface_sam_ssh.h | 97 + - .../x86/surface_sam/surface_sam_vhf.c | 276 +++ - 18 files changed, 7254 insertions(+), 4 deletions(-) + .../x86/surface_sam/surface_sam_san.c | 883 +++++++++ + .../x86/surface_sam/surface_sam_san.h | 30 + + .../x86/surface_sam/surface_sam_sid.c | 137 ++ + .../x86/surface_sam/surface_sam_sid_gpelid.c | 224 +++ + .../surface_sam/surface_sam_sid_perfmode.c | 216 ++ + .../x86/surface_sam/surface_sam_sid_power.c | 1264 ++++++++++++ + .../x86/surface_sam/surface_sam_sid_vhf.c | 428 ++++ + .../x86/surface_sam/surface_sam_ssh.c | 1744 +++++++++++++++++ + .../x86/surface_sam/surface_sam_ssh.h | 98 + + .../x86/surface_sam/surface_sam_vhf.c | 270 +++ + 18 files changed, 7194 insertions(+), 4 deletions(-) create mode 100644 drivers/platform/x86/surface_sam/Kconfig create mode 100644 drivers/platform/x86/surface_sam/Makefile create mode 100644 drivers/platform/x86/surface_sam/surface_sam_dtx.c @@ -106,23 +106,23 @@ index d707a8edd738..56ebd493b38f 100644 +obj-$(CONFIG_SURFACE_SAM) += surface_sam/ diff --git a/drivers/platform/x86/surface_sam/Kconfig b/drivers/platform/x86/surface_sam/Kconfig new file mode 100644 -index 000000000000..b4513c234c4d +index 000000000000..c4556e58b9a5 --- /dev/null +++ b/drivers/platform/x86/surface_sam/Kconfig -@@ -0,0 +1,163 @@ +@@ -0,0 +1,164 @@ +menuconfig SURFACE_SAM -+ depends on ACPI -+ tristate "Microsoft Surface/System Aggregator Module and Platform Drivers" -+ ---help--- -+ Drivers for the Surface/System Aggregator Module (SAM) of Microsoft -+ Surface devices. ++ depends on ACPI ++ tristate "Microsoft Surface/System Aggregator Module and Platform Drivers" ++ help ++ Drivers for the Surface/System Aggregator Module (SAM) of Microsoft ++ Surface devices. + -+ SAM is an embedded controller that provides access to various -+ functionalities on these devices, including battery status, keyboard -+ events (on the Laptops) and many more. ++ SAM is an embedded controller that provides access to various ++ functionalities on these devices, including battery status, keyboard ++ events (on the Laptops) and many more. + -+ Say M/Y here if you have a Microsoft Surface device with a SAM device -+ (i.e. 5th generation or later). ++ Say M/Y here if you have a Microsoft Surface device with a SAM device ++ (i.e. 5th generation or later). + +config SURFACE_SAM_SSH + tristate "Surface Serial Hub Driver" @@ -130,7 +130,7 @@ index 000000000000..b4513c234c4d + depends on SERIAL_DEV_CTRL_TTYPORT + select CRC_CCITT + default m -+ ---help--- ++ help + Surface Serial Hub driver for 5th generation (or later) Microsoft + Surface devices. + @@ -148,7 +148,7 @@ index 000000000000..b4513c234c4d + depends on SURFACE_SAM_SSH + depends on SYSFS + default n -+ ---help--- ++ help + Debug device for direct communication with the embedded controller + found on 5th generation (and later) Microsoft Surface devices (e.g. + Book 2, Laptop, Laptop 2, Pro 2017, Pro 6, ...) via sysfs. @@ -159,7 +159,7 @@ index 000000000000..b4513c234c4d + tristate "Surface ACPI Notify Driver" + depends on SURFACE_SAM_SSH + default m -+ ---help--- ++ help + Surface ACPI Notify driver for 5th generation (or later) Microsoft + Surface devices. + @@ -174,7 +174,7 @@ index 000000000000..b4513c234c4d + depends on SURFACE_SAM_SSH + depends on HID + default m -+ ---help--- ++ help + Surface Virtual HID Framework driver for 5th generation (or later) + Microsoft Surface devices. + @@ -188,7 +188,7 @@ index 000000000000..b4513c234c4d + depends on SURFACE_SAM_SSH + depends on INPUT + default m -+ ---help--- ++ help + Surface Detachment System (DTX) driver for the Microsoft Surface Book + 2. This driver provides support for proper detachment handling in + user-space, status-events relating to the base and support for @@ -204,8 +204,9 @@ index 000000000000..b4513c234c4d + tristate "Surface dGPU Hot-Plug System (dGPU-HPS) Driver" + depends on SURFACE_SAM_SSH + depends on SURFACE_SAM_SAN ++ depends on GPIO_SYSFS + default m -+ ---help--- ++ help + Driver to properly handle hot-plugging and explicit power-on/power-off + of the discrete GPU (dGPU) on the Surface Book 2. + @@ -215,7 +216,7 @@ index 000000000000..b4513c234c4d + tristate "Surface Platform Integration Driver" + depends on SURFACE_SAM_SSH + default m -+ ---help--- ++ help + Surface Platform Integration Driver for the Microsoft Surface Devices. + This driver loads various model-specific sub-drivers, including + battery and keyboard support on 7th generation Surface devices, proper @@ -229,7 +230,7 @@ index 000000000000..b4513c234c4d + tristate "Surface Lid Wakeup Driver" + depends on SURFACE_SAM_SID + default m -+ ---help--- ++ help + Driver to set up device wake-up via lid on Intel-based Microsoft + Surface devices. These devices do not wake up from sleep as their GPE + interrupt is not configured automatically. This driver solves that @@ -242,8 +243,8 @@ index 000000000000..b4513c234c4d + depends on SURFACE_SAM_SID + depends on SYSFS + default m -+ ---help--- -+ This driver provides suport for setting performance-modes on Surface ++ help ++ This driver provides support for setting performance-modes on Surface + devices via the perf_mode sysfs attribute. Currently only supports the + Surface Book 2. Performance-modes directly influence the fan-profile + of the device, allowing to choose between higher performance or @@ -256,7 +257,7 @@ index 000000000000..b4513c234c4d + depends on SURFACE_SAM_SID + depends on HID + default m -+ ---help--- ++ help + This driver provides support for HID devices connected via the Surface + SAM embedded controller. It provides support for keyboard and touchpad + on the Surface Laptop 3 models. @@ -268,7 +269,7 @@ index 000000000000..b4513c234c4d + depends on SURFACE_SAM_SID + select POWER_SUPPLY + default m -+ ---help--- ++ help + This driver provides support for the battery and AC on 7th generation + Surface devices. + @@ -291,10 +292,11 @@ index 000000000000..188975ccde5c +obj-$(CONFIG_SURFACE_SAM_SID_VHF) += surface_sam_sid_vhf.o diff --git a/drivers/platform/x86/surface_sam/surface_sam_dtx.c b/drivers/platform/x86/surface_sam/surface_sam_dtx.c new file mode 100644 -index 000000000000..4b924de6ab09 +index 000000000000..1e772fd5b0be --- /dev/null +++ b/drivers/platform/x86/surface_sam/surface_sam_dtx.c -@@ -0,0 +1,623 @@ +@@ -0,0 +1,604 @@ ++// SPDX-License-Identifier: GPL-2.0 +/* + * Detachment system (DTX) driver for Microsoft Surface Book 2. + */ @@ -414,13 +416,11 @@ index 000000000000..4b924de6ab09 + }; + + status = surface_sam_ssh_rqst(&rqst, &result); -+ if (status) { ++ if (status) + return status; -+ } + -+ if (result.len != 1) { ++ if (result.len != 1) + return -EFAULT; -+ } + + return result.data[0]; +} @@ -443,14 +443,14 @@ index 000000000000..4b924de6ab09 + +static int dtx_cmd_get_opmode(int __user *buf) +{ -+ int opmode = surface_sam_query_opmpde(); -+ if (opmode < 0) { -+ return opmode; -+ } ++ int opmode; + -+ if (put_user(opmode, buf)) { ++ opmode = surface_sam_query_opmpde(); ++ if (opmode < 0) ++ return opmode; ++ ++ if (put_user(opmode, buf)) + return -EACCES; -+ } + + return 0; +} @@ -463,9 +463,8 @@ index 000000000000..4b924de6ab09 + + // initialize client + client = kzalloc(sizeof(struct surface_dtx_client), GFP_KERNEL); -+ if (!client) { ++ if (!client) + return -ENOMEM; -+ } + + spin_lock_init(&client->buffer_lock); + client->buffer_head = 0; @@ -507,37 +506,32 @@ index 000000000000..4b924de6ab09 + size_t read = 0; + int status = 0; + -+ if (count != 0 && count < sizeof(struct surface_dtx_event)) { ++ if (count != 0 && count < sizeof(struct surface_dtx_event)) + return -EINVAL; -+ } + -+ if (!ddev->active) { ++ if (!ddev->active) + return -ENODEV; -+ } + + // check availability -+ if (client->buffer_head == client->buffer_tail){ -+ if (file->f_flags & O_NONBLOCK) { ++ if (client->buffer_head == client->buffer_tail) { ++ if (file->f_flags & O_NONBLOCK) + return -EAGAIN; -+ } + + status = wait_event_interruptible(ddev->waitq, + client->buffer_head != client->buffer_tail || + !ddev->active); -+ if (status) { ++ if (status) + return status; -+ } + -+ if (!ddev->active) { ++ if (!ddev->active) + return -ENODEV; -+ } + } + + // copy events one by one + while (read + sizeof(struct surface_dtx_event) <= count) { + spin_lock_irq(&client->buffer_lock); + -+ if(client->buffer_head == client->buffer_tail) { ++ if (client->buffer_head == client->buffer_tail) { + spin_unlock_irq(&client->buffer_lock); + break; + } @@ -548,9 +542,8 @@ index 000000000000..4b924de6ab09 + spin_unlock_irq(&client->buffer_lock); + + // copy to userspace -+ if(copy_to_user(buf, &event, sizeof(struct surface_dtx_event))) { ++ if (copy_to_user(buf, &event, sizeof(struct surface_dtx_event))) + return -EFAULT; -+ } + + read += sizeof(struct surface_dtx_event); + } @@ -565,15 +558,13 @@ index 000000000000..4b924de6ab09 + + poll_wait(file, &client->ddev->waitq, pt); + -+ if (client->ddev->active) { ++ if (client->ddev->active) + mask = EPOLLOUT | EPOLLWRNORM; -+ } else { ++ else + mask = EPOLLHUP | EPOLLERR; -+ } + -+ if (client->buffer_head != client->buffer_tail) { ++ if (client->buffer_head != client->buffer_tail) + mask |= EPOLLIN | EPOLLRDNORM; -+ } + + return mask; +} @@ -592,9 +583,8 @@ index 000000000000..4b924de6ab09 + int status; + + status = mutex_lock_interruptible(&ddev->mutex); -+ if (status) { ++ if (status) + return status; -+ } + + if (!ddev->active) { + mutex_unlock(&ddev->mutex); @@ -688,9 +678,8 @@ index 000000000000..4b924de6ab09 + + // get operation mode + opmode = surface_sam_query_opmpde(); -+ if (opmode < 0) { ++ if (opmode < 0) + printk(DTX_ERR "EC request failed with error %d\n", opmode); -+ } + + // send DTX event + event.type = 0x11; @@ -702,7 +691,7 @@ index 000000000000..4b924de6ab09 + + // send SW_TABLET_MODE event + spin_lock(&ddev->input_lock); -+ input_report_switch(ddev->input_dev, SW_TABLET_MODE, opmode == 0x00); ++ input_report_switch(ddev->input_dev, SW_TABLET_MODE, opmode != DTX_OPMODE_LAPTOP); + input_sync(ddev->input_dev); + spin_unlock(&ddev->input_lock); +} @@ -752,14 +741,12 @@ index 000000000000..4b924de6ab09 + int status; + + status = surface_sam_ssh_set_event_handler(SAM_EVENT_DTX_RQID, surface_dtx_evt_dtx, ddev); -+ if (status) { ++ if (status) + goto err_handler; -+ } + + status = surface_sam_ssh_enable_event_source(SAM_EVENT_DTX_TC, 0x01, SAM_EVENT_DTX_RQID); -+ if (status) { ++ if (status) + goto err_source; -+ } + + return 0; + @@ -782,9 +769,8 @@ index 000000000000..4b924de6ab09 + int status; + + input_dev = input_allocate_device(); -+ if (!input_dev) { ++ if (!input_dev) + return ERR_PTR(-ENOMEM); -+ } + + input_dev->name = DTX_INPUT_NAME; + input_dev->dev.parent = &pdev->dev; @@ -800,7 +786,7 @@ index 000000000000..4b924de6ab09 + return ERR_PTR(status); + } + -+ input_report_switch(input_dev, SW_TABLET_MODE, status == 0x00); ++ input_report_switch(input_dev, SW_TABLET_MODE, status != DTX_OPMODE_LAPTOP); + + status = input_register_device(input_dev); + if (status) { @@ -820,14 +806,12 @@ index 000000000000..4b924de6ab09 + + // link to ec + status = surface_sam_ssh_consumer_register(&pdev->dev); -+ if (status) { ++ if (status) + return status == -ENXIO ? -EPROBE_DEFER : status; -+ } + + input_dev = surface_dtx_register_inputdev(pdev); -+ if (IS_ERR(input_dev)) { ++ if (IS_ERR(input_dev)) + return PTR_ERR(input_dev); -+ } + + // initialize device + mutex_lock(&ddev->mutex); @@ -844,15 +828,13 @@ index 000000000000..4b924de6ab09 + mutex_unlock(&ddev->mutex); + + status = misc_register(&ddev->mdev); -+ if (status) { ++ if (status) + goto err_register; -+ } + + // enable events + status = surface_dtx_events_setup(ddev); -+ if (status) { ++ if (status) + goto err_events_setup; -+ } + + return 0; + @@ -920,10 +902,11 @@ index 000000000000..4b924de6ab09 +MODULE_LICENSE("GPL v2"); diff --git a/drivers/platform/x86/surface_sam/surface_sam_hps.c b/drivers/platform/x86/surface_sam/surface_sam_hps.c new file mode 100644 -index 000000000000..3b123bd3dcfe +index 000000000000..4fba5ee75a66 --- /dev/null +++ b/drivers/platform/x86/surface_sam/surface_sam_hps.c @@ -0,0 +1,1110 @@ ++// SPDX-License-Identifier: GPL-2.0 +/* + * Surface dGPU hot-plug system driver. + * Supports explicit setting of the dGPU power-state on the Surface Book 2 and @@ -993,7 +976,8 @@ index 000000000000..3b123bd3dcfe + SHPS_DGPU_POWER_UNKNOWN = 2, +}; + -+static const char* shps_dgpu_power_str(enum shps_dgpu_power power) { ++static const char *shps_dgpu_power_str(enum shps_dgpu_power power) ++{ + if (power == SHPS_DGPU_POWER_OFF) + return "off"; + else if (power == SHPS_DGPU_POWER_ON) @@ -1022,7 +1006,7 @@ index 000000000000..3b123bd3dcfe +#define SHPS_STATE_BIT_WAKE_ENABLED 2 /* wakeup via base-presence GPIO enabled */ + + -+#define SHPS_DGPU_PARAM_PERM (S_IRUGO | S_IWUSR) ++#define SHPS_DGPU_PARAM_PERM 0644 + +enum shps_dgpu_power_mp { + SHPS_DGPU_MP_POWER_OFF = SHPS_DGPU_POWER_OFF, @@ -1039,13 +1023,11 @@ index 000000000000..3b123bd3dcfe + int status; + + status = kstrtoint(val, 0, &power); -+ if (status) { ++ if (status) + return status; -+ } + -+ if (power < __SHPS_DGPU_MP_POWER_START || power > __SHPS_DGPU_MP_POWER_END) { ++ if (power < __SHPS_DGPU_MP_POWER_START || power > __SHPS_DGPU_MP_POWER_END) + return -EINVAL; -+ } + + return param_set_int(val, kp); +} @@ -1086,18 +1068,18 @@ index 000000000000..3b123bd3dcfe + return surface_sam_ssh_rqst(&rqst, NULL); +} + -+inline static int shps_dtx_latch_lock(void) ++static inline int shps_dtx_latch_lock(void) +{ + return dtx_cmd_simple(SAM_DTX_CID_LATCH_LOCK); +} + -+inline static int shps_dtx_latch_unlock(void) ++static inline int shps_dtx_latch_unlock(void) +{ + return dtx_cmd_simple(SAM_DTX_CID_LATCH_UNLOCK); +} + + -+static int shps_dgpu_dsm_get_pci_addr(struct platform_device *pdev, const char* entry) ++static int shps_dgpu_dsm_get_pci_addr(struct platform_device *pdev, const char *entry) +{ + acpi_handle handle = ACPI_HANDLE(&pdev->dev); + union acpi_object *result; @@ -1151,7 +1133,7 @@ index 000000000000..3b123bd3dcfe + return bus << 8 | PCI_DEVFN(dev, fun); +} + -+static struct pci_dev *shps_dgpu_dsm_get_pci_dev(struct platform_device *pdev, const char* entry) ++static struct pci_dev *shps_dgpu_dsm_get_pci_dev(struct platform_device *pdev, const char *entry) +{ + struct pci_dev *dev; + int addr; @@ -1202,7 +1184,7 @@ index 000000000000..3b123bd3dcfe + param.integer.value = power == SHPS_DGPU_POWER_ON; + + result = acpi_evaluate_dsm_typed(handle, &SHPS_DSM_UUID, SHPS_DSM_REVISION, -+ SHPS_DSM_GPU_POWER, ¶m, ACPI_TYPE_BUFFER); ++ SHPS_DSM_GPU_POWER, ¶m, ACPI_TYPE_BUFFER); + + if (IS_ERR_OR_NULL(result)) + return result ? PTR_ERR(result) : -EIO; @@ -1387,20 +1369,23 @@ index 000000000000..3b123bd3dcfe + if (status) + shps_dtx_latch_unlock(); + -+ return status; + } else { + status = shps_dgpu_rp_set_power(pdev, power); + if (status) + return status; + -+ return shps_dtx_latch_unlock(); ++ status = shps_dtx_latch_unlock(); + } ++ ++ return status; +} + + +static int shps_dgpu_is_present(struct platform_device *pdev) +{ -+ struct shps_driver_data *drvdata = platform_get_drvdata(pdev); ++ struct shps_driver_data *drvdata; ++ ++ drvdata = platform_get_drvdata(pdev); + return gpiod_get_value_cansleep(drvdata->gpio_dgpu_presence); +} + @@ -1628,9 +1613,8 @@ index 000000000000..3b123bd3dcfe + struct shps_driver_data *drvdata = platform_get_drvdata(pdev); + int status = 0; + -+ if (test_and_clear_bit(SHPS_STATE_BIT_WAKE_ENABLED, &drvdata->state)) { ++ if (test_and_clear_bit(SHPS_STATE_BIT_WAKE_ENABLED, &drvdata->state)) + status = disable_irq_wake(drvdata->irq_base_presence); -+ } + + return status; +} @@ -1902,15 +1886,13 @@ index 000000000000..3b123bd3dcfe + + // link to SSH + status = surface_sam_ssh_consumer_register(&pdev->dev); -+ if (status) { ++ if (status) + return status == -ENXIO ? -EPROBE_DEFER : status; -+ } + + // link to SAN + status = surface_sam_san_consumer_register(&pdev->dev, 0); -+ if (status) { ++ if (status) + return status == -ENXIO ? -EPROBE_DEFER : status; -+ } + + status = acpi_dev_add_driver_gpios(shps_dev, shps_acpi_gpios); + if (status) @@ -2019,7 +2001,7 @@ index 000000000000..3b123bd3dcfe +}; +MODULE_DEVICE_TABLE(acpi, shps_acpi_match); + -+struct platform_driver surface_sam_hps = { ++static struct platform_driver surface_sam_hps = { + .probe = shps_probe, + .remove = shps_remove, + .shutdown = shps_shutdown, @@ -2036,10 +2018,11 @@ index 000000000000..3b123bd3dcfe +MODULE_LICENSE("GPL v2"); diff --git a/drivers/platform/x86/surface_sam/surface_sam_san.c b/drivers/platform/x86/surface_sam/surface_sam_san.c new file mode 100644 -index 000000000000..aa0cfc4262be +index 000000000000..63478945e6b2 --- /dev/null +++ b/drivers/platform/x86/surface_sam/surface_sam_san.c -@@ -0,0 +1,901 @@ +@@ -0,0 +1,883 @@ ++// SPDX-License-Identifier: GPL-2.0 +/* + * Surface ACPI Notify (SAN) and ACPI integration driver for SAM. + * Translates communication from ACPI to SSH and back. @@ -2062,7 +2045,7 @@ index 000000000000..aa0cfc4262be + +static const guid_t SAN_DSM_UUID = + GUID_INIT(0x93b666c5, 0x70c6, 0x469f, 0xa2, 0x15, 0x3d, -+ 0x48, 0x7c, 0x91, 0xab, 0x3c); ++ 0x48, 0x7c, 0x91, 0xab, 0x3c); + +#define SAM_EVENT_DELAY_PWR_ADAPTER msecs_to_jiffies(5000) +#define SAM_EVENT_DELAY_PWR_BST msecs_to_jiffies(2500) @@ -2244,11 +2227,10 @@ index 000000000000..aa0cfc4262be + + dev_dbg(dev, "notify power event 0x%02x\n", event); + obj = acpi_evaluate_dsm_typed(san, &SAN_DSM_UUID, SAN_DSM_REVISION, -+ (u8) event, NULL, ACPI_TYPE_BUFFER); ++ (u8) event, NULL, ACPI_TYPE_BUFFER); + -+ if (IS_ERR_OR_NULL(obj)) { ++ if (IS_ERR_OR_NULL(obj)) + return obj ? PTR_ERR(obj) : -ENXIO; -+ } + + if (obj->buffer.length != 1 || obj->buffer.pointer[0] != 0) { + dev_err(dev, "got unexpected result from _DSM\n"); @@ -2269,12 +2251,11 @@ index 000000000000..aa0cfc4262be + param.integer.value = iid; + + obj = acpi_evaluate_dsm_typed(san, &SAN_DSM_UUID, SAN_DSM_REVISION, -+ SAN_DSM_FN_NOTIFY_SENSOR_TRIP_POINT, ++ SAN_DSM_FN_NOTIFY_SENSOR_TRIP_POINT, + ¶m, ACPI_TYPE_BUFFER); + -+ if (IS_ERR_OR_NULL(obj)) { ++ if (IS_ERR_OR_NULL(obj)) + return obj ? PTR_ERR(obj) : -ENXIO; -+ } + + if (obj->buffer.length != 1 || obj->buffer.pointer[0] != 0) { + dev_err(dev, "got unexpected result from _DSM\n"); @@ -2286,7 +2267,7 @@ index 000000000000..aa0cfc4262be +} + + -+inline static int san_evt_power_adapter(struct device *dev, struct surface_sam_ssh_event *event) ++static inline int san_evt_power_adapter(struct device *dev, struct surface_sam_ssh_event *event) +{ + int status; + @@ -2318,16 +2299,15 @@ index 000000000000..aa0cfc4262be + return 0; +} + -+inline static int san_evt_power_bix(struct device *dev, struct surface_sam_ssh_event *event) ++static inline int san_evt_power_bix(struct device *dev, struct surface_sam_ssh_event *event) +{ + enum san_pwr_event evcode; + int status; + -+ if (event->iid == 0x02) { ++ if (event->iid == 0x02) + evcode = SAN_PWR_EVENT_BAT2_INFO; -+ } else { ++ else + evcode = SAN_PWR_EVENT_BAT1_INFO; -+ } + + status = san_acpi_notify_power_event(dev, evcode); + if (status) { @@ -2338,16 +2318,15 @@ index 000000000000..aa0cfc4262be + return 0; +} + -+inline static int san_evt_power_bst(struct device *dev, struct surface_sam_ssh_event *event) ++static inline int san_evt_power_bst(struct device *dev, struct surface_sam_ssh_event *event) +{ + enum san_pwr_event evcode; + int status; + -+ if (event->iid == 0x02) { ++ if (event->iid == 0x02) + evcode = SAN_PWR_EVENT_BAT2_STAT; -+ } else { ++ else + evcode = SAN_PWR_EVENT_BAT1_STAT; -+ } + + status = san_acpi_notify_power_event(dev, evcode); + if (status) { @@ -2413,7 +2392,7 @@ index 000000000000..aa0cfc4262be +} + + -+inline static int san_evt_thermal_notify(struct device *dev, struct surface_sam_ssh_event *event) ++static inline int san_evt_thermal_notify(struct device *dev, struct surface_sam_ssh_event *event) +{ + int status; + @@ -2498,9 +2477,8 @@ index 000000000000..aa0cfc4262be + int status = 0; + int try; + -+ if (!gsb_rqst) { ++ if (!gsb_rqst) + return AE_OK; -+ } + + rqst.tc = gsb_rqst->tc; + rqst.cid = gsb_rqst->cid; @@ -2514,17 +2492,16 @@ index 000000000000..aa0cfc4262be + result.len = 0; + result.data = kzalloc(result.cap, GFP_KERNEL); + -+ if (!result.data) { ++ if (!result.data) + return AE_NO_MEMORY; -+ } + + for (try = 0; try < SAN_RQST_RETRY; try++) { -+ if (try) { -+ dev_warn(ctx->dev, SAN_RQST_TAG "IO error occured, trying again\n"); -+ } ++ if (try) ++ dev_warn(ctx->dev, SAN_RQST_TAG "IO error occurred, trying again\n"); + + status = surface_sam_ssh_rqst(&rqst, &result); -+ if (status != -EIO) break; ++ if (status != -EIO) ++ break; + } + + if (rqst.tc == 0x11 && rqst.cid == 0x0D && status == -EPERM) { @@ -2576,9 +2553,8 @@ index 000000000000..aa0cfc4262be + struct surface_sam_san_rqsg rqsg = {}; + int status; + -+ if (!gsb_rqsg) { ++ if (!gsb_rqsg) + return AE_OK; -+ } + + rqsg.tc = gsb_rqsg->tc; + rqsg.cid = gsb_rqsg->cid; @@ -2739,22 +2715,19 @@ index 000000000000..aa0cfc4262be + u32 max_links = 0; + int status; + -+ if (!cons) { ++ if (!cons) + return 0; -+ } + + // count links -+ for (con = cons; con->path; ++con) { ++ for (con = cons; con->path; ++con) + max_links += 1; -+ } + + // allocate -+ links = kzalloc(max_links * sizeof(struct san_consumer_link), GFP_KERNEL); ++ links = kcalloc(max_links, sizeof(struct san_consumer_link), GFP_KERNEL); + link = &links[0]; + -+ if (!links) { ++ if (!links) + return -ENOMEM; -+ } + + // create links + for (con = cons; con->path; ++con) { @@ -2769,9 +2742,8 @@ index 000000000000..aa0cfc4262be + } + + status = acpi_bus_get_device(handle, &adev); -+ if (status) { ++ if (status) + goto cleanup; -+ } + + link->link = device_link_add(&adev->dev, &pdev->dev, con->flags); + if (!(link->link)) { @@ -2790,25 +2762,23 @@ index 000000000000..aa0cfc4262be + +cleanup: + for (link = link - 1; link >= links; --link) { -+ if (link->properties->flags & DL_FLAG_STATELESS) { ++ if (link->properties->flags & DL_FLAG_STATELESS) + device_link_del(link->link); -+ } + } + + return status; +} + -+static void san_consumers_unlink(struct san_consumers *consumers) { ++static void san_consumers_unlink(struct san_consumers *consumers) ++{ + u32 i; + -+ if (!consumers) { ++ if (!consumers) + return; -+ } + + for (i = 0; i < consumers->num; ++i) { -+ if (consumers->links[i].properties->flags & DL_FLAG_STATELESS) { ++ if (consumers->links[i].properties->flags & DL_FLAG_STATELESS) + device_link_del(consumers->links[i].link); -+ } + } + + kfree(consumers->links); @@ -2831,22 +2801,19 @@ index 000000000000..aa0cfc4262be + * consumer to set up a device_link. + */ + status = surface_sam_ssh_consumer_register(&pdev->dev); -+ if (status) { ++ if (status) + return status == -ENXIO ? -EPROBE_DEFER : status; -+ } + + drvdata = kzalloc(sizeof(struct san_drvdata), GFP_KERNEL); -+ if (!drvdata) { ++ if (!drvdata) + return -ENOMEM; -+ } + + drvdata->opreg_ctx.dev = &pdev->dev; + + cons = acpi_device_get_match_data(&pdev->dev); + status = san_consumers_link(pdev, cons, &drvdata->consumers); -+ if (status) { ++ if (status) + goto err_consumers; -+ } + + platform_set_drvdata(pdev, drvdata); + @@ -2861,21 +2828,18 @@ index 000000000000..aa0cfc4262be + } + + status = san_enable_events(pdev); -+ if (status) { ++ if (status) + goto err_enable_events; -+ } + + mutex_lock(&rqsg_if.lock); -+ if (!rqsg_if.san_dev) { ++ if (!rqsg_if.san_dev) + rqsg_if.san_dev = &pdev->dev; -+ } else { ++ else + status = -EBUSY; -+ } + mutex_unlock(&rqsg_if.lock); + -+ if (status) { ++ if (status) + goto err_install_dev; -+ } + + acpi_walk_dep_device_list(san); + return 0; @@ -2922,7 +2886,7 @@ index 000000000000..aa0cfc4262be +}; + +static const struct acpi_device_id surface_sam_san_match[] = { -+ { "MSHW0091", (long unsigned int) san_mshw0091_consumers }, ++ { "MSHW0091", (unsigned long) san_mshw0091_consumers }, + { }, +}; +MODULE_DEVICE_TABLE(acpi, surface_sam_san_match); @@ -2943,10 +2907,11 @@ index 000000000000..aa0cfc4262be +MODULE_LICENSE("GPL v2"); diff --git a/drivers/platform/x86/surface_sam/surface_sam_san.h b/drivers/platform/x86/surface_sam/surface_sam_san.h new file mode 100644 -index 000000000000..1ea8713db367 +index 000000000000..85b6d6569947 --- /dev/null +++ b/drivers/platform/x86/surface_sam/surface_sam_san.h -@@ -0,0 +1,29 @@ +@@ -0,0 +1,30 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Interface for Surface ACPI/Notify (SAN). + * @@ -2966,7 +2931,7 @@ index 000000000000..1ea8713db367 + u8 tc; // target category + u8 cid; // command ID + u8 iid; // instance ID -+ u8 cdl; // command data length (lenght of payload) ++ u8 cdl; // command data length (length of payload) + u8 *pld; // pointer to payload of length cdl +}; + @@ -2978,10 +2943,11 @@ index 000000000000..1ea8713db367 +#endif /* _SURFACE_SAM_SAN_H */ diff --git a/drivers/platform/x86/surface_sam/surface_sam_sid.c b/drivers/platform/x86/surface_sam/surface_sam_sid.c new file mode 100644 -index 000000000000..f64dcd590494 +index 000000000000..fb49d0e00808 --- /dev/null +++ b/drivers/platform/x86/surface_sam/surface_sam_sid.c -@@ -0,0 +1,117 @@ +@@ -0,0 +1,137 @@ ++// SPDX-License-Identifier: GPL-2.0 +/* + * Surface Integration Driver. + * MFD driver to provide device/model dependent functionality. @@ -2995,14 +2961,16 @@ index 000000000000..f64dcd590494 + + +static const struct mfd_cell sid_devs_sp4[] = { -+ { .name = "surface_sam_sid_gpelid", .id = -1 }, ++ { .name = "surface_sam_sid_gpelid", .id = -1 }, ++ { .name = "surface_sam_sid_perfmode", .id = -1 }, + { }, +}; + +static const struct mfd_cell sid_devs_sp7[] = { -+ { .name = "surface_sam_sid_gpelid", .id = -1 }, -+ { .name = "surface_sam_sid_ac", .id = -1 }, -+ { .name = "surface_sam_sid_battery", .id = -1 }, ++ { .name = "surface_sam_sid_gpelid", .id = -1 }, ++ { .name = "surface_sam_sid_ac", .id = -1 }, ++ { .name = "surface_sam_sid_battery", .id = -1 }, ++ { .name = "surface_sam_sid_perfmode", .id = -1 }, + { }, +}; + @@ -3028,10 +2996,11 @@ index 000000000000..f64dcd590494 +}; + +static const struct mfd_cell sid_devs_sl3_13[] = { -+ { .name = "surface_sam_sid_gpelid", .id = -1 }, -+ { .name = "surface_sam_sid_vhf", .id = -1 }, -+ { .name = "surface_sam_sid_ac", .id = -1 }, -+ { .name = "surface_sam_sid_battery", .id = -1 }, ++ { .name = "surface_sam_sid_gpelid", .id = -1 }, ++ { .name = "surface_sam_sid_vhf", .id = -1 }, ++ { .name = "surface_sam_sid_ac", .id = -1 }, ++ { .name = "surface_sam_sid_battery", .id = -1 }, ++ { .name = "surface_sam_sid_perfmode", .id = -1 }, + { }, +}; + @@ -3043,14 +3012,30 @@ index 000000000000..f64dcd590494 +}; + +static const struct acpi_device_id surface_sam_sid_match[] = { -+ { "MSHW0081", (unsigned long)sid_devs_sp4 }, /* Surface Pro 4, 5, and 6 */ -+ { "MSHW0116", (unsigned long)sid_devs_sp7 }, /* Surface Pro 7 */ -+ { "MSHW0080", (unsigned long)sid_devs_sb1 }, /* Surface Book 1 */ -+ { "MSHW0107", (unsigned long)sid_devs_sb2 }, /* Surface Book 2 */ -+ { "MSHW0086", (unsigned long)sid_devs_sl1 }, /* Surface Laptop 1 */ -+ { "MSHW0112", (unsigned long)sid_devs_sl2 }, /* Surface Laptop 2 */ -+ { "MSHW0114", (unsigned long)sid_devs_sl3_13 }, /* Surface Laptop 3 (13") */ -+ { "MSHW0110", (unsigned long)sid_devs_sl3_15 }, /* Surface Laptop 3 (15") */ ++ /* Surface Pro 4, 5, and 6 */ ++ { "MSHW0081", (unsigned long)sid_devs_sp4 }, ++ ++ /* Surface Pro 7 */ ++ { "MSHW0116", (unsigned long)sid_devs_sp7 }, ++ ++ /* Surface Book 1 */ ++ { "MSHW0080", (unsigned long)sid_devs_sb1 }, ++ ++ /* Surface Book 2 */ ++ { "MSHW0107", (unsigned long)sid_devs_sb2 }, ++ ++ /* Surface Laptop 1 */ ++ { "MSHW0086", (unsigned long)sid_devs_sl1 }, ++ ++ /* Surface Laptop 2 */ ++ { "MSHW0112", (unsigned long)sid_devs_sl2 }, ++ ++ /* Surface Laptop 3 (13") */ ++ { "MSHW0114", (unsigned long)sid_devs_sl3_13 }, ++ ++ /* Surface Laptop 3 (15") */ ++ { "MSHW0110", (unsigned long)sid_devs_sl3_15 }, ++ + { }, +}; +MODULE_DEVICE_TABLE(acpi, surface_sam_sid_match); @@ -3101,10 +3086,11 @@ index 000000000000..f64dcd590494 +MODULE_LICENSE("GPL v2"); diff --git a/drivers/platform/x86/surface_sam/surface_sam_sid_gpelid.c b/drivers/platform/x86/surface_sam/surface_sam_sid_gpelid.c new file mode 100644 -index 000000000000..ce32ebf4d94d +index 000000000000..286411701d36 --- /dev/null +++ b/drivers/platform/x86/surface_sam/surface_sam_sid_gpelid.c -@@ -0,0 +1,219 @@ +@@ -0,0 +1,224 @@ ++// SPDX-License-Identifier: GPL-2.0 +/* + * Surface Lid driver to enable wakeup from suspend via the lid. + */ @@ -3245,25 +3231,29 @@ index 000000000000..ce32ebf4d94d + +static int surface_sam_sid_gpelid_suspend(struct device *dev) +{ -+ const struct sid_lid_device *ldev = dev_get_drvdata(dev); ++ const struct sid_lid_device *ldev; ++ ++ ldev = dev_get_drvdata(dev); + return sid_lid_enable_wakeup(ldev, true); +} + +static int surface_sam_sid_gpelid_resume(struct device *dev) +{ -+ const struct sid_lid_device *ldev = dev_get_drvdata(dev); ++ const struct sid_lid_device *ldev; ++ ++ ldev = dev_get_drvdata(dev); + return sid_lid_enable_wakeup(ldev, false); +} + +static SIMPLE_DEV_PM_OPS(surface_sam_sid_gpelid_pm, -+ surface_sam_sid_gpelid_suspend, -+ surface_sam_sid_gpelid_resume); ++ surface_sam_sid_gpelid_suspend, ++ surface_sam_sid_gpelid_resume); + + +static int surface_sam_sid_gpelid_probe(struct platform_device *pdev) +{ + const struct dmi_system_id *match; -+ struct sid_lid_device *dev; ++ struct sid_lid_device *dev; + acpi_handle lid_handle; + int status; + @@ -3271,9 +3261,9 @@ index 000000000000..ce32ebf4d94d + if (!match) + return -ENODEV; + -+ dev = match->driver_data; -+ if (!dev) -+ return -ENODEV; ++ dev = match->driver_data; ++ if (!dev) ++ return -ENODEV; + + status = acpi_get_handle(NULL, (acpi_string)dev->acpi_path, &lid_handle); + if (status) @@ -3290,11 +3280,11 @@ index 000000000000..ce32ebf4d94d + status = sid_lid_enable_wakeup(dev, false); + if (status) { + acpi_disable_gpe(NULL, dev->gpe_number); -+ return status; -+ } ++ return status; ++ } + -+ platform_set_drvdata(pdev, dev); -+ return 0; ++ platform_set_drvdata(pdev, dev); ++ return 0; +} + +static int surface_sam_sid_gpelid_remove(struct platform_device *pdev) @@ -3303,10 +3293,10 @@ index 000000000000..ce32ebf4d94d + + /* restore default behavior without this module */ + sid_lid_enable_wakeup(dev, false); -+ acpi_disable_gpe(NULL, dev->gpe_number); ++ acpi_disable_gpe(NULL, dev->gpe_number); + -+ platform_set_drvdata(pdev, NULL); -+ return 0; ++ platform_set_drvdata(pdev, NULL); ++ return 0; +} + +static struct platform_driver surface_sam_sid_gpelid = { @@ -3326,10 +3316,11 @@ index 000000000000..ce32ebf4d94d +MODULE_ALIAS("platform:surface_sam_sid_gpelid"); diff --git a/drivers/platform/x86/surface_sam/surface_sam_sid_perfmode.c b/drivers/platform/x86/surface_sam/surface_sam_sid_perfmode.c new file mode 100644 -index 000000000000..880a2567cf1b +index 000000000000..f74e2b51604d --- /dev/null +++ b/drivers/platform/x86/surface_sam/surface_sam_sid_perfmode.c -@@ -0,0 +1,225 @@ +@@ -0,0 +1,216 @@ ++// SPDX-License-Identifier: GPL-2.0 +/* + * Surface Performance Mode Driver. + * Allows to change cooling capabilities based on user preference. @@ -3343,7 +3334,7 @@ index 000000000000..880a2567cf1b +#include "surface_sam_ssh.h" + + -+#define SID_PARAM_PERM (S_IRUGO | S_IWUSR) ++#define SID_PARAM_PERM 0644 + +enum sam_perf_mode { + SAM_PERF_MODE_NORMAL = 1, @@ -3389,13 +3380,11 @@ index 000000000000..880a2567cf1b + }; + + status = surface_sam_ssh_rqst(&rqst, &result); -+ if (status) { ++ if (status) + return status; -+ } + -+ if (result.len != 8) { ++ if (result.len != 8) + return -EFAULT; -+ } + + return get_unaligned_le32(&result.data[0]); +} @@ -3414,9 +3403,8 @@ index 000000000000..880a2567cf1b + .pld = payload, + }; + -+ if (perf_mode < __SAM_PERF_MODE__START || perf_mode > __SAM_PERF_MODE__END) { ++ if (perf_mode < __SAM_PERF_MODE__START || perf_mode > __SAM_PERF_MODE__END) + return -EINVAL; -+ } + + put_unaligned_le32(perf_mode, &rqst.pld[0]); + return surface_sam_ssh_rqst(&rqst, NULL); @@ -3429,13 +3417,11 @@ index 000000000000..880a2567cf1b + int status; + + status = kstrtoint(val, 0, &perf_mode); -+ if (status) { ++ if (status) + return status; -+ } + -+ if (perf_mode < __SID_PARAM_PERF_MODE__START || perf_mode > __SID_PARAM_PERF_MODE__END) { ++ if (perf_mode < __SID_PARAM_PERF_MODE__START || perf_mode > __SID_PARAM_PERF_MODE__END) + return -EINVAL; -+ } + + return param_set_int(val, kp); +} @@ -3469,20 +3455,18 @@ index 000000000000..880a2567cf1b +} + +static ssize_t perf_mode_store(struct device *dev, struct device_attribute *attr, -+ const char *data, size_t count) ++ const char *data, size_t count) +{ + int perf_mode; + int status; + + status = kstrtoint(data, 0, &perf_mode); -+ if (status) { ++ if (status) + return status; -+ } + + status = surface_sam_perf_mode_set(perf_mode); -+ if (status) { ++ if (status) + return status; -+ } + + // TODO: Should we notify ACPI here? + // @@ -3509,23 +3493,20 @@ index 000000000000..880a2567cf1b + + // link to ec + status = surface_sam_ssh_consumer_register(&pdev->dev); -+ if (status) { ++ if (status) + return status == -ENXIO ? -EPROBE_DEFER : status; -+ } + + // set initial perf_mode + if (param_perf_mode_init != SID_PARAM_PERF_MODE_AS_IS) { + status = surface_sam_perf_mode_set(param_perf_mode_init); -+ if (status) { ++ if (status) + return status; -+ } + } + + // register perf_mode attribute + status = sysfs_create_file(&pdev->dev.kobj, &dev_attr_perf_mode.attr); -+ if (status) { ++ if (status) + goto err_sysfs; -+ } + + return 0; + @@ -3557,10 +3538,11 @@ index 000000000000..880a2567cf1b +MODULE_ALIAS("platform:surface_sam_sid_perfmode"); diff --git a/drivers/platform/x86/surface_sam/surface_sam_sid_power.c b/drivers/platform/x86/surface_sam/surface_sam_sid_power.c new file mode 100644 -index 000000000000..1f2c88eda394 +index 000000000000..eb925bdda883 --- /dev/null +++ b/drivers/platform/x86/surface_sam/surface_sam_sid_power.c -@@ -0,0 +1,1259 @@ +@@ -0,0 +1,1264 @@ ++// SPDX-License-Identifier: GPL-2.0 +/* + * Surface SID Battery/AC Driver. + * Provides support for the battery and AC on 7th generation Surface devices. @@ -3894,7 +3876,7 @@ index 000000000000..1f2c88eda394 +struct spwr_subsystem { + struct mutex lock; + -+ unsigned refcount; ++ unsigned int refcount; + struct spwr_ac_device *ac; + struct spwr_battery_device *battery[__SPWR_NUM_BAT]; +}; @@ -3950,18 +3932,18 @@ index 000000000000..1f2c88eda394 +static int spwr_battery_unregister(struct spwr_battery_device *bat); + + -+inline static bool spwr_battery_present(struct spwr_battery_device *bat) ++static inline bool spwr_battery_present(struct spwr_battery_device *bat) +{ + return bat->sta & SAM_BATTERY_STA_PRESENT; +} + + -+inline static int spwr_battery_load_sta(struct spwr_battery_device *bat) ++static inline int spwr_battery_load_sta(struct spwr_battery_device *bat) +{ + return sam_psy_get_sta(bat->id + 1, &bat->sta); +} + -+inline static int spwr_battery_load_bix(struct spwr_battery_device *bat) ++static inline int spwr_battery_load_bix(struct spwr_battery_device *bat) +{ + if (!spwr_battery_present(bat)) + return 0; @@ -3969,7 +3951,7 @@ index 000000000000..1f2c88eda394 + return sam_psy_get_bix(bat->id + 1, &bat->bix); +} + -+inline static int spwr_battery_load_bst(struct spwr_battery_device *bat) ++static inline int spwr_battery_load_bst(struct spwr_battery_device *bat) +{ + if (!spwr_battery_present(bat)) + return 0; @@ -3978,13 +3960,13 @@ index 000000000000..1f2c88eda394 +} + + -+inline static int spwr_battery_set_alarm_unlocked(struct spwr_battery_device *bat, u32 value) ++static inline int spwr_battery_set_alarm_unlocked(struct spwr_battery_device *bat, u32 value) +{ + bat->alarm = value; + return sam_psy_set_btp(bat->id + 1, bat->alarm); +} + -+inline static int spwr_battery_set_alarm(struct spwr_battery_device *bat, u32 value) ++static inline int spwr_battery_set_alarm(struct spwr_battery_device *bat, u32 value) +{ + int status; + @@ -3995,7 +3977,7 @@ index 000000000000..1f2c88eda394 + return status; +} + -+inline static int spwr_battery_update_bst_unlocked(struct spwr_battery_device *bat, bool cached) ++static inline int spwr_battery_update_bst_unlocked(struct spwr_battery_device *bat, bool cached) +{ + unsigned long cache_deadline = bat->timestamp + msecs_to_jiffies(cache_time); + int status; @@ -4026,7 +4008,7 @@ index 000000000000..1f2c88eda394 + return status; +} + -+inline static int spwr_battery_update_bix_unlocked(struct spwr_battery_device *bat) ++static inline int spwr_battery_update_bix_unlocked(struct spwr_battery_device *bat) +{ + int status; + @@ -4057,7 +4039,7 @@ index 000000000000..1f2c88eda394 + return status; +} + -+inline static int spwr_ac_update_unlocked(struct spwr_ac_device *ac) ++static inline int spwr_ac_update_unlocked(struct spwr_ac_device *ac) +{ + return sam_psy_get_psrc(0x00, &ac->state); +} @@ -4235,7 +4217,7 @@ index 000000000000..1f2c88eda394 +} + + -+inline static int spwr_battery_prop_status(struct spwr_battery_device *bat) ++static inline int spwr_battery_prop_status(struct spwr_battery_device *bat) +{ + if (bat->bst.state & SAM_BATTERY_STATE_DISCHARGING) + return POWER_SUPPLY_STATUS_DISCHARGING; @@ -4252,7 +4234,7 @@ index 000000000000..1f2c88eda394 + return POWER_SUPPLY_STATUS_UNKNOWN; +} + -+inline static int spwr_battery_prop_technology(struct spwr_battery_device *bat) ++static inline int spwr_battery_prop_technology(struct spwr_battery_device *bat) +{ + if (!strcasecmp("NiCd", bat->bix.type)) + return POWER_SUPPLY_TECHNOLOGY_NiCd; @@ -4272,7 +4254,7 @@ index 000000000000..1f2c88eda394 + return POWER_SUPPLY_TECHNOLOGY_UNKNOWN; +} + -+inline static int spwr_battery_prop_capacity(struct spwr_battery_device *bat) ++static inline int spwr_battery_prop_capacity(struct spwr_battery_device *bat) +{ + if (bat->bst.remaining_cap && bat->bix.last_full_charge_cap) + return bat->bst.remaining_cap * 100 / bat->bix.last_full_charge_cap; @@ -4280,7 +4262,7 @@ index 000000000000..1f2c88eda394 + return 0; +} + -+inline static int spwr_battery_prop_capacity_level(struct spwr_battery_device *bat) ++static inline int spwr_battery_prop_capacity_level(struct spwr_battery_device *bat) +{ + if (bat->bst.state & SAM_BATTERY_STATE_CRITICAL) + return POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL; @@ -4462,14 +4444,12 @@ index 000000000000..1f2c88eda394 + int status; + + status = surface_sam_ssh_set_event_handler(SAM_PWR_RQID, spwr_handle_event, NULL); -+ if (status) { ++ if (status) + goto err_handler; -+ } + + status = surface_sam_ssh_enable_event_source(SAM_PWR_TC, 0x01, SAM_PWR_RQID); -+ if (status) { ++ if (status) + goto err_source; -+ } + + return 0; + @@ -4674,7 +4654,7 @@ index 000000000000..1f2c88eda394 + int status; + + if (bat->id < 0 || bat->id >= __SPWR_NUM_BAT) -+ return -EINVAL ; ++ return -EINVAL; + + mutex_lock(&spwr_subsystem.lock); + if (spwr_subsystem.battery[bat->id] != bat) { @@ -4703,7 +4683,9 @@ index 000000000000..1f2c88eda394 +#ifdef CONFIG_PM_SLEEP +static int surface_sam_sid_battery_resume(struct device *dev) +{ -+ struct spwr_battery_device *bat = dev_get_drvdata(dev); ++ struct spwr_battery_device *bat; ++ ++ bat = dev_get_drvdata(dev); + return spwr_battery_recheck(bat); +} +#else @@ -4732,7 +4714,9 @@ index 000000000000..1f2c88eda394 + +static int surface_sam_sid_battery_remove(struct platform_device *pdev) +{ -+ struct spwr_battery_device *bat = platform_get_drvdata(pdev); ++ struct spwr_battery_device *bat; ++ ++ bat = platform_get_drvdata(pdev); + return spwr_battery_unregister(bat); +} + @@ -4775,7 +4759,9 @@ index 000000000000..1f2c88eda394 + +static int surface_sam_sid_ac_remove(struct platform_device *pdev) +{ -+ struct spwr_ac_device *ac = platform_get_drvdata(pdev); ++ struct spwr_ac_device *ac; ++ ++ ac = platform_get_drvdata(pdev); + return spwr_ac_unregister(ac); +} + @@ -4822,10 +4808,11 @@ index 000000000000..1f2c88eda394 +MODULE_ALIAS("platform:surface_sam_sid_battery"); diff --git a/drivers/platform/x86/surface_sam/surface_sam_sid_vhf.c b/drivers/platform/x86/surface_sam/surface_sam_sid_vhf.c new file mode 100644 -index 000000000000..dc5be3a14a8c +index 000000000000..9cf912a44171 --- /dev/null +++ b/drivers/platform/x86/surface_sam/surface_sam_sid_vhf.c -@@ -0,0 +1,440 @@ +@@ -0,0 +1,428 @@ ++// SPDX-License-Identifier: GPL-2.0 +/* + * Microsofs Surface HID (VHF) driver for HID input events via SAM. + * Used for keyboard input events on the 7th generation Surface Laptops. @@ -4949,19 +4936,18 @@ index 000000000000..dc5be3a14a8c + .pri = 0x02, + .snc = 0x01, + .cdl = sizeof(struct surface_sam_sid_vhf_meta_rqst), -+ .pld = (u8*)&resp.rqst, ++ .pld = (u8 *)&resp.rqst, + }; + + struct surface_sam_ssh_buf result = { + .cap = sizeof(struct surface_sam_sid_vhf_meta_resp), + .len = 0, -+ .data = (u8*)&resp, ++ .data = (u8 *)&resp, + }; + + status = surface_sam_ssh_rqst(&rqst, &result); -+ if (status) { ++ if (status) + return status; -+ } + + *meta = resp.data.meta; + @@ -4989,20 +4975,19 @@ index 000000000000..dc5be3a14a8c + .pri = 0x02, + .snc = 0x01, + .cdl = sizeof(struct surface_sam_sid_vhf_meta_rqst), -+ .pld = (u8*)&resp.rqst, ++ .pld = (u8 *)&resp.rqst, + }; + + struct surface_sam_ssh_buf result = { + .cap = sizeof(struct surface_sam_sid_vhf_meta_resp), + .len = 0, -+ .data = (u8*)&resp, ++ .data = (u8 *)&resp, + }; + + // first fetch 00 to get the total length + status = surface_sam_ssh_rqst(&rqst, &result); -+ if (status) { ++ if (status) + return status; -+ } + + len = resp.data.info.hid_len; + @@ -5099,8 +5084,8 @@ index 000000000000..dc5be3a14a8c + rqst.pri = SURFACE_SAM_PRIORITY_HIGH; + rqst.iid = 0x00; // windows tends to distinguish iids, but EC will take it + rqst.cid = cid; -+ rqst.snc = HID_REQ_GET_REPORT == reqtype ? 0x01 : 0x00; -+ rqst.cdl = HID_REQ_GET_REPORT == reqtype ? 0x01 : len; ++ rqst.snc = reqtype == HID_REQ_GET_REPORT ? 0x01 : 0x00; ++ rqst.cdl = reqtype == HID_REQ_GET_REPORT ? 0x01 : len; + rqst.pld = buf; + + result.cap = len; @@ -5112,13 +5097,11 @@ index 000000000000..dc5be3a14a8c + status = surface_sam_ssh_rqst(&rqst, &result); + hid_dbg(hid, "%s: status %i\n", __func__, status); + -+ if (status) { ++ if (status) + return status; -+ } + -+ if (result.len > 0) { ++ if (result.len > 0) + print_hex_dump_debug("response:", DUMP_PREFIX_OFFSET, 16, 1, result.data, result.len, false); -+ } + + return result.len; +} @@ -5138,9 +5121,8 @@ index 000000000000..dc5be3a14a8c + struct hid_device *hid; + + hid = hid_allocate_device(); -+ if (IS_ERR(hid)) { ++ if (IS_ERR(hid)) + return hid; -+ } + + hid->dev.parent = &pdev->dev; + @@ -5160,13 +5142,11 @@ index 000000000000..dc5be3a14a8c + struct sid_vhf_evtctx *ctx = (struct sid_vhf_evtctx *)data; + + // skip if HID hasn't started yet -+ if (!test_bit(VHF_HID_STARTED, &ctx->flags)) { ++ if (!test_bit(VHF_HID_STARTED, &ctx->flags)) + return 0; -+ } + -+ if (event->tc == SAM_EVENT_SID_VHF_TC && (event->cid == 0x00 || event->cid == 0x03 || event->cid == 0x04)) { ++ if (event->tc == SAM_EVENT_SID_VHF_TC && (event->cid == 0x00 || event->cid == 0x03 || event->cid == 0x04)) + return hid_input_report(ctx->hid, HID_INPUT_REPORT, event->pld, event->len, 1); -+ } + + dev_warn(ctx->dev, "unsupported event (tc = %d, cid = %d)\n", event->tc, event->cid); + return 0; @@ -5181,19 +5161,16 @@ index 000000000000..dc5be3a14a8c + + // add device link to EC + status = surface_sam_ssh_consumer_register(&pdev->dev); -+ if (status) { ++ if (status) + return status == -ENXIO ? -EPROBE_DEFER : status; -+ } + + drvdata = kzalloc(sizeof(struct sid_vhf_drvdata), GFP_KERNEL); -+ if (!drvdata) { ++ if (!drvdata) + return -ENOMEM; -+ } + + status = vhf_get_metadata(0x00, &meta); -+ if (status) { ++ if (status) + goto err_create_hid; -+ } + + hid = sid_vhf_create_hid_device(pdev, &meta); + if (IS_ERR(hid)) { @@ -5210,19 +5187,16 @@ index 000000000000..dc5be3a14a8c + SAM_EVENT_SID_VHF_RQID, + sid_vhf_event_handler, + &drvdata->event_ctx); -+ if (status) { ++ if (status) + goto err_event_handler; -+ } + + status = surface_sam_ssh_enable_event_source(SAM_EVENT_SID_VHF_TC, 0x01, SAM_EVENT_SID_VHF_RQID); -+ if (status) { ++ if (status) + goto err_event_source; -+ } + + status = hid_add_device(hid); -+ if (status) { ++ if (status) + goto err_add_hid; -+ } + + return 0; + @@ -5268,10 +5242,11 @@ index 000000000000..dc5be3a14a8c +MODULE_ALIAS("platform:surface_sam_sid_vhf"); diff --git a/drivers/platform/x86/surface_sam/surface_sam_ssh.c b/drivers/platform/x86/surface_sam/surface_sam_ssh.c new file mode 100644 -index 000000000000..34905cf29a51 +index 000000000000..988be7c2d286 --- /dev/null +++ b/drivers/platform/x86/surface_sam/surface_sam_ssh.c -@@ -0,0 +1,1773 @@ +@@ -0,0 +1,1744 @@ ++// SPDX-License-Identifier: GPL-2.0 +/* + * Surface Serial Hub (SSH) driver for communication with the Surface/System + * Aggregator Module. @@ -5499,7 +5474,7 @@ index 000000000000..34905cf29a51 +}; + + -+inline static struct sam_ssh_ec *surface_sam_ssh_acquire(void) ++static inline struct sam_ssh_ec *surface_sam_ssh_acquire(void) +{ + struct sam_ssh_ec *ec = &ssh_ec; + @@ -5507,12 +5482,12 @@ index 000000000000..34905cf29a51 + return ec; +} + -+inline static void surface_sam_ssh_release(struct sam_ssh_ec *ec) ++static inline void surface_sam_ssh_release(struct sam_ssh_ec *ec) +{ + mutex_unlock(&ec->lock); +} + -+inline static struct sam_ssh_ec *surface_sam_ssh_acquire_init(void) ++static inline struct sam_ssh_ec *surface_sam_ssh_acquire_init(void) +{ + struct sam_ssh_ec *ec = surface_sam_ssh_acquire(); + @@ -5531,14 +5506,12 @@ index 000000000000..34905cf29a51 + struct device_link *link; + + ec = surface_sam_ssh_acquire_init(); -+ if (!ec) { ++ if (!ec) + return -ENXIO; -+ } + + link = device_link_add(consumer, &ec->serdev->dev, flags); -+ if (!link) { ++ if (!link) + return -EFAULT; -+ } + + surface_sam_ssh_release(ec); + return 0; @@ -5546,12 +5519,15 @@ index 000000000000..34905cf29a51 +EXPORT_SYMBOL_GPL(surface_sam_ssh_consumer_register); + + -+inline static u16 sam_rqid_to_rqst(u16 rqid) { ++static inline u16 sam_rqid_to_rqst(u16 rqid) ++{ + return rqid << SURFACE_SAM_SSH_RQID_EVENT_BITS; +} + -+inline static bool sam_rqid_is_event(u16 rqid) { ++static inline bool sam_rqid_is_event(u16 rqid) ++{ + const u16 mask = (1 << SURFACE_SAM_SSH_RQID_EVENT_BITS) - 1; ++ + return rqid != 0 && (rqid | mask) == mask; +} + @@ -5579,16 +5555,15 @@ index 000000000000..34905cf29a51 + int status; + + // only allow RQIDs that lie within event spectrum -+ if (!sam_rqid_is_event(rqid)) { ++ if (!sam_rqid_is_event(rqid)) + return -EINVAL; -+ } + + status = surface_sam_ssh_rqst(&rqst, &result); + + if (buf[0] != 0x00) { -+ printk(KERN_WARNING SSH_RQST_TAG_FULL -+ "unexpected result while enabling event source: 0x%02x\n", -+ buf[0]); ++ pr_warn(SSH_RQST_TAG_FULL ++ "unexpected result while enabling event source: 0x%02x\n", ++ buf[0]); + } + + return status; @@ -5620,16 +5595,15 @@ index 000000000000..34905cf29a51 + int status; + + // only allow RQIDs that lie within event spectrum -+ if (!sam_rqid_is_event(rqid)) { ++ if (!sam_rqid_is_event(rqid)) + return -EINVAL; -+ } + + status = surface_sam_ssh_rqst(&rqst, &result); + + if (buf[0] != 0x00) { -+ printk(KERN_WARNING SSH_RQST_TAG_FULL -+ "unexpected result while disabling event source: 0x%02x\n", -+ buf[0]); ++ pr_warn(SSH_RQST_TAG_FULL ++ "unexpected result while disabling event source: 0x%02x\n", ++ buf[0]); + } + + return status; @@ -5649,18 +5623,15 @@ index 000000000000..34905cf29a51 + struct sam_ssh_ec *ec; + unsigned long flags; + -+ if (!sam_rqid_is_event(rqid)) { ++ if (!sam_rqid_is_event(rqid)) + return -EINVAL; -+ } + + ec = surface_sam_ssh_acquire_init(); -+ if (!ec) { ++ if (!ec) + return -ENXIO; -+ } + -+ if (!delay) { ++ if (!delay) + delay = sam_event_default_delay; -+ } + + spin_lock_irqsave(&ec->events.lock, flags); + // check if we already have a handler @@ -5686,14 +5657,12 @@ index 000000000000..34905cf29a51 + struct sam_ssh_ec *ec; + unsigned long flags; + -+ if (!sam_rqid_is_event(rqid)) { ++ if (!sam_rqid_is_event(rqid)) + return -EINVAL; -+ } + + ec = surface_sam_ssh_acquire_init(); -+ if (!ec) { ++ if (!ec) + return -ENXIO; -+ } + + spin_lock_irqsave(&ec->events.lock, flags); + @@ -5716,24 +5685,24 @@ index 000000000000..34905cf29a51 +EXPORT_SYMBOL_GPL(surface_sam_ssh_remove_event_handler); + + -+inline static u16 ssh_crc(const u8 *buf, size_t size) ++static inline u16 ssh_crc(const u8 *buf, size_t size) +{ + return crc_ccitt_false(0xffff, buf, size); +} + -+inline static void ssh_write_u16(struct ssh_writer *writer, u16 in) ++static inline void ssh_write_u16(struct ssh_writer *writer, u16 in) +{ + put_unaligned_le16(in, writer->ptr); + writer->ptr += 2; +} + -+inline static void ssh_write_crc(struct ssh_writer *writer, ++static inline void ssh_write_crc(struct ssh_writer *writer, + const u8 *buf, size_t size) +{ + ssh_write_u16(writer, ssh_crc(buf, size)); +} + -+inline static void ssh_write_syn(struct ssh_writer *writer) ++static inline void ssh_write_syn(struct ssh_writer *writer) +{ + u8 *w = writer->ptr; + @@ -5743,7 +5712,7 @@ index 000000000000..34905cf29a51 + writer->ptr = w; +} + -+inline static void ssh_write_ter(struct ssh_writer *writer) ++static inline void ssh_write_ter(struct ssh_writer *writer) +{ + u8 *w = writer->ptr; + @@ -5753,13 +5722,13 @@ index 000000000000..34905cf29a51 + writer->ptr = w; +} + -+inline static void ssh_write_buf(struct ssh_writer *writer, ++static inline void ssh_write_buf(struct ssh_writer *writer, + u8 *in, size_t len) +{ + writer->ptr = memcpy(writer->ptr, in, len) + len; +} + -+inline static void ssh_write_hdr(struct ssh_writer *writer, ++static inline void ssh_write_hdr(struct ssh_writer *writer, + const struct surface_sam_ssh_rqst *rqst, + struct sam_ssh_ec *ec) +{ @@ -5776,7 +5745,7 @@ index 000000000000..34905cf29a51 + ssh_write_crc(writer, begin, writer->ptr - begin); +} + -+inline static void ssh_write_cmd(struct ssh_writer *writer, ++static inline void ssh_write_cmd(struct ssh_writer *writer, + const struct surface_sam_ssh_rqst *rqst, + struct sam_ssh_ec *ec) +{ @@ -5802,7 +5771,7 @@ index 000000000000..34905cf29a51 + ssh_write_crc(writer, begin, writer->ptr - begin); +} + -+inline static void ssh_write_ack(struct ssh_writer *writer, u8 seq) ++static inline void ssh_write_ack(struct ssh_writer *writer, u8 seq) +{ + struct ssh_frame_ctrl *ack = (struct ssh_frame_ctrl *)writer->ptr; + u8 *begin = writer->ptr; @@ -5817,12 +5786,12 @@ index 000000000000..34905cf29a51 + ssh_write_crc(writer, begin, writer->ptr - begin); +} + -+inline static void ssh_writer_reset(struct ssh_writer *writer) ++static inline void ssh_writer_reset(struct ssh_writer *writer) +{ + writer->ptr = writer->data; +} + -+inline static int ssh_writer_flush(struct sam_ssh_ec *ec) ++static inline int ssh_writer_flush(struct sam_ssh_ec *ec) +{ + struct ssh_writer *writer = &ec->writer; + struct serdev_device *serdev = ec->serdev; @@ -5832,13 +5801,13 @@ index 000000000000..34905cf29a51 + + dev_dbg(&ec->serdev->dev, "sending message\n"); + print_hex_dump_debug("send: ", DUMP_PREFIX_OFFSET, 16, 1, -+ writer->data, writer->ptr - writer->data, false); ++ writer->data, writer->ptr - writer->data, false); + + status = serdev_device_write(serdev, writer->data, len, SSH_WRITE_TIMEOUT); + return status >= 0 ? 0 : status; +} + -+inline static void ssh_write_msg_cmd(struct sam_ssh_ec *ec, ++static inline void ssh_write_msg_cmd(struct sam_ssh_ec *ec, + const struct surface_sam_ssh_rqst *rqst) +{ + ssh_writer_reset(&ec->writer); @@ -5847,7 +5816,7 @@ index 000000000000..34905cf29a51 + ssh_write_cmd(&ec->writer, rqst, ec); +} + -+inline static void ssh_write_msg_ack(struct sam_ssh_ec *ec, u8 seq) ++static inline void ssh_write_msg_ack(struct sam_ssh_ec *ec, u8 seq) +{ + ssh_writer_reset(&ec->writer); + ssh_write_syn(&ec->writer); @@ -5855,7 +5824,7 @@ index 000000000000..34905cf29a51 + ssh_write_ter(&ec->writer); +} + -+inline static void ssh_receiver_restart(struct sam_ssh_ec *ec, ++static inline void ssh_receiver_restart(struct sam_ssh_ec *ec, + const struct surface_sam_ssh_rqst *rqst) +{ + unsigned long flags; @@ -5870,7 +5839,7 @@ index 000000000000..34905cf29a51 + spin_unlock_irqrestore(&ec->receiver.lock, flags); +} + -+inline static void ssh_receiver_discard(struct sam_ssh_ec *ec) ++static inline void ssh_receiver_discard(struct sam_ssh_ec *ec) +{ + unsigned long flags; + @@ -5903,18 +5872,16 @@ index 000000000000..34905cf29a51 + // send command, try to get an ack response + for (try = 0; try < SSH_NUM_RETRY; try++) { + status = ssh_writer_flush(ec); -+ if (status) { ++ if (status) + goto out; -+ } + + rem = wait_for_completion_timeout(&ec->receiver.signal, SSH_READ_TIMEOUT); + if (rem) { + // completion assures valid packet, thus ignore returned length + (void) !kfifo_out(&ec->receiver.fifo, &packet, sizeof(packet)); + -+ if (packet.type == SSH_FRAME_TYPE_ACK) { ++ if (packet.type == SSH_FRAME_TYPE_ACK) + break; -+ } + } + } + @@ -5953,9 +5920,8 @@ index 000000000000..34905cf29a51 + if (packet.type == SSH_FRAME_TYPE_CMD) { + ssh_write_msg_ack(ec, packet.seq); + status = ssh_writer_flush(ec); -+ if (status) { ++ if (status) + goto out; -+ } + } + } + @@ -5971,7 +5937,7 @@ index 000000000000..34905cf29a51 + + ec = surface_sam_ssh_acquire_init(); + if (!ec) { -+ printk(KERN_WARNING SSH_RQST_TAG_FULL "embedded controller is uninitialized\n"); ++ pr_warn(SSH_RQST_TAG_FULL "embedded controller is uninitialized\n"); + return -ENXIO; + } + @@ -6010,14 +5976,15 @@ index 000000000000..34905cf29a51 + result.data = buf, + }; + -+ int status = surface_sam_ssh_rqst_unlocked(ec, &rqst, &result); -+ if (status) { ++ int status; ++ ++ status = surface_sam_ssh_rqst_unlocked(ec, &rqst, &result); ++ if (status) + return status; -+ } + + if (buf[0] != 0x00) { + dev_warn(&ec->serdev->dev, -+ "unexpected result while trying to resume EC: 0x%02x\n", ++ "unexpected result while trying to resume EC: 0x%02x\n", + buf[0]); + } + @@ -6044,14 +6011,15 @@ index 000000000000..34905cf29a51 + result.data = buf, + }; + -+ int status = surface_sam_ssh_rqst_unlocked(ec, &rqst, &result); -+ if (status) { ++ int status; ++ ++ status = surface_sam_ssh_rqst_unlocked(ec, &rqst, &result); ++ if (status) + return status; -+ } + + if (buf[0] != 0x00) { + dev_warn(&ec->serdev->dev, -+ "unexpected result while trying to suspend EC: 0x%02x\n", ++ "unexpected result while trying to suspend EC: 0x%02x\n", + buf[0]); + } + @@ -6059,19 +6027,21 @@ index 000000000000..34905cf29a51 +} + + -+inline static bool ssh_is_valid_syn(const u8 *ptr) ++static inline bool ssh_is_valid_syn(const u8 *ptr) +{ + return ptr[0] == 0xaa && ptr[1] == 0x55; +} + -+inline static bool ssh_is_valid_ter(const u8 *ptr) ++static inline bool ssh_is_valid_ter(const u8 *ptr) +{ + return ptr[0] == 0xff && ptr[1] == 0xff; +} + -+inline static bool ssh_is_valid_crc(const u8 *begin, const u8 *end) ++static inline bool ssh_is_valid_crc(const u8 *begin, const u8 *end) +{ -+ u16 crc = ssh_crc(begin, end - begin); ++ u16 crc; ++ ++ crc = ssh_crc(begin, end - begin); + return (end[0] == (crc & 0xff)) && (end[1] == (crc >> 8)); +} + @@ -6098,7 +6068,7 @@ index 000000000000..34905cf29a51 + + dev_dbg(&ec->serdev->dev, "sending message\n"); + print_hex_dump_debug("send: ", DUMP_PREFIX_OFFSET, 16, 1, -+ buf, SSH_MSG_LEN_CTRL, false); ++ buf, SSH_MSG_LEN_CTRL, false); + + status = serdev_device_write(ec->serdev, buf, SSH_MSG_LEN_CTRL, SSH_WRITE_TIMEOUT); + return status >= 0 ? 0 : status; @@ -6117,19 +6087,17 @@ index 000000000000..34905cf29a51 + ec = work->ec; + dev = &ec->serdev->dev; + -+ // make sure we load a fresh ec state ++ /* make sure we load a fresh ec state */ + smp_mb(); + + if (ec->state == SSH_EC_INITIALIZED) { + status = surface_sam_ssh_send_ack(ec, work->seq); -+ if (status) { ++ if (status) + dev_err(dev, SSH_EVENT_TAG "failed to send ACK: %d\n", status); -+ } + } + -+ if (refcount_dec_and_test(&work->refcount)) { ++ if (refcount_dec_and_test(&work->refcount)) + kfree(work); -+ } +} + +static void surface_sam_ssh_event_work_evt_handler(struct work_struct *_work) @@ -6162,24 +6130,20 @@ index 000000000000..34905cf29a51 + * guaranteed to be valid at least until this function returns. + */ + -+ if (handler) { ++ if (handler) + status = handler(event, handler_data); -+ } else { ++ else + dev_warn(dev, SSH_EVENT_TAG "unhandled event (rqid: %04x)\n", event->rqid); -+ } + -+ if (status) { ++ if (status) + dev_err(dev, SSH_EVENT_TAG "error handling event: %d\n", status); -+ } + -+ if (refcount_dec_and_test(&work->refcount)) { ++ if (refcount_dec_and_test(&work->refcount)) + kfree(work); -+ } +} + +static void ssh_handle_event(struct sam_ssh_ec *ec, const u8 *buf) +{ -+ struct device *dev = &ec->serdev->dev; + const struct ssh_frame_ctrl *ctrl; + const struct ssh_frame_cmd *cmd; + struct ssh_event_work *work; @@ -6196,10 +6160,8 @@ index 000000000000..34905cf29a51 + pld_len = ctrl->len - SSH_BYTELEN_CMDFRAME; + + work = kzalloc(sizeof(struct ssh_event_work) + pld_len, GFP_ATOMIC); -+ if (!work) { -+ dev_warn(dev, SSH_EVENT_TAG "failed to allocate memory, dropping event\n"); ++ if (!work) + return; -+ } + + refcount_set(&work->refcount, 1); + work->ec = ec; @@ -6210,7 +6172,7 @@ index 000000000000..34905cf29a51 + work->event.iid = cmd->iid; + work->event.pri = cmd->pri_in; + work->event.len = pld_len; -+ work->event.pld = ((u8*) work) + sizeof(struct ssh_event_work); ++ work->event.pld = ((u8 *)work) + sizeof(struct ssh_event_work); + + memcpy(work->event.pld, buf + SSH_FRAME_OFFS_CMD_PLD, pld_len); + @@ -6254,9 +6216,8 @@ index 000000000000..34905cf29a51 + ctrl = (const struct ssh_frame_ctrl *)(ctrl_begin); + + // actual length check -+ if (size < SSH_MSG_LEN_CTRL) { ++ if (size < SSH_MSG_LEN_CTRL) + return 0; // need more bytes -+ } + + // validate TERM + if (!ssh_is_valid_ter(buf + SSH_FRAME_OFFS_TERM)) { @@ -6331,9 +6292,8 @@ index 000000000000..34905cf29a51 + cmd = (const struct ssh_frame_cmd *)(cmd_begin); + + // we need at least a full control frame -+ if (size < (SSH_BYTELEN_SYNC + SSH_BYTELEN_CTRL + SSH_BYTELEN_CRC)) { ++ if (size < (SSH_BYTELEN_SYNC + SSH_BYTELEN_CTRL + SSH_BYTELEN_CRC)) + return 0; // need more bytes -+ } + + // validate control-frame CRC + if (!ssh_is_valid_crc(ctrl_begin, ctrl_end)) { @@ -6347,9 +6307,8 @@ index 000000000000..34905cf29a51 + + // actual length check (ctrl->len contains command-frame but not crc) + msg_len = SSH_MSG_LEN_CMD_BASE + ctrl->len; -+ if (size < msg_len) { ++ if (size < msg_len) + return 0; // need more bytes -+ } + + cmd_end = cmd_begin + ctrl->len; + @@ -6420,9 +6379,8 @@ index 000000000000..34905cf29a51 + struct ssh_frame_ctrl *ctrl; + + // we need at least a control frame to check what to do -+ if (size < (SSH_BYTELEN_SYNC + SSH_BYTELEN_CTRL)) { ++ if (size < (SSH_BYTELEN_SYNC + SSH_BYTELEN_CTRL)) + return 0; // need more bytes -+ } + + // make sure we're actually at the start of a new message + if (!ssh_is_valid_syn(buf)) { @@ -6430,7 +6388,7 @@ index 000000000000..34905cf29a51 + return size; // discard everything + } + -+ // handle individual message types seperately ++ // handle individual message types separately + ctrl = (struct ssh_frame_ctrl *)(buf + SSH_FRAME_OFFS_CTRL); + + switch (ctrl->type) { @@ -6476,7 +6434,8 @@ index 000000000000..34905cf29a51 + while (offs < rcv->eval_buf.len) { + n = rcv->eval_buf.len - offs; + n = ssh_eval_buf(ec, rcv->eval_buf.ptr + offs, n); -+ if (n <= 0) break; // need more bytes ++ if (n <= 0) ++ break; // need more bytes + + offs += n; + } @@ -6510,11 +6469,10 @@ index 000000000000..34905cf29a51 +} __packed; + +static ssize_t rqst_read(struct file *f, struct kobject *kobj, struct bin_attribute *attr, -+ char *buf, loff_t offs, size_t count) ++ char *buf, loff_t offs, size_t count) +{ -+ if (offs < 0 || count + offs > SURFACE_SAM_SSH_MAX_RQST_RESPONSE) { ++ if (offs < 0 || count + offs > SURFACE_SAM_SSH_MAX_RQST_RESPONSE) + return -EINVAL; -+ } + + memcpy(buf, sam_ssh_debug_rqst_buf_sysfs + offs, count); + return count; @@ -6529,20 +6487,17 @@ index 000000000000..34905cf29a51 + int status; + + // check basic write constriants -+ if (offs != 0 || count > SURFACE_SAM_SSH_MAX_RQST_PAYLOAD + sizeof(struct sysfs_rqst)) { ++ if (offs != 0 || count > SURFACE_SAM_SSH_MAX_RQST_PAYLOAD + sizeof(struct sysfs_rqst)) + return -EINVAL; -+ } + -+ if (count < sizeof(struct sysfs_rqst)) { ++ if (count < sizeof(struct sysfs_rqst)) + return -EINVAL; -+ } + + input = (struct sysfs_rqst *)buf; + + // payload length should be consistent with data provided -+ if (input->cdl + sizeof(struct sysfs_rqst) != count) { ++ if (input->cdl + sizeof(struct sysfs_rqst) != count) + return -EINVAL; -+ } + + rqst.tc = input->tc; + rqst.cid = input->cid; @@ -6558,9 +6513,8 @@ index 000000000000..34905cf29a51 + result.data = sam_ssh_debug_rqst_buf_res; + + status = surface_sam_ssh_rqst(&rqst, &result); -+ if (status) { ++ if (status) + return status; -+ } + + sam_ssh_debug_rqst_buf_sysfs[0] = result.len; + memcpy(sam_ssh_debug_rqst_buf_sysfs + 1, result.data, result.len); @@ -6573,24 +6527,24 @@ index 000000000000..34905cf29a51 +static const BIN_ATTR_RW(rqst, SURFACE_SAM_SSH_MAX_RQST_RESPONSE + 1); + + -+int surface_sam_ssh_sysfs_register(struct device *dev) ++static int surface_sam_ssh_sysfs_register(struct device *dev) +{ + return sysfs_create_bin_file(&dev->kobj, &bin_attr_rqst); +} + -+void surface_sam_ssh_sysfs_unregister(struct device *dev) ++static void surface_sam_ssh_sysfs_unregister(struct device *dev) +{ + sysfs_remove_bin_file(&dev->kobj, &bin_attr_rqst); +} + +#else /* CONFIG_SURFACE_ACPI_SSH_DEBUG_DEVICE */ + -+int surface_sam_ssh_sysfs_register(struct device *dev) ++static int surface_sam_ssh_sysfs_register(struct device *dev) +{ + return 0; +} + -+void surface_sam_ssh_sysfs_unregister(struct device *dev) ++static void surface_sam_ssh_sysfs_unregister(struct device *dev) +{ +} + @@ -6648,14 +6602,12 @@ index 000000000000..34905cf29a51 + struct acpi_resource_uart_serialbus *uart; + int status = 0; + -+ if (resource->type != ACPI_RESOURCE_TYPE_SERIAL_BUS) { ++ if (resource->type != ACPI_RESOURCE_TYPE_SERIAL_BUS) + return AE_OK; -+ } + + serial = &resource->data.common_serial_bus; -+ if (serial->type != ACPI_RESOURCE_SERIAL_TYPE_UART) { ++ if (serial->type != ACPI_RESOURCE_SERIAL_TYPE_UART) + return AE_OK; -+ } + + uart = &resource->data.uart_serial_bus; + @@ -6663,9 +6615,8 @@ index 000000000000..34905cf29a51 + serdev_device_set_baudrate(serdev, uart->default_baud_rate); + + // serdev currently only supports RTSCTS flow control -+ if (uart->flow_control & SSH_SUPPORTED_FLOW_CONTROL_MASK) { ++ if (uart->flow_control & SSH_SUPPORTED_FLOW_CONTROL_MASK) + dev_warn(&serdev->dev, "unsupported flow control (value: 0x%02x)\n", uart->flow_control); -+ } + + // set RTSCTS flow control + serdev_device_set_flow_control(serdev, uart->flow_control & ACPI_UART_FLOW_CONTROL_HW); @@ -6771,8 +6722,8 @@ index 000000000000..34905cf29a51 +}; + + -+int surface_sam_ssh_sysfs_register(struct device *dev); -+void surface_sam_ssh_sysfs_unregister(struct device *dev); ++static int surface_sam_ssh_sysfs_register(struct device *dev); ++static void surface_sam_ssh_sysfs_unregister(struct device *dev); + +static int surface_sam_ssh_probe(struct serdev_device *serdev) +{ @@ -6862,30 +6813,26 @@ index 000000000000..34905cf29a51 + + serdev_device_set_drvdata(serdev, ec); + -+ // ensure everything is properly set-up before we open the device ++ /* ensure everything is properly set-up before we open the device */ + smp_mb(); + + serdev_device_set_client_ops(serdev, &ssh_device_ops); + status = serdev_device_open(serdev); -+ if (status) { ++ if (status) + goto err_open; -+ } + + status = acpi_walk_resources(ssh, METHOD_NAME__CRS, -+ ssh_setup_from_resource, serdev); -+ if (ACPI_FAILURE(status)) { ++ ssh_setup_from_resource, serdev); ++ if (ACPI_FAILURE(status)) + goto err_devinit; -+ } + + status = surface_sam_ssh_ec_resume(ec); -+ if (status) { ++ if (status) + goto err_devinit; -+ } + + status = surface_sam_ssh_sysfs_register(&serdev->dev); -+ if (status) { ++ if (status) + goto err_devinit; -+ } + + surface_sam_ssh_release(ec); + @@ -6931,18 +6878,16 @@ index 000000000000..34905cf29a51 + int status; + + ec = surface_sam_ssh_acquire_init(); -+ if (!ec) { ++ if (!ec) + return; -+ } + + free_irq(ec->irq, serdev); + surface_sam_ssh_sysfs_unregister(&serdev->dev); + + // suspend EC and disable events + status = surface_sam_ssh_ec_suspend(ec); -+ if (status) { ++ if (status) + dev_err(&serdev->dev, "failed to suspend EC: %d\n", status); -+ } + + // make sure all events (received up to now) have been properly handled + flush_workqueue(ec->events.queue_ack); @@ -6952,14 +6897,14 @@ index 000000000000..34905cf29a51 + spin_lock_irqsave(&ec->events.lock, flags); + memset(ec->events.handler, 0, + sizeof(struct ssh_event_handler) -+ * SAM_NUM_EVENT_TYPES); ++ * SAM_NUM_EVENT_TYPES); + spin_unlock_irqrestore(&ec->events.lock, flags); + + // set device to deinitialized state + ec->state = SSH_EC_UNINITIALIZED; + ec->serdev = NULL; + -+ // ensure state and serdev get set before continuing ++ /* ensure state and serdev get set before continuing */ + smp_mb(); + + /* @@ -6972,9 +6917,9 @@ index 000000000000..34905cf29a51 + serdev_device_close(serdev); + + /* -+ * Only at this point, no new events can be received. Destroying the -+ * workqueue here flushes all remaining events. Those events will be -+ * silently ignored and neither ACKed nor any handler gets called. ++ * Only at this point, no new events can be received. Destroying the ++ * workqueue here flushes all remaining events. Those events will be ++ * silently ignored and neither ACKed nor any handler gets called. + */ + destroy_workqueue(ec->events.queue_ack); + destroy_workqueue(ec->events.queue_evt); @@ -7047,10 +6992,11 @@ index 000000000000..34905cf29a51 +MODULE_LICENSE("GPL v2"); diff --git a/drivers/platform/x86/surface_sam/surface_sam_ssh.h b/drivers/platform/x86/surface_sam/surface_sam_ssh.h new file mode 100644 -index 000000000000..714bba6a9457 +index 000000000000..435b5c7bac9a --- /dev/null +++ b/drivers/platform/x86/surface_sam/surface_sam_ssh.h -@@ -0,0 +1,97 @@ +@@ -0,0 +1,98 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Interface for Surface Serial Hub (SSH). + * @@ -7110,7 +7056,7 @@ index 000000000000..714bba6a9457 + u8 iid; // instance ID + u8 pri; // priority + u8 snc; // expect response flag -+ u8 cdl; // command data length (lenght of payload) ++ u8 cdl; // command data length (length of payload) + u8 *pld; // pointer to payload of length cdl +}; + @@ -7150,12 +7096,13 @@ index 000000000000..714bba6a9457 +#endif /* _SURFACE_SAM_SSH_H */ diff --git a/drivers/platform/x86/surface_sam/surface_sam_vhf.c b/drivers/platform/x86/surface_sam/surface_sam_vhf.c new file mode 100644 -index 000000000000..0ed0ebbdb3cb +index 000000000000..a00763805eca --- /dev/null +++ b/drivers/platform/x86/surface_sam/surface_sam_vhf.c -@@ -0,0 +1,276 @@ +@@ -0,0 +1,270 @@ ++// SPDX-License-Identifier: GPL-2.0 +/* -+ * Virtual HID Framwork (VHF) driver for input events via SAM. ++ * Virtual HID Framework (VHF) driver for input events via SAM. + * Used for keyboard input events on the Surface Laptops. + */ + @@ -7308,9 +7255,8 @@ index 000000000000..0ed0ebbdb3cb + struct hid_device *hid; + + hid = hid_allocate_device(); -+ if (IS_ERR(hid)) { ++ if (IS_ERR(hid)) + return hid; -+ } + + hid->dev.parent = &pdev->dev; + @@ -7329,9 +7275,8 @@ index 000000000000..0ed0ebbdb3cb +{ + struct vhf_evtctx *ctx = (struct vhf_evtctx *)data; + -+ if (event->tc == 0x08 && (event->cid == 0x03 || event->cid == 0x04)) { ++ if (event->tc == 0x08 && (event->cid == 0x03 || event->cid == 0x04)) + return hid_input_report(ctx->hid, HID_INPUT_REPORT, event->pld, event->len, 1); -+ } + + dev_warn(ctx->dev, "unsupported event (tc = %d, cid = %d)\n", event->tc, event->cid); + return 0; @@ -7345,14 +7290,12 @@ index 000000000000..0ed0ebbdb3cb + + // add device link to EC + status = surface_sam_ssh_consumer_register(&pdev->dev); -+ if (status) { ++ if (status) + return status == -ENXIO ? -EPROBE_DEFER : status; -+ } + + drvdata = kzalloc(sizeof(struct vhf_drvdata), GFP_KERNEL); -+ if (!drvdata) { ++ if (!drvdata) + return -ENOMEM; -+ } + + hid = vhf_create_hid_device(pdev); + if (IS_ERR(hid)) { @@ -7361,9 +7304,8 @@ index 000000000000..0ed0ebbdb3cb + } + + status = hid_add_device(hid); -+ if (status) { ++ if (status) + goto err_add_hid; -+ } + + drvdata->event_ctx.dev = &pdev->dev; + drvdata->event_ctx.hid = hid; @@ -7372,16 +7314,14 @@ index 000000000000..0ed0ebbdb3cb + + status = surface_sam_ssh_set_event_handler( + SAM_EVENT_VHF_RQID, -+ vhf_event_handler, ++ vhf_event_handler, + &drvdata->event_ctx); -+ if (status) { ++ if (status) + goto err_add_hid; -+ } + + status = surface_sam_ssh_enable_event_source(SAM_EVENT_VHF_TC, 0x01, SAM_EVENT_VHF_RQID); -+ if (status) { ++ if (status) + goto err_event_source; -+ } + + return 0; + @@ -7431,5 +7371,5 @@ index 000000000000..0ed0ebbdb3cb +MODULE_DESCRIPTION("Virtual HID Framework Driver for 5th Generation Surface Devices"); +MODULE_LICENSE("GPL v2"); -- -2.25.0 +2.25.1 diff --git a/patches/5.5/0005-surface-lte.patch b/patches/5.5/0005-surface-lte.patch index 5ed7cb012..68f939dcb 100644 --- a/patches/5.5/0005-surface-lte.patch +++ b/patches/5.5/0005-surface-lte.patch @@ -1,4 +1,4 @@ -From b320e77ae285b2f4e42b6df18e0b0f04c96c6c21 Mon Sep 17 00:00:00 2001 +From 57027f7807afd9632dc87270fcfb000a8496ce32 Mon Sep 17 00:00:00 2001 From: qzed Date: Tue, 17 Sep 2019 17:21:43 +0200 Subject: [PATCH 5/7] surface-lte @@ -20,5 +20,5 @@ index 613f91add03d..e1428222dd73 100644 /* Huawei devices */ {DEVICE_HWI(0x03f0, 0x581d)}, /* HP lt4112 LTE/HSPA+ Gobi 4G Modem (Huawei me906e) */ -- -2.25.0 +2.25.1 diff --git a/patches/5.5/0006-wifi.patch b/patches/5.5/0006-wifi.patch index f1ae131d7..39acca88d 100644 --- a/patches/5.5/0006-wifi.patch +++ b/patches/5.5/0006-wifi.patch @@ -1,13 +1,58 @@ -From 5dcda52bdd2ff95eaab22ce628aa703fa60d7b1f Mon Sep 17 00:00:00 2001 +From a926655d1999213564b845bb2db49d777a8c0a85 Mon Sep 17 00:00:00 2001 From: sebanc <22224731+sebanc@users.noreply.github.com> Date: Mon, 4 Nov 2019 09:30:57 +0100 Subject: [PATCH 6/7] wifi --- + .../net/wireless/marvell/mwifiex/cfg80211.c | 26 +++++++ drivers/net/wireless/marvell/mwifiex/pcie.c | 74 ++++++++++--------- - .../net/wireless/marvell/mwifiex/sta_cmd.c | 15 +--- - 2 files changed, 41 insertions(+), 48 deletions(-) + .../net/wireless/marvell/mwifiex/sta_cmd.c | 26 +------ + 3 files changed, 67 insertions(+), 59 deletions(-) +diff --git a/drivers/net/wireless/marvell/mwifiex/cfg80211.c b/drivers/net/wireless/marvell/mwifiex/cfg80211.c +index d89684168500..108d7ac6a0dd 100644 +--- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c ++++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c +@@ -25,6 +25,11 @@ + static char *reg_alpha2; + module_param(reg_alpha2, charp, 0); + ++static bool allow_ps_mode; ++module_param(allow_ps_mode, bool, 0444); ++MODULE_PARM_DESC(allow_ps_mode, ++ "allow WiFi power management to be enabled. (default: disallowed)"); ++ + static const struct ieee80211_iface_limit mwifiex_ap_sta_limits[] = { + { + .max = 3, .types = BIT(NL80211_IFTYPE_STATION) | +@@ -439,6 +444,27 @@ mwifiex_cfg80211_set_power_mgmt(struct wiphy *wiphy, + + ps_mode = enabled; + ++ /* Allow ps_mode to be enabled only when allow_ps_mode is set ++ * (but always allow ps_mode to be disabled in case it gets enabled ++ * for unknown reason and you want to disable it) */ ++ if (ps_mode && !allow_ps_mode) { ++ dev_info(priv->adapter->dev, ++ "Request to enable ps_mode received but it's disallowed " ++ "by module parameter. Rejecting the request.\n"); ++ ++ /* Return negative value to inform userspace tools that setting ++ * power_save to be enabled is not permitted. */ ++ return -1; ++ } ++ ++ if (ps_mode) ++ dev_warn(priv->adapter->dev, ++ "WARN: Request to enable ps_mode received. Enabling it. " ++ "Disable it if you encounter connection instability.\n"); ++ else ++ dev_info(priv->adapter->dev, ++ "Request to disable ps_mode received. Disabling it.\n"); ++ + return mwifiex_drv_set_power(priv, &ps_mode); + } + diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c index fc1706d0647d..b3380ed75431 100644 --- a/drivers/net/wireless/marvell/mwifiex/pcie.c @@ -125,7 +170,7 @@ index fc1706d0647d..b3380ed75431 100644 } diff --git a/drivers/net/wireless/marvell/mwifiex/sta_cmd.c b/drivers/net/wireless/marvell/mwifiex/sta_cmd.c -index 4ed10cf82f9a..013db4386c39 100644 +index 4ed10cf82f9a..977b57c0908f 100644 --- a/drivers/net/wireless/marvell/mwifiex/sta_cmd.c +++ b/drivers/net/wireless/marvell/mwifiex/sta_cmd.c @@ -2265,14 +2265,13 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no, @@ -144,7 +189,25 @@ index 4ed10cf82f9a..013db4386c39 100644 if (first_sta) { if (priv->adapter->iface_type == MWIFIEX_PCIE) { -@@ -2395,18 +2394,6 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta, bool init) +@@ -2339,17 +2338,6 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta, bool init) + if (ret) + return -1; + +- if (priv->bss_type != MWIFIEX_BSS_TYPE_UAP) { +- /* Enable IEEE PS by default */ +- priv->adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_PSP; +- ret = mwifiex_send_cmd(priv, +- HostCmd_CMD_802_11_PS_MODE_ENH, +- EN_AUTO_PS, BITMAP_STA_PS, NULL, +- true); +- if (ret) +- return -1; +- } +- + if (drcs) { + adapter->drcs_enabled = true; + if (ISSUPP_DRCS_ENABLED(adapter->fw_cap_info)) +@@ -2395,18 +2383,6 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta, bool init) if (ret) return -1; @@ -164,5 +227,5 @@ index 4ed10cf82f9a..013db4386c39 100644 /* Send cmd to FW to enable/disable 11D function */ state_11d = ENABLE_11D; -- -2.25.0 +2.25.1 diff --git a/patches/5.5/0007-ipts.patch b/patches/5.5/0007-ipts.patch index 77220dc59..80751c69b 100644 --- a/patches/5.5/0007-ipts.patch +++ b/patches/5.5/0007-ipts.patch @@ -1,4 +1,4 @@ -From a229e405b925f6d740e16a34edd014d9344aa520 Mon Sep 17 00:00:00 2001 +From 503f194c91971b94a7a558e8108fa82b26c0d375 Mon Sep 17 00:00:00 2001 From: Dorian Stoll Date: Mon, 27 Jan 2020 21:16:20 +0100 Subject: [PATCH 7/7] ipts @@ -7,43 +7,48 @@ Subject: [PATCH 7/7] ipts drivers/input/touchscreen/Kconfig | 2 + drivers/input/touchscreen/Makefile | 1 + drivers/input/touchscreen/ipts/Kconfig | 16 ++ - drivers/input/touchscreen/ipts/Makefile | 16 ++ + drivers/input/touchscreen/ipts/Makefile | 17 ++ drivers/input/touchscreen/ipts/context.h | 61 ++++ - drivers/input/touchscreen/ipts/control.c | 93 ++++++ + drivers/input/touchscreen/ipts/control.c | 94 +++++++ drivers/input/touchscreen/ipts/control.h | 18 ++ - drivers/input/touchscreen/ipts/devices.c | 46 +++ - drivers/input/touchscreen/ipts/devices.h | 33 +++ - drivers/input/touchscreen/ipts/hid.c | 126 +++++++++ - drivers/input/touchscreen/ipts/hid.h | 17 ++ + drivers/input/touchscreen/ipts/data.c | 107 +++++++ + drivers/input/touchscreen/ipts/data.h | 12 + + drivers/input/touchscreen/ipts/hid.c | 38 +++ + drivers/input/touchscreen/ipts/hid.h | 13 + drivers/input/touchscreen/ipts/init.c | 93 ++++++ drivers/input/touchscreen/ipts/math.c | 103 +++++++ drivers/input/touchscreen/ipts/math.h | 21 ++ drivers/input/touchscreen/ipts/params.c | 27 ++ drivers/input/touchscreen/ipts/params.h | 15 + - .../touchscreen/ipts/protocol/commands.h | 55 ++++ - .../input/touchscreen/ipts/protocol/enums.h | 59 ++++ + drivers/input/touchscreen/ipts/payload.c | 52 ++++ + drivers/input/touchscreen/ipts/payload.h | 14 + + .../touchscreen/ipts/protocol/commands.h | 61 ++++ + .../input/touchscreen/ipts/protocol/data.h | 30 ++ .../input/touchscreen/ipts/protocol/events.h | 29 ++ - .../touchscreen/ipts/protocol/responses.h | 40 +++ - .../input/touchscreen/ipts/protocol/touch.h | 62 ++++ - drivers/input/touchscreen/ipts/receiver.c | 266 ++++++++++++++++++ + .../touchscreen/ipts/protocol/feedback.h | 30 ++ + .../input/touchscreen/ipts/protocol/payload.h | 47 ++++ + .../touchscreen/ipts/protocol/responses.h | 62 ++++ + .../touchscreen/ipts/protocol/singletouch.h | 17 ++ + .../input/touchscreen/ipts/protocol/stylus.h | 51 ++++ + drivers/input/touchscreen/ipts/receiver.c | 265 ++++++++++++++++++ drivers/input/touchscreen/ipts/receiver.h | 8 + drivers/input/touchscreen/ipts/resources.c | 131 +++++++++ drivers/input/touchscreen/ipts/resources.h | 11 + - drivers/input/touchscreen/ipts/singletouch.c | 56 ++++ - drivers/input/touchscreen/ipts/singletouch.h | 13 + - drivers/input/touchscreen/ipts/stylus.c | 159 +++++++++++ - drivers/input/touchscreen/ipts/stylus.h | 13 + + drivers/input/touchscreen/ipts/singletouch.c | 64 +++++ + drivers/input/touchscreen/ipts/singletouch.h | 14 + + drivers/input/touchscreen/ipts/stylus.c | 191 +++++++++++++ + drivers/input/touchscreen/ipts/stylus.h | 14 + drivers/misc/mei/hw-me-regs.h | 2 + drivers/misc/mei/pci-me.c | 2 + include/uapi/linux/input.h | 1 + - 32 files changed, 1595 insertions(+) + 37 files changed, 1734 insertions(+) create mode 100644 drivers/input/touchscreen/ipts/Kconfig create mode 100644 drivers/input/touchscreen/ipts/Makefile create mode 100644 drivers/input/touchscreen/ipts/context.h create mode 100644 drivers/input/touchscreen/ipts/control.c create mode 100644 drivers/input/touchscreen/ipts/control.h - create mode 100644 drivers/input/touchscreen/ipts/devices.c - create mode 100644 drivers/input/touchscreen/ipts/devices.h + create mode 100644 drivers/input/touchscreen/ipts/data.c + create mode 100644 drivers/input/touchscreen/ipts/data.h create mode 100644 drivers/input/touchscreen/ipts/hid.c create mode 100644 drivers/input/touchscreen/ipts/hid.h create mode 100644 drivers/input/touchscreen/ipts/init.c @@ -51,11 +56,16 @@ Subject: [PATCH 7/7] ipts create mode 100644 drivers/input/touchscreen/ipts/math.h create mode 100644 drivers/input/touchscreen/ipts/params.c create mode 100644 drivers/input/touchscreen/ipts/params.h + create mode 100644 drivers/input/touchscreen/ipts/payload.c + create mode 100644 drivers/input/touchscreen/ipts/payload.h create mode 100644 drivers/input/touchscreen/ipts/protocol/commands.h - create mode 100644 drivers/input/touchscreen/ipts/protocol/enums.h + create mode 100644 drivers/input/touchscreen/ipts/protocol/data.h create mode 100644 drivers/input/touchscreen/ipts/protocol/events.h + create mode 100644 drivers/input/touchscreen/ipts/protocol/feedback.h + create mode 100644 drivers/input/touchscreen/ipts/protocol/payload.h create mode 100644 drivers/input/touchscreen/ipts/protocol/responses.h - create mode 100644 drivers/input/touchscreen/ipts/protocol/touch.h + create mode 100644 drivers/input/touchscreen/ipts/protocol/singletouch.h + create mode 100644 drivers/input/touchscreen/ipts/protocol/stylus.h create mode 100644 drivers/input/touchscreen/ipts/receiver.c create mode 100644 drivers/input/touchscreen/ipts/receiver.h create mode 100644 drivers/input/touchscreen/ipts/resources.c @@ -112,10 +122,10 @@ index 000000000000..d3c530dafa94 + module will be called ipts. diff --git a/drivers/input/touchscreen/ipts/Makefile b/drivers/input/touchscreen/ipts/Makefile new file mode 100644 -index 000000000000..d80808175788 +index 000000000000..0f7c904e7317 --- /dev/null +++ b/drivers/input/touchscreen/ipts/Makefile -@@ -0,0 +1,16 @@ +@@ -0,0 +1,17 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Makefile for the IPTS touchscreen driver @@ -123,18 +133,19 @@ index 000000000000..d80808175788 + +obj-$(CONFIG_TOUCHSCREEN_IPTS) += ipts.o +ipts-objs := control.o -+ipts-objs += devices.o ++ipts-objs += data.o +ipts-objs += hid.o +ipts-objs += init.o +ipts-objs += math.o +ipts-objs += params.o ++ipts-objs += payload.o +ipts-objs += receiver.o +ipts-objs += resources.o +ipts-objs += singletouch.o +ipts-objs += stylus.o diff --git a/drivers/input/touchscreen/ipts/context.h b/drivers/input/touchscreen/ipts/context.h new file mode 100644 -index 000000000000..97a6e13c30c5 +index 000000000000..13ea03b6482e --- /dev/null +++ b/drivers/input/touchscreen/ipts/context.h @@ -0,0 +1,61 @@ @@ -148,13 +159,15 @@ index 000000000000..97a6e13c30c5 +#include +#include + -+#include "devices.h" -+#include "protocol/enums.h" ++#include "protocol/commands.h" +#include "protocol/responses.h" + -+/* -+ * IPTS driver states -+ */ ++/* HACK: Workaround for DKMS build without BUS_MEI patch */ ++#ifndef BUS_MEI ++#define BUS_MEI 0x44 ++#endif ++ ++/* IPTS driver states */ +enum ipts_host_status { + IPTS_HOST_STATUS_NONE, + IPTS_HOST_STATUS_INIT, @@ -165,7 +178,6 @@ index 000000000000..97a6e13c30c5 +}; + +struct ipts_buffer_info { -+ u32 size; + u8 *address; + dma_addr_t dma_address; +}; @@ -174,12 +186,11 @@ index 000000000000..97a6e13c30c5 + struct mei_cl_device *client_dev; + struct device *dev; + struct ipts_device_info device_info; -+ struct ipts_device_config device_cfg; + + enum ipts_host_status status; + enum ipts_sensor_mode mode; + -+ struct ipts_buffer_info touch_data[16]; ++ struct ipts_buffer_info data[16]; + struct ipts_buffer_info feedback[16]; + struct ipts_buffer_info doorbell; + @@ -191,7 +202,7 @@ index 000000000000..97a6e13c30c5 + struct ipts_buffer_info host2me; + + struct task_struct *receiver_loop; -+ struct task_struct *hid_loop; ++ struct task_struct *data_loop; + + struct input_dev *stylus; + struct input_dev *singletouch; @@ -201,21 +212,21 @@ index 000000000000..97a6e13c30c5 +#endif /* _IPTS_CONTEXT_H_ */ diff --git a/drivers/input/touchscreen/ipts/control.c b/drivers/input/touchscreen/ipts/control.c new file mode 100644 -index 000000000000..66ccea1b0a74 +index 000000000000..9179eca66558 --- /dev/null +++ b/drivers/input/touchscreen/ipts/control.c -@@ -0,0 +1,93 @@ +@@ -0,0 +1,94 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include + +#include "context.h" ++#include "data.h" +#include "params.h" +#include "protocol/commands.h" -+#include "protocol/enums.h" +#include "protocol/events.h" -+#include "protocol/touch.h" ++#include "protocol/feedback.h" +#include "resources.h" + +int ipts_control_send(struct ipts_context *ipts, @@ -287,6 +298,7 @@ index 000000000000..66ccea1b0a74 + if (old_status < IPTS_HOST_STATUS_RESOURCE_READY) + return; + ++ ipts_data_free(ipts); + ipts_resources_free(ipts); +} + @@ -322,107 +334,15 @@ index 000000000000..e57609c85d62 + u32 buffer, u32 transaction); + +#endif /* _IPTS_CONTROL_H_ */ -diff --git a/drivers/input/touchscreen/ipts/devices.c b/drivers/input/touchscreen/ipts/devices.c +diff --git a/drivers/input/touchscreen/ipts/data.c b/drivers/input/touchscreen/ipts/data.c new file mode 100644 -index 000000000000..10593a85e083 +index 000000000000..568bf04f7ea6 --- /dev/null -+++ b/drivers/input/touchscreen/ipts/devices.c -@@ -0,0 +1,46 @@ -+// SPDX-License-Identifier: GPL-2.0-or-later -+ -+#include -+#include -+ -+#include "devices.h" -+ -+static const struct ipts_device_config ipts_devices[] = { -+ { -+ .vendor_id = 0x1B96, -+ .device_id = 0x006A, -+ .max_stylus_pressure = 1024, -+ .stylus_protocol = IPTS_STYLUS_PROTOCOL_GEN1, -+ }, -+ { -+ .vendor_id = 0x1B96, -+ .device_id = 0x005e, -+ .max_stylus_pressure = 1024, -+ .stylus_protocol = IPTS_STYLUS_PROTOCOL_GEN1, -+ }, -+}; -+ -+struct ipts_device_config ipts_devices_get_config(u32 vendor, u32 device) -+{ -+ int i; -+ struct ipts_device_config cfg; -+ -+ for (i = 0; i < ARRAY_SIZE(ipts_devices); i++) { -+ cfg = ipts_devices[i]; -+ -+ if (cfg.vendor_id != vendor) -+ continue; -+ if (cfg.device_id != device) -+ continue; -+ -+ return cfg; -+ } -+ -+ // No device was found, so return a default config -+ cfg.vendor_id = vendor; -+ cfg.device_id = device; -+ cfg.max_stylus_pressure = 4096; -+ cfg.stylus_protocol = IPTS_STYLUS_PROTOCOL_GEN2; -+ -+ return cfg; -+} -diff --git a/drivers/input/touchscreen/ipts/devices.h b/drivers/input/touchscreen/ipts/devices.h -new file mode 100644 -index 000000000000..9bf8da9fbfab ---- /dev/null -+++ b/drivers/input/touchscreen/ipts/devices.h -@@ -0,0 +1,33 @@ -+/* SPDX-License-Identifier: GPL-2.0-or-later */ -+ -+#ifndef _IPTS_DEVICES_H_ -+#define _IPTS_DEVICES_H_ -+ -+#include -+ -+/* -+ * These names describe the different iterations of the IPTS stylus protocol. -+ * -+ * IPTS_STYLUS_PROTOCOL_GEN1 can be found on devices that don't have -+ * support for tilt, and only 1024 pressure levels. (Using NTRIG digitizers) -+ * -+ * IPTS_STYLUS_PROTOCOL_GEN2 can be found on devices that support tilting -+ * the stylus, with 4096 levels of pressure. (Using MS digitizers) -+ * -+ * New generations have to be added as they are discovered. -+ */ -+enum ipts_stylus_protocol { -+ IPTS_STYLUS_PROTOCOL_GEN1, -+ IPTS_STYLUS_PROTOCOL_GEN2 -+}; -+ -+struct ipts_device_config { -+ u32 vendor_id; -+ u32 device_id; -+ u32 max_stylus_pressure; -+ enum ipts_stylus_protocol stylus_protocol; -+}; -+ -+struct ipts_device_config ipts_devices_get_config(u32 vendor, u32 device); -+ -+#endif /* _IPTS_DEVICES_H_ */ -diff --git a/drivers/input/touchscreen/ipts/hid.c b/drivers/input/touchscreen/ipts/hid.c -new file mode 100644 -index 000000000000..866e8f02864f ---- /dev/null -+++ b/drivers/input/touchscreen/ipts/hid.c -@@ -0,0 +1,126 @@ ++++ b/drivers/input/touchscreen/ipts/data.c +@@ -0,0 +1,107 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +#include -+#include +#include +#include + @@ -430,42 +350,16 @@ index 000000000000..866e8f02864f +#include "control.h" +#include "hid.h" +#include "params.h" -+#include "protocol/enums.h" -+#include "protocol/touch.h" -+#include "singletouch.h" -+#include "stylus.h" ++#include "payload.h" ++#include "protocol/data.h" + -+static enum ipts_report_type ipts_hid_parse_report_type( -+ struct ipts_context *ipts, struct ipts_touch_data *data) -+{ -+ // If the buffer contains HID data, we are in single touch mode -+ // -+ // On gen7 IPTS will send other data using HID reports, -+ // so we have to additionally filter out the touch reports. -+ if (data->type == IPTS_TOUCH_DATA_TYPE_HID_REPORT && -+ data->data[0] == 0x40) -+ return IPTS_REPORT_TYPE_SINGLETOUCH; -+ -+ // If the buffer doesn't contain touch data -+ // we don't care about it -+ if (data->type != IPTS_TOUCH_DATA_TYPE_FRAME) -+ return IPTS_REPORT_TYPE_MAX; -+ -+ // If the number 0x6 is written at offset 14, -+ // the report describes a stylus -+ if (data->data[14] == 0x6) -+ return IPTS_REPORT_TYPE_STYLUS; -+ -+ return IPTS_REPORT_TYPE_MAX; -+} -+ -+static void ipts_hid_handle_input(struct ipts_context *ipts, int buffer_id) ++static void ipts_data_handle_input(struct ipts_context *ipts, int buffer_id) +{ + struct ipts_buffer_info buffer; -+ struct ipts_touch_data *data; ++ struct ipts_data *data; + -+ buffer = ipts->touch_data[buffer_id]; -+ data = (struct ipts_touch_data *)buffer.address; ++ buffer = ipts->data[buffer_id]; ++ data = (struct ipts_data *)buffer.address; + + if (ipts_params.debug) { + dev_info(ipts->dev, "Buffer %d\n", buffer_id); @@ -473,14 +367,14 @@ index 000000000000..866e8f02864f + data->data, data->size, false); + } + -+ switch (ipts_hid_parse_report_type(ipts, data)) { -+ case IPTS_REPORT_TYPE_STYLUS: -+ ipts_stylus_parse_report(ipts, data); ++ switch (data->type) { ++ case IPTS_DATA_TYPE_PAYLOAD: ++ ipts_payload_handle_input(ipts, data); + break; -+ case IPTS_REPORT_TYPE_SINGLETOUCH: -+ ipts_singletouch_parse_report(ipts, data); ++ case IPTS_DATA_TYPE_HID_REPORT: ++ ipts_hid_handle_input(ipts, data); + break; -+ case IPTS_REPORT_TYPE_MAX: ++ default: + // ignore + break; + } @@ -488,18 +382,19 @@ index 000000000000..866e8f02864f + ipts_control_send_feedback(ipts, buffer_id, data->transaction); +} + -+int ipts_hid_loop(void *data) ++int ipts_data_loop(void *data) +{ -+ time64_t ll_timeout; -+ u32 doorbell, last_doorbell; ++ time64_t timeout; ++ u32 doorbell; ++ u32 last_doorbell; + struct ipts_context *ipts; + -+ ll_timeout = ktime_get_seconds() + 5; ++ timeout = ktime_get_seconds() + 5; + ipts = (struct ipts_context *)data; + last_doorbell = 0; + doorbell = 0; + -+ dev_info(ipts->dev, "Starting input loop\n"); ++ dev_info(ipts->dev, "Starting data loop\n"); + + while (!kthread_should_stop()) { + if (ipts->status != IPTS_HOST_STATUS_STARTED) { @@ -507,70 +402,135 @@ index 000000000000..866e8f02864f + continue; + } + -+ // IPTS will increment the doorbell after it filled up -+ // all of the touch data buffers. If the doorbell didn't -+ // change, there is no work for us to do. ++ // IPTS will increment the doorbell after if filled up one of ++ // the data buffers. If the doorbell didn't change, there is ++ // no work for us to do. Otherwise, the value of the doorbell ++ // will stand for the *next* buffer thats going to be filled. + doorbell = *(u32 *)ipts->doorbell.address; + if (doorbell == last_doorbell) + goto sleep; + -+ ll_timeout = ktime_get_seconds() + 5; ++ timeout = ktime_get_seconds() + 5; + + while (last_doorbell != doorbell) { -+ ipts_hid_handle_input(ipts, last_doorbell % 16); ++ ipts_data_handle_input(ipts, last_doorbell % 16); + last_doorbell++; + } +sleep: -+ if (ll_timeout > ktime_get_seconds()) ++ if (timeout > ktime_get_seconds()) + usleep_range(5000, 30000); + else + msleep(200); + } + -+ dev_info(ipts->dev, "Stopping input loop\n"); ++ dev_info(ipts->dev, "Stopping data loop\n"); + return 0; +} + ++int ipts_data_init(struct ipts_context *ipts) ++{ ++ int ret; ++ ++ ret = ipts_payload_init(ipts); ++ if (ret) ++ return ret; ++ ++ ret = ipts_hid_init(ipts); ++ if (ret) ++ return ret; ++ ++ return 0; ++} ++ ++void ipts_data_free(struct ipts_context *ipts) ++{ ++ ipts_payload_free(ipts); ++ ipts_hid_free(ipts); ++} +diff --git a/drivers/input/touchscreen/ipts/data.h b/drivers/input/touchscreen/ipts/data.h +new file mode 100644 +index 000000000000..fa72c1be0945 +--- /dev/null ++++ b/drivers/input/touchscreen/ipts/data.h +@@ -0,0 +1,12 @@ ++/* SPDX-License-Identifier: GPL-2.0-or-later */ ++ ++#ifndef _IPTS_DATA_H_ ++#define _IPTS_DATA_H_ ++ ++#include "context.h" ++ ++int ipts_data_loop(void *data); ++int ipts_data_init(struct ipts_context *ipts); ++void ipts_data_free(struct ipts_context *ipts); ++ ++#endif /* _IPTS_DATA_H_ */ +diff --git a/drivers/input/touchscreen/ipts/hid.c b/drivers/input/touchscreen/ipts/hid.c +new file mode 100644 +index 000000000000..2642990b8c42 +--- /dev/null ++++ b/drivers/input/touchscreen/ipts/hid.c +@@ -0,0 +1,38 @@ ++// SPDX-License-Identifier: GPL-2.0-or-later ++ ++#include "context.h" ++#include "protocol/data.h" ++#include "singletouch.h" ++ ++/* ++ * IPTS on surface gen7 appears to make heavy use of HID reports, unlike ++ * previous generations. This file can be used to implement handling for ++ * them in the future, seperated from the actual singletouch implementation. ++ */ ++ ++void ipts_hid_handle_input(struct ipts_context *ipts, struct ipts_data *data) ++{ ++ // Make sure that we only handle singletouch inputs ++ // 40 is the report id of the singletouch device in the generic ++ // IPTS HID descriptor. ++ if (data->data[0] != 0x40) ++ return; ++ ++ ipts_singletouch_handle_input(ipts, data); ++} ++ +int ipts_hid_init(struct ipts_context *ipts) +{ + int ret; + -+ ret = ipts_stylus_init(ipts); -+ if (ret) -+ return ret; -+ + ret = ipts_singletouch_init(ipts); + if (ret) + return ret; + + return 0; +} ++ ++void ipts_hid_free(struct ipts_context *ipts) ++{ ++ ipts_singletouch_free(ipts); ++} diff --git a/drivers/input/touchscreen/ipts/hid.h b/drivers/input/touchscreen/ipts/hid.h new file mode 100644 -index 000000000000..c6f2ca814c2f +index 000000000000..e6cf38fce454 --- /dev/null +++ b/drivers/input/touchscreen/ipts/hid.h -@@ -0,0 +1,17 @@ +@@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#ifndef _IPTS_HID_H_ +#define _IPTS_HID_H_ + +#include "context.h" ++#include "protocol/data.h" + -+enum ipts_report_type { -+ IPTS_REPORT_TYPE_STYLUS, -+ IPTS_REPORT_TYPE_SINGLETOUCH, -+ IPTS_REPORT_TYPE_MAX -+}; -+ ++int ipts_hid_handle_input(struct ipts_context *ipts, struct ipts_data *data); +int ipts_hid_init(struct ipts_context *ipts); -+int ipts_hid_loop(void *data); ++void ipts_hid_free(struct ipts_context *ipts); + +#endif /* _IPTS_HID_H_ */ diff --git a/drivers/input/touchscreen/ipts/init.c b/drivers/input/touchscreen/ipts/init.c new file mode 100644 -index 000000000000..46f7c7ed1534 +index 000000000000..fb70d55542af --- /dev/null +++ b/drivers/input/touchscreen/ipts/init.c @@ -0,0 +1,93 @@ @@ -583,7 +543,7 @@ index 000000000000..46f7c7ed1534 + +#include "context.h" +#include "control.h" -+#include "hid.h" ++#include "data.h" +#include "receiver.h" + +#define IPTS_MEI_UUID UUID_LE(0x3e8d0870, 0x271a, 0x4208, \ @@ -628,8 +588,8 @@ index 000000000000..46f7c7ed1534 + + ipts->receiver_loop = kthread_run(ipts_receiver_loop, (void *)ipts, + "ipts_receiver_loop"); -+ ipts->hid_loop = kthread_run(ipts_hid_loop, (void *)ipts, -+ "ipts_hid_loop"); ++ ipts->data_loop = kthread_run(ipts_data_loop, (void *)ipts, ++ "ipts_data_loop"); + + ipts_control_start(ipts); + @@ -645,7 +605,7 @@ index 000000000000..46f7c7ed1534 + ipts_control_stop(ipts); + mei_cldev_disable(cldev); + kthread_stop(ipts->receiver_loop); -+ kthread_stop(ipts->hid_loop); ++ kthread_stop(ipts->data_loop); + + return 0; +} @@ -857,12 +817,90 @@ index 000000000000..1f992a3bc21b +extern struct ipts_modparams ipts_params; + +#endif /* _IPTS_PARAMS_H_ */ +diff --git a/drivers/input/touchscreen/ipts/payload.c b/drivers/input/touchscreen/ipts/payload.c +new file mode 100644 +index 000000000000..3572ddc0f2fb +--- /dev/null ++++ b/drivers/input/touchscreen/ipts/payload.c +@@ -0,0 +1,52 @@ ++// SPDX-License-Identifier: GPL-2.0-or-later ++ ++#include ++ ++#include "context.h" ++#include "protocol/data.h" ++#include "protocol/payload.h" ++#include "stylus.h" ++ ++void ipts_payload_handle_input(struct ipts_context *ipts, ++ struct ipts_data *data) ++{ ++ u32 i, offset; ++ struct ipts_payload *payload; ++ struct ipts_payload_frame *frame; ++ ++ payload = (struct ipts_payload *)data->data; ++ offset = 0; ++ ++ for (i = 0; i < payload->num_frames; i++) { ++ frame = (struct ipts_payload_frame *)&payload->data[offset]; ++ offset += sizeof(struct ipts_payload_frame) + frame->size; ++ ++ switch (frame->type) { ++ case IPTS_PAYLOAD_FRAME_TYPE_STYLUS: ++ ipts_stylus_handle_input(ipts, frame); ++ break; ++ case IPTS_PAYLOAD_FRAME_TYPE_TOUCH: ++ // ignored (for the moment) ++ break; ++ default: ++ // ignored ++ break; ++ } ++ } ++} ++ ++int ipts_payload_init(struct ipts_context *ipts) ++{ ++ int ret; ++ ++ ret = ipts_stylus_init(ipts); ++ if (ret) ++ return ret; ++ ++ return 0; ++} ++ ++void ipts_payload_free(struct ipts_context *ipts) ++{ ++ ipts_stylus_free(ipts); ++} +diff --git a/drivers/input/touchscreen/ipts/payload.h b/drivers/input/touchscreen/ipts/payload.h +new file mode 100644 +index 000000000000..6603714bb6fd +--- /dev/null ++++ b/drivers/input/touchscreen/ipts/payload.h +@@ -0,0 +1,14 @@ ++/* SPDX-License-Identifier: GPL-2.0-or-later */ ++ ++#ifndef _IPTS_PAYLOAD_H_ ++#define _IPTS_PAYLOAD_H_ ++ ++#include "context.h" ++#include "protocol/data.h" ++ ++void ipts_payload_handle_input(struct ipts_context *ipts, ++ struct ipts_data *data); ++int ipts_payload_init(struct ipts_context *ipts); ++void ipts_payload_free(struct ipts_context *ipts); ++ ++#endif /* _IPTS_PAYLOAD_H_ */ diff --git a/drivers/input/touchscreen/ipts/protocol/commands.h b/drivers/input/touchscreen/ipts/protocol/commands.h new file mode 100644 -index 000000000000..919a83264d05 +index 000000000000..2533dfb13584 --- /dev/null +++ b/drivers/input/touchscreen/ipts/protocol/commands.h -@@ -0,0 +1,55 @@ +@@ -0,0 +1,61 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#ifndef _IPTS_PROTOCOL_COMMANDS_H_ @@ -871,14 +909,20 @@ index 000000000000..919a83264d05 +#include +#include + ++enum ipts_sensor_mode { ++ IPTS_SENSOR_MODE_SINGLETOUCH = 0, ++ IPTS_SENSOR_MODE_MULTITOUCH, ++ IPTS_SENSOR_MODE_MAX ++}; ++ +struct ipts_set_mode_cmd { + u32 sensor_mode; + u8 reserved[12]; +} __packed; + +struct ipts_set_mem_window_cmd { -+ u32 touch_data_buffer_addr_lower[16]; -+ u32 touch_data_buffer_addr_upper[16]; ++ u32 data_buffer_addr_lower[16]; ++ u32 data_buffer_addr_upper[16]; + u32 workqueue_addr_lower; + u32 workqueue_addr_upper; + u32 doorbell_addr_lower; @@ -918,71 +962,42 @@ index 000000000000..919a83264d05 +static_assert(sizeof(struct ipts_command) == 324); + +#endif /* _IPTS_PROTOCOL_COMMANDS_H_ */ -diff --git a/drivers/input/touchscreen/ipts/protocol/enums.h b/drivers/input/touchscreen/ipts/protocol/enums.h +diff --git a/drivers/input/touchscreen/ipts/protocol/data.h b/drivers/input/touchscreen/ipts/protocol/data.h new file mode 100644 -index 000000000000..ae952c4cf83c +index 000000000000..148e0545b2e4 --- /dev/null -+++ b/drivers/input/touchscreen/ipts/protocol/enums.h -@@ -0,0 +1,59 @@ ++++ b/drivers/input/touchscreen/ipts/protocol/data.h +@@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + -+#ifndef _IPTS_PROTOCOL_ENUMS_H_ -+#define _IPTS_PROTOCOL_ENUMS_H_ ++#ifndef _IPTS_PROTOCOL_DATA_H_ ++#define _IPTS_PROTOCOL_DATA_H_ + -+/* -+ * IPTS ME state -+ */ -+enum ipts_me_status { -+ IPTS_ME_STATUS_SUCCESS = 0, -+ IPTS_ME_STATUS_INVALID_PARAMS, -+ IPTS_ME_STATUS_ACCESS_DENIED, -+ IPTS_ME_STATUS_CMD_SIZE_ERROR, -+ IPTS_ME_STATUS_NOT_READY, -+ IPTS_ME_STATUS_REQUEST_OUTSTANDING, -+ IPTS_ME_STATUS_NO_SENSOR_FOUND, -+ IPTS_ME_STATUS_OUT_OF_MEMORY, -+ IPTS_ME_STATUS_INTERNAL_ERROR, -+ IPTS_ME_STATUS_SENSOR_DISABLED, -+ IPTS_ME_STATUS_COMPAT_CHECK_FAIL, -+ IPTS_ME_STATUS_SENSOR_EXPECTED_RESET, -+ IPTS_ME_STATUS_SENSOR_UNEXPECTED_RESET, -+ IPTS_ME_STATUS_RESET_FAILED, -+ IPTS_ME_STATUS_TIMEOUT, -+ IPTS_ME_STATUS_TEST_MODE_FAIL, -+ IPTS_ME_STATUS_SENSOR_FAIL_FATAL, -+ IPTS_ME_STATUS_SENSOR_FAIL_NONFATAL, -+ IPTS_ME_STATUS_INVALID_DEVICE_CAPS, -+ IPTS_ME_STATUS_QUIESCE_IO_IN_PROGRESS, -+ IPTS_ME_STATUS_MAX ++#include ++#include ++ ++enum ipts_data_type { ++ IPTS_DATA_TYPE_PAYLOAD = 0, ++ IPTS_DATA_TYPE_ERROR, ++ IPTS_DATA_TYPE_VENDOR_DATA, ++ IPTS_DATA_TYPE_HID_REPORT, ++ IPTS_DATA_TYPE_GET_FEATURES, ++ IPTS_DATA_TYPE_MAX +}; + -+enum ipts_sensor_mode { -+ IPTS_SENSOR_MODE_SINGLETOUCH = 0, -+ IPTS_SENSOR_MODE_MULTITOUCH, -+ IPTS_SENSOR_MODE_MAX -+}; ++struct ipts_data { ++ u32 type; ++ u32 size; ++ u32 buffer; ++ u8 reserved1[20]; ++ u8 transaction; ++ u8 reserved2[31]; ++ u8 data[]; ++} __packed; + -+enum ipts_touch_data_type { -+ IPTS_TOUCH_DATA_TYPE_FRAME = 0, -+ IPTS_TOUCH_DATA_TYPE_ERROR, -+ IPTS_TOUCH_DATA_TYPE_VENDOR_DATA, -+ IPTS_TOUCH_DATA_TYPE_HID_REPORT, -+ IPTS_TOUCH_DATA_TYPE_GET_FEATURES, -+ IPTS_TOUCH_DATA_TYPE_MAX -+}; ++static_assert(sizeof(struct ipts_data) == 64); + -+enum ipts_feedback_type { -+ IPTS_FEEDBACK_TYPE_NONE = 0, -+ IPTS_FEEDBACK_TYPE_SOFT_RESET, -+ IPTS_FEEDBACK_TYPE_GOTO_ARMED, -+ IPTS_FEEDBACK_TYPE_GOTO_SENSING, -+ IPTS_FEEDBACK_TYPE_GOTO_SLEEP, -+ IPTS_FEEDBACK_TYPE_GOTO_DOZE, -+ IPTS_FEEDBACK_TYPE_HARD_RESET, -+ IPTS_FEEDBACK_TYPE_MAX -+}; -+ -+#endif /* _IPTS_PROTOCOL_ENUMS_H_ */ ++#endif /* _IPTS_PROTOCOL_DATA_H_ */ diff --git a/drivers/input/touchscreen/ipts/protocol/events.h b/drivers/input/touchscreen/ipts/protocol/events.h new file mode 100644 index 000000000000..f8b771f90bd2 @@ -1018,12 +1033,101 @@ index 000000000000..f8b771f90bd2 +}; + +#endif /* _IPTS_PROTOCOL_EVENTS_H_ */ +diff --git a/drivers/input/touchscreen/ipts/protocol/feedback.h b/drivers/input/touchscreen/ipts/protocol/feedback.h +new file mode 100644 +index 000000000000..8b3d8b689ee8 +--- /dev/null ++++ b/drivers/input/touchscreen/ipts/protocol/feedback.h +@@ -0,0 +1,30 @@ ++/* SPDX-License-Identifier: GPL-2.0-or-later */ ++ ++#ifndef _IPTS_PROTOCOL_FEEDBACK_H_ ++#define _IPTS_PROTOCOL_FEEDBACK_H_ ++ ++#include ++#include ++ ++enum ipts_feedback_type { ++ IPTS_FEEDBACK_TYPE_NONE = 0, ++ IPTS_FEEDBACK_TYPE_SOFT_RESET, ++ IPTS_FEEDBACK_TYPE_GOTO_ARMED, ++ IPTS_FEEDBACK_TYPE_GOTO_SENSING, ++ IPTS_FEEDBACK_TYPE_GOTO_SLEEP, ++ IPTS_FEEDBACK_TYPE_GOTO_DOZE, ++ IPTS_FEEDBACK_TYPE_HARD_RESET, ++ IPTS_FEEDBACK_TYPE_MAX ++}; ++ ++struct ipts_feedback { ++ u32 type; ++ u32 size; ++ u32 transaction; ++ u8 reserved[52]; ++ u8 data[]; ++} __packed; ++ ++static_assert(sizeof(struct ipts_feedback) == 64); ++ ++#endif /* _IPTS_PROTOCOL_FEEDBACK_H_ */ +diff --git a/drivers/input/touchscreen/ipts/protocol/payload.h b/drivers/input/touchscreen/ipts/protocol/payload.h +new file mode 100644 +index 000000000000..f46da4ea81f2 +--- /dev/null ++++ b/drivers/input/touchscreen/ipts/protocol/payload.h +@@ -0,0 +1,47 @@ ++/* SPDX-License-Identifier: GPL-2.0-or-later */ ++ ++#ifndef _IPTS_PROTOCOL_PAYLOAD_H_ ++#define _IPTS_PROTOCOL_PAYLOAD_H_ ++ ++#include ++#include ++ ++enum ipts_payload_frame_type { ++ IPTS_PAYLOAD_FRAME_TYPE_STYLUS = 6, ++ IPTS_PAYLOAD_FRAME_TYPE_TOUCH = 8, ++}; ++ ++enum ipts_report_type { ++ IPTS_REPORT_TYPE_TOUCH_HEATMAP_DIM = 0x0403, ++ IPTS_REPORT_TYPE_TOUCH_HEATMAP = 0x0425, ++ IPTS_REPORT_TYPE_STYLUS_NO_TILT = 0x0410, ++ IPTS_REPORT_TYPE_STYLUS_TILT = 0x0461, ++ IPTS_REPORT_TYPE_STYLUS_TILT_SERIAL = 0x0460, ++}; ++ ++struct ipts_payload { ++ u32 counter; ++ u32 num_frames; ++ u8 reserved[4]; ++ u8 data[]; ++} __packed; ++ ++struct ipts_payload_frame { ++ u16 index; ++ u16 type; ++ u32 size; ++ u8 reserved[8]; ++ u8 data[]; ++} __packed; ++ ++struct ipts_report { ++ u16 type; ++ u16 size; ++ u8 data[]; ++} __packed; ++ ++static_assert(sizeof(struct ipts_payload) == 12); ++static_assert(sizeof(struct ipts_payload_frame) == 16); ++static_assert(sizeof(struct ipts_report) == 4); ++ ++#endif /* _IPTS_PROTOCOL_PAYLOAD_H_ */ diff --git a/drivers/input/touchscreen/ipts/protocol/responses.h b/drivers/input/touchscreen/ipts/protocol/responses.h new file mode 100644 -index 000000000000..7f8902a1486b +index 000000000000..27153d82a5d6 --- /dev/null +++ b/drivers/input/touchscreen/ipts/protocol/responses.h -@@ -0,0 +1,40 @@ +@@ -0,0 +1,62 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#ifndef _IPTS_PROTOCOL_RESPONSES_H_ @@ -1032,7 +1136,29 @@ index 000000000000..7f8902a1486b +#include +#include + -+#include "enums.h" ++enum ipts_me_status { ++ IPTS_ME_STATUS_SUCCESS = 0, ++ IPTS_ME_STATUS_INVALID_PARAMS, ++ IPTS_ME_STATUS_ACCESS_DENIED, ++ IPTS_ME_STATUS_CMD_SIZE_ERROR, ++ IPTS_ME_STATUS_NOT_READY, ++ IPTS_ME_STATUS_REQUEST_OUTSTANDING, ++ IPTS_ME_STATUS_NO_SENSOR_FOUND, ++ IPTS_ME_STATUS_OUT_OF_MEMORY, ++ IPTS_ME_STATUS_INTERNAL_ERROR, ++ IPTS_ME_STATUS_SENSOR_DISABLED, ++ IPTS_ME_STATUS_COMPAT_CHECK_FAIL, ++ IPTS_ME_STATUS_SENSOR_EXPECTED_RESET, ++ IPTS_ME_STATUS_SENSOR_UNEXPECTED_RESET, ++ IPTS_ME_STATUS_RESET_FAILED, ++ IPTS_ME_STATUS_TIMEOUT, ++ IPTS_ME_STATUS_TEST_MODE_FAIL, ++ IPTS_ME_STATUS_SENSOR_FAIL_FATAL, ++ IPTS_ME_STATUS_SENSOR_FAIL_NONFATAL, ++ IPTS_ME_STATUS_INVALID_DEVICE_CAPS, ++ IPTS_ME_STATUS_QUIESCE_IO_IN_PROGRESS, ++ IPTS_ME_STATUS_MAX ++}; + +struct ipts_device_info { + u16 vendor_id; @@ -1041,7 +1167,7 @@ index 000000000000..7f8902a1486b + u32 fw_rev; + + /* Required size of one touch data buffer */ -+ u32 frame_size; ++ u32 data_size; + + /* Required size of one feedback buffer */ + u32 feedback_size; @@ -1064,38 +1190,57 @@ index 000000000000..7f8902a1486b +static_assert(sizeof(struct ipts_response) == 88); + +#endif /* _IPTS_PROTOCOL_RESPONSES_H_ */ -diff --git a/drivers/input/touchscreen/ipts/protocol/touch.h b/drivers/input/touchscreen/ipts/protocol/touch.h +diff --git a/drivers/input/touchscreen/ipts/protocol/singletouch.h b/drivers/input/touchscreen/ipts/protocol/singletouch.h new file mode 100644 -index 000000000000..86248c015a2e +index 000000000000..bf9912ee2af4 --- /dev/null -+++ b/drivers/input/touchscreen/ipts/protocol/touch.h -@@ -0,0 +1,62 @@ ++++ b/drivers/input/touchscreen/ipts/protocol/singletouch.h +@@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + -+#ifndef _IPTS_PROTOCOL_TOUCH_H_ -+#define _IPTS_PROTOCOL_TOUCH_H_ ++#ifndef _IPTS_PROTOCOL_SINGLETOUCH_H_ ++#define _IPTS_PROTOCOL_SINGLETOUCH_H_ + ++#include +#include + -+struct ipts_touch_data { -+ u32 type; -+ u32 size; -+ u32 buffer; -+ u8 reserved1[20]; -+ u8 transaction; -+ u8 reserved2[31]; -+ u8 data[]; ++struct ipts_singletouch_report { ++ u8 touch; ++ u16 x; ++ u16 y; +} __packed; + -+struct ipts_feedback { -+ u32 type; -+ u32 size; -+ u32 transaction; -+ u8 reserved[52]; -+ u8 data[]; -+} __packed; ++static_assert(sizeof(struct ipts_singletouch_report) == 5); ++ ++#endif /* _IPTS_PROTOCOL_SINGLETOUCH_H_ */ +diff --git a/drivers/input/touchscreen/ipts/protocol/stylus.h b/drivers/input/touchscreen/ipts/protocol/stylus.h +new file mode 100644 +index 000000000000..1ae63c49bc07 +--- /dev/null ++++ b/drivers/input/touchscreen/ipts/protocol/stylus.h +@@ -0,0 +1,51 @@ ++/* SPDX-License-Identifier: GPL-2.0-or-later */ ++ ++#ifndef _IPTS_PROTOCOL_STYLUS_H_ ++#define _IPTS_PROTOCOL_STYLUS_H_ ++ ++#include ++#include + +struct ipts_stylus_report { ++ u8 reports; ++ u8 reserved[3]; ++ u8 data[]; ++} __packed; ++ ++struct ipts_stylus_report_serial { ++ u8 reports; ++ u8 reserved[3]; ++ u32 serial; ++ u8 data[]; ++} __packed; ++ ++struct ipts_stylus_report_data { + u16 timestamp; + u16 mode; + u16 x; @@ -1106,7 +1251,7 @@ index 000000000000..86248c015a2e + u16 reserved; +} __packed; + -+struct ipts_stylus_report_gen1 { ++struct ipts_stylus_report_data_no_tilt { + u8 mode; + u16 x; + u16 y; @@ -1114,39 +1259,31 @@ index 000000000000..86248c015a2e + u8 reserved[5]; +} __packed; + -+struct ipts_singletouch_report { -+ u8 touch; -+ u16 x; -+ u16 y; -+} __packed; ++#define IPTS_STYLUS_REPORT_MODE_PROX BIT(0) ++#define IPTS_STYLUS_REPORT_MODE_TOUCH BIT(1) ++#define IPTS_STYLUS_REPORT_MODE_BUTTON BIT(2) ++#define IPTS_STYLUS_REPORT_MODE_ERASER BIT(3) + -+#define IPTS_STYLUS_REPORT_MODE_PROXIMITY BIT(0) -+#define IPTS_STYLUS_REPORT_MODE_TOUCH BIT(1) -+#define IPTS_STYLUS_REPORT_MODE_BUTTON BIT(2) -+#define IPTS_STYLUS_REPORT_MODE_RUBBER BIT(3) ++static_assert(sizeof(struct ipts_stylus_report) == 4); ++static_assert(sizeof(struct ipts_stylus_report_serial) == 8); ++static_assert(sizeof(struct ipts_stylus_report_data) == 16); ++static_assert(sizeof(struct ipts_stylus_report_data_no_tilt) == 12); + -+static_assert(sizeof(struct ipts_touch_data) == 64); -+static_assert(sizeof(struct ipts_feedback) == 64); -+static_assert(sizeof(struct ipts_stylus_report) == 16); -+static_assert(sizeof(struct ipts_stylus_report_gen1) == 12); -+static_assert(sizeof(struct ipts_singletouch_report) == 5); -+ -+#endif /* _IPTS_PROTOCOL_TOUCH_H_ */ ++#endif /* _IPTS_PAYLOAD_STYLUS_H_ */ diff --git a/drivers/input/touchscreen/ipts/receiver.c b/drivers/input/touchscreen/ipts/receiver.c new file mode 100644 -index 000000000000..06f4509ff1c4 +index 000000000000..ab283994c3e5 --- /dev/null +++ b/drivers/input/touchscreen/ipts/receiver.c -@@ -0,0 +1,266 @@ +@@ -0,0 +1,265 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +#include + +#include "context.h" +#include "control.h" -+#include "hid.h" ++#include "data.h" +#include "protocol/commands.h" -+#include "protocol/enums.h" +#include "protocol/events.h" +#include "protocol/responses.h" +#include "resources.h" @@ -1182,10 +1319,7 @@ index 000000000000..06f4509ff1c4 + ipts->device_info.vendor_id, + ipts->device_info.device_id); + -+ ipts->device_cfg = ipts_devices_get_config(ipts->device_info.vendor_id, -+ ipts->device_info.device_id); -+ -+ if (ipts_hid_init(ipts)) ++ if (ipts_data_init(ipts)) + return; + + *cmd_status = ipts_control_send(ipts, @@ -1234,11 +1368,11 @@ index 000000000000..06f4509ff1c4 + memset(&cmd, 0, sizeof(struct ipts_set_mem_window_cmd)); + + for (i = 0; i < 16; i++) { -+ cmd.touch_data_buffer_addr_lower[i] = -+ lower_32_bits(ipts->touch_data[i].dma_address); ++ cmd.data_buffer_addr_lower[i] = ++ lower_32_bits(ipts->data[i].dma_address); + -+ cmd.touch_data_buffer_addr_upper[i] = -+ upper_32_bits(ipts->touch_data[i].dma_address); ++ cmd.data_buffer_addr_upper[i] = ++ upper_32_bits(ipts->data[i].dma_address); + + cmd.feedback_buffer_addr_lower[i] = + lower_32_bits(ipts->feedback[i].dma_address); @@ -1255,7 +1389,7 @@ index 000000000000..06f4509ff1c4 + + cmd.host2me_addr_lower = lower_32_bits(ipts->host2me.dma_address); + cmd.host2me_addr_upper = upper_32_bits(ipts->host2me.dma_address); -+ cmd.host2me_size = ipts->device_info.frame_size; ++ cmd.host2me_size = ipts->device_info.data_size; + + cmd.workqueue_size = 8192; + cmd.workqueue_item_size = 16; @@ -1367,6 +1501,9 @@ index 000000000000..06f4509ff1c4 + break; + } + ++ if (ipts->status == IPTS_HOST_STATUS_STOPPING) ++ return 0; ++ + if (msg->status == IPTS_ME_STATUS_SENSOR_UNEXPECTED_RESET || + msg->status == IPTS_ME_STATUS_SENSOR_EXPECTED_RESET) { + dev_info(ipts->dev, "Sensor has been reset: %d\n", msg->status); @@ -1420,7 +1557,7 @@ index 000000000000..4d413a0abd4c +#endif /* _IPTS_RECEIVER_H_ */ diff --git a/drivers/input/touchscreen/ipts/resources.c b/drivers/input/touchscreen/ipts/resources.c new file mode 100644 -index 000000000000..b4bec3cb63fd +index 000000000000..704db9fdd3fd --- /dev/null +++ b/drivers/input/touchscreen/ipts/resources.c @@ -0,0 +1,131 @@ @@ -1437,10 +1574,10 @@ index 000000000000..b4bec3cb63fd + u32 feedback_buffer_size; + struct ipts_buffer_info *buffers; + -+ touch_buffer_size = ipts->device_info.frame_size; ++ touch_buffer_size = ipts->device_info.data_size; + feedback_buffer_size = ipts->device_info.feedback_size; + -+ buffers = ipts->touch_data; ++ buffers = ipts->data; + for (i = 0; i < 16; i++) { + if (!buffers[i].address) + continue; @@ -1499,10 +1636,10 @@ index 000000000000..b4bec3cb63fd + u32 feedback_buffer_size; + struct ipts_buffer_info *buffers; + -+ touch_buffer_size = ipts->device_info.frame_size; ++ touch_buffer_size = ipts->device_info.data_size; + feedback_buffer_size = ipts->device_info.feedback_size; + -+ buffers = ipts->touch_data; ++ buffers = ipts->data; + for (i = 0; i < 16; i++) { + buffers[i].address = dmam_alloc_coherent(ipts->dev, + touch_buffer_size, @@ -1574,22 +1711,21 @@ index 000000000000..cf9807b0dbe6 +#endif /* _IPTS_RESOURCES_H_ */ diff --git a/drivers/input/touchscreen/ipts/singletouch.c b/drivers/input/touchscreen/ipts/singletouch.c new file mode 100644 -index 000000000000..237dd89f5816 +index 000000000000..ed70444f649c --- /dev/null +++ b/drivers/input/touchscreen/ipts/singletouch.c -@@ -0,0 +1,56 @@ +@@ -0,0 +1,64 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +#include -+#include +#include + +#include "context.h" -+#include "protocol/enums.h" -+#include "protocol/touch.h" ++#include "protocol/data.h" ++#include "protocol/singletouch.h" + -+void ipts_singletouch_parse_report(struct ipts_context *ipts, -+ struct ipts_touch_data *data) ++void ipts_singletouch_handle_input(struct ipts_context *ipts, ++ struct ipts_data *data) +{ + struct ipts_singletouch_report *report = + (struct ipts_singletouch_report *)&data->data[1]; @@ -1605,7 +1741,7 @@ index 000000000000..237dd89f5816 +{ + int ret; + -+ ipts->singletouch = devm_input_allocate_device(ipts->dev); ++ ipts->singletouch = input_allocate_device(); + if (!ipts->singletouch) + return -ENOMEM; + @@ -1623,71 +1759,79 @@ index 000000000000..237dd89f5816 + ipts->singletouch->id.version = ipts->device_info.fw_rev; + + ipts->singletouch->phys = "heci3"; -+ ipts->singletouch->name = "Intel Precise Touchscreen (Singletouch)"; ++ ipts->singletouch->name = "IPTS Singletouch"; + + ret = input_register_device(ipts->singletouch); + if (ret) { -+ dev_err(ipts->dev, "Failed to register touch device: %d\n", -+ ret); ++ dev_err(ipts->dev, "Cannot register input device: %s (%d)\n", ++ ipts->singletouch->name, ret); ++ input_free_device(ipts->singletouch); + return ret; + } + + return 0; +} ++ ++void ipts_singletouch_free(struct ipts_context *ipts) ++{ ++ if (!ipts->singletouch) ++ return; ++ ++ input_unregister_device(ipts->singletouch); ++} diff --git a/drivers/input/touchscreen/ipts/singletouch.h b/drivers/input/touchscreen/ipts/singletouch.h new file mode 100644 -index 000000000000..6bcaf939c8e3 +index 000000000000..53207497a462 --- /dev/null +++ b/drivers/input/touchscreen/ipts/singletouch.h -@@ -0,0 +1,13 @@ +@@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#ifndef _IPTS_SINGLETOUCH_H_ +#define _IPTS_SINGLETOUCH_H_ + +#include "context.h" -+#include "protocol/touch.h" ++#include "protocol/data.h" + -+void ipts_singletouch_parse_report(struct ipts_context *ipts, -+ struct ipts_touch_data *data); ++void ipts_singletouch_handle_input(struct ipts_context *ipts, ++ struct ipts_data *data); +int ipts_singletouch_init(struct ipts_context *ipts); ++void ipts_singletouch_free(struct ipts_context *ipts); + +#endif /* _IPTS_SINGLETOUCH_H_ */ diff --git a/drivers/input/touchscreen/ipts/stylus.c b/drivers/input/touchscreen/ipts/stylus.c new file mode 100644 -index 000000000000..263aa133b706 +index 000000000000..dbb4fe0bf559 --- /dev/null +++ b/drivers/input/touchscreen/ipts/stylus.c -@@ -0,0 +1,159 @@ +@@ -0,0 +1,191 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + -+#include +#include +#include + +#include "context.h" -+#include "devices.h" +#include "math.h" -+#include "protocol/enums.h" -+#include "protocol/touch.h" ++#include "protocol/payload.h" ++#include "protocol/stylus.h" + -+static void ipts_stylus_handle_report(struct ipts_context *ipts, -+ struct ipts_stylus_report *report) ++static void ipts_stylus_handle_stylus_data(struct ipts_context *ipts, ++ struct ipts_stylus_report_data *data) +{ + u16 tool; -+ u8 prox = report->mode & IPTS_STYLUS_REPORT_MODE_PROXIMITY; -+ u8 touch = report->mode & IPTS_STYLUS_REPORT_MODE_TOUCH; -+ u8 button = report->mode & IPTS_STYLUS_REPORT_MODE_BUTTON; -+ u8 rubber = report->mode & IPTS_STYLUS_REPORT_MODE_RUBBER; ++ u8 prox = data->mode & IPTS_STYLUS_REPORT_MODE_PROX; ++ u8 touch = data->mode & IPTS_STYLUS_REPORT_MODE_TOUCH; ++ u8 button = data->mode & IPTS_STYLUS_REPORT_MODE_BUTTON; ++ u8 rubber = data->mode & IPTS_STYLUS_REPORT_MODE_ERASER; + + s32 tx = 0; + s32 ty = 0; + + // avoid unnecessary computations + // altitude is zero if stylus does not touch the screen -+ if (report->altitude) { -+ ipts_math_altitude_azimuth_to_tilt(report->altitude, -+ report->azimuth, &tx, &ty); ++ if (data->altitude) { ++ ipts_math_altitude_azimuth_to_tilt(data->altitude, ++ data->azimuth, &tx, &ty); + } + + if (prox && rubber) @@ -1706,10 +1850,10 @@ index 000000000000..263aa133b706 + input_report_key(ipts->stylus, ipts->stylus_tool, prox); + input_report_key(ipts->stylus, BTN_STYLUS, button); + -+ input_report_abs(ipts->stylus, ABS_X, report->x); -+ input_report_abs(ipts->stylus, ABS_Y, report->y); -+ input_report_abs(ipts->stylus, ABS_PRESSURE, report->pressure); -+ input_report_abs(ipts->stylus, ABS_MISC, report->timestamp); ++ input_report_abs(ipts->stylus, ABS_X, data->x); ++ input_report_abs(ipts->stylus, ABS_Y, data->y); ++ input_report_abs(ipts->stylus, ABS_PRESSURE, data->pressure); ++ input_report_abs(ipts->stylus, ABS_MISC, data->timestamp); + + input_report_abs(ipts->stylus, ABS_TILT_X, tx); + input_report_abs(ipts->stylus, ABS_TILT_Y, ty); @@ -1717,72 +1861,97 @@ index 000000000000..263aa133b706 + input_sync(ipts->stylus); +} + -+static void ipts_stylus_parse_report_gen1(struct ipts_context *ipts, -+ struct ipts_touch_data *data) ++static void ipts_stylus_handle_report_tilt_serial(struct ipts_context *ipts, ++ struct ipts_report *report) +{ -+ u8 count, i; -+ struct ipts_stylus_report report; -+ struct ipts_stylus_report_gen1 *reports; ++ int i; ++ struct ipts_stylus_report_serial *stylus_report; ++ struct ipts_stylus_report_data *data; + -+ count = data->data[32]; -+ reports = (struct ipts_stylus_report_gen1 *)&data->data[44]; ++ stylus_report = (struct ipts_stylus_report_serial *)report->data; ++ data = (struct ipts_stylus_report_data *)stylus_report->data; + -+ for (i = 0; i < count; i++) { -+ report.mode = reports[i].mode; -+ report.x = reports[i].x; -+ report.y = reports[i].y; -+ report.pressure = reports[i].pressure; ++ // TODO: Track serial number and support multiple styli + -+ // The gen1 protocol doesn't support tilting the stylus -+ report.altitude = 0; -+ report.azimuth = 0; ++ for (i = 0; i < stylus_report->reports; i++) ++ ipts_stylus_handle_stylus_data(ipts, &data[i]); ++} + -+ // Use the buffer ID to emulate a timestamp -+ report.timestamp = data->buffer; ++static void ipts_stylus_handle_report_tilt(struct ipts_context *ipts, ++ struct ipts_report *report) ++{ ++ int i; ++ struct ipts_stylus_report *stylus_report; ++ struct ipts_stylus_report_data *data; + -+ ipts_stylus_handle_report(ipts, &report); ++ stylus_report = (struct ipts_stylus_report *)report->data; ++ data = (struct ipts_stylus_report_data *)stylus_report->data; ++ ++ for (i = 0; i < stylus_report->reports; i++) ++ ipts_stylus_handle_stylus_data(ipts, &data[i]); ++} ++ ++static void ipts_stylus_handle_report_no_tilt(struct ipts_context *ipts, ++ struct ipts_report *report) ++{ ++ int i; ++ struct ipts_stylus_report_serial *stylus_report; ++ struct ipts_stylus_report_data_no_tilt *data; ++ struct ipts_stylus_report_data new_data; ++ ++ stylus_report = (struct ipts_stylus_report_serial *)report->data; ++ data = (struct ipts_stylus_report_data_no_tilt *)stylus_report->data; ++ ++ for (i = 0; i < stylus_report->reports; i++) { ++ new_data.mode = data[i].mode; ++ new_data.x = data[i].x; ++ new_data.y = data[i].y; ++ new_data.pressure = data[i].pressure * 4; ++ new_data.altitude = 0; ++ new_data.azimuth = 0; ++ new_data.timestamp = 0; ++ ++ ipts_stylus_handle_stylus_data(ipts, &new_data); + } +} + -+static void ipts_stylus_parse_report_gen2(struct ipts_context *ipts, -+ struct ipts_touch_data *data) ++void ipts_stylus_handle_input(struct ipts_context *ipts, ++ struct ipts_payload_frame *frame) +{ -+ u8 count, i; -+ struct ipts_stylus_report *reports; ++ int size; ++ struct ipts_report *report; + -+ count = data->data[32]; -+ reports = (struct ipts_stylus_report *)&data->data[40]; ++ size = 0; + -+ for (i = 0; i < count; i++) -+ ipts_stylus_handle_report(ipts, &reports[i]); -+} ++ while (size < frame->size) { ++ report = (struct ipts_report *)&frame->data[size]; ++ size += sizeof(struct ipts_report) + report->size; + -+void ipts_stylus_parse_report(struct ipts_context *ipts, -+ struct ipts_touch_data *data) -+{ -+ switch (ipts->device_cfg.stylus_protocol) { -+ case IPTS_STYLUS_PROTOCOL_GEN1: -+ ipts_stylus_parse_report_gen1(ipts, data); -+ break; -+ case IPTS_STYLUS_PROTOCOL_GEN2: -+ ipts_stylus_parse_report_gen2(ipts, data); -+ break; ++ switch (report->type) { ++ case IPTS_REPORT_TYPE_STYLUS_NO_TILT: ++ ipts_stylus_handle_report_no_tilt(ipts, report); ++ break; ++ case IPTS_REPORT_TYPE_STYLUS_TILT: ++ ipts_stylus_handle_report_tilt(ipts, report); ++ break; ++ case IPTS_REPORT_TYPE_STYLUS_TILT_SERIAL: ++ ipts_stylus_handle_report_tilt_serial(ipts, report); ++ break; ++ default: ++ // ignored ++ break; ++ } + } +} + +int ipts_stylus_init(struct ipts_context *ipts) +{ + int ret; -+ u16 pressure; + -+ ipts->stylus = devm_input_allocate_device(ipts->dev); ++ ipts->stylus = input_allocate_device(); + if (!ipts->stylus) + return -ENOMEM; + -+ pressure = ipts->device_cfg.max_stylus_pressure; -+ -+ ipts->stylus_tool = BTN_TOOL_PEN; -+ + __set_bit(INPUT_PROP_DIRECT, ipts->stylus->propbit); + __set_bit(INPUT_PROP_POINTER, ipts->stylus->propbit); + @@ -1790,7 +1959,7 @@ index 000000000000..263aa133b706 + input_abs_set_res(ipts->stylus, ABS_X, 34); + input_set_abs_params(ipts->stylus, ABS_Y, 0, 7200, 0, 0); + input_abs_set_res(ipts->stylus, ABS_Y, 38); -+ input_set_abs_params(ipts->stylus, ABS_PRESSURE, 0, pressure, 0, 0); ++ input_set_abs_params(ipts->stylus, ABS_PRESSURE, 0, 4096, 0, 0); + input_set_abs_params(ipts->stylus, ABS_TILT_X, -9000, 9000, 0, 0); + input_abs_set_res(ipts->stylus, ABS_TILT_X, 5730); + input_set_abs_params(ipts->stylus, ABS_TILT_Y, -9000, 9000, 0, 0); @@ -1807,34 +1976,44 @@ index 000000000000..263aa133b706 + ipts->stylus->id.version = ipts->device_info.fw_rev; + + ipts->stylus->phys = "heci3"; -+ ipts->stylus->name = "Intel Precise Stylus"; ++ ipts->stylus->name = "IPTS Stylus"; + + ret = input_register_device(ipts->stylus); + if (ret) { -+ dev_err(ipts->dev, "Failed to register stylus device: %d\n", -+ ret); ++ dev_err(ipts->dev, "Cannot register input device: %s (%d)\n", ++ ipts->stylus->name, ret); ++ input_free_device(ipts->stylus); + return ret; + } + + return 0; +} ++ ++void ipts_stylus_free(struct ipts_context *ipts) ++{ ++ if (!ipts->stylus) ++ return; ++ ++ input_unregister_device(ipts->stylus); ++} diff --git a/drivers/input/touchscreen/ipts/stylus.h b/drivers/input/touchscreen/ipts/stylus.h new file mode 100644 -index 000000000000..3b6424ade542 +index 000000000000..5b93add1eac2 --- /dev/null +++ b/drivers/input/touchscreen/ipts/stylus.h -@@ -0,0 +1,13 @@ +@@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#ifndef _IPTS_STYLUS_H_ +#define _IPTS_STYLUS_H_ + +#include "context.h" -+#include "protocol/touch.h" ++#include "protocol/payload.h" + -+void ipts_stylus_parse_report(struct ipts_context *ipts, -+ struct ipts_touch_data *data); ++void ipts_stylus_handle_input(struct ipts_context *ipts, ++ struct ipts_payload_frame *frame); +int ipts_stylus_init(struct ipts_context *ipts); ++void ipts_stylus_free(struct ipts_context *ipts); + +#endif /* _IPTS_STYLUS_H_ */ diff --git a/drivers/misc/mei/hw-me-regs.h b/drivers/misc/mei/hw-me-regs.h @@ -1890,5 +2069,5 @@ index 9a61c28ed3ae..47fc20975245 100644 /* * MT_TOOL types -- -2.25.0 +2.25.1