summaryrefslogtreecommitdiffstats
path: root/drivers/pci/host/pcie-iproc-platform.c
diff options
context:
space:
mode:
authorOza Pawandeep <oza.oza@broadcom.com>2017-08-28 23:43:35 +0200
committerBjorn Helgaas <bhelgaas@google.com>2017-09-05 19:27:03 +0200
commitb91c26c6a539e26261cbe280b9f48311663ce655 (patch)
treee27ec47aabff5110f85dd1e894c66c6a5ea964d1 /drivers/pci/host/pcie-iproc-platform.c
parentPCI: iproc: Work around Stingray CRS defects (diff)
downloadlinux-b91c26c6a539e26261cbe280b9f48311663ce655.tar.xz
linux-b91c26c6a539e26261cbe280b9f48311663ce655.zip
PCI: iproc: Add 500ms delay during device shutdown
During soft reset (e.g., "reboot" from Linux) on some iProc-based SOCs, the LCPLL clock and PERST both go off simultaneously. This seems in accordance with the PCIe Card Electromechanical spec, r2.0, sec 2.2.3, which says the clock goes inactive after PERST# goes active, but doesn't specify how long the clock should be valid after PERST#. However, we have observed that with the iProc Stingray, some Intel NVMe endpoints, e.g., the P3700 400GB series, are not detected correctly upon the next boot sequence unless the clock remains valid for some time after PERST# is asserted. Delay 500ms after asserting PERST# before performing a reboot. The 500ms is experimentally determined. Signed-off-by: Oza Pawandeep <oza.oza@broadcom.com> [bhelgaas: changelog, add spec reference, fold in iproc_pcie_shutdown() export from Arnd Bergmann <arnd@arndb.de>] Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: Ray Jui <ray.jui@broadcom.com> Reviewed-by: Scott Branden <scott.branden@broadcom.com>
Diffstat (limited to 'drivers/pci/host/pcie-iproc-platform.c')
-rw-r--r--drivers/pci/host/pcie-iproc-platform.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/drivers/pci/host/pcie-iproc-platform.c b/drivers/pci/host/pcie-iproc-platform.c
index 22531190bc40..a5073a921a04 100644
--- a/drivers/pci/host/pcie-iproc-platform.c
+++ b/drivers/pci/host/pcie-iproc-platform.c
@@ -134,6 +134,13 @@ static int iproc_pcie_pltfm_remove(struct platform_device *pdev)
return iproc_pcie_remove(pcie);
}
+static void iproc_pcie_pltfm_shutdown(struct platform_device *pdev)
+{
+ struct iproc_pcie *pcie = platform_get_drvdata(pdev);
+
+ iproc_pcie_shutdown(pcie);
+}
+
static struct platform_driver iproc_pcie_pltfm_driver = {
.driver = {
.name = "iproc-pcie",
@@ -141,6 +148,7 @@ static struct platform_driver iproc_pcie_pltfm_driver = {
},
.probe = iproc_pcie_pltfm_probe,
.remove = iproc_pcie_pltfm_remove,
+ .shutdown = iproc_pcie_pltfm_shutdown,
};
module_platform_driver(iproc_pcie_pltfm_driver);