Commit 7f854420 authored by Andrew Lunn's avatar Andrew Lunn Committed by David S. Miller

phy: Add API for {un}registering an mdio device to a bus.

Rather than have drivers directly manipulate the mii_bus structure,
provide and API for registering and unregistering devices on an MDIO
bus, and performing lookups.
Signed-off-by: default avatarAndrew Lunn <andrew@lunn.ch>
Reviewed-by: default avatarFlorian Fainelli <f.fainelli@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 801a8ef5
...@@ -502,7 +502,7 @@ static int au1000_mii_probe(struct net_device *dev) ...@@ -502,7 +502,7 @@ static int au1000_mii_probe(struct net_device *dev)
BUG_ON(aup->mac_id < 0 || aup->mac_id > 1); BUG_ON(aup->mac_id < 0 || aup->mac_id > 1);
if (aup->phy_addr) if (aup->phy_addr)
phydev = aup->mii_bus->phy_map[aup->phy_addr]; phydev = mdiobus_get_phy(aup->mii_bus, aup->phy_addr);
else else
netdev_info(dev, "using PHY-less setup\n"); netdev_info(dev, "using PHY-less setup\n");
return 0; return 0;
...@@ -512,8 +512,8 @@ static int au1000_mii_probe(struct net_device *dev) ...@@ -512,8 +512,8 @@ static int au1000_mii_probe(struct net_device *dev)
* on the current MAC's MII bus * on the current MAC's MII bus
*/ */
for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++)
if (aup->mii_bus->phy_map[phy_addr]) { if (mdiobus_get_phy(aup->mii_bus, aup->phy_addr)) {
phydev = aup->mii_bus->phy_map[phy_addr]; phydev = mdiobus_get_phy(aup->mii_bus, aup->phy_addr);
if (!aup->phy_search_highest_addr) if (!aup->phy_search_highest_addr)
/* break out with first one found */ /* break out with first one found */
break; break;
...@@ -531,7 +531,8 @@ static int au1000_mii_probe(struct net_device *dev) ...@@ -531,7 +531,8 @@ static int au1000_mii_probe(struct net_device *dev)
*/ */
for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) { for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) {
struct phy_device *const tmp_phydev = struct phy_device *const tmp_phydev =
aup->mii_bus->phy_map[phy_addr]; mdiobus_get_phy(aup->mii_bus,
phy_addr);
if (aup->mac_id == 1) if (aup->mac_id == 1)
break; break;
......
...@@ -2272,7 +2272,7 @@ static int b44_register_phy_one(struct b44 *bp) ...@@ -2272,7 +2272,7 @@ static int b44_register_phy_one(struct b44 *bp)
goto err_out_mdiobus; goto err_out_mdiobus;
} }
if (!bp->mii_bus->phy_map[bp->phy_addr] && if (!mdiobus_is_registered_device(bp->mii_bus, bp->phy_addr) &&
(sprom->boardflags_lo & (B44_BOARDFLAG_ROBO | B44_BOARDFLAG_ADM))) { (sprom->boardflags_lo & (B44_BOARDFLAG_ROBO | B44_BOARDFLAG_ADM))) {
dev_info(sdev->dev, dev_info(sdev->dev,
......
...@@ -573,7 +573,7 @@ static int bcmgenet_mii_pd_init(struct bcmgenet_priv *priv) ...@@ -573,7 +573,7 @@ static int bcmgenet_mii_pd_init(struct bcmgenet_priv *priv)
} }
if (pd->phy_address >= 0 && pd->phy_address < PHY_MAX_ADDR) if (pd->phy_address >= 0 && pd->phy_address < PHY_MAX_ADDR)
phydev = mdio->phy_map[pd->phy_address]; phydev = mdiobus_get_phy(mdio, pd->phy_address);
else else
phydev = phy_find_first(mdio); phydev = phy_find_first(mdio);
......
...@@ -1406,7 +1406,7 @@ static void tg3_mdio_config_5785(struct tg3 *tp) ...@@ -1406,7 +1406,7 @@ static void tg3_mdio_config_5785(struct tg3 *tp)
u32 val; u32 val;
struct phy_device *phydev; struct phy_device *phydev;
phydev = tp->mdio_bus->phy_map[tp->phy_addr]; phydev = mdiobus_get_phy(tp->mdio_bus, tp->phy_addr);
switch (phydev->drv->phy_id & phydev->drv->phy_id_mask) { switch (phydev->drv->phy_id & phydev->drv->phy_id_mask) {
case PHY_ID_BCM50610: case PHY_ID_BCM50610:
case PHY_ID_BCM50610M: case PHY_ID_BCM50610M:
...@@ -1554,7 +1554,7 @@ static int tg3_mdio_init(struct tg3 *tp) ...@@ -1554,7 +1554,7 @@ static int tg3_mdio_init(struct tg3 *tp)
return i; return i;
} }
phydev = tp->mdio_bus->phy_map[tp->phy_addr]; phydev = mdiobus_get_phy(tp->mdio_bus, tp->phy_addr);
if (!phydev || !phydev->drv) { if (!phydev || !phydev->drv) {
dev_warn(&tp->pdev->dev, "No PHY devices\n"); dev_warn(&tp->pdev->dev, "No PHY devices\n");
...@@ -1964,7 +1964,7 @@ static void tg3_setup_flow_control(struct tg3 *tp, u32 lcladv, u32 rmtadv) ...@@ -1964,7 +1964,7 @@ static void tg3_setup_flow_control(struct tg3 *tp, u32 lcladv, u32 rmtadv)
u32 old_tx_mode = tp->tx_mode; u32 old_tx_mode = tp->tx_mode;
if (tg3_flag(tp, USE_PHYLIB)) if (tg3_flag(tp, USE_PHYLIB))
autoneg = tp->mdio_bus->phy_map[tp->phy_addr]->autoneg; autoneg = mdiobus_get_phy(tp->mdio_bus, tp->phy_addr)->autoneg;
else else
autoneg = tp->link_config.autoneg; autoneg = tp->link_config.autoneg;
...@@ -2000,7 +2000,7 @@ static void tg3_adjust_link(struct net_device *dev) ...@@ -2000,7 +2000,7 @@ static void tg3_adjust_link(struct net_device *dev)
u8 oldflowctrl, linkmesg = 0; u8 oldflowctrl, linkmesg = 0;
u32 mac_mode, lcl_adv, rmt_adv; u32 mac_mode, lcl_adv, rmt_adv;
struct tg3 *tp = netdev_priv(dev); struct tg3 *tp = netdev_priv(dev);
struct phy_device *phydev = tp->mdio_bus->phy_map[tp->phy_addr]; struct phy_device *phydev = mdiobus_get_phy(tp->mdio_bus, tp->phy_addr);
spin_lock_bh(&tp->lock); spin_lock_bh(&tp->lock);
...@@ -2089,7 +2089,7 @@ static int tg3_phy_init(struct tg3 *tp) ...@@ -2089,7 +2089,7 @@ static int tg3_phy_init(struct tg3 *tp)
/* Bring the PHY back to a known state. */ /* Bring the PHY back to a known state. */
tg3_bmcr_reset(tp); tg3_bmcr_reset(tp);
phydev = tp->mdio_bus->phy_map[tp->phy_addr]; phydev = mdiobus_get_phy(tp->mdio_bus, tp->phy_addr);
/* Attach the MAC to the PHY. */ /* Attach the MAC to the PHY. */
phydev = phy_connect(tp->dev, phydev_name(phydev), phydev = phy_connect(tp->dev, phydev_name(phydev),
...@@ -2116,7 +2116,7 @@ static int tg3_phy_init(struct tg3 *tp) ...@@ -2116,7 +2116,7 @@ static int tg3_phy_init(struct tg3 *tp)
SUPPORTED_Asym_Pause); SUPPORTED_Asym_Pause);
break; break;
default: default:
phy_disconnect(tp->mdio_bus->phy_map[tp->phy_addr]); phy_disconnect(mdiobus_get_phy(tp->mdio_bus, tp->phy_addr));
return -EINVAL; return -EINVAL;
} }
...@@ -2136,7 +2136,7 @@ static void tg3_phy_start(struct tg3 *tp) ...@@ -2136,7 +2136,7 @@ static void tg3_phy_start(struct tg3 *tp)
if (!(tp->phy_flags & TG3_PHYFLG_IS_CONNECTED)) if (!(tp->phy_flags & TG3_PHYFLG_IS_CONNECTED))
return; return;
phydev = tp->mdio_bus->phy_map[tp->phy_addr]; phydev = mdiobus_get_phy(tp->mdio_bus, tp->phy_addr);
if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) { if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) {
tp->phy_flags &= ~TG3_PHYFLG_IS_LOW_POWER; tp->phy_flags &= ~TG3_PHYFLG_IS_LOW_POWER;
...@@ -2156,13 +2156,13 @@ static void tg3_phy_stop(struct tg3 *tp) ...@@ -2156,13 +2156,13 @@ static void tg3_phy_stop(struct tg3 *tp)
if (!(tp->phy_flags & TG3_PHYFLG_IS_CONNECTED)) if (!(tp->phy_flags & TG3_PHYFLG_IS_CONNECTED))
return; return;
phy_stop(tp->mdio_bus->phy_map[tp->phy_addr]); phy_stop(mdiobus_get_phy(tp->mdio_bus, tp->phy_addr));
} }
static void tg3_phy_fini(struct tg3 *tp) static void tg3_phy_fini(struct tg3 *tp)
{ {
if (tp->phy_flags & TG3_PHYFLG_IS_CONNECTED) { if (tp->phy_flags & TG3_PHYFLG_IS_CONNECTED) {
phy_disconnect(tp->mdio_bus->phy_map[tp->phy_addr]); phy_disconnect(mdiobus_get_phy(tp->mdio_bus, tp->phy_addr));
tp->phy_flags &= ~TG3_PHYFLG_IS_CONNECTED; tp->phy_flags &= ~TG3_PHYFLG_IS_CONNECTED;
} }
} }
...@@ -4046,7 +4046,7 @@ static int tg3_power_down_prepare(struct tg3 *tp) ...@@ -4046,7 +4046,7 @@ static int tg3_power_down_prepare(struct tg3 *tp)
struct phy_device *phydev; struct phy_device *phydev;
u32 phyid, advertising; u32 phyid, advertising;
phydev = tp->mdio_bus->phy_map[tp->phy_addr]; phydev = mdiobus_get_phy(tp->mdio_bus, tp->phy_addr);
tp->phy_flags |= TG3_PHYFLG_IS_LOW_POWER; tp->phy_flags |= TG3_PHYFLG_IS_LOW_POWER;
...@@ -12074,7 +12074,7 @@ static int tg3_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) ...@@ -12074,7 +12074,7 @@ static int tg3_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
struct phy_device *phydev; struct phy_device *phydev;
if (!(tp->phy_flags & TG3_PHYFLG_IS_CONNECTED)) if (!(tp->phy_flags & TG3_PHYFLG_IS_CONNECTED))
return -EAGAIN; return -EAGAIN;
phydev = tp->mdio_bus->phy_map[tp->phy_addr]; phydev = mdiobus_get_phy(tp->mdio_bus, tp->phy_addr);
return phy_ethtool_gset(phydev, cmd); return phy_ethtool_gset(phydev, cmd);
} }
...@@ -12141,7 +12141,7 @@ static int tg3_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) ...@@ -12141,7 +12141,7 @@ static int tg3_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
struct phy_device *phydev; struct phy_device *phydev;
if (!(tp->phy_flags & TG3_PHYFLG_IS_CONNECTED)) if (!(tp->phy_flags & TG3_PHYFLG_IS_CONNECTED))
return -EAGAIN; return -EAGAIN;
phydev = tp->mdio_bus->phy_map[tp->phy_addr]; phydev = mdiobus_get_phy(tp->mdio_bus, tp->phy_addr);
return phy_ethtool_sset(phydev, cmd); return phy_ethtool_sset(phydev, cmd);
} }
...@@ -12296,7 +12296,7 @@ static int tg3_nway_reset(struct net_device *dev) ...@@ -12296,7 +12296,7 @@ static int tg3_nway_reset(struct net_device *dev)
if (tg3_flag(tp, USE_PHYLIB)) { if (tg3_flag(tp, USE_PHYLIB)) {
if (!(tp->phy_flags & TG3_PHYFLG_IS_CONNECTED)) if (!(tp->phy_flags & TG3_PHYFLG_IS_CONNECTED))
return -EAGAIN; return -EAGAIN;
r = phy_start_aneg(tp->mdio_bus->phy_map[tp->phy_addr]); r = phy_start_aneg(mdiobus_get_phy(tp->mdio_bus, tp->phy_addr));
} else { } else {
u32 bmcr; u32 bmcr;
...@@ -12414,7 +12414,7 @@ static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam ...@@ -12414,7 +12414,7 @@ static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam
u32 newadv; u32 newadv;
struct phy_device *phydev; struct phy_device *phydev;
phydev = tp->mdio_bus->phy_map[tp->phy_addr]; phydev = mdiobus_get_phy(tp->mdio_bus, tp->phy_addr);
if (!(phydev->supported & SUPPORTED_Pause) || if (!(phydev->supported & SUPPORTED_Pause) ||
(!(phydev->supported & SUPPORTED_Asym_Pause) && (!(phydev->supported & SUPPORTED_Asym_Pause) &&
...@@ -13924,7 +13924,7 @@ static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) ...@@ -13924,7 +13924,7 @@ static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
struct phy_device *phydev; struct phy_device *phydev;
if (!(tp->phy_flags & TG3_PHYFLG_IS_CONNECTED)) if (!(tp->phy_flags & TG3_PHYFLG_IS_CONNECTED))
return -EAGAIN; return -EAGAIN;
phydev = tp->mdio_bus->phy_map[tp->phy_addr]; phydev = mdiobus_get_phy(tp->mdio_bus, tp->phy_addr);
return phy_mii_ioctl(phydev, ifr, cmd); return phy_mii_ioctl(phydev, ifr, cmd);
} }
......
...@@ -678,7 +678,7 @@ static int ethoc_mdio_probe(struct net_device *dev) ...@@ -678,7 +678,7 @@ static int ethoc_mdio_probe(struct net_device *dev)
int err; int err;
if (priv->phy_id != -1) if (priv->phy_id != -1)
phy = priv->mdio->phy_map[priv->phy_id]; phy = mdiobus_get_phy(priv->mdio, priv->phy_id);
else else
phy = phy_find_first(priv->mdio); phy = phy_find_first(priv->mdio);
...@@ -766,7 +766,7 @@ static int ethoc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) ...@@ -766,7 +766,7 @@ static int ethoc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
if (mdio->phy_id >= PHY_MAX_ADDR) if (mdio->phy_id >= PHY_MAX_ADDR)
return -ERANGE; return -ERANGE;
phy = priv->mdio->phy_map[mdio->phy_id]; phy = mdiobus_get_phy(priv->mdio, mdio->phy_id);
if (!phy) if (!phy)
return -ENODEV; return -ENODEV;
} else { } else {
......
...@@ -839,7 +839,7 @@ static int ftgmac100_mii_probe(struct ftgmac100 *priv) ...@@ -839,7 +839,7 @@ static int ftgmac100_mii_probe(struct ftgmac100 *priv)
/* search for connect PHY device */ /* search for connect PHY device */
for (i = 0; i < PHY_MAX_ADDR; i++) { for (i = 0; i < PHY_MAX_ADDR; i++) {
struct phy_device *tmp = priv->mii_bus->phy_map[i]; struct phy_device *tmp = mdiobus_get_phy(priv->mii_bus, i);
if (tmp) { if (tmp) {
phydev = tmp; phydev = tmp;
......
...@@ -48,6 +48,7 @@ ...@@ -48,6 +48,7 @@
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/mdio.h>
#include <linux/phy.h> #include <linux/phy.h>
#include <linux/fec.h> #include <linux/fec.h>
#include <linux/of.h> #include <linux/of.h>
...@@ -1926,11 +1927,7 @@ static int fec_enet_mii_probe(struct net_device *ndev) ...@@ -1926,11 +1927,7 @@ static int fec_enet_mii_probe(struct net_device *ndev)
} else { } else {
/* check for attached phy */ /* check for attached phy */
for (phy_id = 0; (phy_id < PHY_MAX_ADDR); phy_id++) { for (phy_id = 0; (phy_id < PHY_MAX_ADDR); phy_id++) {
if ((fep->mii_bus->phy_mask & (1 << phy_id))) if (!mdiobus_is_registered_device(fep->mii_bus, phy_id))
continue;
if (fep->mii_bus->phy_map[phy_id] == NULL)
continue;
if (fep->mii_bus->phy_map[phy_id]->phy_id == 0)
continue; continue;
if (dev_id--) if (dev_id--)
continue; continue;
......
...@@ -180,7 +180,7 @@ int sxgbe_mdio_register(struct net_device *ndev) ...@@ -180,7 +180,7 @@ int sxgbe_mdio_register(struct net_device *ndev)
} }
for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) { for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) {
struct phy_device *phy = mdio_bus->phy_map[phy_addr]; struct phy_device *phy = mdiobus_get_phy(mdio_bus, phy_addr);
if (phy) { if (phy) {
char irq_num[4]; char irq_num[4];
......
...@@ -1158,7 +1158,8 @@ static int smsc9420_mii_probe(struct net_device *dev) ...@@ -1158,7 +1158,8 @@ static int smsc9420_mii_probe(struct net_device *dev)
BUG_ON(pd->phy_dev); BUG_ON(pd->phy_dev);
/* Device only supports internal PHY at address 1 */ /* Device only supports internal PHY at address 1 */
if (!pd->mii_bus->phy_map[1]) { phydev = mdiobus_get_phy(pd->mii_bus, 1);
if (!phydev) {
netdev_err(dev, "no PHY found at address 1\n"); netdev_err(dev, "no PHY found at address 1\n");
return -ENODEV; return -ENODEV;
} }
......
...@@ -252,7 +252,7 @@ int stmmac_mdio_register(struct net_device *ndev) ...@@ -252,7 +252,7 @@ int stmmac_mdio_register(struct net_device *ndev)
found = 0; found = 0;
for (addr = 0; addr < PHY_MAX_ADDR; addr++) { for (addr = 0; addr < PHY_MAX_ADDR; addr++) {
struct phy_device *phydev = new_bus->phy_map[addr]; struct phy_device *phydev = mdiobus_get_phy(new_bus, addr);
if (phydev) { if (phydev) {
int act = 0; int act = 0;
char irq_num[4]; char irq_num[4];
......
...@@ -393,7 +393,7 @@ static int davinci_mdio_probe(struct platform_device *pdev) ...@@ -393,7 +393,7 @@ static int davinci_mdio_probe(struct platform_device *pdev)
/* scan and dump the bus */ /* scan and dump the bus */
for (addr = 0; addr < PHY_MAX_ADDR; addr++) { for (addr = 0; addr < PHY_MAX_ADDR; addr++) {
phy = data->bus->phy_map[addr]; phy = mdiobus_get_phy(data->bus, addr);
if (phy) { if (phy) {
dev_info(dev, "phy[%d]: device %s, driver %s\n", dev_info(dev, "phy[%d]: device %s, driver %s\n",
phy->mdio.addr, phydev_name(phy), phy->mdio.addr, phydev_name(phy),
......
...@@ -38,6 +38,48 @@ ...@@ -38,6 +38,48 @@
#include <asm/irq.h> #include <asm/irq.h>
int mdiobus_register_device(struct mdio_device *mdiodev)
{
if (mdiodev->bus->mdio_map[mdiodev->addr])
return -EBUSY;
mdiodev->bus->mdio_map[mdiodev->addr] = mdiodev;
return 0;
}
EXPORT_SYMBOL(mdiobus_register_device);
int mdiobus_unregister_device(struct mdio_device *mdiodev)
{
if (mdiodev->bus->mdio_map[mdiodev->addr] != mdiodev)
return -EINVAL;
mdiodev->bus->mdio_map[mdiodev->addr] = NULL;
return 0;
}
EXPORT_SYMBOL(mdiobus_unregister_device);
struct phy_device *mdiobus_get_phy(struct mii_bus *bus, int addr)
{
struct mdio_device *mdiodev = bus->mdio_map[addr];
if (!mdiodev)
return NULL;
if (!(mdiodev->flags & MDIO_DEVICE_FLAG_PHY))
return NULL;
return container_of(mdiodev, struct phy_device, mdio);
}
EXPORT_SYMBOL(mdiobus_get_phy);
bool mdiobus_is_registered_device(struct mii_bus *bus, int addr)
{
return bus->mdio_map[addr];
}
EXPORT_SYMBOL(mdiobus_is_registered_device);
/** /**
* mdiobus_alloc_size - allocate a mii_bus structure * mdiobus_alloc_size - allocate a mii_bus structure
* @size: extra amount of memory to allocate for private storage. * @size: extra amount of memory to allocate for private storage.
...@@ -299,7 +341,7 @@ int __mdiobus_register(struct mii_bus *bus, struct module *owner) ...@@ -299,7 +341,7 @@ int __mdiobus_register(struct mii_bus *bus, struct module *owner)
error: error:
while (--i >= 0) { while (--i >= 0) {
struct phy_device *phydev = bus->phy_map[i]; struct phy_device *phydev = mdiobus_get_phy(bus, i);
if (phydev) { if (phydev) {
phy_device_remove(phydev); phy_device_remove(phydev);
phy_device_free(phydev); phy_device_free(phydev);
...@@ -318,7 +360,7 @@ void mdiobus_unregister(struct mii_bus *bus) ...@@ -318,7 +360,7 @@ void mdiobus_unregister(struct mii_bus *bus)
bus->state = MDIOBUS_UNREGISTERED; bus->state = MDIOBUS_UNREGISTERED;
for (i = 0; i < PHY_MAX_ADDR; i++) { for (i = 0; i < PHY_MAX_ADDR; i++) {
struct phy_device *phydev = bus->phy_map[i]; struct phy_device *phydev = mdiobus_get_phy(bus, i);
if (phydev) { if (phydev) {
phy_device_remove(phydev); phy_device_remove(phydev);
phy_device_free(phydev); phy_device_free(phydev);
......
...@@ -166,6 +166,7 @@ struct phy_device *phy_device_create(struct mii_bus *bus, int addr, int phy_id, ...@@ -166,6 +166,7 @@ struct phy_device *phy_device_create(struct mii_bus *bus, int addr, int phy_id,
mdiodev->dev.bus = &mdio_bus_type; mdiodev->dev.bus = &mdio_bus_type;
mdiodev->bus = bus; mdiodev->bus = bus;
mdiodev->addr = addr; mdiodev->addr = addr;
mdiodev->flags = MDIO_DEVICE_FLAG_PHY;
dev->speed = 0; dev->speed = 0;
dev->duplex = -1; dev->duplex = -1;
...@@ -383,10 +384,9 @@ int phy_device_register(struct phy_device *phydev) ...@@ -383,10 +384,9 @@ int phy_device_register(struct phy_device *phydev)
{ {
int err; int err;
/* Don't register a phy if one is already registered at this address */ err = mdiobus_register_device(&phydev->mdio);
if (phydev->mdio.bus->phy_map[phydev->mdio.addr]) if (err)
return -EINVAL; return err;
phydev->mdio.bus->phy_map[phydev->mdio.addr] = phydev;
/* Run all of the fixups for this PHY */ /* Run all of the fixups for this PHY */
err = phy_scan_fixups(phydev); err = phy_scan_fixups(phydev);
...@@ -404,7 +404,7 @@ int phy_device_register(struct phy_device *phydev) ...@@ -404,7 +404,7 @@ int phy_device_register(struct phy_device *phydev)
return 0; return 0;
out: out:
phydev->mdio.bus->phy_map[phydev->mdio.addr] = NULL; mdiobus_unregister_device(&phydev->mdio);
return err; return err;
} }
EXPORT_SYMBOL(phy_device_register); EXPORT_SYMBOL(phy_device_register);
...@@ -419,11 +419,8 @@ EXPORT_SYMBOL(phy_device_register); ...@@ -419,11 +419,8 @@ EXPORT_SYMBOL(phy_device_register);
*/ */
void phy_device_remove(struct phy_device *phydev) void phy_device_remove(struct phy_device *phydev)
{ {
struct mii_bus *bus = phydev->mdio.bus;
int addr = phydev->mdio.addr;
device_del(&phydev->mdio.dev); device_del(&phydev->mdio.dev);
bus->phy_map[addr] = NULL; mdiobus_unregister_device(&phydev->mdio);
} }
EXPORT_SYMBOL(phy_device_remove); EXPORT_SYMBOL(phy_device_remove);
...@@ -433,11 +430,13 @@ EXPORT_SYMBOL(phy_device_remove); ...@@ -433,11 +430,13 @@ EXPORT_SYMBOL(phy_device_remove);
*/ */
struct phy_device *phy_find_first(struct mii_bus *bus) struct phy_device *phy_find_first(struct mii_bus *bus)
{ {
struct phy_device *phydev;
int addr; int addr;
for (addr = 0; addr < PHY_MAX_ADDR; addr++) { for (addr = 0; addr < PHY_MAX_ADDR; addr++) {
if (bus->phy_map[addr]) phydev = mdiobus_get_phy(bus, addr);
return bus->phy_map[addr]; if (phydev)
return phydev;
} }
return NULL; return NULL;
} }
......
...@@ -193,7 +193,7 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np) ...@@ -193,7 +193,7 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np)
for (addr = 0; addr < PHY_MAX_ADDR; addr++) { for (addr = 0; addr < PHY_MAX_ADDR; addr++) {
/* skip already registered PHYs */ /* skip already registered PHYs */
if (mdio->phy_map[addr]) if (mdiobus_is_registered_device(mdio, addr))
continue; continue;
/* be noisy to encourage people to set reg property */ /* be noisy to encourage people to set reg property */
......
...@@ -19,9 +19,12 @@ struct mdio_device { ...@@ -19,9 +19,12 @@ struct mdio_device {
struct mii_bus *bus; struct mii_bus *bus;
/* Bus address of the MDIO device (0-31) */ /* Bus address of the MDIO device (0-31) */
int addr; int addr;
int flags;
}; };
#define to_mdio_device(d) container_of(d, struct mdio_device, dev) #define to_mdio_device(d) container_of(d, struct mdio_device, dev)
#define MDIO_DEVICE_FLAG_PHY 1
static inline bool mdio_phy_id_is_c45(int phy_id) static inline bool mdio_phy_id_is_c45(int phy_id)
{ {
return (phy_id & MDIO_PHY_ID_C45) && !(phy_id & ~MDIO_PHY_ID_C45_MASK); return (phy_id & MDIO_PHY_ID_C45) && !(phy_id & ~MDIO_PHY_ID_C45_MASK);
...@@ -188,4 +191,9 @@ int mdiobus_read_nested(struct mii_bus *bus, int addr, u32 regnum); ...@@ -188,4 +191,9 @@ int mdiobus_read_nested(struct mii_bus *bus, int addr, u32 regnum);
int mdiobus_write(struct mii_bus *bus, int addr, u32 regnum, u16 val); int mdiobus_write(struct mii_bus *bus, int addr, u32 regnum, u16 val);
int mdiobus_write_nested(struct mii_bus *bus, int addr, u32 regnum, u16 val); int mdiobus_write_nested(struct mii_bus *bus, int addr, u32 regnum, u16 val);
int mdiobus_register_device(struct mdio_device *mdiodev);
int mdiobus_unregister_device(struct mdio_device *mdiodev);
bool mdiobus_is_registered_device(struct mii_bus *bus, int addr);
struct phy_device *mdiobus_get_phy(struct mii_bus *bus, int addr);
#endif /* __LINUX_MDIO_H__ */ #endif /* __LINUX_MDIO_H__ */
...@@ -180,7 +180,7 @@ struct mii_bus { ...@@ -180,7 +180,7 @@ struct mii_bus {
struct device dev; struct device dev;
/* list of all PHYs on bus */ /* list of all PHYs on bus */
struct phy_device *phy_map[PHY_MAX_ADDR]; struct mdio_device *mdio_map[PHY_MAX_ADDR];
/* PHY addresses to be ignored when probing */ /* PHY addresses to be ignored when probing */
u32 phy_mask; u32 phy_mask;
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include <linux/phy_fixed.h> #include <linux/phy_fixed.h>
#include <linux/of_net.h> #include <linux/of_net.h>
#include <linux/of_mdio.h> #include <linux/of_mdio.h>
#include <linux/mdio.h>
#include <net/rtnetlink.h> #include <net/rtnetlink.h>
#include <net/switchdev.h> #include <net/switchdev.h>
#include <linux/if_bridge.h> #include <linux/if_bridge.h>
...@@ -997,7 +998,7 @@ static int dsa_slave_phy_connect(struct dsa_slave_priv *p, ...@@ -997,7 +998,7 @@ static int dsa_slave_phy_connect(struct dsa_slave_priv *p,
{ {
struct dsa_switch *ds = p->parent; struct dsa_switch *ds = p->parent;
p->phy = ds->slave_mii_bus->phy_map[addr]; p->phy = mdiobus_get_phy(ds->slave_mii_bus, addr);
if (!p->phy) { if (!p->phy) {
netdev_err(slave_dev, "no phy at %d\n", addr); netdev_err(slave_dev, "no phy at %d\n", addr);
return -ENODEV; return -ENODEV;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment