aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Hesselbarth <sebastian.hesselbarth@gmail.com>2013-08-13 08:25:23 -0400
committerJason Cooper <jason@lakedaemon.net>2013-09-30 10:58:43 -0400
commit52ba992e201f47b878019f268391aa0e27592906 (patch)
tree597d5361fc22a4680c6ca1bff45becbe4b95a423
parente5615c30c1c921dda957638ddf9c9437fcb7bb36 (diff)
PCI: mvebu: add support for reset on GPIO
This patch adds a check for DT passed reset-gpios property and deasserts/ asserts reset pin on probe/remove with configurable delay. Corresponding binding documentation is also updated. Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Signed-off-by: Jason Cooper <jason@lakedaemon.net>
-rw-r--r--Documentation/devicetree/bindings/pci/mvebu-pci.txt6
-rw-r--r--drivers/pci/host/pci-mvebu.c33
2 files changed, 38 insertions, 1 deletions
diff --git a/Documentation/devicetree/bindings/pci/mvebu-pci.txt b/Documentation/devicetree/bindings/pci/mvebu-pci.txt
index 638673aec306..8bb3245e1946 100644
--- a/Documentation/devicetree/bindings/pci/mvebu-pci.txt
+++ b/Documentation/devicetree/bindings/pci/mvebu-pci.txt
@@ -76,6 +76,8 @@ and the following optional properties:
76- marvell,pcie-lane: the physical PCIe lane number, for ports having 76- marvell,pcie-lane: the physical PCIe lane number, for ports having
77 multiple lanes. If this property is not found, we assume that the 77 multiple lanes. If this property is not found, we assume that the
78 value is 0. 78 value is 0.
79- reset-gpios: optional gpio to PERST#
80- reset-delay-us: delay in us to wait after reset de-assertion
79 81
80Example: 82Example:
81 83
@@ -138,6 +140,10 @@ pcie-controller {
138 interrupt-map = <0 0 0 0 &mpic 58>; 140 interrupt-map = <0 0 0 0 &mpic 58>;
139 marvell,pcie-port = <0>; 141 marvell,pcie-port = <0>;
140 marvell,pcie-lane = <0>; 142 marvell,pcie-lane = <0>;
143 /* low-active PERST# reset on GPIO 25 */
144 reset-gpios = <&gpio0 25 1>;
145 /* wait 20ms for device settle after reset deassertion */
146 reset-delay-us = <20000>;
141 clocks = <&gateclk 5>; 147 clocks = <&gateclk 5>;
142 status = "disabled"; 148 status = "disabled";
143 }; 149 };
diff --git a/drivers/pci/host/pci-mvebu.c b/drivers/pci/host/pci-mvebu.c
index af23038a52ac..2d5f414bc45a 100644
--- a/drivers/pci/host/pci-mvebu.c
+++ b/drivers/pci/host/pci-mvebu.c
@@ -9,14 +9,17 @@
9#include <linux/kernel.h> 9#include <linux/kernel.h>
10#include <linux/pci.h> 10#include <linux/pci.h>
11#include <linux/clk.h> 11#include <linux/clk.h>
12#include <linux/delay.h>
13#include <linux/gpio.h>
12#include <linux/module.h> 14#include <linux/module.h>
13#include <linux/mbus.h> 15#include <linux/mbus.h>
14#include <linux/msi.h> 16#include <linux/msi.h>
15#include <linux/slab.h> 17#include <linux/slab.h>
16#include <linux/platform_device.h> 18#include <linux/platform_device.h>
17#include <linux/of_address.h> 19#include <linux/of_address.h>
18#include <linux/of_pci.h>
19#include <linux/of_irq.h> 20#include <linux/of_irq.h>
21#include <linux/of_gpio.h>
22#include <linux/of_pci.h>
20#include <linux/of_platform.h> 23#include <linux/of_platform.h>
21 24
22/* 25/*
@@ -126,6 +129,9 @@ struct mvebu_pcie_port {
126 unsigned int io_target; 129 unsigned int io_target;
127 unsigned int io_attr; 130 unsigned int io_attr;
128 struct clk *clk; 131 struct clk *clk;
132 int reset_gpio;
133 int reset_active_low;
134 char *reset_name;
129 struct mvebu_sw_pci_bridge bridge; 135 struct mvebu_sw_pci_bridge bridge;
130 struct device_node *dn; 136 struct device_node *dn;
131 struct mvebu_pcie *pcie; 137 struct mvebu_pcie *pcie;
@@ -857,6 +863,7 @@ static int mvebu_pcie_probe(struct platform_device *pdev)
857 i = 0; 863 i = 0;
858 for_each_child_of_node(pdev->dev.of_node, child) { 864 for_each_child_of_node(pdev->dev.of_node, child) {
859 struct mvebu_pcie_port *port = &pcie->ports[i]; 865 struct mvebu_pcie_port *port = &pcie->ports[i];
866 enum of_gpio_flags flags;
860 867
861 if (!of_device_is_available(child)) 868 if (!of_device_is_available(child))
862 continue; 869 continue;
@@ -897,6 +904,30 @@ static int mvebu_pcie_probe(struct platform_device *pdev)
897 continue; 904 continue;
898 } 905 }
899 906
907 port->reset_gpio = of_get_named_gpio_flags(child,
908 "reset-gpios", 0, &flags);
909 if (gpio_is_valid(port->reset_gpio)) {
910 u32 reset_udelay = 20000;
911
912 port->reset_active_low = flags & OF_GPIO_ACTIVE_LOW;
913 port->reset_name = kasprintf(GFP_KERNEL,
914 "pcie%d.%d-reset", port->port, port->lane);
915 of_property_read_u32(child, "reset-delay-us",
916 &reset_udelay);
917
918 ret = devm_gpio_request_one(&pdev->dev,
919 port->reset_gpio, GPIOF_DIR_OUT, port->reset_name);
920 if (ret) {
921 if (ret == -EPROBE_DEFER)
922 return ret;
923 continue;
924 }
925
926 gpio_set_value(port->reset_gpio,
927 (port->reset_active_low) ? 1 : 0);
928 msleep(reset_udelay/1000);
929 }
930
900 port->clk = of_clk_get_by_name(child, NULL); 931 port->clk = of_clk_get_by_name(child, NULL);
901 if (IS_ERR(port->clk)) { 932 if (IS_ERR(port->clk)) {
902 dev_err(&pdev->dev, "PCIe%d.%d: cannot get clock\n", 933 dev_err(&pdev->dev, "PCIe%d.%d: cannot get clock\n",