Add code to handle optional reset GPIO in the KSZ switch driver. The switch has a reset GPIO line which can be controlled by the CPU, so make sure it is configured correctly in such setups.
Signed-off-by: Marek Vasut <ma...@denx.de> Cc: Vivien Didelot <vivien.dide...@savoirfairelinux.com> Cc: Woojung Huh <woojung....@microchip.com> Cc: David S. Miller <da...@davemloft.net> Cc: Tristram Ha <tristram...@microchip.com> --- drivers/net/dsa/microchip/ksz_common.c | 26 ++++++++++++++++++++++++++ drivers/net/dsa/microchip/ksz_priv.h | 2 ++ 2 files changed, 28 insertions(+) diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c index 9705808c3af7a..1f50b31722958 100644 --- a/drivers/net/dsa/microchip/ksz_common.c +++ b/drivers/net/dsa/microchip/ksz_common.c @@ -8,12 +8,14 @@ #include <linux/delay.h> #include <linux/export.h> #include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/platform_data/microchip-ksz.h> #include <linux/phy.h> #include <linux/etherdevice.h> #include <linux/if_bridge.h> +#include <linux/of_gpio.h> #include <linux/of_net.h> #include <net/dsa.h> #include <net/switchdev.h> @@ -289,11 +291,31 @@ EXPORT_SYMBOL(ksz_switch_alloc); int ksz_switch_register(struct ksz_device *dev, const struct ksz_dev_ops *ops) { + struct device_node *np = dev->dev->of_node; + enum of_gpio_flags reset_gpio_flags; + unsigned long flags; + int reset_gpio; int ret; if (dev->pdata) dev->chip_id = dev->pdata->chip_id; + dev->reset_gpio = -1; + reset_gpio = of_get_named_gpio_flags(np, "reset-gpios", 0, + &reset_gpio_flags); + if (reset_gpio >= 0) { + flags = (reset_gpio_flags == OF_GPIO_ACTIVE_LOW) ? + GPIOF_ACTIVE_LOW : 0; + ret = devm_gpio_request_one(dev->dev, reset_gpio, flags, + "switch-reset"); + if (ret) { + dev_err(dev->dev, "failed to get reset-gpios: %d\n", ret); + return -EIO; + } + dev->reset_gpio = reset_gpio; + gpiod_set_value(gpio_to_desc(reset_gpio), 0); + } + mutex_init(&dev->reg_mutex); mutex_init(&dev->stats_mutex); mutex_init(&dev->alu_mutex); @@ -329,6 +351,10 @@ void ksz_switch_remove(struct ksz_device *dev) { dev->dev_ops->exit(dev); dsa_unregister_switch(dev->ds); + + if (dev->reset_gpio >= 0) + gpiod_set_value(gpio_to_desc(dev->reset_gpio), 1); + } EXPORT_SYMBOL(ksz_switch_remove); diff --git a/drivers/net/dsa/microchip/ksz_priv.h b/drivers/net/dsa/microchip/ksz_priv.h index a38ff0841ed4e..6dd2ebfd6e12f 100644 --- a/drivers/net/dsa/microchip/ksz_priv.h +++ b/drivers/net/dsa/microchip/ksz_priv.h @@ -59,6 +59,8 @@ struct ksz_device { void *priv; + int reset_gpio; /* Optional reset GPIO */ + /* chip specific data */ u32 chip_id; int num_vlans; -- 2.18.0