Просмотр исходного кода

Update v4.19 patches

Changes:
 - SAM:
   - Update DTX driver state after resume.
   - Add DTX Documentation, misc. fixes, and cleanup.

Links:
- SAM: https://github.com/linux-surface/surface-aggregator-module/commit/af4bb01042d8ab707d8a73d4ee7ff770223a1c2f
- kernel: https://github.com/linux-surface/kernel/commit/8bb4052b6bfb2fc8abe989df45cc17b06f13af46
Maximilian Luz 4 лет назад
Родитель
Сommit
3d9db379b4

+ 4 - 2
patches/4.19/0001-surface3-power.patch

@@ -1,8 +1,10 @@
-From 68915ae484c9d8881ed344ee3c639b1d11d8f29c Mon Sep 17 00:00:00 2001
+From 7712e7c7b39ac4af2c8d4d5a9a22ecc0d5a25077 Mon Sep 17 00:00:00 2001
 From: Maximilian Luz <luzmaximilian@gmail.com>
 Date: Sat, 28 Sep 2019 18:00:43 +0200
-Subject: [PATCH 01/11] surface3-power
+Subject: [PATCH] platform/x86: Surface 3 battery platform operation region
+ support
 
+Patchset: surface3-power
 ---
  drivers/platform/x86/Kconfig          |   7 +
  drivers/platform/x86/Makefile         |   1 +

+ 28 - 2
patches/4.19/0002-surface3-touchscreen-dma-fix.patch

@@ -1,8 +1,34 @@
-From 26e5e3d5780b48ef1f2a7115ef7a1ef1f4bf1e67 Mon Sep 17 00:00:00 2001
+From 6893037808c47ada1b0bf8705ebe7f60dfd600b0 Mon Sep 17 00:00:00 2001
 From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
 Date: Sun, 5 Jul 2020 14:56:20 +0300
-Subject: [PATCH 02/11] surface3-touchscreen-dma-fix
+Subject: [PATCH] dmaengine: dw: Initialize channel before each transfer
 
+In some cases DMA can be used only with a consumer which does runtime power
+management and on the platforms, that have DMA auto power gating logic
+(see comments in the drivers/acpi/acpi_lpss.c), may result in DMA losing
+its context. Simple mitigation of this issue is to initialize channel
+each time the consumer initiates a transfer.
+
+Fixes: cfdf5b6cc598 ("dw_dmac: add support for Lynxpoint DMA controllers")
+Reported-by: Tsuchiya Yuto <kitakar@gmail.com>
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
+BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=206403
+Link: https://lore.kernel.org/r/20200705115620.51929-1-andriy.shevchenko@linux.intel.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+
+(cherry picked from commit 99ba8b9b0d9780e9937eb1d488d120e9e5c2533d)
+[Reason for cherry-picking this commit:
+  This commit fixes touch input when using DMA mode on Surface 3's
+  touchscreen.
+  Note: this commit was not backported to v4.19 by upstream. For now,
+  backport this patch ourselves.]
+[ Conflicts:
+	drivers/dma/dw/core.c
+ Resolved conflict by accepting current change then removed
+ DW_DMA_IS_INITIALIZED lines]
+Signed-off-by: Tsuchiya Yuto <kitakar@gmail.com>
+Patchset: surface3-touchscreen-dma-fix
 ---
  drivers/dma/dw/core.c | 12 ------------
  1 file changed, 12 deletions(-)

+ 34 - 4
patches/4.19/0003-surface3-oemb.patch

@@ -1,8 +1,38 @@
-From 118ae75f050cf4934c6b97d11f088492c2a628aa Mon Sep 17 00:00:00 2001
-From: Chih-Wei Huang <cwhuang@linux.org.tw>
-Date: Tue, 18 Sep 2018 11:01:37 +0800
-Subject: [PATCH 03/11] surface3-oemb
+From bbc85da670e31aa65b92bead468c33f5d50ff55b Mon Sep 17 00:00:00 2001
+From: Tsuchiya Yuto <kitakar@gmail.com>
+Date: Sun, 18 Oct 2020 16:42:44 +0900
+Subject: [PATCH] (surface3-oemb) add DMI matches for Surface 3 with broken DMI
+ table
 
+On some Surface 3, the DMI table gets corrupted for unknown reasons
+and breaks existing DMI matching used for device-specific quirks.
+
+This commit adds the (broken) DMI data into dmi_system_id tables used
+for quirks so that each driver can enable quirks even on the affected
+systems.
+
+On affected systems, DMI data will look like this:
+    $ grep . /sys/devices/virtual/dmi/id/{bios_vendor,board_name,board_vendor,\
+    chassis_vendor,product_name,sys_vendor}
+    /sys/devices/virtual/dmi/id/bios_vendor:American Megatrends Inc.
+    /sys/devices/virtual/dmi/id/board_name:OEMB
+    /sys/devices/virtual/dmi/id/board_vendor:OEMB
+    /sys/devices/virtual/dmi/id/chassis_vendor:OEMB
+    /sys/devices/virtual/dmi/id/product_name:OEMB
+    /sys/devices/virtual/dmi/id/sys_vendor:OEMB
+
+Expected:
+    $ grep . /sys/devices/virtual/dmi/id/{bios_vendor,board_name,board_vendor,\
+    chassis_vendor,product_name,sys_vendor}
+    /sys/devices/virtual/dmi/id/bios_vendor:American Megatrends Inc.
+    /sys/devices/virtual/dmi/id/board_name:Surface 3
+    /sys/devices/virtual/dmi/id/board_vendor:Microsoft Corporation
+    /sys/devices/virtual/dmi/id/chassis_vendor:Microsoft Corporation
+    /sys/devices/virtual/dmi/id/product_name:Surface 3
+    /sys/devices/virtual/dmi/id/sys_vendor:Microsoft Corporation
+
+Signed-off-by: Tsuchiya Yuto <kitakar@gmail.com>
+Patchset: surface3-oemb
 ---
  drivers/platform/x86/surface3-wmi.c               | 7 +++++++
  sound/soc/codecs/rt5645.c                         | 9 +++++++++

+ 259 - 95
patches/4.19/0004-surface-buttons.patch

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

+ 20 - 2
patches/4.19/0005-suspend.patch

@@ -1,8 +1,26 @@
-From fb6b7e1a29e622cf19c57c17f397661ec9dae1da Mon Sep 17 00:00:00 2001
+From 8273cec8ad42f5a6d2349347878331069c296f07 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 05/11] suspend
+Subject: [PATCH] nvme: Backport changes for suspend
 
+Backported commits are:
+
+- torvalds/linux@4eaefe8c621c6195c91044396ed8060c179f7aae
+  (nvme-pci: Allow PCI bus-level PM to be used if ASPM is disabled)
+
+- torvalds/linux@accd2dd72c8f087441d725dd916688171519e4e6
+  (PCI/ASPM: Add pcie_aspm_enabled())
+
+- torvalds/linux@d916b1be94b6dc8d293abed2451f3062f6af7551
+  (nvme-pci: use host managed power state for suspend)
+
+- torvalds/linux@1a87ee657c530bb2f3e39e4ac184d48f5f959cda
+  (nvme: export get and set features)
+
+- torvalds/linux@d6135c3a1ec0cddda7b8b8e1b5b4abeeafd98289
+  (nvme-pci: Sync queues on reset)
+
+Patchset: suspend
 ---
  drivers/nvme/host/core.c |  36 ++++++++++++--
  drivers/nvme/host/nvme.h |   7 +++

+ 3 - 2
patches/4.19/0006-ipts.patch

@@ -1,8 +1,9 @@
-From f4a9111f3d630f2ad9a1746caa0d5c0bc319cb13 Mon Sep 17 00:00:00 2001
+From 067c4fbb383132758816350e07d5003b48d14fda Mon Sep 17 00:00:00 2001
 From: Maximilian Luz <luzmaximilian@gmail.com>
 Date: Sat, 28 Sep 2019 17:58:17 +0200
-Subject: [PATCH 06/11] ipts
+Subject: [PATCH] Add support for Intel IPTS touch devices
 
+Patchset: ipts
 ---
  drivers/gpu/drm/i915/Makefile               |    3 +
  drivers/gpu/drm/i915/i915_debugfs.c         |   63 +-

+ 1128 - 339
patches/4.19/0007-wifi.patch

@@ -1,139 +1,28 @@
-From d172c88f96b9e9187ea7d00231b7c124040526ae Mon Sep 17 00:00:00 2001
-From: kitakar5525 <34676735+kitakar5525@users.noreply.github.com>
-Date: Thu, 20 Feb 2020 16:51:11 +0900
-Subject: [PATCH 07/11] wifi
+From 80f7516fb978e63b6a7e04db4e774d5496071509 Mon Sep 17 00:00:00 2001
+From: Chuhong Yuan <hslester96@gmail.com>
+Date: Wed, 24 Jul 2019 19:27:45 +0800
+Subject: [PATCH] mwifiex: pcie: Use dev_get_drvdata
 
+Instead of using to_pci_dev + pci_get_drvdata,
+use dev_get_drvdata to make code simpler.
+
+Signed-off-by: Chuhong Yuan <hslester96@gmail.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+
+(cherry picked from commit ffa4d78cbc2644b4867b8129b3fbb5ddcdfcdba2)
+Reason for cherry-picking this commit:
+  to avoid conflicts when backporting incoming commits
+Signed-off-by: Tsuchiya Yuto (kitakar5525) <kitakar@gmail.com>
+Patchset: wifi
 ---
- drivers/net/wireless/marvell/mwifiex/Makefile |   1 +
- .../net/wireless/marvell/mwifiex/cfg80211.c   |  26 ++
- drivers/net/wireless/marvell/mwifiex/main.c   |   6 +-
- drivers/net/wireless/marvell/mwifiex/pcie.c   |  92 +++++--
- drivers/net/wireless/marvell/mwifiex/pcie.h   |   3 +
- .../wireless/marvell/mwifiex/pcie_quirks.c    | 255 ++++++++++++++++++
- .../wireless/marvell/mwifiex/pcie_quirks.h    |  17 ++
- .../net/wireless/marvell/mwifiex/sta_cmd.c    |  14 +-
- 8 files changed, 376 insertions(+), 38 deletions(-)
- create mode 100644 drivers/net/wireless/marvell/mwifiex/pcie_quirks.c
- create mode 100644 drivers/net/wireless/marvell/mwifiex/pcie_quirks.h
+ drivers/net/wireless/marvell/mwifiex/pcie.c | 8 ++------
+ 1 file changed, 2 insertions(+), 6 deletions(-)
 
-diff --git a/drivers/net/wireless/marvell/mwifiex/Makefile b/drivers/net/wireless/marvell/mwifiex/Makefile
-index fdfd9bf15ed4..8a1e7c5b9c6e 100644
---- a/drivers/net/wireless/marvell/mwifiex/Makefile
-+++ b/drivers/net/wireless/marvell/mwifiex/Makefile
-@@ -49,6 +49,7 @@ mwifiex_sdio-y += sdio.o
- obj-$(CONFIG_MWIFIEX_SDIO) += mwifiex_sdio.o
- 
- mwifiex_pcie-y += pcie.o
-+mwifiex_pcie-y += pcie_quirks.o
- obj-$(CONFIG_MWIFIEX_PCIE) += mwifiex_pcie.o
- 
- mwifiex_usb-y += usb.o
-diff --git a/drivers/net/wireless/marvell/mwifiex/cfg80211.c b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
-index 650191db25cb..dd487fc9c1a1 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/main.c b/drivers/net/wireless/marvell/mwifiex/main.c
-index e48b47f42554..55b71e3d0127 100644
---- a/drivers/net/wireless/marvell/mwifiex/main.c
-+++ b/drivers/net/wireless/marvell/mwifiex/main.c
-@@ -1458,7 +1458,7 @@ static void mwifiex_uninit_sw(struct mwifiex_adapter *adapter)
- }
- 
- /*
-- * This function gets called during PCIe function level reset.
-+ * This function can be used for shutting down the adapter SW.
-  */
- int mwifiex_shutdown_sw(struct mwifiex_adapter *adapter)
- {
-@@ -1474,6 +1474,8 @@ int mwifiex_shutdown_sw(struct mwifiex_adapter *adapter)
- 	priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
- 	mwifiex_deauthenticate(priv, NULL);
- 
-+	mwifiex_init_shutdown_fw(priv, MWIFIEX_FUNC_SHUTDOWN);
-+
- 	mwifiex_uninit_sw(adapter);
- 
- 	if (adapter->if_ops.down_dev)
-@@ -1483,7 +1485,7 @@ int mwifiex_shutdown_sw(struct mwifiex_adapter *adapter)
- }
- EXPORT_SYMBOL_GPL(mwifiex_shutdown_sw);
- 
--/* This function gets called during PCIe function level reset. Required
-+/* This function can be used for reinitting the adapter SW. Required
-  * code is extracted from mwifiex_add_card()
-  */
- int
 diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c
-index 991b9cc18000..30cd52c2485f 100644
+index 991b9cc18000..2aa0436d3548 100644
 --- a/drivers/net/wireless/marvell/mwifiex/pcie.c
 +++ b/drivers/net/wireless/marvell/mwifiex/pcie.c
-@@ -27,12 +27,18 @@
- #include "wmm.h"
- #include "11n.h"
- #include "pcie.h"
-+#include "pcie_quirks.h"
- 
- #define PCIE_VERSION	"1.0"
- #define DRV_NAME        "Marvell mwifiex PCIe"
- 
- static struct mwifiex_if_ops pcie_ops;
- 
-+static bool enable_device_dump;
-+module_param(enable_device_dump, bool, 0644);
-+MODULE_PARM_DESC(enable_device_dump,
-+		 "enable device_dump (default: disabled)");
-+
- static const struct of_device_id mwifiex_pcie_of_match_table[] = {
- 	{ .compatible = "pci11ab,2b42" },
- 	{ .compatible = "pci1b4b,2b42" },
-@@ -144,19 +150,13 @@ static bool mwifiex_pcie_ok_to_access_hw(struct mwifiex_adapter *adapter)
-  * registered functions must have drivers with suspend and resume
-  * methods. Failing that the kernel simply removes the whole card.
-  *
-- * If already not suspended, this function allocates and sends a host
-- * sleep activate request to the firmware and turns off the traffic.
-+ * This function shuts down the adapter.
-  */
+@@ -150,10 +150,8 @@ static bool mwifiex_pcie_ok_to_access_hw(struct mwifiex_adapter *adapter)
  static int mwifiex_pcie_suspend(struct device *dev)
  {
  	struct mwifiex_adapter *adapter;
@@ -142,114 +31,136 @@ index 991b9cc18000..30cd52c2485f 100644
 +	struct pcie_service_card *card = dev_get_drvdata(dev);
  
 -	card = pci_get_drvdata(pdev);
--
--	/* Might still be loading firmware */
--	wait_for_completion(&card->fw_done);
- 
- 	adapter = card->adapter;
- 	if (!adapter) {
-@@ -164,22 +164,15 @@ static int mwifiex_pcie_suspend(struct device *dev)
- 		return 0;
- 	}
- 
--	mwifiex_enable_wake(adapter);
--
--	/* Enable the Host Sleep */
--	if (!mwifiex_enable_hs(adapter)) {
-+	/* Shut down SW */
-+	if (mwifiex_shutdown_sw(adapter)) {
- 		mwifiex_dbg(adapter, ERROR,
- 			    "cmd: failed to suspend\n");
--		clear_bit(MWIFIEX_IS_HS_ENABLING, &adapter->work_flags);
--		mwifiex_disable_wake(adapter);
- 		return -EFAULT;
- 	}
- 
--	flush_workqueue(adapter->workqueue);
--
- 	/* Indicate device suspended */
- 	set_bit(MWIFIEX_IS_SUSPENDED, &adapter->work_flags);
--	clear_bit(MWIFIEX_IS_HS_ENABLING, &adapter->work_flags);
  
- 	return 0;
- }
-@@ -189,16 +182,14 @@ static int mwifiex_pcie_suspend(struct device *dev)
-  * registered functions must have drivers with suspend and resume
-  * methods. Failing that the kernel simply removes the whole card.
-  *
-- * If already not resumed, this function turns on the traffic and
-- * sends a host sleep cancel request to the firmware.
-+ * If already not resumed, this function reinits the adapter.
-  */
+ 	/* Might still be loading firmware */
+ 	wait_for_completion(&card->fw_done);
+@@ -195,10 +193,8 @@ static int mwifiex_pcie_suspend(struct device *dev)
  static int mwifiex_pcie_resume(struct device *dev)
  {
  	struct mwifiex_adapter *adapter;
 -	struct pcie_service_card *card;
 -	struct pci_dev *pdev = to_pci_dev(dev);
 +	struct pcie_service_card *card = dev_get_drvdata(dev);
-+	int ret;
  
 -	card = pci_get_drvdata(pdev);
  
  	if (!card->adapter) {
  		dev_err(dev, "adapter structure is not valid\n");
-@@ -215,9 +206,11 @@ static int mwifiex_pcie_resume(struct device *dev)
- 
- 	clear_bit(MWIFIEX_IS_SUSPENDED, &adapter->work_flags);
- 
--	mwifiex_cancel_hs(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA),
--			  MWIFIEX_ASYNC_CMD);
--	mwifiex_disable_wake(adapter);
-+	ret = mwifiex_reinit_sw(adapter);
-+	if (ret)
-+		dev_err(dev, "reinit failed: %d\n", ret);
-+	else
-+		mwifiex_dbg(adapter, INFO, "%s, successful\n", __func__);
- 
- 	return 0;
- }
-@@ -233,8 +226,13 @@ static int mwifiex_pcie_probe(struct pci_dev *pdev,
- 					const struct pci_device_id *ent)
- {
- 	struct pcie_service_card *card;
-+	struct pci_dev *parent_pdev = pci_upstream_bridge(pdev);
- 	int ret;
- 
-+	/* disable bridge_d3 to fix driver crashing after suspend on gen4+
-+	 * Surface devices */
-+	parent_pdev->bridge_d3 = false;
-+
- 	pr_debug("info: vendor=0x%4.04X device=0x%4.04X rev=%d\n",
- 		 pdev->vendor, pdev->device, pdev->revision);
- 
-@@ -265,6 +263,9 @@ static int mwifiex_pcie_probe(struct pci_dev *pdev,
- 			return ret;
- 	}
- 
-+	/* check quirks */
-+	mwifiex_initialize_quirks(card);
-+
- 	if (mwifiex_add_card(card, &card->fw_done, &pcie_ops,
- 			     MWIFIEX_PCIE, &pdev->dev)) {
- 		pr_err("%s failed\n", __func__);
-@@ -380,7 +381,16 @@ static void mwifiex_pcie_reset_prepare(struct pci_dev *pdev)
- 	mwifiex_shutdown_sw(adapter);
+-- 
+2.28.0
+
+From ed5d12e11559f0340ea3e73283a33ddb0b410e4c Mon Sep 17 00:00:00 2001
+From: Tsuchiya Yuto <kitakar@gmail.com>
+Date: Thu, 24 Sep 2020 18:02:06 +0900
+Subject: [PATCH] mwifiex: pcie: skip cancel_work_sync() on reset failure path
+
+If a reset is performed, but even the reset fails for some reasons (e.g.,
+on Surface devices, the fw reset requires another quirks),
+cancel_work_sync() hangs in mwifiex_cleanup_pcie().
+
+    # reset performed after firmware went into bad state
+    kernel: mwifiex_pcie 0000:01:00.0: WLAN FW already running! Skip FW dnld
+    kernel: mwifiex_pcie 0000:01:00.0: WLAN FW is active
+    # but even the reset failed
+    kernel: mwifiex_pcie 0000:01:00.0: mwifiex_cmd_timeout_func: Timeout cmd id = 0xfa, act = 0xa000
+    kernel: mwifiex_pcie 0000:01:00.0: num_data_h2c_failure = 0
+    kernel: mwifiex_pcie 0000:01:00.0: num_cmd_h2c_failure = 0
+    kernel: mwifiex_pcie 0000:01:00.0: is_cmd_timedout = 1
+    kernel: mwifiex_pcie 0000:01:00.0: num_tx_timeout = 0
+    kernel: mwifiex_pcie 0000:01:00.0: last_cmd_index = 2
+    kernel: mwifiex_pcie 0000:01:00.0: last_cmd_id: 16 00 a4 00 fa 00 a4 00 7f 00
+    kernel: mwifiex_pcie 0000:01:00.0: last_cmd_act: 00 00 00 00 00 a0 00 00 00 00
+    kernel: mwifiex_pcie 0000:01:00.0: last_cmd_resp_index = 0
+    kernel: mwifiex_pcie 0000:01:00.0: last_cmd_resp_id: 16 80 7f 80 16 80 a4 80 7f 80
+    kernel: mwifiex_pcie 0000:01:00.0: last_event_index = 1 kernel: mwifiex_pcie 0000:01:00.0: last_event: 58 00 58 00 58 00 58 00 58 00
+    kernel: mwifiex_pcie 0000:01:00.0: data_sent=0 cmd_sent=1
+    kernel: mwifiex_pcie 0000:01:00.0: ps_mode=0 ps_state=0
+    kernel: mwifiex_pcie 0000:01:00.0: info: _mwifiex_fw_dpc: unregister device
+    # mwifiex_pcie_work hanged
+    kernel: INFO: task kworker/0:0:24857 blocked for more than 122 seconds.
+    kernel:       Tainted: G        W  OE     5.3.11-arch1-1 #1
+    kernel: "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
+    kernel: kworker/0:0     D    0 24857      2 0x80004000
+    kernel: Workqueue: events mwifiex_pcie_work [mwifiex_pcie]
+    kernel: Call Trace:
+    kernel:  ? __schedule+0x27f/0x6d0
+    kernel:  schedule+0x43/0xd0
+    kernel:  schedule_timeout+0x299/0x3d0
+    kernel:  ? __switch_to_asm+0x40/0x70
+    kernel:  wait_for_common+0xeb/0x190
+    kernel:  ? wake_up_q+0x60/0x60
+    kernel:  __flush_work+0x130/0x1e0
+    kernel:  ? flush_workqueue_prep_pwqs+0x130/0x130
+    kernel:  __cancel_work_timer+0x123/0x1b0
+    kernel:  mwifiex_cleanup_pcie+0x28/0xd0 [mwifiex_pcie]
+    kernel:  mwifiex_free_adapter+0x24/0xe0 [mwifiex]
+    kernel:  _mwifiex_fw_dpc+0x28d/0x520 [mwifiex]
+    kernel:  mwifiex_reinit_sw+0x15d/0x2c0 [mwifiex]
+    kernel:  mwifiex_pcie_reset_done+0x50/0x80 [mwifiex_pcie]
+    kernel:  pci_try_reset_function+0x38/0x70
+    kernel:  process_one_work+0x1d1/0x3a0
+    kernel:  worker_thread+0x4a/0x3d0
+    kernel:  kthread+0xfb/0x130
+    kernel:  ? process_one_work+0x3a0/0x3a0
+    kernel:  ? kthread_park+0x80/0x80
+    kernel:  ret_from_fork+0x35/0x40
+
+This is a deadlock caused by calling cancel_work_sync() in
+mwifiex_cleanup_pcie():
+
+- Device resets are done via mwifiex_pcie_card_reset()
+- which schedules card->work to call mwifiex_pcie_card_reset_work()
+- which calls pci_try_reset_function().
+- This leads to mwifiex_pcie_reset_done() be called on the same workqueue,
+  which in turn calls
+- mwifiex_reinit_sw() and that calls
+- _mwifiex_fw_dpc().
+
+The problem is now that _mwifiex_fw_dpc() calls mwifiex_free_adapter()
+in case firmware initialization fails. That ends up calling
+mwifiex_cleanup_pcie().
+
+Note that all those calls are still running on the workqueue. So when
+mwifiex_cleanup_pcie() now calls cancel_work_sync(), it's really waiting
+on itself to complete, causing a deadlock.
+
+This commit fixes the deadlock by skipping cancel_work_sync() on a reset
+failure path.
+
+After this commit, when reset fails, the following output is
+expected to be shown:
+
+    kernel: mwifiex_pcie 0000:03:00.0: info: _mwifiex_fw_dpc: unregister device
+    kernel: mwifiex: Failed to bring up adapter: -5
+    kernel: mwifiex_pcie 0000:03:00.0: reinit failed: -5
+
+To reproduce this issue, for example, try putting the root port of wifi
+into D3 (replace "00:1d.3" with your setup).
+
+    # put into D3 (root port)
+    sudo setpci -v -s 00:1d.3 CAP_PM+4.b=0b
+
+Signed-off-by: Tsuchiya Yuto <kitakar@gmail.com>
+Patchset: wifi
+---
+ drivers/net/wireless/marvell/mwifiex/pcie.c | 18 +++++++++++++++++-
+ drivers/net/wireless/marvell/mwifiex/pcie.h |  2 ++
+ 2 files changed, 19 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c
+index 2aa0436d3548..4e655038e3f3 100644
+--- a/drivers/net/wireless/marvell/mwifiex/pcie.c
++++ b/drivers/net/wireless/marvell/mwifiex/pcie.c
+@@ -377,6 +377,8 @@ static void mwifiex_pcie_reset_prepare(struct pci_dev *pdev)
  	clear_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP, &card->work_flags);
  	clear_bit(MWIFIEX_IFACE_WORK_CARD_RESET, &card->work_flags);
-+
-+	/* For Surface gen4+ devices, we need to put wifi into D3cold right
-+	 * before performing FLR
-+	 */
-+	if (card->quirks & QUIRK_FW_RST_D3COLD)
-+		mwifiex_pcie_reset_d3cold_quirk(pdev);
-+
  	mwifiex_dbg(adapter, INFO, "%s, successful\n", __func__);
 +
 +	card->pci_reset_ongoing = true;
  }
  
  /*
-@@ -409,6 +419,8 @@ static void mwifiex_pcie_reset_done(struct pci_dev *pdev)
+@@ -405,6 +407,8 @@ static void mwifiex_pcie_reset_done(struct pci_dev *pdev)
  		dev_err(&pdev->dev, "reinit failed: %d\n", ret);
  	else
  		mwifiex_dbg(adapter, INFO, "%s, successful\n", __func__);
@@ -258,37 +169,7 @@ index 991b9cc18000..30cd52c2485f 100644
  }
  
  static const struct pci_error_handlers mwifiex_pcie_err_handler = {
-@@ -2789,6 +2801,12 @@ static void mwifiex_pcie_fw_dump(struct mwifiex_adapter *adapter)
- 
- static void mwifiex_pcie_device_dump_work(struct mwifiex_adapter *adapter)
- {
-+	if (!enable_device_dump) {
-+		mwifiex_dbg(adapter, MSG,
-+			    "device_dump is disabled by module parameter\n");
-+		return;
-+	}
-+
- 	adapter->devdump_data = vzalloc(MWIFIEX_FW_DUMP_SIZE);
- 	if (!adapter->devdump_data) {
- 		mwifiex_dbg(adapter, ERROR,
-@@ -2806,6 +2824,16 @@ static void mwifiex_pcie_card_reset_work(struct mwifiex_adapter *adapter)
- {
- 	struct pcie_service_card *card = adapter->card;
- 
-+	/* On Surface 3, reset_wsid method removes then re-probes card by
-+	 * itself. So, need to place it here and skip performing any other
-+	 * reset-related works.
-+	 */
-+	if (card->quirks & QUIRK_FW_RST_WSID_S3) {
-+		mwifiex_pcie_reset_wsid_quirk(card->dev);
-+		/* skip performing any other reset-related works */
-+		return;
-+	}
-+
- 	/* We can't afford to wait here; remove() might be waiting on us. If we
- 	 * can't grab the device lock, maybe we'll get another chance later.
- 	 */
-@@ -3000,7 +3028,19 @@ static void mwifiex_cleanup_pcie(struct mwifiex_adapter *adapter)
+@@ -2996,7 +3000,19 @@ static void mwifiex_cleanup_pcie(struct mwifiex_adapter *adapter)
  	int ret;
  	u32 fw_status;
  
@@ -310,60 +191,119 @@ index 991b9cc18000..30cd52c2485f 100644
  	ret = mwifiex_read_reg(adapter, reg->fw_status, &fw_status);
  	if (fw_status == FIRMWARE_READY_PCIE) {
 diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.h b/drivers/net/wireless/marvell/mwifiex/pcie.h
-index f7ce9b6db6b4..f7e968306a0c 100644
+index f7ce9b6db6b4..72d0c01ff359 100644
 --- a/drivers/net/wireless/marvell/mwifiex/pcie.h
 +++ b/drivers/net/wireless/marvell/mwifiex/pcie.h
-@@ -391,6 +391,9 @@ struct pcie_service_card {
+@@ -391,6 +391,8 @@ struct pcie_service_card {
  	struct mwifiex_msix_context share_irq_ctx;
  	struct work_struct work;
  	unsigned long work_flags;
 +
 +	bool pci_reset_ongoing;
-+	unsigned long quirks;
  };
  
  static inline int
-diff --git a/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c
-new file mode 100644
-index 000000000000..34dcd84f02a6
---- /dev/null
-+++ b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c
-@@ -0,0 +1,255 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * File for PCIe quirks.
-+ */
-+
-+/* The low-level PCI operations will be performed in this file. Therefore,
-+ * let's use dev_*() instead of mwifiex_dbg() here to avoid troubles (e.g.
-+ * to avoid using mwifiex_adapter struct before init or wifi is powered
-+ * down, or causes NULL ptr deref).
-+ */
-+
-+#include <linux/acpi.h>
-+#include <linux/dmi.h>
-+
-+#include "pcie_quirks.h"
-+
-+/* For reset_wsid quirk */
-+#define ACPI_WSID_PATH		"\\_SB.WSID"
-+#define WSID_REV		0x0
-+#define WSID_FUNC_WIFI_PWR_OFF	0x1
-+#define WSID_FUNC_WIFI_PWR_ON	0x2
-+/* WSID _DSM UUID: "534ea3bf-fcc2-4e7a-908f-a13978f0c7ef" */
-+static const guid_t wsid_dsm_guid =
-+	GUID_INIT(0x534ea3bf, 0xfcc2, 0x4e7a,
-+		  0x90, 0x8f, 0xa1, 0x39, 0x78, 0xf0, 0xc7, 0xef);
-+
-+/* quirk table based on DMI matching */
-+static const struct dmi_system_id mwifiex_quirk_table[] = {
+-- 
+2.28.0
+
+From 45ddc398a7d6afa875840ab9f4fb920da3b3eb0f Mon Sep 17 00:00:00 2001
+From: Tsuchiya Yuto <kitakar@gmail.com>
+Date: Mon, 28 Sep 2020 17:46:49 +0900
+Subject: [PATCH] mwifiex: pcie: add DMI-based quirk impl for Surface devices
+
+This commit adds quirk implementation based on DMI matching with DMI
+table for Surface devices.
+
+This implementation can be used for quirks later.
+
+Signed-off-by: Tsuchiya Yuto <kitakar@gmail.com>
+Patchset: wifi
+---
+ drivers/net/wireless/marvell/mwifiex/Makefile |   1 +
+ drivers/net/wireless/marvell/mwifiex/pcie.c   |   4 +
+ drivers/net/wireless/marvell/mwifiex/pcie.h   |   1 +
+ .../wireless/marvell/mwifiex/pcie_quirks.c    | 114 ++++++++++++++++++
+ .../wireless/marvell/mwifiex/pcie_quirks.h    |  11 ++
+ 5 files changed, 131 insertions(+)
+ create mode 100644 drivers/net/wireless/marvell/mwifiex/pcie_quirks.c
+ create mode 100644 drivers/net/wireless/marvell/mwifiex/pcie_quirks.h
+
+diff --git a/drivers/net/wireless/marvell/mwifiex/Makefile b/drivers/net/wireless/marvell/mwifiex/Makefile
+index fdfd9bf15ed4..8a1e7c5b9c6e 100644
+--- a/drivers/net/wireless/marvell/mwifiex/Makefile
++++ b/drivers/net/wireless/marvell/mwifiex/Makefile
+@@ -49,6 +49,7 @@ mwifiex_sdio-y += sdio.o
+ obj-$(CONFIG_MWIFIEX_SDIO) += mwifiex_sdio.o
+ 
+ mwifiex_pcie-y += pcie.o
++mwifiex_pcie-y += pcie_quirks.o
+ obj-$(CONFIG_MWIFIEX_PCIE) += mwifiex_pcie.o
+ 
+ mwifiex_usb-y += usb.o
+diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c
+index 4e655038e3f3..d56c9d7f36bd 100644
+--- a/drivers/net/wireless/marvell/mwifiex/pcie.c
++++ b/drivers/net/wireless/marvell/mwifiex/pcie.c
+@@ -27,6 +27,7 @@
+ #include "wmm.h"
+ #include "11n.h"
+ #include "pcie.h"
++#include "pcie_quirks.h"
+ 
+ #define PCIE_VERSION	"1.0"
+ #define DRV_NAME        "Marvell mwifiex PCIe"
+@@ -261,6 +262,9 @@ static int mwifiex_pcie_probe(struct pci_dev *pdev,
+ 			return ret;
+ 	}
+ 
++	/* check quirks */
++	mwifiex_initialize_quirks(card);
++
+ 	if (mwifiex_add_card(card, &card->fw_done, &pcie_ops,
+ 			     MWIFIEX_PCIE, &pdev->dev)) {
+ 		pr_err("%s failed\n", __func__);
+diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.h b/drivers/net/wireless/marvell/mwifiex/pcie.h
+index 72d0c01ff359..f7e968306a0c 100644
+--- a/drivers/net/wireless/marvell/mwifiex/pcie.h
++++ b/drivers/net/wireless/marvell/mwifiex/pcie.h
+@@ -393,6 +393,7 @@ struct pcie_service_card {
+ 	unsigned long work_flags;
+ 
+ 	bool pci_reset_ongoing;
++	unsigned long quirks;
+ };
+ 
+ static inline int
+diff --git a/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c
+new file mode 100644
+index 000000000000..929aee2b0a60
+--- /dev/null
++++ b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c
+@@ -0,0 +1,114 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * File for PCIe quirks.
++ */
++
++/* The low-level PCI operations will be performed in this file. Therefore,
++ * let's use dev_*() instead of mwifiex_dbg() here to avoid troubles (e.g.
++ * to avoid using mwifiex_adapter struct before init or wifi is powered
++ * down, or causes NULL ptr deref).
++ */
++
++#include <linux/dmi.h>
++
++#include "pcie_quirks.h"
++
++/* quirk table based on DMI matching */
++static const struct dmi_system_id mwifiex_quirk_table[] = {
 +	{
 +		.ident = "Surface Pro 4",
 +		.matches = {
 +			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
 +			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Pro 4"),
 +		},
-+		.driver_data = (void *)QUIRK_FW_RST_D3COLD,
++		.driver_data = 0,
 +	},
 +	{
 +		.ident = "Surface Pro 5",
@@ -372,7 +312,7 @@ index 000000000000..34dcd84f02a6
 +			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
 +			DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "Surface_Pro_1796"),
 +		},
-+		.driver_data = (void *)QUIRK_FW_RST_D3COLD,
++		.driver_data = 0,
 +	},
 +	{
 +		.ident = "Surface Pro 5 (LTE)",
@@ -381,7 +321,7 @@ index 000000000000..34dcd84f02a6
 +			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
 +			DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "Surface_Pro_1807"),
 +		},
-+		.driver_data = (void *)QUIRK_FW_RST_D3COLD,
++		.driver_data = 0,
 +	},
 +	{
 +		.ident = "Surface Pro 6",
@@ -389,7 +329,7 @@ index 000000000000..34dcd84f02a6
 +			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
 +			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Pro 6"),
 +		},
-+		.driver_data = (void *)QUIRK_FW_RST_D3COLD,
++		.driver_data = 0,
 +	},
 +	{
 +		.ident = "Surface Book 1",
@@ -397,7 +337,7 @@ index 000000000000..34dcd84f02a6
 +			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
 +			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Book"),
 +		},
-+		.driver_data = (void *)QUIRK_FW_RST_D3COLD,
++		.driver_data = 0,
 +	},
 +	{
 +		.ident = "Surface Book 2",
@@ -405,7 +345,7 @@ index 000000000000..34dcd84f02a6
 +			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
 +			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Book 2"),
 +		},
-+		.driver_data = (void *)QUIRK_FW_RST_D3COLD,
++		.driver_data = 0,
 +	},
 +	{
 +		.ident = "Surface Laptop 1",
@@ -413,7 +353,7 @@ index 000000000000..34dcd84f02a6
 +			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
 +			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Laptop"),
 +		},
-+		.driver_data = (void *)QUIRK_FW_RST_D3COLD,
++		.driver_data = 0,
 +	},
 +	{
 +		.ident = "Surface Laptop 2",
@@ -421,7 +361,7 @@ index 000000000000..34dcd84f02a6
 +			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
 +			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Laptop 2"),
 +		},
-+		.driver_data = (void *)QUIRK_FW_RST_D3COLD,
++		.driver_data = 0,
 +	},
 +	{
 +		.ident = "Surface 3",
@@ -429,16 +369,7 @@ index 000000000000..34dcd84f02a6
 +			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
 +			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface 3"),
 +		},
-+		.driver_data = (void *)QUIRK_FW_RST_WSID_S3,
-+	},
-+	{
-+		.ident = "Surface 3",
-+		.matches = {
-+			DMI_EXACT_MATCH(DMI_BIOS_VENDOR, "American Megatrends Inc."),
-+			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "OEMB"),
-+			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "OEMB"),
-+		},
-+		.driver_data = (void *)QUIRK_FW_RST_WSID_S3,
++		.driver_data = 0,
 +	},
 +	{
 +		.ident = "Surface Pro 3",
@@ -462,11 +393,156 @@ index 000000000000..34dcd84f02a6
 +
 +	if (!card->quirks)
 +		dev_info(&pdev->dev, "no quirks enabled\n");
++}
+diff --git a/drivers/net/wireless/marvell/mwifiex/pcie_quirks.h b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.h
+new file mode 100644
+index 000000000000..5326ae7e5671
+--- /dev/null
++++ b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.h
+@@ -0,0 +1,11 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++/*
++ * Header file for PCIe quirks.
++ */
++
++#include "pcie.h"
++
++/* quirks */
++// quirk flags can be added here
++
++void mwifiex_initialize_quirks(struct pcie_service_card *card);
+-- 
+2.28.0
+
+From 73c434f78849f6483b76719748abef519a20faa7 Mon Sep 17 00:00:00 2001
+From: Tsuchiya Yuto <kitakar@gmail.com>
+Date: Tue, 29 Sep 2020 17:25:22 +0900
+Subject: [PATCH] mwifiex: pcie: add reset_d3cold quirk for Surface gen4+
+ devices
+
+To reset mwifiex on Surface gen4+ (Pro 4 or later gen) devices, it
+seems that putting the wifi device into D3cold is required according
+to errata.inf file on Windows installation (Windows/INF/errata.inf).
+
+This patch adds a function that performs power-cycle (put into D3cold
+then D0) and call the function at the end of reset_prepare().
+
+Note: Need to also reset the parent device (bridge) of wifi on SB1;
+it might be because the bridge of wifi always reports it's in D3hot.
+When I tried to reset only the wifi device (not touching parent), it gave
+the following error and the reset failed:
+
+    acpi device:4b: Cannot transition to power state D0 for parent in D3hot
+    mwifiex_pcie 0000:03:00.0: can't change power state from D3cold to D0 (config space inaccessible)
+
+Signed-off-by: Tsuchiya Yuto <kitakar@gmail.com>
+Patchset: wifi
+---
+ drivers/net/wireless/marvell/mwifiex/pcie.c   |  7 ++
+ .../wireless/marvell/mwifiex/pcie_quirks.c    | 73 +++++++++++++++++--
+ .../wireless/marvell/mwifiex/pcie_quirks.h    |  3 +-
+ 3 files changed, 74 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c
+index d56c9d7f36bd..408fe05b9384 100644
+--- a/drivers/net/wireless/marvell/mwifiex/pcie.c
++++ b/drivers/net/wireless/marvell/mwifiex/pcie.c
+@@ -380,6 +380,13 @@ static void mwifiex_pcie_reset_prepare(struct pci_dev *pdev)
+ 	mwifiex_shutdown_sw(adapter);
+ 	clear_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP, &card->work_flags);
+ 	clear_bit(MWIFIEX_IFACE_WORK_CARD_RESET, &card->work_flags);
++
++	/* For Surface gen4+ devices, we need to put wifi into D3cold right
++	 * before performing FLR
++	 */
++	if (card->quirks & QUIRK_FW_RST_D3COLD)
++		mwifiex_pcie_reset_d3cold_quirk(pdev);
++
+ 	mwifiex_dbg(adapter, INFO, "%s, successful\n", __func__);
+ 
+ 	card->pci_reset_ongoing = true;
+diff --git a/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c
+index 929aee2b0a60..edc739c542fe 100644
+--- a/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c
++++ b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c
+@@ -21,7 +21,7 @@ static const struct dmi_system_id mwifiex_quirk_table[] = {
+ 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
+ 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Pro 4"),
+ 		},
+-		.driver_data = 0,
++		.driver_data = (void *)QUIRK_FW_RST_D3COLD,
+ 	},
+ 	{
+ 		.ident = "Surface Pro 5",
+@@ -30,7 +30,7 @@ static const struct dmi_system_id mwifiex_quirk_table[] = {
+ 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
+ 			DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "Surface_Pro_1796"),
+ 		},
+-		.driver_data = 0,
++		.driver_data = (void *)QUIRK_FW_RST_D3COLD,
+ 	},
+ 	{
+ 		.ident = "Surface Pro 5 (LTE)",
+@@ -39,7 +39,7 @@ static const struct dmi_system_id mwifiex_quirk_table[] = {
+ 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
+ 			DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "Surface_Pro_1807"),
+ 		},
+-		.driver_data = 0,
++		.driver_data = (void *)QUIRK_FW_RST_D3COLD,
+ 	},
+ 	{
+ 		.ident = "Surface Pro 6",
+@@ -47,7 +47,7 @@ static const struct dmi_system_id mwifiex_quirk_table[] = {
+ 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
+ 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Pro 6"),
+ 		},
+-		.driver_data = 0,
++		.driver_data = (void *)QUIRK_FW_RST_D3COLD,
+ 	},
+ 	{
+ 		.ident = "Surface Book 1",
+@@ -55,7 +55,7 @@ static const struct dmi_system_id mwifiex_quirk_table[] = {
+ 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
+ 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Book"),
+ 		},
+-		.driver_data = 0,
++		.driver_data = (void *)QUIRK_FW_RST_D3COLD,
+ 	},
+ 	{
+ 		.ident = "Surface Book 2",
+@@ -63,7 +63,7 @@ static const struct dmi_system_id mwifiex_quirk_table[] = {
+ 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
+ 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Book 2"),
+ 		},
+-		.driver_data = 0,
++		.driver_data = (void *)QUIRK_FW_RST_D3COLD,
+ 	},
+ 	{
+ 		.ident = "Surface Laptop 1",
+@@ -71,7 +71,7 @@ static const struct dmi_system_id mwifiex_quirk_table[] = {
+ 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
+ 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Laptop"),
+ 		},
+-		.driver_data = 0,
++		.driver_data = (void *)QUIRK_FW_RST_D3COLD,
+ 	},
+ 	{
+ 		.ident = "Surface Laptop 2",
+@@ -79,7 +79,7 @@ static const struct dmi_system_id mwifiex_quirk_table[] = {
+ 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
+ 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Laptop 2"),
+ 		},
+-		.driver_data = 0,
++		.driver_data = (void *)QUIRK_FW_RST_D3COLD,
+ 	},
+ 	{
+ 		.ident = "Surface 3",
+@@ -111,4 +111,61 @@ void mwifiex_initialize_quirks(struct pcie_service_card *card)
+ 
+ 	if (!card->quirks)
+ 		dev_info(&pdev->dev, "no quirks enabled\n");
 +	if (card->quirks & QUIRK_FW_RST_D3COLD)
 +		dev_info(&pdev->dev, "quirk reset_d3cold enabled\n");
-+	if (card->quirks & QUIRK_FW_RST_WSID_S3)
-+		dev_info(&pdev->dev,
-+			 "quirk reset_wsid for Surface 3 enabled\n");
 +}
 +
 +static void mwifiex_pcie_set_power_d3cold(struct pci_dev *pdev)
@@ -522,7 +598,122 @@ index 000000000000..34dcd84f02a6
 +		return ret;
 +
 +	return 0;
-+}
+ }
+diff --git a/drivers/net/wireless/marvell/mwifiex/pcie_quirks.h b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.h
+index 5326ae7e5671..8b9dcb5070d8 100644
+--- a/drivers/net/wireless/marvell/mwifiex/pcie_quirks.h
++++ b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.h
+@@ -6,6 +6,7 @@
+ #include "pcie.h"
+ 
+ /* quirks */
+-// quirk flags can be added here
++#define QUIRK_FW_RST_D3COLD	BIT(0)
+ 
+ void mwifiex_initialize_quirks(struct pcie_service_card *card);
++int mwifiex_pcie_reset_d3cold_quirk(struct pci_dev *pdev);
+-- 
+2.28.0
+
+From 68d4b66ab18907af945a39efb8bd02666edf073b Mon Sep 17 00:00:00 2001
+From: Tsuchiya Yuto <kitakar@gmail.com>
+Date: Tue, 29 Sep 2020 17:32:22 +0900
+Subject: [PATCH] mwifiex: pcie: add reset_wsid quirk for Surface 3
+
+This commit adds reset_wsid quirk and uses this quirk for Surface 3 on
+card reset.
+
+To reset mwifiex on Surface 3, it seems that calling the _DSM method
+exists in \_SB.WSID [1] device is required.
+
+On Surface 3, calling the _DSM method removes/re-probes the card by
+itself. So, need to place the reset function before performing FLR and
+skip performing any other reset-related works.
+
+Note that Surface Pro 3 also has the WSID device [2], but it seems to need
+more work. This commit only supports Surface 3 yet.
+
+[1] https://github.com/linux-surface/acpidumps/blob/05cba925f3a515f222acb5b3551a032ddde958fe/surface_3/dsdt.dsl#L11947-L12011
+[2] https://github.com/linux-surface/acpidumps/blob/05cba925f3a515f222acb5b3551a032ddde958fe/surface_pro_3/dsdt.dsl#L12164-L12216
+
+Signed-off-by: Tsuchiya Yuto <kitakar@gmail.com>
+Patchset: wifi
+---
+ drivers/net/wireless/marvell/mwifiex/pcie.c   | 10 +++
+ .../wireless/marvell/mwifiex/pcie_quirks.c    | 77 ++++++++++++++++++-
+ .../wireless/marvell/mwifiex/pcie_quirks.h    |  5 ++
+ 3 files changed, 91 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c
+index 408fe05b9384..290427c98630 100644
+--- a/drivers/net/wireless/marvell/mwifiex/pcie.c
++++ b/drivers/net/wireless/marvell/mwifiex/pcie.c
+@@ -2817,6 +2817,16 @@ static void mwifiex_pcie_card_reset_work(struct mwifiex_adapter *adapter)
+ {
+ 	struct pcie_service_card *card = adapter->card;
+ 
++	/* On Surface 3, reset_wsid method removes then re-probes card by
++	 * itself. So, need to place it here and skip performing any other
++	 * reset-related works.
++	 */
++	if (card->quirks & QUIRK_FW_RST_WSID_S3) {
++		mwifiex_pcie_reset_wsid_quirk(card->dev);
++		/* skip performing any other reset-related works */
++		return;
++	}
++
+ 	/* We can't afford to wait here; remove() might be waiting on us. If we
+ 	 * can't grab the device lock, maybe we'll get another chance later.
+ 	 */
+diff --git a/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c
+index edc739c542fe..f0a6fa0a7ae5 100644
+--- a/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c
++++ b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c
+@@ -9,10 +9,21 @@
+  * down, or causes NULL ptr deref).
+  */
+ 
++#include <linux/acpi.h>
+ #include <linux/dmi.h>
+ 
+ #include "pcie_quirks.h"
+ 
++/* For reset_wsid quirk */
++#define ACPI_WSID_PATH		"\\_SB.WSID"
++#define WSID_REV		0x0
++#define WSID_FUNC_WIFI_PWR_OFF	0x1
++#define WSID_FUNC_WIFI_PWR_ON	0x2
++/* WSID _DSM UUID: "534ea3bf-fcc2-4e7a-908f-a13978f0c7ef" */
++static const guid_t wsid_dsm_guid =
++	GUID_INIT(0x534ea3bf, 0xfcc2, 0x4e7a,
++		  0x90, 0x8f, 0xa1, 0x39, 0x78, 0xf0, 0xc7, 0xef);
++
+ /* quirk table based on DMI matching */
+ static const struct dmi_system_id mwifiex_quirk_table[] = {
+ 	{
+@@ -87,7 +98,7 @@ static const struct dmi_system_id mwifiex_quirk_table[] = {
+ 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
+ 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface 3"),
+ 		},
+-		.driver_data = 0,
++		.driver_data = (void *)QUIRK_FW_RST_WSID_S3,
+ 	},
+ 	{
+ 		.ident = "Surface Pro 3",
+@@ -113,6 +124,9 @@ void mwifiex_initialize_quirks(struct pcie_service_card *card)
+ 		dev_info(&pdev->dev, "no quirks enabled\n");
+ 	if (card->quirks & QUIRK_FW_RST_D3COLD)
+ 		dev_info(&pdev->dev, "quirk reset_d3cold enabled\n");
++	if (card->quirks & QUIRK_FW_RST_WSID_S3)
++		dev_info(&pdev->dev,
++			 "quirk reset_wsid for Surface 3 enabled\n");
+ }
+ 
+ static void mwifiex_pcie_set_power_d3cold(struct pci_dev *pdev)
+@@ -169,3 +183,64 @@ int mwifiex_pcie_reset_d3cold_quirk(struct pci_dev *pdev)
+ 
+ 	return 0;
+ }
 +
 +int mwifiex_pcie_reset_wsid_quirk(struct pci_dev *pdev)
 +{
@@ -585,53 +776,651 @@ index 000000000000..34dcd84f02a6
 +	return 0;
 +}
 diff --git a/drivers/net/wireless/marvell/mwifiex/pcie_quirks.h b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.h
-new file mode 100644
-index 000000000000..3ef7440418e3
---- /dev/null
+index 8b9dcb5070d8..3ef7440418e3 100644
+--- a/drivers/net/wireless/marvell/mwifiex/pcie_quirks.h
 +++ b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.h
-@@ -0,0 +1,17 @@
-+/* SPDX-License-Identifier: GPL-2.0 */
-+/*
-+ * Header file for PCIe quirks.
-+ */
-+
-+#include "pcie.h"
-+
-+/* quirks */
-+#define QUIRK_FW_RST_D3COLD	BIT(0)
+@@ -7,6 +7,11 @@
+ 
+ /* quirks */
+ #define QUIRK_FW_RST_D3COLD	BIT(0)
 +/* Surface 3 and Surface Pro 3 have the same _DSM method but need to
 + * be handled differently. Currently, only S3 is supported.
 + */
 +#define QUIRK_FW_RST_WSID_S3	BIT(1)
-+
-+void mwifiex_initialize_quirks(struct pcie_service_card *card);
-+int mwifiex_pcie_reset_d3cold_quirk(struct pci_dev *pdev);
+ 
+ void mwifiex_initialize_quirks(struct pcie_service_card *card);
+ int mwifiex_pcie_reset_d3cold_quirk(struct pci_dev *pdev);
 +int mwifiex_pcie_reset_wsid_quirk(struct pci_dev *pdev);
+-- 
+2.28.0
+
+From 570dab9301a4f95fc96f635b3d58d55a39ba2fcf Mon Sep 17 00:00:00 2001
+From: Tsuchiya Yuto <kitakar@gmail.com>
+Date: Wed, 30 Sep 2020 18:08:24 +0900
+Subject: [PATCH] mwifiex: pcie: (OEMB) add quirk for Surface 3 with broken DMI
+ table
+
+(made referring to http://git.osdn.net/view?p=android-x86/kernel.git;a=commitdiff;h=18e2e857c57633b25b3b4120f212224a108cd883)
+
+On some Surface 3, the DMI table gets corrupted for unknown reasons
+and breaks existing DMI matching used for device-specific quirks.
+
+This commit adds the (broken) DMI info for the affected Surface 3.
+
+On affected systems, DMI info will look like this:
+    $ grep . /sys/devices/virtual/dmi/id/{bios_vendor,board_name,board_vendor,\
+    chassis_vendor,product_name,sys_vendor}
+    /sys/devices/virtual/dmi/id/bios_vendor:American Megatrends Inc.
+    /sys/devices/virtual/dmi/id/board_name:OEMB
+    /sys/devices/virtual/dmi/id/board_vendor:OEMB
+    /sys/devices/virtual/dmi/id/chassis_vendor:OEMB
+    /sys/devices/virtual/dmi/id/product_name:OEMB
+    /sys/devices/virtual/dmi/id/sys_vendor:OEMB
+
+Expected:
+    $ grep . /sys/devices/virtual/dmi/id/{bios_vendor,board_name,board_vendor,\
+    chassis_vendor,product_name,sys_vendor}
+    /sys/devices/virtual/dmi/id/bios_vendor:American Megatrends Inc.
+    /sys/devices/virtual/dmi/id/board_name:Surface 3
+    /sys/devices/virtual/dmi/id/board_vendor:Microsoft Corporation
+    /sys/devices/virtual/dmi/id/chassis_vendor:Microsoft Corporation
+    /sys/devices/virtual/dmi/id/product_name:Surface 3
+    /sys/devices/virtual/dmi/id/sys_vendor:Microsoft Corporation
+
+Signed-off-by: Tsuchiya Yuto <kitakar@gmail.com>
+Patchset: wifi
+---
+ drivers/net/wireless/marvell/mwifiex/pcie_quirks.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c
+index f0a6fa0a7ae5..34dcd84f02a6 100644
+--- a/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c
++++ b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c
+@@ -100,6 +100,15 @@ static const struct dmi_system_id mwifiex_quirk_table[] = {
+ 		},
+ 		.driver_data = (void *)QUIRK_FW_RST_WSID_S3,
+ 	},
++	{
++		.ident = "Surface 3",
++		.matches = {
++			DMI_EXACT_MATCH(DMI_BIOS_VENDOR, "American Megatrends Inc."),
++			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "OEMB"),
++			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "OEMB"),
++		},
++		.driver_data = (void *)QUIRK_FW_RST_WSID_S3,
++	},
+ 	{
+ 		.ident = "Surface Pro 3",
+ 		.matches = {
+-- 
+2.28.0
+
+From 34c2ccb41cddec7c3346d11808008d2c00897c8d Mon Sep 17 00:00:00 2001
+From: Tsuchiya Yuto <kitakar@gmail.com>
+Date: Thu, 24 Sep 2020 01:56:29 +0900
+Subject: [PATCH] mwifiex: fix mwifiex_shutdown_sw() causing sw reset failure
+
+When FLR is performed but without fw reset for some reasons (e.g. on
+Surface devices, fw reset requires another quirk), it fails to reset
+properly. You can trigger the issue on such devices via debugfs entry
+for reset:
+
+    $ echo 1 | sudo tee /sys/kernel/debug/mwifiex/mlan0/reset
+
+and the resulting dmesg log:
+
+    mwifiex_pcie 0000:03:00.0: Resetting per request
+    mwifiex_pcie 0000:03:00.0: info: successfully disconnected from [BSSID]: reason code 3
+    mwifiex_pcie 0000:03:00.0: PREP_CMD: card is removed
+    mwifiex_pcie 0000:03:00.0: deleting the crypto keys
+    mwifiex_pcie 0000:03:00.0: PREP_CMD: card is removed
+    mwifiex_pcie 0000:03:00.0: deleting the crypto keys
+    mwifiex_pcie 0000:03:00.0: PREP_CMD: card is removed
+    mwifiex_pcie 0000:03:00.0: deleting the crypto keys
+    mwifiex_pcie 0000:03:00.0: PREP_CMD: card is removed
+    mwifiex_pcie 0000:03:00.0: deleting the crypto keys
+    mwifiex_pcie 0000:03:00.0: PREP_CMD: card is removed
+    mwifiex_pcie 0000:03:00.0: deleting the crypto keys
+    mwifiex_pcie 0000:03:00.0: PREP_CMD: card is removed
+    mwifiex_pcie 0000:03:00.0: deleting the crypto keys
+    mwifiex_pcie 0000:03:00.0: info: shutdown mwifiex...
+    mwifiex_pcie 0000:03:00.0: PREP_CMD: card is removed
+    mwifiex_pcie 0000:03:00.0: PREP_CMD: card is removed
+    mwifiex_pcie 0000:03:00.0: WLAN FW already running! Skip FW dnld
+    mwifiex_pcie 0000:03:00.0: WLAN FW is active
+    mwifiex_pcie 0000:03:00.0: Unknown api_id: 4
+    mwifiex_pcie 0000:03:00.0: info: MWIFIEX VERSION: mwifiex 1.0 (15.68.19.p21)
+    mwifiex_pcie 0000:03:00.0: driver_version = mwifiex 1.0 (15.68.19.p21)
+    mwifiex_pcie 0000:03:00.0: info: trying to associate to '[SSID]' bssid [BSSID]
+    mwifiex_pcie 0000:03:00.0: info: associated to bssid [BSSID] successfully
+    mwifiex_pcie 0000:03:00.0: cmd_wait_q terminated: -110
+    mwifiex_pcie 0000:03:00.0: info: successfully disconnected from [BSSID]: reason code 15
+    mwifiex_pcie 0000:03:00.0: cmd_wait_q terminated: -110
+    mwifiex_pcie 0000:03:00.0: deleting the crypto keys
+    mwifiex_pcie 0000:03:00.0: cmd_wait_q terminated: -110
+    mwifiex_pcie 0000:03:00.0: deleting the crypto keys
+    mwifiex_pcie 0000:03:00.0: cmd_wait_q terminated: -110
+    mwifiex_pcie 0000:03:00.0: deleting the crypto keys
+    [...]
+
+When comparing mwifiex_shutdown_sw() with mwifiex_pcie_remove(), it
+lacks mwifiex_init_shutdown_fw().
+
+This commit fixes mwifiex_shutdown_sw() by adding the missing
+mwifiex_init_shutdown_fw().
+
+Fixes: 4c5dae59d2e9 ("mwifiex: add PCIe function level reset support")
+Signed-off-by: Tsuchiya Yuto <kitakar@gmail.com>
+Patchset: wifi
+---
+ drivers/net/wireless/marvell/mwifiex/main.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/wireless/marvell/mwifiex/main.c b/drivers/net/wireless/marvell/mwifiex/main.c
+index e48b47f42554..ceac611ef086 100644
+--- a/drivers/net/wireless/marvell/mwifiex/main.c
++++ b/drivers/net/wireless/marvell/mwifiex/main.c
+@@ -1474,6 +1474,8 @@ int mwifiex_shutdown_sw(struct mwifiex_adapter *adapter)
+ 	priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
+ 	mwifiex_deauthenticate(priv, NULL);
+ 
++	mwifiex_init_shutdown_fw(priv, MWIFIEX_FUNC_SHUTDOWN);
++
+ 	mwifiex_uninit_sw(adapter);
+ 
+ 	if (adapter->if_ops.down_dev)
+-- 
+2.28.0
+
+From 2c363d783f3605142464fa5049101a76b01df40d Mon Sep 17 00:00:00 2001
+From: Tsuchiya Yuto <kitakar@gmail.com>
+Date: Thu, 24 Sep 2020 01:56:34 +0900
+Subject: [PATCH] mwifiex: pcie: use shutdown_sw()/reinit_sw() on
+ suspend()/resume()
+
+There are issues with S0ix achievement and AP scanning after suspend
+with the current Host Sleep method.
+
+When using the Host Sleep method, it prevents the platform to reach S0ix
+during suspend. Also, after suspend, sometimes AP scanning won't work,
+resulting in non-working wifi.
+
+To fix such issues, perform shutdown_sw()/reinit_sw() instead of Host
+Sleep.
+
+As a side effect, this patch disables wakeups (means that Wake-On-WLAN
+can't be used anymore, if it was working before), and might also reset
+some internal states.
+
+Note that suspend() no longer checks if it's already suspended.
+
+With the previous Host Sleep method, the check was done by looking at
+adapter->hs_activated in mwifiex_enable_hs() [sta_ioctl.c], but not
+MWIFIEX_IS_SUSPENDED. So, what the previous method checked was instead
+Host Sleep state, not suspend itself. Therefore, there is no need to check
+the suspend state now.
+
+Also removed comment for suspend state check at top of suspend()
+accordingly.
+
+Signed-off-by: Tsuchiya Yuto <kitakar@gmail.com>
+Patchset: wifi
+---
+ drivers/net/wireless/marvell/mwifiex/main.c |  4 +--
+ drivers/net/wireless/marvell/mwifiex/pcie.c | 29 +++++++--------------
+ 2 files changed, 12 insertions(+), 21 deletions(-)
+
+diff --git a/drivers/net/wireless/marvell/mwifiex/main.c b/drivers/net/wireless/marvell/mwifiex/main.c
+index ceac611ef086..55b71e3d0127 100644
+--- a/drivers/net/wireless/marvell/mwifiex/main.c
++++ b/drivers/net/wireless/marvell/mwifiex/main.c
+@@ -1458,7 +1458,7 @@ static void mwifiex_uninit_sw(struct mwifiex_adapter *adapter)
+ }
+ 
+ /*
+- * This function gets called during PCIe function level reset.
++ * This function can be used for shutting down the adapter SW.
+  */
+ int mwifiex_shutdown_sw(struct mwifiex_adapter *adapter)
+ {
+@@ -1485,7 +1485,7 @@ int mwifiex_shutdown_sw(struct mwifiex_adapter *adapter)
+ }
+ EXPORT_SYMBOL_GPL(mwifiex_shutdown_sw);
+ 
+-/* This function gets called during PCIe function level reset. Required
++/* This function can be used for reinitting the adapter SW. Required
+  * code is extracted from mwifiex_add_card()
+  */
+ int
+diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c
+index 290427c98630..d80eb18fb0d1 100644
+--- a/drivers/net/wireless/marvell/mwifiex/pcie.c
++++ b/drivers/net/wireless/marvell/mwifiex/pcie.c
+@@ -145,8 +145,7 @@ static bool mwifiex_pcie_ok_to_access_hw(struct mwifiex_adapter *adapter)
+  * registered functions must have drivers with suspend and resume
+  * methods. Failing that the kernel simply removes the whole card.
+  *
+- * If already not suspended, this function allocates and sends a host
+- * sleep activate request to the firmware and turns off the traffic.
++ * This function shuts down the adapter.
+  */
+ static int mwifiex_pcie_suspend(struct device *dev)
+ {
+@@ -154,31 +153,21 @@ static int mwifiex_pcie_suspend(struct device *dev)
+ 	struct pcie_service_card *card = dev_get_drvdata(dev);
+ 
+ 
+-	/* Might still be loading firmware */
+-	wait_for_completion(&card->fw_done);
+-
+ 	adapter = card->adapter;
+ 	if (!adapter) {
+ 		dev_err(dev, "adapter is not valid\n");
+ 		return 0;
+ 	}
+ 
+-	mwifiex_enable_wake(adapter);
+-
+-	/* Enable the Host Sleep */
+-	if (!mwifiex_enable_hs(adapter)) {
++	/* Shut down SW */
++	if (mwifiex_shutdown_sw(adapter)) {
+ 		mwifiex_dbg(adapter, ERROR,
+ 			    "cmd: failed to suspend\n");
+-		clear_bit(MWIFIEX_IS_HS_ENABLING, &adapter->work_flags);
+-		mwifiex_disable_wake(adapter);
+ 		return -EFAULT;
+ 	}
+ 
+-	flush_workqueue(adapter->workqueue);
+-
+ 	/* Indicate device suspended */
+ 	set_bit(MWIFIEX_IS_SUSPENDED, &adapter->work_flags);
+-	clear_bit(MWIFIEX_IS_HS_ENABLING, &adapter->work_flags);
+ 
+ 	return 0;
+ }
+@@ -188,13 +177,13 @@ static int mwifiex_pcie_suspend(struct device *dev)
+  * registered functions must have drivers with suspend and resume
+  * methods. Failing that the kernel simply removes the whole card.
+  *
+- * If already not resumed, this function turns on the traffic and
+- * sends a host sleep cancel request to the firmware.
++ * If already not resumed, this function reinits the adapter.
+  */
+ static int mwifiex_pcie_resume(struct device *dev)
+ {
+ 	struct mwifiex_adapter *adapter;
+ 	struct pcie_service_card *card = dev_get_drvdata(dev);
++	int ret;
+ 
+ 
+ 	if (!card->adapter) {
+@@ -212,9 +201,11 @@ static int mwifiex_pcie_resume(struct device *dev)
+ 
+ 	clear_bit(MWIFIEX_IS_SUSPENDED, &adapter->work_flags);
+ 
+-	mwifiex_cancel_hs(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA),
+-			  MWIFIEX_ASYNC_CMD);
+-	mwifiex_disable_wake(adapter);
++	ret = mwifiex_reinit_sw(adapter);
++	if (ret)
++		dev_err(dev, "reinit failed: %d\n", ret);
++	else
++		mwifiex_dbg(adapter, INFO, "%s, successful\n", __func__);
+ 
+ 	return 0;
+ }
+-- 
+2.28.0
+
+From e29ab6dce0e19ec82c04421da520d6a8cd4a7f17 Mon Sep 17 00:00:00 2001
+From: Tsuchiya Yuto <kitakar@gmail.com>
+Date: Mon, 24 Aug 2020 17:11:35 +0900
+Subject: [PATCH] mwifiex: pcie: add enable_device_dump module parameter
+
+The devicve_dump may take a little bit long time and users may want to
+disable the dump for daily usage.
+
+This commit adds a new module parameter and disables device_dump by
+default.
+
+Signed-off-by: Tsuchiya Yuto <kitakar@gmail.com>
+Patchset: wifi
+---
+ drivers/net/wireless/marvell/mwifiex/pcie.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c
+index d80eb18fb0d1..ea766584d3b7 100644
+--- a/drivers/net/wireless/marvell/mwifiex/pcie.c
++++ b/drivers/net/wireless/marvell/mwifiex/pcie.c
+@@ -34,6 +34,11 @@
+ 
+ static struct mwifiex_if_ops pcie_ops;
+ 
++static bool enable_device_dump;
++module_param(enable_device_dump, bool, 0644);
++MODULE_PARM_DESC(enable_device_dump,
++		 "enable device_dump (default: disabled)");
++
+ static const struct of_device_id mwifiex_pcie_of_match_table[] = {
+ 	{ .compatible = "pci11ab,2b42" },
+ 	{ .compatible = "pci1b4b,2b42" },
+@@ -2791,6 +2796,12 @@ static void mwifiex_pcie_fw_dump(struct mwifiex_adapter *adapter)
+ 
+ static void mwifiex_pcie_device_dump_work(struct mwifiex_adapter *adapter)
+ {
++	if (!enable_device_dump) {
++		mwifiex_dbg(adapter, MSG,
++			    "device_dump is disabled by module parameter\n");
++		return;
++	}
++
+ 	adapter->devdump_data = vzalloc(MWIFIEX_FW_DUMP_SIZE);
+ 	if (!adapter->devdump_data) {
+ 		mwifiex_dbg(adapter, ERROR,
+-- 
+2.28.0
+
+From 3cf8c0e5130ca4accf9548c6851d08ebf73b2fc6 Mon Sep 17 00:00:00 2001
+From: Tsuchiya Yuto <kitakar@gmail.com>
+Date: Sun, 4 Oct 2020 00:11:49 +0900
+Subject: [PATCH] mwifiex: pcie: disable bridge_d3 for Surface gen4+
+
+Currently, mwifiex fw will crash after suspend on recent kernel series.
+On Windows, it seems that the root port of wifi will never enter D3 state
+(stay on D0 state). And on Linux, disabling the D3 state for the
+bridge fixes fw crashing after suspend.
+
+This commit disables the D3 state of root port on driver initialization
+and fixes fw crashing after suspend.
+
+Signed-off-by: Tsuchiya Yuto <kitakar@gmail.com>
+Patchset: wifi
+---
+ drivers/net/wireless/marvell/mwifiex/pcie.c   |  7 +++++
+ .../wireless/marvell/mwifiex/pcie_quirks.c    | 27 +++++++++++++------
+ .../wireless/marvell/mwifiex/pcie_quirks.h    |  1 +
+ 3 files changed, 27 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c
+index ea766584d3b7..f8c7e6ce0c3c 100644
+--- a/drivers/net/wireless/marvell/mwifiex/pcie.c
++++ b/drivers/net/wireless/marvell/mwifiex/pcie.c
+@@ -226,6 +226,7 @@ static int mwifiex_pcie_probe(struct pci_dev *pdev,
+ 					const struct pci_device_id *ent)
+ {
+ 	struct pcie_service_card *card;
++	struct pci_dev *parent_pdev = pci_upstream_bridge(pdev);
+ 	int ret;
+ 
+ 	pr_debug("info: vendor=0x%4.04X device=0x%4.04X rev=%d\n",
+@@ -267,6 +268,12 @@ static int mwifiex_pcie_probe(struct pci_dev *pdev,
+ 		return -1;
+ 	}
+ 
++	/* disable bridge_d3 for Surface gen4+ devices to fix fw crashing
++	 * after suspend
++	 */
++	if (card->quirks & QUIRK_NO_BRIDGE_D3)
++		parent_pdev->bridge_d3 = false;
++
+ 	return 0;
+ }
+ 
+diff --git a/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c
+index 34dcd84f02a6..a2aeb2af907e 100644
+--- a/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c
++++ b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c
+@@ -32,7 +32,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = {
+ 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
+ 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Pro 4"),
+ 		},
+-		.driver_data = (void *)QUIRK_FW_RST_D3COLD,
++		.driver_data = (void *)(QUIRK_FW_RST_D3COLD |
++					QUIRK_NO_BRIDGE_D3),
+ 	},
+ 	{
+ 		.ident = "Surface Pro 5",
+@@ -41,7 +42,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = {
+ 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
+ 			DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "Surface_Pro_1796"),
+ 		},
+-		.driver_data = (void *)QUIRK_FW_RST_D3COLD,
++		.driver_data = (void *)(QUIRK_FW_RST_D3COLD |
++					QUIRK_NO_BRIDGE_D3),
+ 	},
+ 	{
+ 		.ident = "Surface Pro 5 (LTE)",
+@@ -50,7 +52,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = {
+ 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
+ 			DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "Surface_Pro_1807"),
+ 		},
+-		.driver_data = (void *)QUIRK_FW_RST_D3COLD,
++		.driver_data = (void *)(QUIRK_FW_RST_D3COLD |
++					QUIRK_NO_BRIDGE_D3),
+ 	},
+ 	{
+ 		.ident = "Surface Pro 6",
+@@ -58,7 +61,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = {
+ 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
+ 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Pro 6"),
+ 		},
+-		.driver_data = (void *)QUIRK_FW_RST_D3COLD,
++		.driver_data = (void *)(QUIRK_FW_RST_D3COLD |
++					QUIRK_NO_BRIDGE_D3),
+ 	},
+ 	{
+ 		.ident = "Surface Book 1",
+@@ -66,7 +70,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = {
+ 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
+ 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Book"),
+ 		},
+-		.driver_data = (void *)QUIRK_FW_RST_D3COLD,
++		.driver_data = (void *)(QUIRK_FW_RST_D3COLD |
++					QUIRK_NO_BRIDGE_D3),
+ 	},
+ 	{
+ 		.ident = "Surface Book 2",
+@@ -74,7 +79,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = {
+ 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
+ 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Book 2"),
+ 		},
+-		.driver_data = (void *)QUIRK_FW_RST_D3COLD,
++		.driver_data = (void *)(QUIRK_FW_RST_D3COLD |
++					QUIRK_NO_BRIDGE_D3),
+ 	},
+ 	{
+ 		.ident = "Surface Laptop 1",
+@@ -82,7 +88,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = {
+ 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
+ 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Laptop"),
+ 		},
+-		.driver_data = (void *)QUIRK_FW_RST_D3COLD,
++		.driver_data = (void *)(QUIRK_FW_RST_D3COLD |
++					QUIRK_NO_BRIDGE_D3),
+ 	},
+ 	{
+ 		.ident = "Surface Laptop 2",
+@@ -90,7 +97,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = {
+ 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
+ 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Laptop 2"),
+ 		},
+-		.driver_data = (void *)QUIRK_FW_RST_D3COLD,
++		.driver_data = (void *)(QUIRK_FW_RST_D3COLD |
++					QUIRK_NO_BRIDGE_D3),
+ 	},
+ 	{
+ 		.ident = "Surface 3",
+@@ -136,6 +144,9 @@ void mwifiex_initialize_quirks(struct pcie_service_card *card)
+ 	if (card->quirks & QUIRK_FW_RST_WSID_S3)
+ 		dev_info(&pdev->dev,
+ 			 "quirk reset_wsid for Surface 3 enabled\n");
++	if (card->quirks & QUIRK_NO_BRIDGE_D3)
++		dev_info(&pdev->dev,
++			 "quirk no_brigde_d3 enabled\n");
+ }
+ 
+ static void mwifiex_pcie_set_power_d3cold(struct pci_dev *pdev)
+diff --git a/drivers/net/wireless/marvell/mwifiex/pcie_quirks.h b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.h
+index 3ef7440418e3..a95ebac06e13 100644
+--- a/drivers/net/wireless/marvell/mwifiex/pcie_quirks.h
++++ b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.h
+@@ -11,6 +11,7 @@
+  * be handled differently. Currently, only S3 is supported.
+  */
+ #define QUIRK_FW_RST_WSID_S3	BIT(1)
++#define QUIRK_NO_BRIDGE_D3	BIT(2)
+ 
+ void mwifiex_initialize_quirks(struct pcie_service_card *card);
+ int mwifiex_pcie_reset_d3cold_quirk(struct pci_dev *pdev);
+-- 
+2.28.0
+
+From 52e3edee84ced375bb626773318578f3fd020194 Mon Sep 17 00:00:00 2001
+From: Tsuchiya Yuto <kitakar@gmail.com>
+Date: Sun, 4 Oct 2020 00:25:48 +0900
+Subject: [PATCH] mwifiex: add allow_ps_mode module parameter
+
+This commit adds the allow_ps_mode module parameter and set it false
+(disallowed) by default, to make ps_mode (power_save) control easier.
+
+On some setups (e.g., with 5GHz AP), power_save causes connection
+completely unstable. So, we need to disable it. However, userspace tools
+may try to enable it. For this reason, we need to tell userspace that
+power_save is disallowed by default.
+
+When this parameter is set to false, changing the power_save mode will
+be disallowed like the following:
+
+    $ sudo iw dev mlan0 set power_save on
+    command failed: Operation not permitted (-1)
+
+Signed-off-by: Tsuchiya Yuto <kitakar@gmail.com>
+Patchset: wifi
+---
+ drivers/net/wireless/marvell/mwifiex/cfg80211.c | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+diff --git a/drivers/net/wireless/marvell/mwifiex/cfg80211.c b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
+index 650191db25cb..dd1f08a2325f 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, 0644);
++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,17 @@ mwifiex_cfg80211_set_power_mgmt(struct wiphy *wiphy,
+ 
+ 	ps_mode = enabled;
+ 
++	/* Allow ps_mode to be enabled only when allow_ps_mode is true */
++	if (ps_mode && !allow_ps_mode) {
++		mwifiex_dbg(priv->adapter, MSG,
++			    "Enabling ps_mode disallowed by modparam\n");
++
++		/* Return -EPERM to inform userspace tools that setting
++		 * power_save to be enabled is not permitted.
++		 */
++		return -EPERM;
++	}
++
+ 	return mwifiex_drv_set_power(priv, &ps_mode);
+ }
+ 
+-- 
+2.28.0
+
+From 2a4cdeb78a41d90ee8062d4ed03ad0acd7b83c71 Mon Sep 17 00:00:00 2001
+From: Tsuchiya Yuto <kitakar@gmail.com>
+Date: Sun, 4 Oct 2020 00:38:48 +0900
+Subject: [PATCH] mwifiex: print message when changing ps_mode
+
+Users may want to know the ps_mode state change (e.g., diagnosing
+connection issues). This commit adds the print when changing ps_mode.
+
+Signed-off-by: Tsuchiya Yuto <kitakar@gmail.com>
+Patchset: wifi
+---
+ drivers/net/wireless/marvell/mwifiex/cfg80211.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/drivers/net/wireless/marvell/mwifiex/cfg80211.c b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
+index dd1f08a2325f..ee88da92b97c 100644
+--- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c
++++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
+@@ -455,6 +455,13 @@ mwifiex_cfg80211_set_power_mgmt(struct wiphy *wiphy,
+ 		return -EPERM;
+ 	}
+ 
++	if (ps_mode)
++		mwifiex_dbg(priv->adapter, MSG,
++			    "Enabling ps_mode, disable if unstable.\n");
++	else
++		mwifiex_dbg(priv->adapter, MSG,
++			    "Disabling ps_mode.\n");
++
+ 	return mwifiex_drv_set_power(priv, &ps_mode);
+ }
+ 
+-- 
+2.28.0
+
+From 13febaae5f0d645765c83a0c4141514434458b39 Mon Sep 17 00:00:00 2001
+From: Tsuchiya Yuto <kitakar@gmail.com>
+Date: Sun, 4 Oct 2020 00:59:37 +0900
+Subject: [PATCH] mwifiex: disable ps_mode explicitly by default instead
+
+At least on Surface devices, the ps_mode causes connection unstable,
+especially with 5GHz APs. Then, it eventually causes fw crashing.
+
+This commit disables ps_mode by default instead of enabling it.
+
+Required code is extracted from mwifiex_drv_set_power().
+
+Signed-off-by: Tsuchiya Yuto <kitakar@gmail.com>
+Patchset: wifi
+---
+ drivers/net/wireless/marvell/mwifiex/sta_cmd.c | 11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
 diff --git a/drivers/net/wireless/marvell/mwifiex/sta_cmd.c b/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
-index 4ed10cf82f9a..bd735eb04981 100644
+index 4ed10cf82f9a..ed0fffb9eba6 100644
 --- a/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
 +++ b/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
-@@ -2339,16 +2339,10 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta, bool init)
- 		if (ret)
+@@ -2340,14 +2340,19 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta, bool init)
  			return -1;
  
--		if (priv->bss_type != MWIFIEX_BSS_TYPE_UAP) {
+ 		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,
++			/* Disable IEEE PS by default */
++			priv->adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_CAM;
+ 			ret = mwifiex_send_cmd(priv,
+ 					       HostCmd_CMD_802_11_PS_MODE_ENH,
 -					       EN_AUTO_PS, BITMAP_STA_PS, NULL,
--					       true);
--			if (ret)
--				return -1;
--		}
-+		/* Not enabling ps_mode (IEEE power_save) by default. Enabling
-+		 * this causes connection instability, especially on 5GHz APs
-+		 * and eventually causes "firmware wakeup failed". Therefore,
-+		 * the relevant code was removed from here. */
++					       DIS_AUTO_PS, BITMAP_STA_PS, NULL,
+ 					       true);
+ 			if (ret)
+ 				return -1;
++			ret = mwifiex_send_cmd(priv,
++					       HostCmd_CMD_802_11_PS_MODE_ENH,
++					       GET_PS, 0, NULL, false);
++			if (ret)
++				return -1;
+ 		}
  
  		if (drcs) {
- 			adapter->drcs_enabled = true;
 -- 
 2.28.0
 

+ 36 - 9
patches/4.19/0010-surface-gpe.patch → patches/4.19/0008-surface-gpe.patch

@@ -1,8 +1,35 @@
-From 5796288595a85c616fb0b3eabd9e7a240d519287 Mon Sep 17 00:00:00 2001
+From a80e327970c6f03b0516fd354f2df0563b1497f2 Mon Sep 17 00:00:00 2001
 From: Maximilian Luz <luzmaximilian@gmail.com>
 Date: Sun, 16 Aug 2020 23:39:56 +0200
-Subject: [PATCH 10/11] surface-gpe
+Subject: [PATCH] platform/x86: Add Driver to set up lid GPEs on MS Surface
+ device
 
+Conventionally, wake-up events for a specific device, in our case the
+lid device, are managed via the ACPI _PRW field. While this does not
+seem strictly necessary based on ACPI spec, the kernel disables GPE
+wakeups to avoid non-wakeup interrupts preventing suspend by default and
+only enables GPEs associated via the _PRW field with a wake-up capable
+device. This behavior has been introduced in commit
+
+    f941d3e41da7f86bdb9dcc1977c2bcc6b89bfe47
+    ACPI: EC / PM: Disable non-wakeup GPEs for suspend-to-idle
+
+and is described in more detail in its commit message.
+
+Unfortunately, on MS Surface devices, there is no _PRW field present on
+the lid device, thus no GPE is associated with it, and therefore the GPE
+responsible for sending the status-change notification to the lid gets
+disabled during suspend, making it impossible to wake the device via the
+lid.
+
+This patch introduces a pseudo-device and respective driver which, based
+on some DMI matching, mark the corresponding GPE of the lid device for
+wake and enable it during suspend. The behavior of this driver models
+the behavior of the ACPI/PM core for normal wakeup GPEs, properly
+declared via the _PRW field.
+
+Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com>
+Patchset: surface-gpe
 ---
  drivers/platform/x86/Kconfig       |   9 +
  drivers/platform/x86/Makefile      |   1 +
@@ -11,12 +38,12 @@ Subject: [PATCH 10/11] surface-gpe
  create mode 100644 drivers/platform/x86/surface_gpe.c
 
 diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
-index 1e1ec7e562e8..0b50f1e4c437 100644
+index 0d20ffdb5a67..cd2442056cec 100644
 --- a/drivers/platform/x86/Kconfig
 +++ b/drivers/platform/x86/Kconfig
-@@ -1175,6 +1175,15 @@ config SURFACE_BOOK1_DGPU_SWITCH
- 	  This driver provides a sysfs switch to set the power-state of the
- 	  discrete GPU found on the Microsoft Surface Book 1.
+@@ -1168,6 +1168,15 @@ config SURFACE_3_POWER_OPREGION
+ 	  Select this option to enable support for ACPI operation
+ 	  region of the Surface 3 battery platform driver.
  
 +config SURFACE_GPE
 +	tristate "Surface GPE/Lid Driver"
@@ -31,13 +58,13 @@ index 1e1ec7e562e8..0b50f1e4c437 100644
  	tristate "Intel P-Unit IPC Driver"
  	---help---
 diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
-index 3911b95487c7..0dfc55b07a48 100644
+index 2ea90039a3e4..49238e9d4abf 100644
 --- a/drivers/platform/x86/Makefile
 +++ b/drivers/platform/x86/Makefile
-@@ -83,6 +83,7 @@ obj-$(CONFIG_SURFACE_PRO3_BUTTON)	+= surfacepro3_button.o
+@@ -82,6 +82,7 @@ obj-$(CONFIG_TOUCHSCREEN_DMI)	+= touchscreen_dmi.o
+ obj-$(CONFIG_SURFACE_PRO3_BUTTON)	+= surfacepro3_button.o
  obj-$(CONFIG_SURFACE_3_BUTTON)	+= surface3_button.o
  obj-$(CONFIG_SURFACE_3_POWER_OPREGION) += surface3_power.o
- obj-$(CONFIG_SURFACE_BOOK1_DGPU_SWITCH)	+= sb1_dgpu_sw.o
 +obj-$(CONFIG_SURFACE_GPE)	+= surface_gpe.o
  obj-$(CONFIG_INTEL_PUNIT_IPC)  += intel_punit_ipc.o
  obj-$(CONFIG_INTEL_BXTWC_PMIC_TMU)	+= intel_bxtwc_tmu.o

+ 82 - 15
patches/4.19/0009-surface-sam-over-hid.patch

@@ -1,15 +1,57 @@
-From b91f59f3002ceab95cae05a5bc6c9428063b1485 Mon Sep 17 00:00:00 2001
+From bcb8584fbaa4854a8bcfc35c167712df1230cd5a Mon Sep 17 00:00:00 2001
 From: Maximilian Luz <luzmaximilian@gmail.com>
 Date: Sat, 25 Jul 2020 17:19:53 +0200
-Subject: [PATCH 09/11] surface-sam-over-hid
+Subject: [PATCH] i2c: acpi: Implement RawBytes read access
 
+Microsoft Surface Pro 4 and Book 1 devices access the MSHW0030 I2C
+device via a generic serial bus operation region and RawBytes read
+access. On the Surface Book 1, this access is required to turn on (and
+off) the discrete GPU.
+
+Multiple things are to note here:
+
+a) The RawBytes access is device/driver dependent. The ACPI
+   specification states:
+
+   > Raw accesses assume that the writer has knowledge of the bus that
+   > the access is made over and the device that is being accessed. The
+   > protocol may only ensure that the buffer is transmitted to the
+   > appropriate driver, but the driver must be able to interpret the
+   > buffer to communicate to a register.
+
+   Thus this implementation may likely not work on other devices
+   accessing I2C via the RawBytes accessor type.
+
+b) The MSHW0030 I2C device is an HID-over-I2C device which seems to
+   serve multiple functions:
+
+   1. It is the main access point for the legacy-type Surface Aggregator
+      Module (also referred to as SAM-over-HID, as opposed to the newer
+      SAM-over-SSH/UART). It has currently not been determined on how
+      support for the legacy SAM should be implemented. Likely via a
+      custom HID driver.
+
+   2. It seems to serve as the HID device for the Integrated Sensor Hub.
+      This might complicate matters with regards to implementing a
+      SAM-over-HID driver required by legacy SAM.
+
+In light of this, the simplest approach has been chosen for now.
+However, it may make more sense regarding breakage and compatibility to
+either provide functionality for replacing or enhancing the default
+operation region handler via some additional API functions, or even to
+completely blacklist MSHW0030 from the I2C core and provide a custom
+driver for it.
+
+Replacing/enhancing the default operation region handler would, however,
+either require some sort of secondary driver and access point for it,
+from which the new API functions would be called and the new handler
+(part) would be installed, or hard-coding them via some sort of
+quirk-like interface into the I2C core.
+
+Patchset: surface-sam-over-hid
 ---
- drivers/i2c/i2c-core-acpi.c        |  35 +++++++
- drivers/platform/x86/Kconfig       |   7 ++
- drivers/platform/x86/Makefile      |   1 +
- drivers/platform/x86/sb1_dgpu_sw.c | 162 +++++++++++++++++++++++++++++
- 4 files changed, 205 insertions(+)
- create mode 100644 drivers/platform/x86/sb1_dgpu_sw.c
+ drivers/i2c/i2c-core-acpi.c | 35 +++++++++++++++++++++++++++++++++++
+ 1 file changed, 35 insertions(+)
 
 diff --git a/drivers/i2c/i2c-core-acpi.c b/drivers/i2c/i2c-core-acpi.c
 index eb0569359387..c2b5a2aca731 100644
@@ -64,13 +106,38 @@ index eb0569359387..c2b5a2aca731 100644
  	default:
  		dev_warn(&adapter->dev, "protocol 0x%02x not supported for client 0x%02x\n",
  			 accessor_type, client->addr);
+-- 
+2.28.0
+
+From 53e895a0bfdf74dddb2f295f4d4e1ab93229fc40 Mon Sep 17 00:00:00 2001
+From: Maximilian Luz <luzmaximilian@gmail.com>
+Date: Sun, 6 Sep 2020 04:01:19 +0200
+Subject: [PATCH] platform/x86: Add driver for Surface Book 1 dGPU switch
+
+Add driver exposing the discrete GPU power-switch of the  Microsoft
+Surface Book 1 to user-space.
+
+On the Surface Book 1, the dGPU power is controlled via the Surface
+System Aggregator Module (SAM). The specific SAM-over-HID command for
+this is exposed via ACPI. This module provides a simple driver exposing
+the ACPI call via a sysfs parameter to user-space, so that users can
+easily power-on/-off the dGPU.
+
+Patchset: surface-sam-over-hid
+---
+ drivers/platform/x86/Kconfig       |   7 ++
+ drivers/platform/x86/Makefile      |   1 +
+ drivers/platform/x86/sb1_dgpu_sw.c | 162 +++++++++++++++++++++++++++++
+ 3 files changed, 170 insertions(+)
+ create mode 100644 drivers/platform/x86/sb1_dgpu_sw.c
+
 diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
-index 0d20ffdb5a67..1e1ec7e562e8 100644
+index cd2442056cec..52fdf87b21f2 100644
 --- a/drivers/platform/x86/Kconfig
 +++ b/drivers/platform/x86/Kconfig
-@@ -1168,6 +1168,13 @@ config SURFACE_3_POWER_OPREGION
- 	  Select this option to enable support for ACPI operation
- 	  region of the Surface 3 battery platform driver.
+@@ -1177,6 +1177,13 @@ config SURFACE_GPE
+ 	  accordingly. It is required on those devices to allow wake-ups from
+ 	  suspend by opening the lid.
  
 +config SURFACE_BOOK1_DGPU_SWITCH
 +	tristate "Surface Book 1 dGPU Switch Driver"
@@ -83,13 +150,13 @@ index 0d20ffdb5a67..1e1ec7e562e8 100644
  	tristate "Intel P-Unit IPC Driver"
  	---help---
 diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
-index 2ea90039a3e4..3911b95487c7 100644
+index 49238e9d4abf..6b028d1ee802 100644
 --- a/drivers/platform/x86/Makefile
 +++ b/drivers/platform/x86/Makefile
-@@ -82,6 +82,7 @@ obj-$(CONFIG_TOUCHSCREEN_DMI)	+= touchscreen_dmi.o
- obj-$(CONFIG_SURFACE_PRO3_BUTTON)	+= surfacepro3_button.o
+@@ -83,6 +83,7 @@ obj-$(CONFIG_SURFACE_PRO3_BUTTON)	+= surfacepro3_button.o
  obj-$(CONFIG_SURFACE_3_BUTTON)	+= surface3_button.o
  obj-$(CONFIG_SURFACE_3_POWER_OPREGION) += surface3_power.o
+ obj-$(CONFIG_SURFACE_GPE)	+= surface_gpe.o
 +obj-$(CONFIG_SURFACE_BOOK1_DGPU_SWITCH)	+= sb1_dgpu_sw.o
  obj-$(CONFIG_INTEL_PUNIT_IPC)  += intel_punit_ipc.o
  obj-$(CONFIG_INTEL_BXTWC_PMIC_TMU)	+= intel_bxtwc_tmu.o

Разница между файлами не показана из-за своего большого размера
+ 1623 - 520
patches/4.19/0010-surface-sam.patch


+ 3 - 3
patches/4.19/0011-i2c-core-Restore-acpi_walk_dep_device_list-getting-c.patch

@@ -1,8 +1,8 @@
-From e134b2f1c836a5beef7d16d86393744387bb4830 Mon Sep 17 00:00:00 2001
+From c523e2ba98307da63f228ec499d9f011e4ebd916 Mon Sep 17 00:00:00 2001
 From: Hans de Goede <hdegoede@redhat.com>
 Date: Wed, 14 Oct 2020 16:41:58 +0200
-Subject: [PATCH 11/11] i2c: core: Restore acpi_walk_dep_device_list() getting
- called after registering the ACPI i2c devs
+Subject: [PATCH] i2c: core: Restore acpi_walk_dep_device_list() getting called
+ after registering the ACPI i2c devs
 
 Commit 21653a4181ff ("i2c: core: Call i2c_acpi_install_space_handler()
 before i2c_acpi_register_devices()")'s intention was to only move the

+ 1 - 0
pkg/arch/kernel-lts/0008-surface-gpe.patch

@@ -0,0 +1 @@
+../../../patches/4.19/0008-surface-gpe.patch

+ 0 - 1
pkg/arch/kernel-lts/0008-surface-sam.patch

@@ -1 +0,0 @@
-../../../patches/4.19/0008-surface-sam.patch

+ 0 - 1
pkg/arch/kernel-lts/0010-surface-gpe.patch

@@ -1 +0,0 @@
-../../../patches/4.19/0010-surface-gpe.patch

+ 1 - 0
pkg/arch/kernel-lts/0010-surface-sam.patch

@@ -0,0 +1 @@
+../../../patches/4.19/0010-surface-sam.patch

+ 13 - 13
pkg/arch/kernel-lts/PKGBUILD

@@ -27,9 +27,9 @@ source=(
   0005-suspend.patch
   0006-ipts.patch
   0007-wifi.patch
-  0008-surface-sam.patch
+  0008-surface-gpe.patch
   0009-surface-sam-over-hid.patch
-  0010-surface-gpe.patch
+  0010-surface-sam.patch
   0011-i2c-core-Restore-acpi_walk_dep_device_list-getting-c.patch
 )
 validpgpkeys=(
@@ -42,17 +42,17 @@ sha256sums=('c7b134c6d45f77df0909c225300e64379d7f9d69abd9ad73ff6a289aa2b6a36e'
             '4e68572e7cc4c5368f0236e0792660ae8498373988625dca46e509399a7eaea6'
             'a13581d3c6dc595206e4fe7fcf6b542e7a1bdbe96101f0f010fc5be49f99baf2'
             '1c4963e4a911e74ed56f1fe0065c31201edca9a5e3f89eb30b7063f9981ebdd8'
-            '3892c3974f53e87e2efa059326359c3108bba1a411eecd5a2b614174384e8755'
-            'e73d7567a23d10babda2124a65337c8f57ff61fbb1c65a629afdfcc7a3d542e2'
-            '33c4264b920e2e4466de8369e3f2fcf3383c2e0eb68dacff82e107ae9f8d2354'
-            '20c72eea089af4ca105bec93bd7c7e91c2e8fbe5d24c88188e4ca2c77699a7ab'
-            '776ce945b51e59c543e19cc9e006b5047b22ec06255c2cce1163152aa3c65894'
-            '6185565a16689190140e6fe19df4d51fac4eeb1ac4a927855ec555f2274d7d0c'
-            'd205cf4756307c6c0909e26ca4b2ca45354a82df29255cd5809caf4b6aed41e1'
-            '0f5f2b61befacc735689604af5f6641b6b490d83745f4c78d13e9d2621e6f383'
-            '227182760913e58b9e42efd3315136379bd2c0a6cb5116ac7659baf98a40dcfe'
-            'f50f44b4c132387923ee0fd1209ec860e4ab9d33ef03155ae36596d52f8e3ae4'
-            '2de700c366cf3273f49d02efc5dc0416a5ff12eccf3d7847f21f1923458f1883')
+            '111b4f7814d49c06f3f328feba30c8991e423acce36aa9c737a31489a64b9e5d'
+            'b85aa40e2c3c04514aa14538c7486653cc987276acffae532e3b8516d3328bfc'
+            '602fb64b0b2073e0b016f39be34d86113fb0b3e63b4490cc26611d1313b3665e'
+            '99bc4ce339713433a06d936bb6c339d2797b6bec8e7af91be017bcf30bc658b3'
+            '0d0bd51185191cdc29405db26cfa8d79debb85aa090931672b8ac5c3ee4a7e10'
+            '0383649af9c5f63c47b515d03e9279a4090fec1fb32a9d47692a491c80f5a1b5'
+            'e5fd01b8fdb8c53f46ac58fdffd4d7a75f009217e5f2a484ac00a6bb9968eab4'
+            '4a5c643ec9a3c3e15ceff45e024fce0462dc314b516fe0620de6858178d96fc8'
+            'f28bc22540ad92769c4bd787140ab759f665f262f1c9cb8827010d8c8f6c5d4c'
+            '71deb9a7421a7ba3be46059e5246a2900b1d1cd206339716f1fb9f1c848731d7'
+            '12dd1c955d2b9123afaad2690d65905ea394f297ba27ab4fec32dd5655553c8c')
 
 export KBUILD_BUILD_HOST=archlinux
 export KBUILD_BUILD_USER=$pkgbase

Некоторые файлы не были показаны из-за большого количества измененных файлов