Skip to content

Commit

Permalink
net: dsa: mv88e6xxx: Refactor MDIO so driver registers mdio bus
Browse files Browse the repository at this point in the history
Have the switch driver register its own MDIO bus. This allows for an
mdio property in the device tree, with child nodes for phys, which
can be referenced via phandles, etc.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
Reviewed-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Andrew Lunn authored and David S. Miller committed Jun 4, 2016
1 parent 03a4a54 commit b516d45
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 9 deletions.
89 changes: 80 additions & 9 deletions drivers/net/dsa/mv88e6xxx.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <linux/list.h>
#include <linux/mdio.h>
#include <linux/module.h>
#include <linux/of_mdio.h>
#include <linux/netdevice.h>
#include <linux/gpio/consumer.h>
#include <linux/phy.h>
Expand Down Expand Up @@ -3130,13 +3131,11 @@ static int mv88e6xxx_setup(struct dsa_switch *ds)
int i;

ps->ds = ds;
ds->slave_mii_bus = ps->mdio_bus;

if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_EEPROM))
mutex_init(&ps->eeprom_mutex);

if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_PPU))
mv88e6xxx_ppu_state_init(ps);

mutex_lock(&ps->smi_mutex);

err = mv88e6xxx_switch_reset(ps);
Expand Down Expand Up @@ -3192,9 +3191,9 @@ static int mv88e6xxx_port_to_mdio_addr(struct mv88e6xxx_priv_state *ps,
return -EINVAL;
}

static int mv88e6xxx_mdio_read(struct dsa_switch *ds, int port, int regnum)
static int mv88e6xxx_mdio_read(struct mii_bus *bus, int port, int regnum)
{
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
struct mv88e6xxx_priv_state *ps = bus->priv;
int addr = mv88e6xxx_port_to_mdio_addr(ps, port);
int ret;

Expand All @@ -3214,10 +3213,10 @@ static int mv88e6xxx_mdio_read(struct dsa_switch *ds, int port, int regnum)
return ret;
}

static int mv88e6xxx_mdio_write(struct dsa_switch *ds, int port, int regnum,
static int mv88e6xxx_mdio_write(struct mii_bus *bus, int port, int regnum,
u16 val)
{
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
struct mv88e6xxx_priv_state *ps = bus->priv;
int addr = mv88e6xxx_port_to_mdio_addr(ps, port);
int ret;

Expand All @@ -3237,6 +3236,66 @@ static int mv88e6xxx_mdio_write(struct dsa_switch *ds, int port, int regnum,
return ret;
}

static int mv88e6xxx_mdio_register(struct mv88e6xxx_priv_state *ps,
struct device_node *np)
{
static int index;
struct mii_bus *bus;
int err;

if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_PPU))
mv88e6xxx_ppu_state_init(ps);

if (np)
ps->mdio_np = of_get_child_by_name(np, "mdio");

bus = devm_mdiobus_alloc(ps->dev);
if (!bus)
return -ENOMEM;

bus->priv = (void *)ps;
if (np) {
bus->name = np->full_name;
snprintf(bus->id, MII_BUS_ID_SIZE, "%s", np->full_name);
} else {
bus->name = "mv88e6xxx SMI";
snprintf(bus->id, MII_BUS_ID_SIZE, "mv88e6xxx-%d", index++);
}

bus->read = mv88e6xxx_mdio_read;
bus->write = mv88e6xxx_mdio_write;
bus->parent = ps->dev;

if (ps->mdio_np)
err = of_mdiobus_register(bus, ps->mdio_np);
else
err = mdiobus_register(bus);
if (err) {
dev_err(ps->dev, "Cannot register MDIO bus (%d)\n", err);
goto out;
}
ps->mdio_bus = bus;

return 0;

out:
if (ps->mdio_np)
of_node_put(ps->mdio_np);

return err;
}

static void mv88e6xxx_mdio_unregister(struct mv88e6xxx_priv_state *ps)

{
struct mii_bus *bus = ps->mdio_bus;

mdiobus_unregister(bus);

if (ps->mdio_np)
of_node_put(ps->mdio_np);
}

#ifdef CONFIG_NET_DSA_HWMON

static int mv88e61xx_get_temp(struct dsa_switch *ds, int *temp)
Expand Down Expand Up @@ -3549,6 +3608,7 @@ static const char *mv88e6xxx_drv_probe(struct device *dsa_dev,
struct mii_bus *bus;
const char *name;
int id, prod_num, rev;
int err;

bus = dsa_host_dev_to_mii_bus(host_dev);
if (!bus)
Expand All @@ -3575,8 +3635,13 @@ static const char *mv88e6xxx_drv_probe(struct device *dsa_dev,
ps->bus = bus;
ps->sw_addr = sw_addr;
ps->info = info;
ps->dev = dsa_dev;
mutex_init(&ps->smi_mutex);

err = mv88e6xxx_mdio_register(ps, NULL);
if (err)
return NULL;

*priv = ps;

dev_info(&ps->bus->dev, "switch 0x%x probed: %s, revision %u\n",
Expand All @@ -3590,8 +3655,6 @@ struct dsa_switch_driver mv88e6xxx_switch_driver = {
.probe = mv88e6xxx_drv_probe,
.setup = mv88e6xxx_setup,
.set_addr = mv88e6xxx_set_addr,
.phy_read = mv88e6xxx_mdio_read,
.phy_write = mv88e6xxx_mdio_write,
.adjust_link = mv88e6xxx_adjust_link,
.get_strings = mv88e6xxx_get_strings,
.get_ethtool_stats = mv88e6xxx_get_ethtool_stats,
Expand Down Expand Up @@ -3677,6 +3740,12 @@ int mv88e6xxx_probe(struct mdio_device *mdiodev)
!of_property_read_u32(np, "eeprom-length", &eeprom_len))
ps->eeprom_len = eeprom_len;

err = mv88e6xxx_mdio_register(ps, mdiodev->dev.of_node);
if (err)
return err;

ds->slave_mii_bus = ps->mdio_bus;

dev_set_drvdata(dev, ds);

dev_info(dev, "switch 0x%x probed: %s, revision %u\n",
Expand All @@ -3691,6 +3760,8 @@ static void mv88e6xxx_remove(struct mdio_device *mdiodev)
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);

put_device(&ps->bus->dev);

mv88e6xxx_mdio_unregister(ps);
}

static const struct of_device_id mv88e6xxx_of_match[] = {
Expand Down
6 changes: 6 additions & 0 deletions drivers/net/dsa/mv88e6xxx.h
Original file line number Diff line number Diff line change
Expand Up @@ -600,6 +600,12 @@ struct mv88e6xxx_priv_state {

/* set to size of eeprom if supported by the switch */
int eeprom_len;

/* Device node for the MDIO bus */
struct device_node *mdio_np;

/* And the MDIO bus itself */
struct mii_bus *mdio_bus;
};

enum stat_type {
Expand Down

0 comments on commit b516d45

Please sign in to comment.