--- /dev/null
+From a0d4c7eb71dd08a89ad631177bb0cbbabd598f84 Mon Sep 17 00:00:00 2001
+From: Chaotian Jing <chaotian.jing@mediatek.com>
+Date: Thu, 5 Sep 2019 15:53:18 +0800
+Subject: mmc: block: Add CMD13 polling for MMC IOCTLS with R1B response
+
+From: Chaotian Jing <chaotian.jing@mediatek.com>
+
+commit a0d4c7eb71dd08a89ad631177bb0cbbabd598f84 upstream.
+
+MMC IOCTLS with R1B responses may cause the card to enter the busy state,
+which means it's not ready to receive a new request. To prevent new
+requests from being sent to the card, use a CMD13 polling loop to verify
+that the card returns to the transfer state, before completing the request.
+
+Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
+Reviewed-by: Avri Altman <avri.altman@wdc.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/mmc/core/block.c | 147 +++++++++++++++++------------------------------
+ 1 file changed, 55 insertions(+), 92 deletions(-)
+
+--- a/drivers/mmc/core/block.c
++++ b/drivers/mmc/core/block.c
+@@ -409,38 +409,6 @@ static int mmc_blk_ioctl_copy_to_user(st
+ return 0;
+ }
+
+-static int ioctl_rpmb_card_status_poll(struct mmc_card *card, u32 *status,
+- u32 retries_max)
+-{
+- int err;
+- u32 retry_count = 0;
+-
+- if (!status || !retries_max)
+- return -EINVAL;
+-
+- do {
+- err = __mmc_send_status(card, status, 5);
+- if (err)
+- break;
+-
+- if (!R1_STATUS(*status) &&
+- (R1_CURRENT_STATE(*status) != R1_STATE_PRG))
+- break; /* RPMB programming operation complete */
+-
+- /*
+- * Rechedule to give the MMC device a chance to continue
+- * processing the previous command without being polled too
+- * frequently.
+- */
+- usleep_range(1000, 5000);
+- } while (++retry_count < retries_max);
+-
+- if (retry_count == retries_max)
+- err = -EPERM;
+-
+- return err;
+-}
+-
+ static int ioctl_do_sanitize(struct mmc_card *card)
+ {
+ int err;
+@@ -469,6 +437,58 @@ out:
+ return err;
+ }
+
++static inline bool mmc_blk_in_tran_state(u32 status)
++{
++ /*
++ * Some cards mishandle the status bits, so make sure to check both the
++ * busy indication and the card state.
++ */
++ return status & R1_READY_FOR_DATA &&
++ (R1_CURRENT_STATE(status) == R1_STATE_TRAN);
++}
++
++static int card_busy_detect(struct mmc_card *card, unsigned int timeout_ms,
++ u32 *resp_errs)
++{
++ unsigned long timeout = jiffies + msecs_to_jiffies(timeout_ms);
++ int err = 0;
++ u32 status;
++
++ do {
++ bool done = time_after(jiffies, timeout);
++
++ err = __mmc_send_status(card, &status, 5);
++ if (err) {
++ dev_err(mmc_dev(card->host),
++ "error %d requesting status\n", err);
++ return err;
++ }
++
++ /* Accumulate any response error bits seen */
++ if (resp_errs)
++ *resp_errs |= status;
++
++ /*
++ * Timeout if the device never becomes ready for data and never
++ * leaves the program state.
++ */
++ if (done) {
++ dev_err(mmc_dev(card->host),
++ "Card stuck in wrong state! %s status: %#x\n",
++ __func__, status);
++ return -ETIMEDOUT;
++ }
++
++ /*
++ * Some cards mishandle the status bits,
++ * so make sure to check both the busy
++ * indication and the card state.
++ */
++ } while (!mmc_blk_in_tran_state(status));
++
++ return err;
++}
++
+ static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md,
+ struct mmc_blk_ioc_data *idata)
+ {
+@@ -478,7 +498,6 @@ static int __mmc_blk_ioctl_cmd(struct mm
+ struct scatterlist sg;
+ int err;
+ unsigned int target_part;
+- u32 status = 0;
+
+ if (!card || !md || !idata)
+ return -EINVAL;
+@@ -612,16 +631,12 @@ static int __mmc_blk_ioctl_cmd(struct mm
+
+ memcpy(&(idata->ic.response), cmd.resp, sizeof(cmd.resp));
+
+- if (idata->rpmb) {
++ if (idata->rpmb || (cmd.flags & MMC_RSP_R1B)) {
+ /*
+- * Ensure RPMB command has completed by polling CMD13
++ * Ensure RPMB/R1B command has completed by polling CMD13
+ * "Send Status".
+ */
+- err = ioctl_rpmb_card_status_poll(card, &status, 5);
+- if (err)
+- dev_err(mmc_dev(card->host),
+- "%s: Card Status=0x%08X, error %d\n",
+- __func__, status, err);
++ err = card_busy_detect(card, MMC_BLK_TIMEOUT_MS, NULL);
+ }
+
+ return err;
+@@ -971,58 +986,6 @@ static unsigned int mmc_blk_data_timeout
+ return ms;
+ }
+
+-static inline bool mmc_blk_in_tran_state(u32 status)
+-{
+- /*
+- * Some cards mishandle the status bits, so make sure to check both the
+- * busy indication and the card state.
+- */
+- return status & R1_READY_FOR_DATA &&
+- (R1_CURRENT_STATE(status) == R1_STATE_TRAN);
+-}
+-
+-static int card_busy_detect(struct mmc_card *card, unsigned int timeout_ms,
+- u32 *resp_errs)
+-{
+- unsigned long timeout = jiffies + msecs_to_jiffies(timeout_ms);
+- int err = 0;
+- u32 status;
+-
+- do {
+- bool done = time_after(jiffies, timeout);
+-
+- err = __mmc_send_status(card, &status, 5);
+- if (err) {
+- dev_err(mmc_dev(card->host),
+- "error %d requesting status\n", err);
+- return err;
+- }
+-
+- /* Accumulate any response error bits seen */
+- if (resp_errs)
+- *resp_errs |= status;
+-
+- /*
+- * Timeout if the device never becomes ready for data and never
+- * leaves the program state.
+- */
+- if (done) {
+- dev_err(mmc_dev(card->host),
+- "Card stuck in wrong state! %s status: %#x\n",
+- __func__, status);
+- return -ETIMEDOUT;
+- }
+-
+- /*
+- * Some cards mishandle the status bits,
+- * so make sure to check both the busy
+- * indication and the card state.
+- */
+- } while (!mmc_blk_in_tran_state(status));
+-
+- return err;
+-}
+-
+ static int mmc_blk_reset(struct mmc_blk_data *md, struct mmc_host *host,
+ int type)
+ {
--- /dev/null
+From 3869468e0c4800af52bfe1e0b72b338dcdae2cfc Mon Sep 17 00:00:00 2001
+From: Chaotian Jing <chaotian.jing@mediatek.com>
+Date: Thu, 5 Sep 2019 15:53:17 +0800
+Subject: mmc: block: Make card_busy_detect() a bit more generic
+
+From: Chaotian Jing <chaotian.jing@mediatek.com>
+
+commit 3869468e0c4800af52bfe1e0b72b338dcdae2cfc upstream.
+
+To prepare for more users of card_busy_detect(), let's drop the struct
+request * as an in-parameter and convert to log the error message via
+dev_err() instead of pr_err().
+
+Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
+Reviewed-by: Avri Altman <avri.altman@wdc.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/mmc/core/block.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+--- a/drivers/mmc/core/block.c
++++ b/drivers/mmc/core/block.c
+@@ -982,7 +982,7 @@ static inline bool mmc_blk_in_tran_state
+ }
+
+ static int card_busy_detect(struct mmc_card *card, unsigned int timeout_ms,
+- struct request *req, u32 *resp_errs)
++ u32 *resp_errs)
+ {
+ unsigned long timeout = jiffies + msecs_to_jiffies(timeout_ms);
+ int err = 0;
+@@ -993,8 +993,8 @@ static int card_busy_detect(struct mmc_c
+
+ err = __mmc_send_status(card, &status, 5);
+ if (err) {
+- pr_err("%s: error %d requesting status\n",
+- req->rq_disk->disk_name, err);
++ dev_err(mmc_dev(card->host),
++ "error %d requesting status\n", err);
+ return err;
+ }
+
+@@ -1007,9 +1007,9 @@ static int card_busy_detect(struct mmc_c
+ * leaves the program state.
+ */
+ if (done) {
+- pr_err("%s: Card stuck in wrong state! %s %s status: %#x\n",
+- mmc_hostname(card->host),
+- req->rq_disk->disk_name, __func__, status);
++ dev_err(mmc_dev(card->host),
++ "Card stuck in wrong state! %s status: %#x\n",
++ __func__, status);
+ return -ETIMEDOUT;
+ }
+
+@@ -1678,7 +1678,7 @@ static int mmc_blk_fix_state(struct mmc_
+
+ mmc_blk_send_stop(card, timeout);
+
+- err = card_busy_detect(card, timeout, req, NULL);
++ err = card_busy_detect(card, timeout, NULL);
+
+ mmc_retune_release(card->host);
+
+@@ -1902,7 +1902,7 @@ static int mmc_blk_card_busy(struct mmc_
+ if (mmc_host_is_spi(card->host) || rq_data_dir(req) == READ)
+ return 0;
+
+- err = card_busy_detect(card, MMC_BLK_TIMEOUT_MS, req, &status);
++ err = card_busy_detect(card, MMC_BLK_TIMEOUT_MS, &status);
+
+ /*
+ * Do not assume data transferred correctly if there are any error bits
--- /dev/null
+From f338bb9f0179cb959977b74e8331b312264d720b Mon Sep 17 00:00:00 2001
+From: George Cherian <george.cherian@marvell.com>
+Date: Mon, 11 Nov 2019 02:43:03 +0000
+Subject: PCI: Apply Cavium ACS quirk to ThunderX2 and ThunderX3
+
+From: George Cherian <george.cherian@marvell.com>
+
+commit f338bb9f0179cb959977b74e8331b312264d720b upstream.
+
+Enhance the ACS quirk for Cavium Processors. Add the root port vendor IDs
+for ThunderX2 and ThunderX3 series of processors.
+
+[bhelgaas: add Fixes: and stable tag]
+Fixes: f2ddaf8dfd4a ("PCI: Apply Cavium ThunderX ACS quirk to more Root Ports")
+Link: https://lore.kernel.org/r/20191111024243.GA11408@dc5-eodlnx05.marvell.com
+Signed-off-by: George Cherian <george.cherian@marvell.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Robert Richter <rrichter@marvell.com>
+Cc: stable@vger.kernel.org # v4.12+
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/pci/quirks.c | 20 +++++++++++++-------
+ 1 file changed, 13 insertions(+), 7 deletions(-)
+
+--- a/drivers/pci/quirks.c
++++ b/drivers/pci/quirks.c
+@@ -4219,15 +4219,21 @@ static int pci_quirk_amd_sb_acs(struct p
+
+ static bool pci_quirk_cavium_acs_match(struct pci_dev *dev)
+ {
++ if (!pci_is_pcie(dev) || pci_pcie_type(dev) != PCI_EXP_TYPE_ROOT_PORT)
++ return false;
++
++ switch (dev->device) {
+ /*
+- * Effectively selects all downstream ports for whole ThunderX 1
+- * family by 0xf800 mask (which represents 8 SoCs), while the lower
+- * bits of device ID are used to indicate which subdevice is used
+- * within the SoC.
++ * Effectively selects all downstream ports for whole ThunderX1
++ * (which represents 8 SoCs).
+ */
+- return (pci_is_pcie(dev) &&
+- (pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT) &&
+- ((dev->device & 0xf800) == 0xa000));
++ case 0xa000 ... 0xa7ff: /* ThunderX1 */
++ case 0xaf84: /* ThunderX2 */
++ case 0xb884: /* ThunderX3 */
++ return true;
++ default:
++ return false;
++ }
+ }
+
+ static int pci_quirk_cavium_acs(struct pci_dev *dev, u16 acs_flags)
--- /dev/null
+From d8558ac8c93d429d65d7490b512a3a67e559d0d4 Mon Sep 17 00:00:00 2001
+From: Steffen Liebergeld <steffen.liebergeld@kernkonzept.com>
+Date: Wed, 18 Sep 2019 15:16:52 +0200
+Subject: PCI: Fix Intel ACS quirk UPDCR register address
+
+From: Steffen Liebergeld <steffen.liebergeld@kernkonzept.com>
+
+commit d8558ac8c93d429d65d7490b512a3a67e559d0d4 upstream.
+
+According to documentation [0] the correct offset for the Upstream Peer
+Decode Configuration Register (UPDCR) is 0x1014. It was previously defined
+as 0x1114.
+
+d99321b63b1f ("PCI: Enable quirks for PCIe ACS on Intel PCH root ports")
+intended to enforce isolation between PCI devices allowing them to be put
+into separate IOMMU groups. Due to the wrong register offset the intended
+isolation was not fully enforced. This is fixed with this patch.
+
+Please note that I did not test this patch because I have no hardware that
+implements this register.
+
+[0] https://www.intel.com/content/dam/www/public/us/en/documents/datasheets/4th-gen-core-family-mobile-i-o-datasheet.pdf (page 325)
+Fixes: d99321b63b1f ("PCI: Enable quirks for PCIe ACS on Intel PCH root ports")
+Link: https://lore.kernel.org/r/7a3505df-79ba-8a28-464c-88b83eefffa6@kernkonzept.com
+Signed-off-by: Steffen Liebergeld <steffen.liebergeld@kernkonzept.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Andrew Murray <andrew.murray@arm.com>
+Acked-by: Ashok Raj <ashok.raj@intel.com>
+Cc: stable@vger.kernel.org # v3.15+
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/pci/quirks.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/pci/quirks.c
++++ b/drivers/pci/quirks.c
+@@ -4576,7 +4576,7 @@ int pci_dev_specific_acs_enabled(struct
+ #define INTEL_BSPR_REG_BPPD (1 << 9)
+
+ /* Upstream Peer Decode Configuration Register */
+-#define INTEL_UPDCR_REG 0x1114
++#define INTEL_UPDCR_REG 0x1014
+ /* 5:0 Peer Decode Enable bits */
+ #define INTEL_UPDCR_REG_MASK 0x3f
+
--- /dev/null
+From e045fa29e89383c717e308609edd19d2fd29e1be Mon Sep 17 00:00:00 2001
+From: Jian-Hong Pan <jian-hong@endlessm.com>
+Date: Tue, 8 Oct 2019 11:42:39 +0800
+Subject: PCI/MSI: Fix incorrect MSI-X masking on resume
+
+From: Jian-Hong Pan <jian-hong@endlessm.com>
+
+commit e045fa29e89383c717e308609edd19d2fd29e1be upstream.
+
+When a driver enables MSI-X, msix_program_entries() reads the MSI-X Vector
+Control register for each vector and saves it in desc->masked. Each
+register is 32 bits and bit 0 is the actual Mask bit.
+
+When we restored these registers during resume, we previously set the Mask
+bit if *any* bit in desc->masked was set instead of when the Mask bit
+itself was set:
+
+ pci_restore_state
+ pci_restore_msi_state
+ __pci_restore_msix_state
+ for_each_pci_msi_entry
+ msix_mask_irq(entry, entry->masked) <-- entire u32 word
+ __pci_msix_desc_mask_irq(desc, flag)
+ mask_bits = desc->masked & ~PCI_MSIX_ENTRY_CTRL_MASKBIT
+ if (flag) <-- testing entire u32, not just bit 0
+ mask_bits |= PCI_MSIX_ENTRY_CTRL_MASKBIT
+ writel(mask_bits, desc_addr + PCI_MSIX_ENTRY_VECTOR_CTRL)
+
+This means that after resume, MSI-X vectors were masked when they shouldn't
+be, which leads to timeouts like this:
+
+ nvme nvme0: I/O 978 QID 3 timeout, completion polled
+
+On resume, set the Mask bit only when the saved Mask bit from suspend was
+set.
+
+This should remove the need for 19ea025e1d28 ("nvme: Add quirk for Kingston
+NVME SSD running FW E8FK11.T").
+
+[bhelgaas: commit log, move fix to __pci_msix_desc_mask_irq()]
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=204887
+Link: https://lore.kernel.org/r/20191008034238.2503-1-jian-hong@endlessm.com
+Fixes: f2440d9acbe8 ("PCI MSI: Refactor interrupt masking code")
+Signed-off-by: Jian-Hong Pan <jian-hong@endlessm.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/pci/msi.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/pci/msi.c
++++ b/drivers/pci/msi.c
+@@ -211,7 +211,7 @@ u32 __pci_msix_desc_mask_irq(struct msi_
+ return 0;
+
+ mask_bits &= ~PCI_MSIX_ENTRY_CTRL_MASKBIT;
+- if (flag)
++ if (flag & PCI_MSIX_ENTRY_CTRL_MASKBIT)
+ mask_bits |= PCI_MSIX_ENTRY_CTRL_MASKBIT;
+ writel(mask_bits, pci_msix_desc_addr(desc) + PCI_MSIX_ENTRY_VECTOR_CTRL);
+
--- /dev/null
+From 157c1062fcd86ade3c674503705033051fd3d401 Mon Sep 17 00:00:00 2001
+From: Lukas Wunner <lukas@wunner.de>
+Date: Fri, 9 Aug 2019 12:28:43 +0200
+Subject: PCI: pciehp: Avoid returning prematurely from sysfs requests
+
+From: Lukas Wunner <lukas@wunner.de>
+
+commit 157c1062fcd86ade3c674503705033051fd3d401 upstream.
+
+A sysfs request to enable or disable a PCIe hotplug slot should not
+return before it has been carried out. That is sought to be achieved by
+waiting until the controller's "pending_events" have been cleared.
+
+However the IRQ thread pciehp_ist() clears the "pending_events" before
+it acts on them. If pciehp_sysfs_enable_slot() / _disable_slot() happen
+to check the "pending_events" after they have been cleared but while
+pciehp_ist() is still running, the functions may return prematurely
+with an incorrect return value.
+
+Fix by introducing an "ist_running" flag which must be false before a sysfs
+request is allowed to return.
+
+Fixes: 32a8cef274fe ("PCI: pciehp: Enable/disable exclusively from IRQ thread")
+Link: https://lore.kernel.org/linux-pci/1562226638-54134-1-git-send-email-wangxiongfeng2@huawei.com
+Link: https://lore.kernel.org/r/4174210466e27eb7e2243dd1d801d5f75baaffd8.1565345211.git.lukas@wunner.de
+Reported-and-tested-by: Xiongfeng Wang <wangxiongfeng2@huawei.com>
+Signed-off-by: Lukas Wunner <lukas@wunner.de>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Cc: stable@vger.kernel.org # v4.19+
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/pci/hotplug/pciehp.h | 2 ++
+ drivers/pci/hotplug/pciehp_ctrl.c | 6 ++++--
+ drivers/pci/hotplug/pciehp_hpc.c | 2 ++
+ 3 files changed, 8 insertions(+), 2 deletions(-)
+
+--- a/drivers/pci/hotplug/pciehp.h
++++ b/drivers/pci/hotplug/pciehp.h
+@@ -106,6 +106,7 @@ struct slot {
+ * that has not yet been cleared by the user
+ * @pending_events: used by the IRQ handler to save events retrieved from the
+ * Slot Status register for later consumption by the IRQ thread
++ * @ist_running: flag to keep user request waiting while IRQ thread is running
+ * @request_result: result of last user request submitted to the IRQ thread
+ * @requester: wait queue to wake up on completion of user request,
+ * used for synchronous slot enable/disable request via sysfs
+@@ -125,6 +126,7 @@ struct controller {
+ unsigned int notification_enabled:1;
+ unsigned int power_fault_detected;
+ atomic_t pending_events;
++ unsigned int ist_running;
+ int request_result;
+ wait_queue_head_t requester;
+ };
+--- a/drivers/pci/hotplug/pciehp_ctrl.c
++++ b/drivers/pci/hotplug/pciehp_ctrl.c
+@@ -383,7 +383,8 @@ int pciehp_sysfs_enable_slot(struct slot
+ ctrl->request_result = -ENODEV;
+ pciehp_request(ctrl, PCI_EXP_SLTSTA_PDC);
+ wait_event(ctrl->requester,
+- !atomic_read(&ctrl->pending_events));
++ !atomic_read(&ctrl->pending_events) &&
++ !ctrl->ist_running);
+ return ctrl->request_result;
+ case POWERON_STATE:
+ ctrl_info(ctrl, "Slot(%s): Already in powering on state\n",
+@@ -416,7 +417,8 @@ int pciehp_sysfs_disable_slot(struct slo
+ mutex_unlock(&p_slot->lock);
+ pciehp_request(ctrl, DISABLE_SLOT);
+ wait_event(ctrl->requester,
+- !atomic_read(&ctrl->pending_events));
++ !atomic_read(&ctrl->pending_events) &&
++ !ctrl->ist_running);
+ return ctrl->request_result;
+ case POWEROFF_STATE:
+ ctrl_info(ctrl, "Slot(%s): Already in powering off state\n",
+--- a/drivers/pci/hotplug/pciehp_hpc.c
++++ b/drivers/pci/hotplug/pciehp_hpc.c
+@@ -620,6 +620,7 @@ static irqreturn_t pciehp_ist(int irq, v
+ irqreturn_t ret;
+ u32 events;
+
++ ctrl->ist_running = true;
+ pci_config_pm_runtime_get(pdev);
+
+ /* rerun pciehp_isr() if the port was inaccessible on interrupt */
+@@ -666,6 +667,7 @@ static irqreturn_t pciehp_ist(int irq, v
+ up_read(&ctrl->reset_lock);
+
+ pci_config_pm_runtime_put(pdev);
++ ctrl->ist_running = false;
+ wake_up(&ctrl->requester);
+ return IRQ_HANDLED;
+ }
--- /dev/null
+From f2c33ccacb2d4bbeae2a255a7ca0cbfd03017b7c Mon Sep 17 00:00:00 2001
+From: Dexuan Cui <decui@microsoft.com>
+Date: Wed, 14 Aug 2019 01:06:55 +0000
+Subject: PCI/PM: Always return devices to D0 when thawing
+
+From: Dexuan Cui <decui@microsoft.com>
+
+commit f2c33ccacb2d4bbeae2a255a7ca0cbfd03017b7c upstream.
+
+pci_pm_thaw_noirq() is supposed to return the device to D0 and restore its
+configuration registers, but previously it only did that for devices whose
+drivers implemented the new power management ops.
+
+Hibernation, e.g., via "echo disk > /sys/power/state", involves freezing
+devices, creating a hibernation image, thawing devices, writing the image,
+and powering off. The fact that thawing did not return devices with legacy
+power management to D0 caused errors, e.g., in this path:
+
+ pci_pm_thaw_noirq
+ if (pci_has_legacy_pm_support(pci_dev)) # true for Mellanox VF driver
+ return pci_legacy_resume_early(dev) # ... legacy PM skips the rest
+ pci_set_power_state(pci_dev, PCI_D0)
+ pci_restore_state(pci_dev)
+ pci_pm_thaw
+ if (pci_has_legacy_pm_support(pci_dev))
+ pci_legacy_resume
+ drv->resume
+ mlx4_resume
+ ...
+ pci_enable_msix_range
+ ...
+ if (dev->current_state != PCI_D0) # <---
+ return -EINVAL;
+
+which caused these warnings:
+
+ mlx4_core a6d1:00:02.0: INTx is not supported in multi-function mode, aborting
+ PM: dpm_run_callback(): pci_pm_thaw+0x0/0xd7 returns -95
+ PM: Device a6d1:00:02.0 failed to thaw: error -95
+
+Return devices to D0 and restore config registers for all devices, not just
+those whose drivers support new power management.
+
+[bhelgaas: also call pci_restore_state() before pci_legacy_resume_early(),
+update comment, add stable tag, commit log]
+Link: https://lore.kernel.org/r/KU1P153MB016637CAEAD346F0AA8E3801BFAD0@KU1P153MB0166.APCP153.PROD.OUTLOOK.COM
+Signed-off-by: Dexuan Cui <decui@microsoft.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Cc: stable@vger.kernel.org # v4.13+
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/pci/pci-driver.c | 17 +++++++++++------
+ 1 file changed, 11 insertions(+), 6 deletions(-)
+
+--- a/drivers/pci/pci-driver.c
++++ b/drivers/pci/pci-driver.c
+@@ -1042,17 +1042,22 @@ static int pci_pm_thaw_noirq(struct devi
+ return error;
+ }
+
+- if (pci_has_legacy_pm_support(pci_dev))
+- return pci_legacy_resume_early(dev);
+-
+ /*
+- * pci_restore_state() requires the device to be in D0 (because of MSI
+- * restoration among other things), so force it into D0 in case the
+- * driver's "freeze" callbacks put it into a low-power state directly.
++ * Both the legacy ->resume_early() and the new pm->thaw_noirq()
++ * callbacks assume the device has been returned to D0 and its
++ * config state has been restored.
++ *
++ * In addition, pci_restore_state() restores MSI-X state in MMIO
++ * space, which requires the device to be in D0, so return it to D0
++ * in case the driver's "freeze" callbacks put it into a low-power
++ * state.
+ */
+ pci_set_power_state(pci_dev, PCI_D0);
+ pci_restore_state(pci_dev);
+
++ if (pci_has_legacy_pm_support(pci_dev))
++ return pci_legacy_resume_early(dev);
++
+ if (drv && drv->pm && drv->pm->thaw_noirq)
+ error = drv->pm->thaw_noirq(dev);
+
--- /dev/null
+From 6acdf7e19b37cb3a9258603d0eab315079c19c5e Mon Sep 17 00:00:00 2001
+From: Logan Gunthorpe <logang@deltatee.com>
+Date: Tue, 10 Sep 2019 13:58:33 -0600
+Subject: PCI/switchtec: Read all 64 bits of part_event_bitmap
+
+From: Logan Gunthorpe <logang@deltatee.com>
+
+commit 6acdf7e19b37cb3a9258603d0eab315079c19c5e upstream.
+
+The part_event_bitmap register is 64 bits wide, so read it with ioread64()
+instead of the 32-bit ioread32().
+
+Fixes: 52eabba5bcdb ("switchtec: Add IOCTLs to the Switchtec driver")
+Link: https://lore.kernel.org/r/20190910195833.3891-1-logang@deltatee.com
+Reported-by: Doug Meyer <dmeyer@gigaio.com>
+Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Cc: stable@vger.kernel.org # v4.12+
+Cc: Kelvin Cao <Kelvin.Cao@microchip.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/pci/switch/switchtec.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/pci/switch/switchtec.c
++++ b/drivers/pci/switch/switchtec.c
+@@ -633,7 +633,7 @@ static int ioctl_event_summary(struct sw
+ u32 reg;
+
+ s.global = ioread32(&stdev->mmio_sw_event->global_summary);
+- s.part_bitmap = ioread32(&stdev->mmio_sw_event->part_event_bitmap);
++ s.part_bitmap = ioread64(&stdev->mmio_sw_event->part_event_bitmap);
+ s.local_part = ioread32(&stdev->mmio_part_cfg->part_event_summary);
+
+ for (i = 0; i < stdev->partition_count; i++) {
tcp-tighten-acceptance-of-acks-not-matching-a-child-socket.patch
tcp-protect-accesses-to-.ts_recent_stamp-with-read-write-_once.patch
revert-arm64-preempt-fix-big-endian-when-checking-preempt-count-in-assembly.patch
+mmc-block-make-card_busy_detect-a-bit-more-generic.patch
+mmc-block-add-cmd13-polling-for-mmc-ioctls-with-r1b-response.patch
+pci-switchtec-read-all-64-bits-of-part_event_bitmap.patch
+pci-pm-always-return-devices-to-d0-when-thawing.patch
+pci-pciehp-avoid-returning-prematurely-from-sysfs-requests.patch
+pci-fix-intel-acs-quirk-updcr-register-address.patch
+pci-msi-fix-incorrect-msi-x-masking-on-resume.patch
+pci-apply-cavium-acs-quirk-to-thunderx2-and-thunderx3.patch