summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax Krummenacher <max.krummenacher@toradex.com>2014-11-21 18:58:02 +0100
committerMax Krummenacher <max.krummenacher@toradex.com>2014-11-21 19:02:44 +0100
commit94a60e7f645965b1e422e4e80aa8ccb9e0ec845c (patch)
tree0b614a7e45d27d7651f4bbb2c3224e01b6e596a8
parentf79675e581a4abda12db31cde3ee71d44016b981 (diff)
pcie-imx6: add reset function for reseting downstream EP
With the following dtb node one can define a gpio to reset downstream endpoints. reset-ep-gpio = <...>; Currently the logic is 1 for reset asserted and 0 for reset deasserted. Some pcie switches require their downstream endpoints to be kept in reset for an additonal millisecond after their reset has been deasserted.
-rw-r--r--drivers/pci/host/pci-imx6.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci-imx6.c
index f201d8905100..485dc8689879 100644
--- a/drivers/pci/host/pci-imx6.c
+++ b/drivers/pci/host/pci-imx6.c
@@ -44,6 +44,7 @@ static u32 test_region_size = SZ_2M;
struct imx6_pcie {
int reset_gpio;
+ int reset_ep_gpio;
int power_on_gpio;
int wake_up_gpio;
int disable_gpio;
@@ -281,9 +282,14 @@ static int imx6_pcie_deassert_core_reset(struct pcie_port *pp)
/* Some boards don't have PCIe reset GPIO. */
if (gpio_is_valid(imx6_pcie->reset_gpio)) {
+ if (gpio_is_valid(imx6_pcie->reset_ep_gpio))
+ gpio_set_value(imx6_pcie->reset_ep_gpio, 1);
gpio_set_value(imx6_pcie->reset_gpio, 0);
msleep(100);
gpio_set_value(imx6_pcie->reset_gpio, 1);
+ msleep(1);
+ if (gpio_is_valid(imx6_pcie->reset_ep_gpio))
+ gpio_set_value(imx6_pcie->reset_ep_gpio, 0);
}
return 0;
@@ -755,6 +761,17 @@ static int __init imx6_pcie_probe(struct platform_device *pdev)
return ret;
}
}
+ imx6_pcie->reset_ep_gpio = of_get_named_gpio(np, "reset-ep-gpio", 0);
+ if (gpio_is_valid(imx6_pcie->reset_ep_gpio)) {
+ ret = devm_gpio_request_one(&pdev->dev,
+ imx6_pcie->reset_ep_gpio,
+ GPIOF_OUT_INIT_HIGH,
+ "PCIe EP reset");
+ if (ret) {
+ dev_err(&pdev->dev, "unable to get reset end point gpio\n");
+ return ret;
+ }
+ }
imx6_pcie->power_on_gpio = of_get_named_gpio(np, "power-on-gpio", 0);
if (gpio_is_valid(imx6_pcie->power_on_gpio)) {