Commit cc30c163 authored by Andrew Lunn's avatar Andrew Lunn Committed by David S. Miller

net: dsa: Add support for a switch reset gpio

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: default avatarAndrew Lunn <andrew@lunn.ch>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 3f8c0f7e
...@@ -31,6 +31,8 @@ A switch child node has the following optional property: ...@@ -31,6 +31,8 @@ A switch child node has the following optional property:
switch. Must be set if the switch can not detect switch. Must be set if the switch can not detect
the presence and/or size of a connected EEPROM, the presence and/or size of a connected EEPROM,
otherwise optional. 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 A switch may have multiple "port" children nodes
...@@ -114,6 +116,7 @@ Example: ...@@ -114,6 +116,7 @@ Example:
#size-cells = <0>; #size-cells = <0>;
reg = <17 1>; /* MDIO address 17, switch 1 in tree */ reg = <17 1>; /* MDIO address 17, switch 1 in tree */
mii-bus = <&mii_bus1>; mii-bus = <&mii_bus1>;
reset-gpios = <&gpio5 1 GPIO_ACTIVE_LOW>;
switch1port0: port@0 { switch1port0: port@0 {
reg = <0>; reg = <0>;
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include <linux/timer.h> #include <linux/timer.h>
#include <linux/workqueue.h> #include <linux/workqueue.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/phy.h> #include <linux/phy.h>
#include <linux/phy_fixed.h> #include <linux/phy_fixed.h>
#include <linux/ethtool.h> #include <linux/ethtool.h>
...@@ -64,6 +65,13 @@ struct dsa_chip_data { ...@@ -64,6 +65,13 @@ struct dsa_chip_data {
* NULL if there is only one switch chip. * NULL if there is only one switch chip.
*/ */
s8 *rtable; 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 { struct dsa_platform_data {
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include <linux/of_mdio.h> #include <linux/of_mdio.h>
#include <linux/of_platform.h> #include <linux/of_platform.h>
#include <linux/of_net.h> #include <linux/of_net.h>
#include <linux/of_gpio.h>
#include <linux/sysfs.h> #include <linux/sysfs.h>
#include <linux/phy_fixed.h> #include <linux/phy_fixed.h>
#include "dsa_priv.h" #include "dsa_priv.h"
...@@ -688,6 +689,9 @@ static int dsa_of_probe(struct device *dev) ...@@ -688,6 +689,9 @@ static int dsa_of_probe(struct device *dev)
const char *port_name; const char *port_name;
int chip_index, port_index; int chip_index, port_index;
const unsigned int *sw_addr, *port_reg; const unsigned int *sw_addr, *port_reg;
int gpio;
enum of_gpio_flags of_flags;
unsigned long flags;
u32 eeprom_len; u32 eeprom_len;
int ret; int ret;
...@@ -766,6 +770,19 @@ static int dsa_of_probe(struct device *dev) ...@@ -766,6 +770,19 @@ static int dsa_of_probe(struct device *dev)
put_device(cd->host_dev); put_device(cd->host_dev);
cd->host_dev = &mdio_bus_switch->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) { for_each_available_child_of_node(child, port) {
port_reg = of_get_property(port, "reg", NULL); port_reg = of_get_property(port, "reg", NULL);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment