From: Greg Kroah-Hartman Date: Sat, 10 Aug 2019 07:10:30 +0000 (+0200) Subject: 5.2-stable patches X-Git-Tag: v4.4.189~1 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d535f53a599efcb0050be7390aad83c0094c3bf0;p=thirdparty%2Fkernel%2Fstable-queue.git 5.2-stable patches added patches: revert-pci-add-missing-link-delays-required-by-the-pcie-spec.patch --- diff --git a/queue-5.2/revert-pci-add-missing-link-delays-required-by-the-pcie-spec.patch b/queue-5.2/revert-pci-add-missing-link-delays-required-by-the-pcie-spec.patch new file mode 100644 index 00000000000..a6a9360b232 --- /dev/null +++ b/queue-5.2/revert-pci-add-missing-link-delays-required-by-the-pcie-spec.patch @@ -0,0 +1,204 @@ +From 0617bdede5114a0002298b12cd0ca2b0cfd0395d Mon Sep 17 00:00:00 2001 +From: Mika Westerberg +Date: Wed, 7 Aug 2019 13:57:18 +0300 +Subject: Revert "PCI: Add missing link delays required by the PCIe spec" + +From: Mika Westerberg + +commit 0617bdede5114a0002298b12cd0ca2b0cfd0395d upstream. + +Commit c2bf1fc212f7 ("PCI: Add missing link delays required by the PCIe +spec") turned out causing issues with some systems either by making them +unresponsive or slowing down runtime and system wide resume of PCIe +devices. While root cause for the unresponsiveness is still under +investigation given the amount of issues reported better to revert it +for now. + +Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=204413 +Link: https://lore.kernel.org/linux-pci/SL2P216MB01878BBCD75F21D882AEEA2880C60@SL2P216MB0187.KORP216.PROD.OUTLOOK.COM/ +Link: https://lore.kernel.org/linux-pci/2857501d-c167-547d-c57d-d5d24ea1f1dc@molgen.mpg.de/ +Reported-by: Matthias Andree +Reported-by: Paul Menzel +Reported-by: Nicholas Johnson +Signed-off-by: Mika Westerberg +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/pci/pci.c | 29 ++++++----------- + drivers/pci/pci.h | 1 + drivers/pci/pcie/portdrv_core.c | 66 ---------------------------------------- + 3 files changed, 10 insertions(+), 86 deletions(-) + +--- a/drivers/pci/pci.c ++++ b/drivers/pci/pci.c +@@ -1004,10 +1004,15 @@ static void __pci_start_power_transition + if (state == PCI_D0) { + pci_platform_power_transition(dev, PCI_D0); + /* +- * Mandatory power management transition delays are +- * handled in the PCIe portdrv resume hooks. ++ * Mandatory power management transition delays, see ++ * PCI Express Base Specification Revision 2.0 Section ++ * 6.6.1: Conventional Reset. Do not delay for ++ * devices powered on/off by corresponding bridge, ++ * because have already delayed for the bridge. + */ + if (dev->runtime_d3cold) { ++ if (dev->d3cold_delay && !dev->imm_ready) ++ msleep(dev->d3cold_delay); + /* + * When powering on a bridge from D3cold, the + * whole hierarchy may be powered on into +@@ -4570,16 +4575,14 @@ static int pci_pm_reset(struct pci_dev * + + return pci_dev_wait(dev, "PM D3->D0", PCIE_RESET_READY_POLL_MS); + } +- + /** +- * pcie_wait_for_link_delay - Wait until link is active or inactive ++ * pcie_wait_for_link - Wait until link is active or inactive + * @pdev: Bridge device + * @active: waiting for active or inactive? +- * @delay: Delay to wait after link has become active (in ms) + * + * Use this to wait till link becomes active or inactive. + */ +-bool pcie_wait_for_link_delay(struct pci_dev *pdev, bool active, int delay) ++bool pcie_wait_for_link(struct pci_dev *pdev, bool active) + { + int timeout = 1000; + bool ret; +@@ -4616,25 +4619,13 @@ bool pcie_wait_for_link_delay(struct pci + timeout -= 10; + } + if (active && ret) +- msleep(delay); ++ msleep(100); + else if (ret != active) + pci_info(pdev, "Data Link Layer Link Active not %s in 1000 msec\n", + active ? "set" : "cleared"); + return ret == active; + } + +-/** +- * pcie_wait_for_link - Wait until link is active or inactive +- * @pdev: Bridge device +- * @active: waiting for active or inactive? +- * +- * Use this to wait till link becomes active or inactive. +- */ +-bool pcie_wait_for_link(struct pci_dev *pdev, bool active) +-{ +- return pcie_wait_for_link_delay(pdev, active, 100); +-} +- + void pci_reset_secondary_bus(struct pci_dev *dev) + { + u16 ctrl; +--- a/drivers/pci/pci.h ++++ b/drivers/pci/pci.h +@@ -493,7 +493,6 @@ static inline int pci_dev_specific_disab + void pcie_do_recovery(struct pci_dev *dev, enum pci_channel_state state, + u32 service); + +-bool pcie_wait_for_link_delay(struct pci_dev *pdev, bool active, int delay); + bool pcie_wait_for_link(struct pci_dev *pdev, bool active); + #ifdef CONFIG_PCIEASPM + void pcie_aspm_init_link_state(struct pci_dev *pdev); +--- a/drivers/pci/pcie/portdrv_core.c ++++ b/drivers/pci/pcie/portdrv_core.c +@@ -9,7 +9,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -379,67 +378,6 @@ static int pm_iter(struct device *dev, v + return 0; + } + +-static int get_downstream_delay(struct pci_bus *bus) +-{ +- struct pci_dev *pdev; +- int min_delay = 100; +- int max_delay = 0; +- +- list_for_each_entry(pdev, &bus->devices, bus_list) { +- if (!pdev->imm_ready) +- min_delay = 0; +- else if (pdev->d3cold_delay < min_delay) +- min_delay = pdev->d3cold_delay; +- if (pdev->d3cold_delay > max_delay) +- max_delay = pdev->d3cold_delay; +- } +- +- return max(min_delay, max_delay); +-} +- +-/* +- * wait_for_downstream_link - Wait for downstream link to establish +- * @pdev: PCIe port whose downstream link is waited +- * +- * Handle delays according to PCIe 4.0 section 6.6.1 before configuration +- * access to the downstream component is permitted. +- * +- * This blocks PCI core resume of the hierarchy below this port until the +- * link is trained. Should be called before resuming port services to +- * prevent pciehp from starting to tear-down the hierarchy too soon. +- */ +-static void wait_for_downstream_link(struct pci_dev *pdev) +-{ +- int delay; +- +- if (pci_pcie_type(pdev) != PCI_EXP_TYPE_ROOT_PORT && +- pci_pcie_type(pdev) != PCI_EXP_TYPE_DOWNSTREAM) +- return; +- +- if (pci_dev_is_disconnected(pdev)) +- return; +- +- if (!pdev->subordinate || list_empty(&pdev->subordinate->devices) || +- !pdev->bridge_d3) +- return; +- +- delay = get_downstream_delay(pdev->subordinate); +- if (!delay) +- return; +- +- dev_dbg(&pdev->dev, "waiting downstream link for %d ms\n", delay); +- +- /* +- * If downstream port does not support speeds greater than 5 GT/s +- * need to wait 100ms. For higher speeds (gen3) we need to wait +- * first for the data link layer to become active. +- */ +- if (pcie_get_speed_cap(pdev) <= PCIE_SPEED_5_0GT) +- msleep(delay); +- else +- pcie_wait_for_link_delay(pdev, true, delay); +-} +- + /** + * pcie_port_device_suspend - suspend port services associated with a PCIe port + * @dev: PCI Express port to handle +@@ -453,8 +391,6 @@ int pcie_port_device_suspend(struct devi + int pcie_port_device_resume_noirq(struct device *dev) + { + size_t off = offsetof(struct pcie_port_service_driver, resume_noirq); +- +- wait_for_downstream_link(to_pci_dev(dev)); + return device_for_each_child(dev, &off, pm_iter); + } + +@@ -485,8 +421,6 @@ int pcie_port_device_runtime_suspend(str + int pcie_port_device_runtime_resume(struct device *dev) + { + size_t off = offsetof(struct pcie_port_service_driver, runtime_resume); +- +- wait_for_downstream_link(to_pci_dev(dev)); + return device_for_each_child(dev, &off, pm_iter); + } + #endif /* PM */ diff --git a/queue-5.2/series b/queue-5.2/series new file mode 100644 index 00000000000..3449179f121 --- /dev/null +++ b/queue-5.2/series @@ -0,0 +1 @@ +revert-pci-add-missing-link-delays-required-by-the-pcie-spec.patch