summaryrefslogtreecommitdiff
path: root/drivers/pci/host/pci-imx6.c
diff options
context:
space:
mode:
authorMax Krummenacher <max.krummenacher@toradex.com>2014-11-21 18:58:02 +0100
committerMarcel Ziswiler <marcel.ziswiler@toradex.com>2018-12-24 01:27:30 +0100
commitf7ba61b78a693a9e2087c534909ab3b534879cf8 (patch)
treea58e920b758228bfe0577581863a91f936feb920 /drivers/pci/host/pci-imx6.c
parentcafea5498f4e8d6c8d80c775a54b1949f6089e0b (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. Signed-off-by: Max Krummenacher <max.krummenacher@toradex.com> Acked-by: Marcel Ziswiler <marcel.ziswiler@toradex.com> (cherry picked from commit 94a60e7f645965b1e422e4e80aa8ccb9e0ec845c) (cherry picked from commit f2bb337d37acd680404371d2530a486bfe821ce2) Conflicts: drivers/pci/host/pci-imx6.c (cherry picked from commit 557f0276856f1731264492ad82fe2f13e2d64831)
Diffstat (limited to 'drivers/pci/host/pci-imx6.c')
-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 c3cc315473ce..5bfe1206a6da 100644
--- a/drivers/pci/host/pci-imx6.c
+++ b/drivers/pci/host/pci-imx6.c
@@ -73,6 +73,7 @@ struct imx_pcie {
int power_on_gpio;
int reset_gpio;
bool gpio_active_high;
+ int reset_ep_gpio;
struct clk *pcie_bus;
struct clk *pcie_inbound_axi;
struct clk *pcie_phy;
@@ -932,11 +933,16 @@ static int imx_pcie_deassert_core_reset(struct imx_pcie *imx_pcie)
/* Some boards don't have PCIe reset GPIO. */
if (gpio_is_valid(imx_pcie->reset_gpio)) {
+ if (gpio_is_valid(imx_pcie->reset_ep_gpio))
+ gpio_set_value_cansleep(imx_pcie->reset_ep_gpio, 1);
gpio_set_value_cansleep(imx_pcie->reset_gpio,
imx_pcie->gpio_active_high);
mdelay(20);
gpio_set_value_cansleep(imx_pcie->reset_gpio,
!imx_pcie->gpio_active_high);
+ mdelay(1);
+ if (gpio_is_valid(imx_pcie->reset_ep_gpio))
+ gpio_set_value_cansleep(imx_pcie->reset_ep_gpio, 0);
mdelay(20);
}
@@ -2330,6 +2336,17 @@ static int imx_pcie_probe(struct platform_device *pdev)
} else if (imx_pcie->dis_gpio == -EPROBE_DEFER) {
return imx_pcie->dis_gpio;
}
+ imx_pcie->reset_ep_gpio = of_get_named_gpio(node, "reset-ep-gpio", 0);
+ if (gpio_is_valid(imx_pcie->reset_ep_gpio)) {
+ ret = devm_gpio_request_one(&pdev->dev,
+ imx_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;
+ }
+ }
imx_pcie->power_on_gpio = of_get_named_gpio(node, "power-on-gpio", 0);
if (gpio_is_valid(imx_pcie->power_on_gpio)) {