switch: reset switch before using it.
SVN-Revision: 35579
This commit is contained in:
parent
f3360fdf67
commit
827e315017
1 changed files with 70 additions and 2 deletions
|
@ -29,6 +29,7 @@
|
|||
#include <linux/ethtool.h>
|
||||
#include <linux/mii.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
#include "switch-core.h"
|
||||
|
@ -73,6 +74,8 @@ struct robo_switch {
|
|||
u16 devid; /* ROBO_DEVICE_ID_53xx */
|
||||
bool is_5350;
|
||||
u8 gmii; /* gigabit mii */
|
||||
int gpio_robo_reset;
|
||||
int gpio_lanports_enable;
|
||||
struct ifreq ifr;
|
||||
struct net_device *dev;
|
||||
unsigned char port[6];
|
||||
|
@ -274,6 +277,27 @@ static void robo_switch_reset(void)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BCM47XX
|
||||
static int get_gpio_pin(const char *name)
|
||||
{
|
||||
int i, err;
|
||||
char nvram_var[10];
|
||||
char buf[30];
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
err = snprintf(nvram_var, sizeof(nvram_var), "gpio%i", i);
|
||||
if (err <= 0)
|
||||
continue;
|
||||
err = bcm47xx_nvram_getenv(nvram_var, buf, sizeof(buf));
|
||||
if (err <= 0)
|
||||
continue;
|
||||
if (!strcmp(name, buf))
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int robo_probe(char *devname)
|
||||
{
|
||||
__u32 phyid;
|
||||
|
@ -317,13 +341,46 @@ static int robo_probe(char *devname)
|
|||
goto err_put;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BCM47XX
|
||||
robo.gpio_lanports_enable = get_gpio_pin("lanports_enable");
|
||||
if (robo.gpio_lanports_enable >= 0) {
|
||||
err = gpio_request(robo.gpio_lanports_enable, "lanports_enable");
|
||||
if (err) {
|
||||
printk(KERN_ERR PFX "error (%i) requesting lanports_enable gpio (%i)\n",
|
||||
err, robo.gpio_lanports_enable);
|
||||
goto err_put;
|
||||
}
|
||||
gpio_direction_output(robo.gpio_lanports_enable, 1);
|
||||
mdelay(5);
|
||||
}
|
||||
|
||||
robo.gpio_robo_reset = get_gpio_pin("robo_reset");
|
||||
if (robo.gpio_robo_reset >= 0) {
|
||||
err = gpio_request(robo.gpio_robo_reset, "robo_reset");
|
||||
if (err) {
|
||||
printk(KERN_ERR PFX "error (%i) requesting robo_reset gpio (%i)\n",
|
||||
err, robo.gpio_robo_reset);
|
||||
goto err_gpio_robo;
|
||||
}
|
||||
gpio_set_value(robo.gpio_robo_reset, 0);
|
||||
gpio_direction_output(robo.gpio_robo_reset, 1);
|
||||
gpio_set_value(robo.gpio_robo_reset, 0);
|
||||
mdelay(50);
|
||||
|
||||
gpio_set_value(robo.gpio_robo_reset, 1);
|
||||
mdelay(20);
|
||||
} else {
|
||||
// TODO: reset the internal robo switch
|
||||
}
|
||||
#endif
|
||||
|
||||
phyid = mdio_read(ROBO_PHY_ADDR, 0x2) |
|
||||
(mdio_read(ROBO_PHY_ADDR, 0x3) << 16);
|
||||
|
||||
if (phyid == 0xffffffff || phyid == 0x55210022) {
|
||||
printk(KERN_ERR PFX "No Robo switch in managed mode found, phy_id = 0x%08x\n", phyid);
|
||||
err = -ENODEV;
|
||||
goto err_put;
|
||||
goto err_gpio_lanports;
|
||||
}
|
||||
|
||||
/* Get the device ID */
|
||||
|
@ -340,12 +397,19 @@ static int robo_probe(char *devname)
|
|||
robo_switch_reset();
|
||||
err = robo_switch_enable();
|
||||
if (err)
|
||||
goto err_put;
|
||||
goto err_gpio_lanports;
|
||||
|
||||
printk(KERN_INFO PFX "found a 5%s%x!%s at %s\n", robo.devid & 0xff00 ? "" : "3", robo.devid,
|
||||
robo.is_5350 ? " It's a 5350." : "", devname);
|
||||
|
||||
return 0;
|
||||
|
||||
err_gpio_lanports:
|
||||
if (robo.gpio_lanports_enable >= 0)
|
||||
gpio_free(robo.gpio_lanports_enable);
|
||||
err_gpio_robo:
|
||||
if (robo.gpio_robo_reset >= 0)
|
||||
gpio_free(robo.gpio_robo_reset);
|
||||
err_put:
|
||||
dev_put(robo.dev);
|
||||
robo.dev = NULL;
|
||||
|
@ -680,6 +744,10 @@ static void __exit robo_exit(void)
|
|||
switch_unregister_driver(DRIVER_NAME);
|
||||
if (robo.dev)
|
||||
dev_put(robo.dev);
|
||||
if (robo.gpio_robo_reset >= 0)
|
||||
gpio_free(robo.gpio_robo_reset);
|
||||
if (robo.gpio_lanports_enable >= 0)
|
||||
gpio_free(robo.gpio_lanports_enable);
|
||||
kfree(robo.device);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue