From: Limeng <meng...@windriver.com>

On xilinx-zcu102 platform, when run kdump feature, an active pcie
device need to be reset with MIO31 so that the crash kernel is able
to boot up successfully.

Signed-off-by: Meng Li <meng...@windriver.com>
[Quanyang: When power on zcu102 board, pcie bus also occur that PCI link
is down, and this patch can fix it. Also, we need add a 100ms delay
for some NIC (Intel X520 etc), or else PCI config read will fail due to
unstable device status.]
Signed-off-by: Quanyang Wang <quanyang.w...@windriver.com>
---
 .../boot/dts/xilinx/zynqmp-zcu102-revA.dts    |  1 +
 drivers/pci/controller/pcie-xilinx-nwl.c      | 35 +++++++++++++++++++
 2 files changed, 36 insertions(+)

diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zcu102-revA.dts 
b/arch/arm64/boot/dts/xilinx/zynqmp-zcu102-revA.dts
index 36863f65e94e..2741040fe26a 100644
--- a/arch/arm64/boot/dts/xilinx/zynqmp-zcu102-revA.dts
+++ b/arch/arm64/boot/dts/xilinx/zynqmp-zcu102-revA.dts
@@ -772,6 +772,7 @@
 
 &pcie {
        status = "okay";
+       reset-gpio = <&gpio 31 GPIO_ACTIVE_HIGH>;
 };
 
 &qspi {
diff --git a/drivers/pci/controller/pcie-xilinx-nwl.c 
b/drivers/pci/controller/pcie-xilinx-nwl.c
index a1fd436dba8f..908166dc4f3e 100644
--- a/drivers/pci/controller/pcie-xilinx-nwl.c
+++ b/drivers/pci/controller/pcie-xilinx-nwl.c
@@ -21,6 +21,8 @@
 #include <linux/pci.h>
 #include <linux/platform_device.h>
 #include <linux/irqchip/chained_irq.h>
+#include <linux/gpio.h>
+#include <linux/of_gpio.h>
 
 #include "../pci.h"
 
@@ -830,6 +832,31 @@ static const struct of_device_id nwl_pcie_of_match[] = {
        {}
 };
 
+static int nwl_pcie_reset_ep_device(struct platform_device *pdev)
+{
+       struct device_node *node = pdev->dev.of_node;
+       int gpio;
+       int err;
+
+       gpio = of_get_named_gpio(node, "reset-gpio", 0);
+       if (!gpio_is_valid(gpio)) {
+               dev_err(&pdev->dev, "failed to parse reset gpio\n");
+               return gpio;
+       }
+
+       err = devm_gpio_request_one(&pdev->dev, gpio, GPIOF_OUT_INIT_HIGH,
+                                       "pcie reset gpio");
+       if (err)
+               return err;
+
+       udelay(2);
+       gpio_set_value(gpio, 0);
+       udelay(10);
+       gpio_set_value(gpio, 1);
+
+       return err;
+}
+
 static int nwl_pcie_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
@@ -841,6 +868,14 @@ static int nwl_pcie_probe(struct platform_device *pdev)
        resource_size_t iobase = 0;
        LIST_HEAD(res);
 
+       err = nwl_pcie_reset_ep_device(pdev);
+       if (err) {
+               dev_err(dev, "fail to reset pcie device\n");
+               return err;
+       }
+       /* wait for ep device reset finished */
+       mdelay(100);
+
        bridge = devm_pci_alloc_host_bridge(dev, sizeof(*pcie));
        if (!bridge)
                return -ENODEV;
-- 
2.17.1

-- 
_______________________________________________
linux-yocto mailing list
linux-yocto@yoctoproject.org
https://lists.yoctoproject.org/listinfo/linux-yocto

Reply via email to