summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhauke <hauke@3c298f89-4303-0410-b956-a3cf2f4a3e73>2013-08-01 19:05:34 +0000
committerhauke <hauke@3c298f89-4303-0410-b956-a3cf2f4a3e73>2013-08-01 19:05:34 +0000
commit3cf5ed065f5e776f8dac1a531d533e6a773ef862 (patch)
tree4e36e23f1a3c7eb59eb1dc8d7eca20ad4dbbd177
parent81ca618b45fe2a063e968e1ae3d90fb01af4db40 (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
-rw-r--r--target/linux/generic/files/drivers/net/phy/b53/b53_common.c29
-rw-r--r--target/linux/generic/files/drivers/net/phy/b53/b53_priv.h14
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