net: dsa: Add support for a switch reset gpio
authorAndrew Lunn <andrew@lunn.ch>
Fri, 20 Nov 2015 02:56:23 +0000 (03:56 +0100)
committerDavid S. Miller <davem@davemloft.net>
Mon, 23 Nov 2015 16:53:10 +0000 (11:53 -0500)
Some boards have a gpio line tied to the switch reset pin. Allow this
gpio to be retrieved from the device tree, and take the switch out of
reset before performing the probe.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
Documentation/devicetree/bindings/net/dsa/dsa.txt
include/net/dsa.h
net/dsa/dsa.c

index 04e6bef3ac3ff431560f53456a34d4b932c7eca0..5fdbbcdf8c4b84109cfeb28d0c77397d0f93aa42 100644 (file)
@@ -31,6 +31,8 @@ A switch child node has the following optional property:
                          switch. Must be set if the switch can not detect
                          the presence and/or size of a connected EEPROM,
                          otherwise optional.
+- reset-gpios          : phandle and specifier to a gpio line connected to
+                         reset pin of the switch chip.
 
 A switch may have multiple "port" children nodes
 
@@ -114,6 +116,7 @@ Example:
                        #size-cells = <0>;
                        reg = <17 1>;   /* MDIO address 17, switch 1 in tree */
                        mii-bus = <&mii_bus1>;
+                       reset-gpios = <&gpio5 1 GPIO_ACTIVE_LOW>;
 
                        switch1port0: port@0 {
                                reg = <0>;
index 82a4c60111733e98310a12d569fb999c8e5ac412..3f23dd9d6a692455d93e88b0a15688874e57bad5 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/timer.h>
 #include <linux/workqueue.h>
 #include <linux/of.h>
+#include <linux/of_gpio.h>
 #include <linux/phy.h>
 #include <linux/phy_fixed.h>
 #include <linux/ethtool.h>
@@ -64,6 +65,13 @@ struct dsa_chip_data {
         * NULL if there is only one switch chip.
         */
        s8              *rtable;
+
+       /*
+        * A switch may have a GPIO line tied to its reset pin. Parse
+        * this from the device tree, and use it before performing
+        * switch soft reset.
+        */
+       struct gpio_desc *reset;
 };
 
 struct dsa_platform_data {
index 1eba07feb34adb451734e18e1c73031c9b7b2e35..0b5565f923cc4bd54e8c210bff93486019b986be 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/of_mdio.h>
 #include <linux/of_platform.h>
 #include <linux/of_net.h>
+#include <linux/of_gpio.h>
 #include <linux/sysfs.h>
 #include <linux/phy_fixed.h>
 #include "dsa_priv.h"
@@ -688,6 +689,9 @@ static int dsa_of_probe(struct device *dev)
        const char *port_name;
        int chip_index, port_index;
        const unsigned int *sw_addr, *port_reg;
+       int gpio;
+       enum of_gpio_flags of_flags;
+       unsigned long flags;
        u32 eeprom_len;
        int ret;
 
@@ -766,6 +770,19 @@ static int dsa_of_probe(struct device *dev)
                        put_device(cd->host_dev);
                        cd->host_dev = &mdio_bus_switch->dev;
                }
+               gpio = of_get_named_gpio_flags(child, "reset-gpios", 0,
+                                              &of_flags);
+               if (gpio_is_valid(gpio)) {
+                       flags = (of_flags == OF_GPIO_ACTIVE_LOW ?
+                                GPIOF_ACTIVE_LOW : 0);
+                       ret = devm_gpio_request_one(dev, gpio, flags,
+                                                   "switch_reset");
+                       if (ret)
+                               goto out_free_chip;
+
+                       cd->reset = gpio_to_desc(gpio);
+                       gpiod_direction_output(cd->reset, 0);
+               }
 
                for_each_available_child_of_node(child, port) {
                        port_reg = of_get_property(port, "reg", NULL);