diff options
author | hauke <hauke@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2013-08-01 19:05:34 +0000 |
---|---|---|
committer | hauke <hauke@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2013-08-01 19:05:34 +0000 |
commit | 3cf5ed065f5e776f8dac1a531d533e6a773ef862 (patch) | |
tree | 4e36e23f1a3c7eb59eb1dc8d7eca20ad4dbbd177 /target/linux | |
parent | 81ca618b45fe2a063e968e1ae3d90fb01af4db40 (diff) |
kernel: b53: add support for GPIO reset
This is needed for some switches used on bcm47xx SoCs like the one on the Asus RT-N66U.
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@37645 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'target/linux')
-rw-r--r-- | target/linux/generic/files/drivers/net/phy/b53/b53_common.c | 29 | ||||
-rw-r--r-- | target/linux/generic/files/drivers/net/phy/b53/b53_priv.h | 14 |
2 files changed, 43 insertions, 0 deletions
diff --git a/target/linux/generic/files/drivers/net/phy/b53/b53_common.c b/target/linux/generic/files/drivers/net/phy/b53/b53_common.c index 86e3a787fb..97968dbf0b 100644 --- a/target/linux/generic/files/drivers/net/phy/b53/b53_common.c +++ b/target/linux/generic/files/drivers/net/phy/b53/b53_common.c @@ -20,6 +20,7 @@ #include <linux/delay.h> #include <linux/export.h> +#include <linux/gpio.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/switch.h> @@ -451,10 +452,30 @@ static int b53_apply(struct b53_device *dev) return 0; } +void b53_switch_reset_gpio(struct b53_device *dev) +{ + int gpio = dev->reset_gpio; + + if (gpio < 0) + return; + + gpio_set_value(gpio, 0); + gpio_direction_output(gpio, 1); + gpio_set_value(gpio, 0); + mdelay(50); + + gpio_set_value(gpio, 1); + mdelay(20); + + dev->current_page = 0xff; +} + static int b53_switch_reset(struct b53_device *dev) { u8 mgmt; + b53_switch_reset_gpio(dev); + b53_read8(dev, B53_CTRL_PAGE, B53_SWITCH_MODE, &mgmt); if (!(mgmt & SM_SW_FWD_EN)) { @@ -1114,6 +1135,7 @@ int b53_switch_init(struct b53_device *dev) { struct switch_dev *sw_dev = &dev->sw_dev; unsigned i; + int ret; for (i = 0; i < ARRAY_SIZE(b53_switch_chips); i++) { const struct b53_chip_data *chip = &b53_switch_chips[i]; @@ -1192,6 +1214,13 @@ int b53_switch_init(struct b53_device *dev) if (!dev->buf) return -ENOMEM; + dev->reset_gpio = b53_switch_get_reset_gpio(dev); + if (dev->reset_gpio >= 0) { + ret = devm_gpio_request(dev->dev, dev->reset_gpio, "robo_reset"); + if (ret) + return ret; + } + return b53_switch_reset(dev); } diff --git a/target/linux/generic/files/drivers/net/phy/b53/b53_priv.h b/target/linux/generic/files/drivers/net/phy/b53/b53_priv.h index fca74ae4b9..53da406407 100644 --- a/target/linux/generic/files/drivers/net/phy/b53/b53_priv.h +++ b/target/linux/generic/files/drivers/net/phy/b53/b53_priv.h @@ -75,6 +75,7 @@ struct b53_device { u8 duplex_reg; u8 jumbo_pm_reg; u8 jumbo_size_reg; + int reset_gpio; /* used ports mask */ u16 enabled_ports; @@ -275,4 +276,17 @@ static inline int b53_write64(struct b53_device *dev, u8 page, u8 reg, return ret; } +#ifdef CONFIG_BCM47XX + +#include <bcm47xx_nvram.h> +static inline int b53_switch_get_reset_gpio(struct b53_device *dev) +{ + return bcm47xx_nvram_gpio_pin("robo_reset"); +} +#else +static inline int b53_switch_get_reset_gpio(struct b53_device *dev) +{ + return -ENOENT; +} +#endif #endif |