Browse Source

Update v5.8 patches

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

 - IPTS:
   This implements a new and refined UAPI interface that should improve
   stability during suspend and move some responsibility into userspace,
   making the driver simpler.

   It also fixes some sleep issues due to improper shutdown of the device.

   Shortlog:
     0a4a44c Add missing include
     31ae03d Improve error handling of ipts_control_* functions
     287dea0 Prevent lockups if stop is called from the receiver thread
     b737a9c On remove, wait until CLEAR_MEM_WINDOW returned.
     c5b66a5 Add GET_DEVICE_READY ioctl
     af0f84a Seperate UAPI initialization and device probing
     4ae7674 Patch the MEI bus to allow sending commands on remove
     27772bc Just a few refactorings...

Links:
- SAM: https://github.com/linux-surface/surface-aggregator-module/commit/af4bb01042d8ab707d8a73d4ee7ff770223a1c2f
- IPTS: https://github.com/linux-surface/intel-precise-touch/commit/0a4a44c2a9b676bd25d1cd916118dcfe3f447849
- kernel: https://github.com/linux-surface/kernel/commit/6e8bb10ad83dee8c6f5f02dc08b2e2d7e5ea3b19
Maximilian Luz 4 years ago
parent
commit
7c0e669f67

+ 34 - 4
patches/5.8/0001-surface3-oemb.patch

@@ -1,8 +1,38 @@
-From 463107b4f3a4b794406270c8333e66619bdadf05 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 1/7] surface3-oemb
+From 783117ef972d0dcc29d1065e4609690c9093a8c3 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 +++++++
  drivers/platform/x86/surface3-wmi.c               | 7 +++++++
  sound/soc/codecs/rt5645.c                         | 9 +++++++++
  sound/soc/codecs/rt5645.c                         | 9 +++++++++

+ 1126 - 360
patches/5.8/0002-wifi.patch

@@ -1,248 +1,116 @@
-From e9076b84d446d05265717b73de4f77e302e78598 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 2/7] wifi
+From c6be0add7574727c5ab9081ff4b46b4f6ef1fdf5 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/Makefile |   1 +
- .../net/wireless/marvell/mwifiex/cfg80211.c   |  26 ++
- drivers/net/wireless/marvell/mwifiex/main.c   |   6 +-
- drivers/net/wireless/marvell/mwifiex/pcie.c   |  84 ++++--
- 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, 374 insertions(+), 32 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 | 18 +++++++++++++++++-
+ drivers/net/wireless/marvell/mwifiex/pcie.h |  2 ++
+ 2 files changed, 19 insertions(+), 1 deletion(-)
 
 
-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 4e4f59c17ded..528eedfbf41c 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) |
-@@ -434,6 +439,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 529099137644..a26eb66865e2 100644
---- a/drivers/net/wireless/marvell/mwifiex/main.c
-+++ b/drivers/net/wireless/marvell/mwifiex/main.c
-@@ -1453,7 +1453,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)
- {
-@@ -1469,6 +1469,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);
- 	adapter->is_up = false;
- 
-@@ -1479,7 +1481,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
 diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c
-index 87b4ccca4b9a..696fa48c1ef5 100644
+index 87b4ccca4b9a..00138d6129f4 100644
 --- a/drivers/net/wireless/marvell/mwifiex/pcie.c
 --- a/drivers/net/wireless/marvell/mwifiex/pcie.c
 +++ b/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,8 +150,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)
- {
-@@ -153,31 +158,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;
- }
-@@ -187,13 +182,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) {
-@@ -211,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;
- }
-@@ -229,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);
- 
-@@ -261,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__);
-@@ -376,7 +381,16 @@ static void mwifiex_pcie_reset_prepare(struct pci_dev *pdev)
- 	mwifiex_shutdown_sw(adapter);
+@@ -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_DEVICE_DUMP, &card->work_flags);
  	clear_bit(MWIFIEX_IFACE_WORK_CARD_RESET, &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__);
  	mwifiex_dbg(adapter, INFO, "%s, successful\n", __func__);
 +
 +
 +	card->pci_reset_ongoing = true;
 +	card->pci_reset_ongoing = true;
  }
  }
  
  
  /*
  /*
-@@ -405,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);
  		dev_err(&pdev->dev, "reinit failed: %d\n", ret);
  	else
  	else
  		mwifiex_dbg(adapter, INFO, "%s, successful\n", __func__);
  		mwifiex_dbg(adapter, INFO, "%s, successful\n", __func__);
@@ -251,37 +119,7 @@ index 87b4ccca4b9a..696fa48c1ef5 100644
  }
  }
  
  
  static const struct pci_error_handlers mwifiex_pcie_err_handler = {
  static const struct pci_error_handlers mwifiex_pcie_err_handler = {
-@@ -2785,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,
-@@ -2802,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.
- 	 */
-@@ -2995,7 +3027,19 @@ static void mwifiex_cleanup_pcie(struct mwifiex_adapter *adapter)
+@@ -2995,7 +2999,19 @@ static void mwifiex_cleanup_pcie(struct mwifiex_adapter *adapter)
  	int ret;
  	int ret;
  	u32 fw_status;
  	u32 fw_status;
  
  
@@ -303,51 +141,110 @@ index 87b4ccca4b9a..696fa48c1ef5 100644
  	ret = mwifiex_read_reg(adapter, reg->fw_status, &fw_status);
  	ret = mwifiex_read_reg(adapter, reg->fw_status, &fw_status);
  	if (fw_status == FIRMWARE_READY_PCIE) {
  	if (fw_status == FIRMWARE_READY_PCIE) {
 diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.h b/drivers/net/wireless/marvell/mwifiex/pcie.h
 diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.h b/drivers/net/wireless/marvell/mwifiex/pcie.h
-index fc59b522f670..51566380f8da 100644
+index fc59b522f670..048f4db6027a 100644
 --- a/drivers/net/wireless/marvell/mwifiex/pcie.h
 --- a/drivers/net/wireless/marvell/mwifiex/pcie.h
 +++ b/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 mwifiex_msix_context share_irq_ctx;
  	struct work_struct work;
  	struct work_struct work;
  	unsigned long work_flags;
  	unsigned long work_flags;
 +
 +
 +	bool pci_reset_ongoing;
 +	bool pci_reset_ongoing;
-+	unsigned long quirks;
  };
  };
  
  
  static inline int
  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);
-+
+-- 
+2.28.0
+
+From 2b463669a76bc7cc2146481fd131cbc1233b9711 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 00138d6129f4..899ce2657880 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 048f4db6027a..51566380f8da 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 */
 +/* quirk table based on DMI matching */
 +static const struct dmi_system_id mwifiex_quirk_table[] = {
 +static const struct dmi_system_id mwifiex_quirk_table[] = {
 +	{
 +	{
@@ -356,7 +253,7 @@ index 000000000000..34dcd84f02a6
 +			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
 +			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
 +			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Pro 4"),
 +			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Pro 4"),
 +		},
 +		},
-+		.driver_data = (void *)QUIRK_FW_RST_D3COLD,
++		.driver_data = 0,
 +	},
 +	},
 +	{
 +	{
 +		.ident = "Surface Pro 5",
 +		.ident = "Surface Pro 5",
@@ -365,7 +262,7 @@ index 000000000000..34dcd84f02a6
 +			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
 +			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
 +			DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "Surface_Pro_1796"),
 +			DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "Surface_Pro_1796"),
 +		},
 +		},
-+		.driver_data = (void *)QUIRK_FW_RST_D3COLD,
++		.driver_data = 0,
 +	},
 +	},
 +	{
 +	{
 +		.ident = "Surface Pro 5 (LTE)",
 +		.ident = "Surface Pro 5 (LTE)",
@@ -374,7 +271,7 @@ index 000000000000..34dcd84f02a6
 +			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
 +			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
 +			DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "Surface_Pro_1807"),
 +			DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "Surface_Pro_1807"),
 +		},
 +		},
-+		.driver_data = (void *)QUIRK_FW_RST_D3COLD,
++		.driver_data = 0,
 +	},
 +	},
 +	{
 +	{
 +		.ident = "Surface Pro 6",
 +		.ident = "Surface Pro 6",
@@ -382,7 +279,7 @@ index 000000000000..34dcd84f02a6
 +			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
 +			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
 +			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Pro 6"),
 +			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Pro 6"),
 +		},
 +		},
-+		.driver_data = (void *)QUIRK_FW_RST_D3COLD,
++		.driver_data = 0,
 +	},
 +	},
 +	{
 +	{
 +		.ident = "Surface Book 1",
 +		.ident = "Surface Book 1",
@@ -390,7 +287,7 @@ index 000000000000..34dcd84f02a6
 +			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
 +			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
 +			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Book"),
 +			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Book"),
 +		},
 +		},
-+		.driver_data = (void *)QUIRK_FW_RST_D3COLD,
++		.driver_data = 0,
 +	},
 +	},
 +	{
 +	{
 +		.ident = "Surface Book 2",
 +		.ident = "Surface Book 2",
@@ -398,7 +295,7 @@ index 000000000000..34dcd84f02a6
 +			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
 +			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
 +			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Book 2"),
 +			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Book 2"),
 +		},
 +		},
-+		.driver_data = (void *)QUIRK_FW_RST_D3COLD,
++		.driver_data = 0,
 +	},
 +	},
 +	{
 +	{
 +		.ident = "Surface Laptop 1",
 +		.ident = "Surface Laptop 1",
@@ -406,7 +303,7 @@ index 000000000000..34dcd84f02a6
 +			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
 +			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
 +			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Laptop"),
 +			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Laptop"),
 +		},
 +		},
-+		.driver_data = (void *)QUIRK_FW_RST_D3COLD,
++		.driver_data = 0,
 +	},
 +	},
 +	{
 +	{
 +		.ident = "Surface Laptop 2",
 +		.ident = "Surface Laptop 2",
@@ -414,7 +311,7 @@ index 000000000000..34dcd84f02a6
 +			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
 +			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
 +			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Laptop 2"),
 +			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Laptop 2"),
 +		},
 +		},
-+		.driver_data = (void *)QUIRK_FW_RST_D3COLD,
++		.driver_data = 0,
 +	},
 +	},
 +	{
 +	{
 +		.ident = "Surface 3",
 +		.ident = "Surface 3",
@@ -422,16 +319,7 @@ index 000000000000..34dcd84f02a6
 +			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
 +			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
 +			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface 3"),
 +			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",
 +		.ident = "Surface Pro 3",
@@ -455,11 +343,156 @@ index 000000000000..34dcd84f02a6
 +
 +
 +	if (!card->quirks)
 +	if (!card->quirks)
 +		dev_info(&pdev->dev, "no quirks enabled\n");
 +		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 e344e3aa7d35ea66edb2d0792bda98ef311a9f98 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 899ce2657880..45488c2bc1c1 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)
 +	if (card->quirks & QUIRK_FW_RST_D3COLD)
 +		dev_info(&pdev->dev, "quirk reset_d3cold enabled\n");
 +		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)
 +static void mwifiex_pcie_set_power_d3cold(struct pci_dev *pdev)
@@ -515,7 +548,122 @@ index 000000000000..34dcd84f02a6
 +		return ret;
 +		return ret;
 +
 +
 +	return 0;
 +	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 a835d3d17471990f1c33e8a566876b1774856ac9 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 45488c2bc1c1..daae572ce94e 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)
 +int mwifiex_pcie_reset_wsid_quirk(struct pci_dev *pdev)
 +{
 +{
@@ -578,53 +726,671 @@ index 000000000000..34dcd84f02a6
 +	return 0;
 +	return 0;
 +}
 +}
 diff --git a/drivers/net/wireless/marvell/mwifiex/pcie_quirks.h b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.h
 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
 +++ 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
 +/* Surface 3 and Surface Pro 3 have the same _DSM method but need to
 + * be handled differently. Currently, only S3 is supported.
 + * be handled differently. Currently, only S3 is supported.
 + */
 + */
 +#define QUIRK_FW_RST_WSID_S3	BIT(1)
 +#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);
-+int mwifiex_pcie_reset_wsid_quirk(struct pci_dev *pdev);
-diff --git a/drivers/net/wireless/marvell/mwifiex/sta_cmd.c b/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
-index 8bd355d7974e..484ba60b51ab 100644
---- a/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
-+++ b/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
-@@ -2332,16 +2332,10 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta, bool init)
- 		if (ret)
- 			return -1;
- 
--		if (priv->bss_type != MWIFIEX_BSS_TYPE_UAP) {
--			/* Enable IEEE PS by default */
--			priv->adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_PSP;
--			ret = mwifiex_send_cmd(priv,
--					       HostCmd_CMD_802_11_PS_MODE_ENH,
--					       EN_AUTO_PS, BITMAP_STA_PS, NULL,
--					       true);
--			if (ret)
--				return -1;
--		}
-+		/* 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. */
  
  
- 		if (drcs) {
- 			adapter->drcs_enabled = true;
+ 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 1a027d9e20179b26a9a89cbc67570dc57decc30e 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 b83d011dd7c568c2db41c520d3fdaadc4ff8954a 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 529099137644..c21f916c05a3 100644
+--- a/drivers/net/wireless/marvell/mwifiex/main.c
++++ b/drivers/net/wireless/marvell/mwifiex/main.c
+@@ -1469,6 +1469,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);
+ 	adapter->is_up = false;
+ 
+-- 
+2.28.0
+
+From 919ef1f9830f57b14ad8af2b812bb25ec7a5dba0 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/pcie.c | 29 +++++++--------------
+ 1 file changed, 10 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c
+index daae572ce94e..b46d56389c3b 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 d63ccbb60c210c361cf48612ea3fc8f882565da6 Mon Sep 17 00:00:00 2001
+From: Tsuchiya Yuto <kitakar@gmail.com>
+Date: Sun, 27 Sep 2020 00:51:38 +0900
+Subject: [PATCH] mwifiex: update comment for shutdown_sw()/reinit_sw()
+ reflecting current state
+
+The functions mwifiex_shutdown_sw() and mwifiex_reinit_sw() can be used
+for more general purposes than the PCIe function level reset. Also, these
+are even not PCIe-specific.
+
+So, let's update the comments at the top of each function accordingly.
+
+Signed-off-by: Tsuchiya Yuto <kitakar@gmail.com>
+Patchset: wifi
+---
+ drivers/net/wireless/marvell/mwifiex/main.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/wireless/marvell/mwifiex/main.c b/drivers/net/wireless/marvell/mwifiex/main.c
+index c21f916c05a3..a26eb66865e2 100644
+--- a/drivers/net/wireless/marvell/mwifiex/main.c
++++ b/drivers/net/wireless/marvell/mwifiex/main.c
+@@ -1453,7 +1453,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)
+ {
+@@ -1481,7 +1481,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
+-- 
+2.28.0
+
+From c7a3556e53d7053e3bfed69c23e4a80a12ec03d4 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 b46d56389c3b..1847a0274991 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 bcf9d4b3af74128a676e6e5b79ac83e6e29fbbef 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 1847a0274991..3bd39d9ba3de 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 7dda35220e0c86d787ea4d1299b7ff645e992acb 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 4e4f59c17ded..1074bcb2606b 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) |
+@@ -434,6 +439,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 390fa12d3af6558f2b4bdb145c45b27129b29ba1 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 8bd355d7974e..621519826685 100644
+--- a/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
++++ b/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
+@@ -2333,14 +2333,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) {
+-			/* Enable IEEE PS by default */
+-			priv->adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_PSP;
++			/* 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,
++					       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) {
+-- 
+2.28.0
+
+From 570c6d717002dd3734452e1d6db0ac8414418b7e 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 1074bcb2606b..67800980a7f0 100644
+--- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c
++++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
+@@ -450,6 +450,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
 2.28.0
 
 

File diff suppressed because it is too large
+ 512 - 337
patches/5.8/0003-ipts.patch


+ 36 - 9
patches/5.8/0006-surface-gpe.patch → patches/5.8/0004-surface-gpe.patch

@@ -1,8 +1,35 @@
-From 3965e53a7027b6a17201233cabe6ed146d2f53ea Mon Sep 17 00:00:00 2001
+From aa25cec8fd87df94cabc33c37cc0a2778d63f3d4 Mon Sep 17 00:00:00 2001
 From: Maximilian Luz <luzmaximilian@gmail.com>
 From: Maximilian Luz <luzmaximilian@gmail.com>
 Date: Sun, 16 Aug 2020 23:39:56 +0200
 Date: Sun, 16 Aug 2020 23:39:56 +0200
-Subject: [PATCH 6/7] 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/Kconfig       |   9 +
  drivers/platform/x86/Makefile      |   1 +
  drivers/platform/x86/Makefile      |   1 +
@@ -11,12 +38,12 @@ Subject: [PATCH 6/7] surface-gpe
  create mode 100644 drivers/platform/x86/surface_gpe.c
  create mode 100644 drivers/platform/x86/surface_gpe.c
 
 
 diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
 diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
-index 14db2795ff63..c64267319696 100644
+index a5ad36083b67..01752d1f40f8 100644
 --- a/drivers/platform/x86/Kconfig
 --- a/drivers/platform/x86/Kconfig
 +++ b/drivers/platform/x86/Kconfig
 +++ b/drivers/platform/x86/Kconfig
-@@ -886,6 +886,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.
+@@ -880,6 +880,15 @@ config SURFACE_PRO3_BUTTON
+ 	help
+ 	  This driver handles the power/home/volume buttons on the Microsoft Surface Pro 3/4 tablet.
  
  
 +config SURFACE_GPE
 +config SURFACE_GPE
 +	tristate "Surface GPE/Lid Driver"
 +	tristate "Surface GPE/Lid Driver"
@@ -31,13 +58,13 @@ index 14db2795ff63..c64267319696 100644
  	tristate "MSI Laptop Extras"
  	tristate "MSI Laptop Extras"
  	depends on ACPI
  	depends on ACPI
 diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
 diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
-index 5156523b5863..ef0c3fcab319 100644
+index 2b85852a1a87..a64ce216719a 100644
 --- a/drivers/platform/x86/Makefile
 --- a/drivers/platform/x86/Makefile
 +++ b/drivers/platform/x86/Makefile
 +++ b/drivers/platform/x86/Makefile
-@@ -86,6 +86,7 @@ obj-$(CONFIG_SURFACE_3_BUTTON)		+= surface3_button.o
+@@ -85,6 +85,7 @@ obj-$(CONFIG_SURFACE3_WMI)		+= surface3-wmi.o
+ obj-$(CONFIG_SURFACE_3_BUTTON)		+= surface3_button.o
  obj-$(CONFIG_SURFACE_3_POWER_OPREGION)	+= surface3_power.o
  obj-$(CONFIG_SURFACE_3_POWER_OPREGION)	+= surface3_power.o
  obj-$(CONFIG_SURFACE_PRO3_BUTTON)	+= surfacepro3_button.o
  obj-$(CONFIG_SURFACE_PRO3_BUTTON)	+= surfacepro3_button.o
- obj-$(CONFIG_SURFACE_BOOK1_DGPU_SWITCH)	+= sb1_dgpu_sw.o
 +obj-$(CONFIG_SURFACE_GPE)		+= surface_gpe.o
 +obj-$(CONFIG_SURFACE_GPE)		+= surface_gpe.o
  
  
  # MSI
  # MSI

+ 82 - 15
patches/5.8/0005-surface-sam-over-hid.patch

@@ -1,15 +1,57 @@
-From 2e7656defabd8c62b9c36b912386f83b8b757d55 Mon Sep 17 00:00:00 2001
+From 256ed7b2d0a06dd15968828ac55d355773b19958 Mon Sep 17 00:00:00 2001
 From: Maximilian Luz <luzmaximilian@gmail.com>
 From: Maximilian Luz <luzmaximilian@gmail.com>
 Date: Sat, 25 Jul 2020 17:19:53 +0200
 Date: Sat, 25 Jul 2020 17:19:53 +0200
-Subject: [PATCH 5/7] 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
 diff --git a/drivers/i2c/i2c-core-acpi.c b/drivers/i2c/i2c-core-acpi.c
 index 2ade99b105b9..60b9cb51d5f7 100644
 index 2ade99b105b9..60b9cb51d5f7 100644
@@ -64,13 +106,38 @@ index 2ade99b105b9..60b9cb51d5f7 100644
  	default:
  	default:
  		dev_warn(&adapter->dev, "protocol 0x%02x not supported for client 0x%02x\n",
  		dev_warn(&adapter->dev, "protocol 0x%02x not supported for client 0x%02x\n",
  			 accessor_type, client->addr);
  			 accessor_type, client->addr);
+-- 
+2.28.0
+
+From 03be5ddae354964501f25958d53525b23c9c6243 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
 diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
-index 0581a54cf562..14db2795ff63 100644
+index 01752d1f40f8..19a560c44511 100644
 --- a/drivers/platform/x86/Kconfig
 --- a/drivers/platform/x86/Kconfig
 +++ b/drivers/platform/x86/Kconfig
 +++ b/drivers/platform/x86/Kconfig
-@@ -879,6 +879,13 @@ config SURFACE_PRO3_BUTTON
- 	help
- 	  This driver handles the power/home/volume buttons on the Microsoft Surface Pro 3/4 tablet.
+@@ -889,6 +889,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
 +config SURFACE_BOOK1_DGPU_SWITCH
 +	tristate "Surface Book 1 dGPU Switch Driver"
 +	tristate "Surface Book 1 dGPU Switch Driver"
@@ -83,13 +150,13 @@ index 0581a54cf562..14db2795ff63 100644
  	tristate "MSI Laptop Extras"
  	tristate "MSI Laptop Extras"
  	depends on ACPI
  	depends on ACPI
 diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
 diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
-index 2b85852a1a87..5156523b5863 100644
+index a64ce216719a..f46d4a3ce746 100644
 --- a/drivers/platform/x86/Makefile
 --- a/drivers/platform/x86/Makefile
 +++ b/drivers/platform/x86/Makefile
 +++ b/drivers/platform/x86/Makefile
-@@ -85,6 +85,7 @@ obj-$(CONFIG_SURFACE3_WMI)		+= surface3-wmi.o
- obj-$(CONFIG_SURFACE_3_BUTTON)		+= surface3_button.o
+@@ -86,6 +86,7 @@ obj-$(CONFIG_SURFACE_3_BUTTON)		+= surface3_button.o
  obj-$(CONFIG_SURFACE_3_POWER_OPREGION)	+= surface3_power.o
  obj-$(CONFIG_SURFACE_3_POWER_OPREGION)	+= surface3_power.o
  obj-$(CONFIG_SURFACE_PRO3_BUTTON)	+= surfacepro3_button.o
  obj-$(CONFIG_SURFACE_PRO3_BUTTON)	+= surfacepro3_button.o
+ obj-$(CONFIG_SURFACE_GPE)		+= surface_gpe.o
 +obj-$(CONFIG_SURFACE_BOOK1_DGPU_SWITCH)	+= sb1_dgpu_sw.o
 +obj-$(CONFIG_SURFACE_BOOK1_DGPU_SWITCH)	+= sb1_dgpu_sw.o
  
  
  # MSI
  # MSI

File diff suppressed because it is too large
+ 886 - 50
patches/5.8/0006-surface-sam.patch


+ 3 - 3
patches/5.8/0007-i2c-core-Restore-acpi_walk_dep_device_list-getting-c.patch

@@ -1,8 +1,8 @@
-From eacbf7fd1be0f691fdd5562413a5eea98a7210e5 Mon Sep 17 00:00:00 2001
+From ccc695a9170dc8469d8637568129d4ed8780448c Mon Sep 17 00:00:00 2001
 From: Hans de Goede <hdegoede@redhat.com>
 From: Hans de Goede <hdegoede@redhat.com>
 Date: Wed, 14 Oct 2020 16:41:58 +0200
 Date: Wed, 14 Oct 2020 16:41:58 +0200
-Subject: [PATCH 7/7] 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()
 Commit 21653a4181ff ("i2c: core: Call i2c_acpi_install_space_handler()
 before i2c_acpi_register_devices()")'s intention was to only move the
 before i2c_acpi_register_devices()")'s intention was to only move the

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

@@ -0,0 +1 @@
+../../../patches/5.8/0004-surface-gpe.patch

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

@@ -1 +0,0 @@
-../../../patches/5.8/0004-surface-sam.patch

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

@@ -1 +0,0 @@
-../../../patches/5.8/0006-surface-gpe.patch

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

@@ -0,0 +1 @@
+../../../patches/5.8/0006-surface-sam.patch

+ 9 - 9
pkg/arch/kernel/PKGBUILD

@@ -28,9 +28,9 @@ source=(
   0001-surface3-oemb.patch
   0001-surface3-oemb.patch
   0002-wifi.patch
   0002-wifi.patch
   0003-ipts.patch
   0003-ipts.patch
-  0004-surface-sam.patch
+  0004-surface-gpe.patch
   0005-surface-sam-over-hid.patch
   0005-surface-sam-over-hid.patch
-  0006-surface-gpe.patch
+  0006-surface-sam.patch
   0007-i2c-core-Restore-acpi_walk_dep_device_list-getting-c.patch
   0007-i2c-core-Restore-acpi_walk_dep_device_list-getting-c.patch
 )
 )
 validpgpkeys=(
 validpgpkeys=(
@@ -42,13 +42,13 @@ sha256sums=('1251a7e13c23ad35c38f8e58227fc0183e7087a81ee030766e2db8cbe2453392'
             '181330a9cf4517abbbe29b93165bc859ad8ca14a43582f4e1d69aae2b5ecc2c9'
             '181330a9cf4517abbbe29b93165bc859ad8ca14a43582f4e1d69aae2b5ecc2c9'
             '7f52b09f0bf62d9b2ba162a424ce99caa50cb671f2b78fca1c1dc81e33e9b57f'
             '7f52b09f0bf62d9b2ba162a424ce99caa50cb671f2b78fca1c1dc81e33e9b57f'
             '8cd2b019aac6d3807a5cdcbbbe0aad81e63193ff3e8dffd7a79d4a1421b858f6'
             '8cd2b019aac6d3807a5cdcbbbe0aad81e63193ff3e8dffd7a79d4a1421b858f6'
-            '7dc41454b2646c743bf6592bcb0706242469380f8e634b9555a7322d7e015800'
-            '3005384427716297fe4e7ed77feba56976188f0b411c2ba7da73aef817c41ce0'
-            'e4245ee8ab19d46d126ce92e0b784944ae7a9c618d5cf5ae11109a946bd75961'
-            '5521a6d90e50a7a188f69e5f7e769bcb03f1994bf5d99a170e4dc0cf416d2352'
-            'afbfc31f6139f37753926c0ba1e1670190144d65dae13b2f4a66182cadd36235'
-            '018c3972a248547a83b3650e3f3b11d83078ea928fdbb3d1b965b3dea0e12973'
-            'ea2c799e490f3c478a821e00db9b4cd7183d703712f91a8b677de30d6639eb4c')
+            'a17c433dfa32ab3c967b217b19ff80aca2cfc07b9179a915b2f5695f07b25b5e'
+            '055f026f07a61cb02071e3cd3f5a93f8b1daf4688c4eebf1d24d7a012e9a0932'
+            '23c107c34d4d71f10d1ee37c228a8492d737c563493f7b71a01cdbcf1a8a7244'
+            '63c90132ef46562733a672cf7fc538c2fa9605605f9ed0bc471d48936147bcaf'
+            'f179f9a2385efee788715ad8acddd68b8cfeee0d79433e22d14341f417dd56da'
+            '750cc0491366373ceb0f24ab7ede555e4691855cee3c6e89a357169f56bf5981'
+            '7126649ec8af8127c28507b70cbf3f2ec125e496e98e3ea2a47e65f7234a2134')
 
 
 
 
 export KBUILD_BUILD_HOST=archlinux
 export KBUILD_BUILD_HOST=archlinux

Some files were not shown because too many files changed in this diff