Skip to content

Commit b516d45

Browse files
lunndavem330
authored andcommitted
net: dsa: mv88e6xxx: Refactor MDIO so driver registers mdio bus
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>
1 parent 03a4a54 commit b516d45

File tree

2 files changed

+86
-9
lines changed

2 files changed

+86
-9
lines changed

drivers/net/dsa/mv88e6xxx.c

Lines changed: 80 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <linux/list.h>
2222
#include <linux/mdio.h>
2323
#include <linux/module.h>
24+
#include <linux/of_mdio.h>
2425
#include <linux/netdevice.h>
2526
#include <linux/gpio/consumer.h>
2627
#include <linux/phy.h>
@@ -3130,13 +3131,11 @@ static int mv88e6xxx_setup(struct dsa_switch *ds)
31303131
int i;
31313132

31323133
ps->ds = ds;
3134+
ds->slave_mii_bus = ps->mdio_bus;
31333135

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

3137-
if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_PPU))
3138-
mv88e6xxx_ppu_state_init(ps);
3139-
31403139
mutex_lock(&ps->smi_mutex);
31413140

31423141
err = mv88e6xxx_switch_reset(ps);
@@ -3192,9 +3191,9 @@ static int mv88e6xxx_port_to_mdio_addr(struct mv88e6xxx_priv_state *ps,
31923191
return -EINVAL;
31933192
}
31943193

3195-
static int mv88e6xxx_mdio_read(struct dsa_switch *ds, int port, int regnum)
3194+
static int mv88e6xxx_mdio_read(struct mii_bus *bus, int port, int regnum)
31963195
{
3197-
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
3196+
struct mv88e6xxx_priv_state *ps = bus->priv;
31983197
int addr = mv88e6xxx_port_to_mdio_addr(ps, port);
31993198
int ret;
32003199

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

3217-
static int mv88e6xxx_mdio_write(struct dsa_switch *ds, int port, int regnum,
3216+
static int mv88e6xxx_mdio_write(struct mii_bus *bus, int port, int regnum,
32183217
u16 val)
32193218
{
3220-
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
3219+
struct mv88e6xxx_priv_state *ps = bus->priv;
32213220
int addr = mv88e6xxx_port_to_mdio_addr(ps, port);
32223221
int ret;
32233222

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

3239+
static int mv88e6xxx_mdio_register(struct mv88e6xxx_priv_state *ps,
3240+
struct device_node *np)
3241+
{
3242+
static int index;
3243+
struct mii_bus *bus;
3244+
int err;
3245+
3246+
if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_PPU))
3247+
mv88e6xxx_ppu_state_init(ps);
3248+
3249+
if (np)
3250+
ps->mdio_np = of_get_child_by_name(np, "mdio");
3251+
3252+
bus = devm_mdiobus_alloc(ps->dev);
3253+
if (!bus)
3254+
return -ENOMEM;
3255+
3256+
bus->priv = (void *)ps;
3257+
if (np) {
3258+
bus->name = np->full_name;
3259+
snprintf(bus->id, MII_BUS_ID_SIZE, "%s", np->full_name);
3260+
} else {
3261+
bus->name = "mv88e6xxx SMI";
3262+
snprintf(bus->id, MII_BUS_ID_SIZE, "mv88e6xxx-%d", index++);
3263+
}
3264+
3265+
bus->read = mv88e6xxx_mdio_read;
3266+
bus->write = mv88e6xxx_mdio_write;
3267+
bus->parent = ps->dev;
3268+
3269+
if (ps->mdio_np)
3270+
err = of_mdiobus_register(bus, ps->mdio_np);
3271+
else
3272+
err = mdiobus_register(bus);
3273+
if (err) {
3274+
dev_err(ps->dev, "Cannot register MDIO bus (%d)\n", err);
3275+
goto out;
3276+
}
3277+
ps->mdio_bus = bus;
3278+
3279+
return 0;
3280+
3281+
out:
3282+
if (ps->mdio_np)
3283+
of_node_put(ps->mdio_np);
3284+
3285+
return err;
3286+
}
3287+
3288+
static void mv88e6xxx_mdio_unregister(struct mv88e6xxx_priv_state *ps)
3289+
3290+
{
3291+
struct mii_bus *bus = ps->mdio_bus;
3292+
3293+
mdiobus_unregister(bus);
3294+
3295+
if (ps->mdio_np)
3296+
of_node_put(ps->mdio_np);
3297+
}
3298+
32403299
#ifdef CONFIG_NET_DSA_HWMON
32413300

32423301
static int mv88e61xx_get_temp(struct dsa_switch *ds, int *temp)
@@ -3549,6 +3608,7 @@ static const char *mv88e6xxx_drv_probe(struct device *dsa_dev,
35493608
struct mii_bus *bus;
35503609
const char *name;
35513610
int id, prod_num, rev;
3611+
int err;
35523612

35533613
bus = dsa_host_dev_to_mii_bus(host_dev);
35543614
if (!bus)
@@ -3575,8 +3635,13 @@ static const char *mv88e6xxx_drv_probe(struct device *dsa_dev,
35753635
ps->bus = bus;
35763636
ps->sw_addr = sw_addr;
35773637
ps->info = info;
3638+
ps->dev = dsa_dev;
35783639
mutex_init(&ps->smi_mutex);
35793640

3641+
err = mv88e6xxx_mdio_register(ps, NULL);
3642+
if (err)
3643+
return NULL;
3644+
35803645
*priv = ps;
35813646

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

3743+
err = mv88e6xxx_mdio_register(ps, mdiodev->dev.of_node);
3744+
if (err)
3745+
return err;
3746+
3747+
ds->slave_mii_bus = ps->mdio_bus;
3748+
36803749
dev_set_drvdata(dev, ds);
36813750

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

36933762
put_device(&ps->bus->dev);
3763+
3764+
mv88e6xxx_mdio_unregister(ps);
36943765
}
36953766

36963767
static const struct of_device_id mv88e6xxx_of_match[] = {

drivers/net/dsa/mv88e6xxx.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -600,6 +600,12 @@ struct mv88e6xxx_priv_state {
600600

601601
/* set to size of eeprom if supported by the switch */
602602
int eeprom_len;
603+
604+
/* Device node for the MDIO bus */
605+
struct device_node *mdio_np;
606+
607+
/* And the MDIO bus itself */
608+
struct mii_bus *mdio_bus;
603609
};
604610

605611
enum stat_type {

0 commit comments

Comments
 (0)