kernel: b53: add support for GPIO reset
[openwrt/svn-archive/archive.git] / target / linux / generic / files / drivers / net / phy / b53 / b53_common.c
index 86e3a787fbb661901bba0f011acf59e0607229cf..97968dbf0b0a2f9a907208d900d5a9bc73db1d95 100644 (file)
@@ -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);
 }