Commit 298cf9be authored by Lennert Buytenhek's avatar Lennert Buytenhek Committed by David S. Miller

phylib: move to dynamic allocation of struct mii_bus

This patch introduces mdiobus_alloc() and mdiobus_free(), and
makes all mdio bus drivers use these functions to allocate their
struct mii_bus'es dynamically.
Signed-off-by: default avatarLennert Buytenhek <buytenh@marvell.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
Acked-by: default avatarAndy Fleming <afleming@freescale.com>
parent 18ee49dd
...@@ -290,7 +290,7 @@ static int mii_probe (struct net_device *dev) ...@@ -290,7 +290,7 @@ static int mii_probe (struct net_device *dev)
if(aup->mac_id == 0) { /* get PHY0 */ if(aup->mac_id == 0) { /* get PHY0 */
# if defined(AU1XXX_PHY0_ADDR) # if defined(AU1XXX_PHY0_ADDR)
phydev = au_macs[AU1XXX_PHY0_BUSID]->mii_bus.phy_map[AU1XXX_PHY0_ADDR]; phydev = au_macs[AU1XXX_PHY0_BUSID]->mii_bus->phy_map[AU1XXX_PHY0_ADDR];
# else # else
printk (KERN_INFO DRV_NAME ":%s: using PHY-less setup\n", printk (KERN_INFO DRV_NAME ":%s: using PHY-less setup\n",
dev->name); dev->name);
...@@ -298,7 +298,7 @@ static int mii_probe (struct net_device *dev) ...@@ -298,7 +298,7 @@ static int mii_probe (struct net_device *dev)
# endif /* defined(AU1XXX_PHY0_ADDR) */ # endif /* defined(AU1XXX_PHY0_ADDR) */
} else if (aup->mac_id == 1) { /* get PHY1 */ } else if (aup->mac_id == 1) { /* get PHY1 */
# if defined(AU1XXX_PHY1_ADDR) # if defined(AU1XXX_PHY1_ADDR)
phydev = au_macs[AU1XXX_PHY1_BUSID]->mii_bus.phy_map[AU1XXX_PHY1_ADDR]; phydev = au_macs[AU1XXX_PHY1_BUSID]->mii_bus->phy_map[AU1XXX_PHY1_ADDR];
# else # else
printk (KERN_INFO DRV_NAME ":%s: using PHY-less setup\n", printk (KERN_INFO DRV_NAME ":%s: using PHY-less setup\n",
dev->name); dev->name);
...@@ -311,8 +311,8 @@ static int mii_probe (struct net_device *dev) ...@@ -311,8 +311,8 @@ static int mii_probe (struct net_device *dev)
/* find the first (lowest address) PHY on the current MAC's MII bus */ /* find the first (lowest address) PHY 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 (aup->mii_bus->phy_map[phy_addr]) {
phydev = aup->mii_bus.phy_map[phy_addr]; phydev = aup->mii_bus->phy_map[phy_addr];
# if !defined(AU1XXX_PHY_SEARCH_HIGHEST_ADDR) # if !defined(AU1XXX_PHY_SEARCH_HIGHEST_ADDR)
break; /* break out with first one found */ break; /* break out with first one found */
# endif # endif
...@@ -331,7 +331,7 @@ static int mii_probe (struct net_device *dev) ...@@ -331,7 +331,7 @@ static int mii_probe (struct net_device *dev)
* the MAC0 MII bus */ * the MAC0 MII bus */
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 =
au_macs[0]->mii_bus.phy_map[phy_addr]; au_macs[0]->mii_bus->phy_map[phy_addr];
if (!tmp_phydev) if (!tmp_phydev)
continue; /* no PHY here... */ continue; /* no PHY here... */
...@@ -698,28 +698,32 @@ static struct net_device * au1000_probe(int port_num) ...@@ -698,28 +698,32 @@ static struct net_device * au1000_probe(int port_num)
*aup->enable = 0; *aup->enable = 0;
aup->mac_enabled = 0; aup->mac_enabled = 0;
aup->mii_bus.priv = dev; aup->mii_bus = mdiobus_alloc();
aup->mii_bus.read = mdiobus_read; if (aup->mii_bus == NULL)
aup->mii_bus.write = mdiobus_write; goto err_out;
aup->mii_bus.reset = mdiobus_reset;
aup->mii_bus.name = "au1000_eth_mii"; aup->mii_bus->priv = dev;
snprintf(aup->mii_bus.id, MII_BUS_ID_SIZE, "%x", aup->mac_id); aup->mii_bus->read = mdiobus_read;
aup->mii_bus.irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL); aup->mii_bus->write = mdiobus_write;
aup->mii_bus->reset = mdiobus_reset;
aup->mii_bus->name = "au1000_eth_mii";
snprintf(aup->mii_bus->id, MII_BUS_ID_SIZE, "%x", aup->mac_id);
aup->mii_bus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL);
for(i = 0; i < PHY_MAX_ADDR; ++i) for(i = 0; i < PHY_MAX_ADDR; ++i)
aup->mii_bus.irq[i] = PHY_POLL; aup->mii_bus->irq[i] = PHY_POLL;
/* if known, set corresponding PHY IRQs */ /* if known, set corresponding PHY IRQs */
#if defined(AU1XXX_PHY_STATIC_CONFIG) #if defined(AU1XXX_PHY_STATIC_CONFIG)
# if defined(AU1XXX_PHY0_IRQ) # if defined(AU1XXX_PHY0_IRQ)
if (AU1XXX_PHY0_BUSID == aup->mac_id) if (AU1XXX_PHY0_BUSID == aup->mac_id)
aup->mii_bus.irq[AU1XXX_PHY0_ADDR] = AU1XXX_PHY0_IRQ; aup->mii_bus->irq[AU1XXX_PHY0_ADDR] = AU1XXX_PHY0_IRQ;
# endif # endif
# if defined(AU1XXX_PHY1_IRQ) # if defined(AU1XXX_PHY1_IRQ)
if (AU1XXX_PHY1_BUSID == aup->mac_id) if (AU1XXX_PHY1_BUSID == aup->mac_id)
aup->mii_bus.irq[AU1XXX_PHY1_ADDR] = AU1XXX_PHY1_IRQ; aup->mii_bus->irq[AU1XXX_PHY1_ADDR] = AU1XXX_PHY1_IRQ;
# endif # endif
#endif #endif
mdiobus_register(&aup->mii_bus); mdiobus_register(aup->mii_bus);
if (mii_probe(dev) != 0) { if (mii_probe(dev) != 0) {
goto err_out; goto err_out;
...@@ -775,6 +779,11 @@ static struct net_device * au1000_probe(int port_num) ...@@ -775,6 +779,11 @@ static struct net_device * au1000_probe(int port_num)
return dev; return dev;
err_out: err_out:
if (aup->mii_bus != NULL) {
mdiobus_unregister(aup->mii_bus);
mdiobus_free(aup->mii_bus);
}
/* here we should have a valid dev plus aup-> register addresses /* here we should have a valid dev plus aup-> register addresses
* so we can reset the mac properly.*/ * so we can reset the mac properly.*/
reset_mac(dev); reset_mac(dev);
...@@ -1005,6 +1014,8 @@ static void __exit au1000_cleanup_module(void) ...@@ -1005,6 +1014,8 @@ static void __exit au1000_cleanup_module(void)
if (dev) { if (dev) {
aup = (struct au1000_private *) dev->priv; aup = (struct au1000_private *) dev->priv;
unregister_netdev(dev); unregister_netdev(dev);
mdiobus_unregister(aup->mii_bus);
mdiobus_free(aup->mii_bus);
for (j = 0; j < NUM_RX_DMA; j++) for (j = 0; j < NUM_RX_DMA; j++)
if (aup->rx_db_inuse[j]) if (aup->rx_db_inuse[j])
ReleaseDB(aup, aup->rx_db_inuse[j]); ReleaseDB(aup, aup->rx_db_inuse[j]);
......
...@@ -106,7 +106,7 @@ struct au1000_private { ...@@ -106,7 +106,7 @@ struct au1000_private {
int old_duplex; int old_duplex;
struct phy_device *phy_dev; struct phy_device *phy_dev;
struct mii_bus mii_bus; struct mii_bus *mii_bus;
/* These variables are just for quick access to certain regs addresses. */ /* These variables are just for quick access to certain regs addresses. */
volatile mac_reg_t *mac; /* mac registers */ volatile mac_reg_t *mac; /* mac registers */
......
...@@ -398,7 +398,7 @@ static int mii_probe(struct net_device *dev) ...@@ -398,7 +398,7 @@ static int mii_probe(struct net_device *dev)
/* 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 *const tmp_phydev = lp->mii_bus.phy_map[i]; struct phy_device *const tmp_phydev = lp->mii_bus->phy_map[i];
if (!tmp_phydev) if (!tmp_phydev)
continue; /* no PHY here... */ continue; /* no PHY here... */
...@@ -1058,17 +1058,21 @@ static int __devinit bfin_mac_probe(struct platform_device *pdev) ...@@ -1058,17 +1058,21 @@ static int __devinit bfin_mac_probe(struct platform_device *pdev)
setup_mac_addr(ndev->dev_addr); setup_mac_addr(ndev->dev_addr);
/* MDIO bus initial */ /* MDIO bus initial */
lp->mii_bus.priv = ndev; lp->mii_bus = mdiobus_alloc();
lp->mii_bus.read = mdiobus_read; if (lp->mii_bus == NULL)
lp->mii_bus.write = mdiobus_write; goto out_err_mdiobus_alloc;
lp->mii_bus.reset = mdiobus_reset;
lp->mii_bus.name = "bfin_mac_mdio"; lp->mii_bus->priv = ndev;
snprintf(lp->mii_bus.id, MII_BUS_ID_SIZE, "0"); lp->mii_bus->read = mdiobus_read;
lp->mii_bus.irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL); lp->mii_bus->write = mdiobus_write;
lp->mii_bus->reset = mdiobus_reset;
lp->mii_bus->name = "bfin_mac_mdio";
snprintf(lp->mii_bus->id, MII_BUS_ID_SIZE, "0");
lp->mii_bus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL);
for (i = 0; i < PHY_MAX_ADDR; ++i) for (i = 0; i < PHY_MAX_ADDR; ++i)
lp->mii_bus.irq[i] = PHY_POLL; lp->mii_bus->irq[i] = PHY_POLL;
rc = mdiobus_register(&lp->mii_bus); rc = mdiobus_register(lp->mii_bus);
if (rc) { if (rc) {
dev_err(&pdev->dev, "Cannot register MDIO bus!\n"); dev_err(&pdev->dev, "Cannot register MDIO bus!\n");
goto out_err_mdiobus_register; goto out_err_mdiobus_register;
...@@ -1121,8 +1125,10 @@ static int __devinit bfin_mac_probe(struct platform_device *pdev) ...@@ -1121,8 +1125,10 @@ static int __devinit bfin_mac_probe(struct platform_device *pdev)
free_irq(IRQ_MAC_RX, ndev); free_irq(IRQ_MAC_RX, ndev);
out_err_request_irq: out_err_request_irq:
out_err_mii_probe: out_err_mii_probe:
mdiobus_unregister(&lp->mii_bus); mdiobus_unregister(lp->mii_bus);
out_err_mdiobus_register: out_err_mdiobus_register:
mdiobus_free(lp->mii_bus);
out_err_mdiobus_alloc:
peripheral_free_list(pin_req); peripheral_free_list(pin_req);
out_err_setup_pin_mux: out_err_setup_pin_mux:
out_err_probe_mac: out_err_probe_mac:
...@@ -1139,7 +1145,8 @@ static int __devexit bfin_mac_remove(struct platform_device *pdev) ...@@ -1139,7 +1145,8 @@ static int __devexit bfin_mac_remove(struct platform_device *pdev)
platform_set_drvdata(pdev, NULL); platform_set_drvdata(pdev, NULL);
mdiobus_unregister(&lp->mii_bus); mdiobus_unregister(lp->mii_bus);
mdiobus_free(lp->mii_bus);
unregister_netdev(ndev); unregister_netdev(ndev);
......
...@@ -66,7 +66,7 @@ struct bfin_mac_local { ...@@ -66,7 +66,7 @@ struct bfin_mac_local {
int old_duplex; int old_duplex;
struct phy_device *phydev; struct phy_device *phydev;
struct mii_bus mii_bus; struct mii_bus *mii_bus;
}; };
extern void bfin_get_ether_addr(char *addr); extern void bfin_get_ether_addr(char *addr);
...@@ -302,13 +302,7 @@ static int cpmac_mdio_reset(struct mii_bus *bus) ...@@ -302,13 +302,7 @@ static int cpmac_mdio_reset(struct mii_bus *bus)
static int mii_irqs[PHY_MAX_ADDR] = { PHY_POLL, }; static int mii_irqs[PHY_MAX_ADDR] = { PHY_POLL, };
static struct mii_bus cpmac_mii = { static struct mii_bus *cpmac_mii;
.name = "cpmac-mii",
.read = cpmac_mdio_read,
.write = cpmac_mdio_write,
.reset = cpmac_mdio_reset,
.irq = mii_irqs,
};
static int cpmac_config(struct net_device *dev, struct ifmap *map) static int cpmac_config(struct net_device *dev, struct ifmap *map)
{ {
...@@ -1116,7 +1110,7 @@ static int __devinit cpmac_probe(struct platform_device *pdev) ...@@ -1116,7 +1110,7 @@ static int __devinit cpmac_probe(struct platform_device *pdev)
for (phy_id = 0; phy_id < PHY_MAX_ADDR; phy_id++) { for (phy_id = 0; phy_id < PHY_MAX_ADDR; phy_id++) {
if (!(pdata->phy_mask & (1 << phy_id))) if (!(pdata->phy_mask & (1 << phy_id)))
continue; continue;
if (!cpmac_mii.phy_map[phy_id]) if (!cpmac_mii->phy_map[phy_id])
continue; continue;
break; break;
} }
...@@ -1168,7 +1162,7 @@ static int __devinit cpmac_probe(struct platform_device *pdev) ...@@ -1168,7 +1162,7 @@ static int __devinit cpmac_probe(struct platform_device *pdev)
priv->msg_enable = netif_msg_init(debug_level, 0xff); priv->msg_enable = netif_msg_init(debug_level, 0xff);
memcpy(dev->dev_addr, pdata->dev_addr, sizeof(dev->dev_addr)); memcpy(dev->dev_addr, pdata->dev_addr, sizeof(dev->dev_addr));
priv->phy = phy_connect(dev, cpmac_mii.phy_map[phy_id]->dev.bus_id, priv->phy = phy_connect(dev, cpmac_mii->phy_map[phy_id]->dev.bus_id,
&cpmac_adjust_link, 0, PHY_INTERFACE_MODE_MII); &cpmac_adjust_link, 0, PHY_INTERFACE_MODE_MII);
if (IS_ERR(priv->phy)) { if (IS_ERR(priv->phy)) {
if (netif_msg_drv(priv)) if (netif_msg_drv(priv))
...@@ -1216,11 +1210,22 @@ int __devinit cpmac_init(void) ...@@ -1216,11 +1210,22 @@ int __devinit cpmac_init(void)
u32 mask; u32 mask;
int i, res; int i, res;
cpmac_mii.priv = ioremap(AR7_REGS_MDIO, 256); cpmac_mii = mdiobus_alloc();
if (cpmac_mii == NULL)
return -ENOMEM;
cpmac_mii->name = "cpmac-mii";
cpmac_mii->read = cpmac_mdio_read;
cpmac_mii->write = cpmac_mdio_write;
cpmac_mii->reset = cpmac_mdio_reset;
cpmac_mii->irq = mii_irqs;
cpmac_mii->priv = ioremap(AR7_REGS_MDIO, 256);
if (!cpmac_mii.priv) { if (!cpmac_mii->priv) {
printk(KERN_ERR "Can't ioremap mdio registers\n"); printk(KERN_ERR "Can't ioremap mdio registers\n");
return -ENXIO; res = -ENXIO;
goto fail_alloc;
} }
#warning FIXME: unhardcode gpio&reset bits #warning FIXME: unhardcode gpio&reset bits
...@@ -1230,10 +1235,10 @@ int __devinit cpmac_init(void) ...@@ -1230,10 +1235,10 @@ int __devinit cpmac_init(void)
ar7_device_reset(AR7_RESET_BIT_CPMAC_HI); ar7_device_reset(AR7_RESET_BIT_CPMAC_HI);
ar7_device_reset(AR7_RESET_BIT_EPHY); ar7_device_reset(AR7_RESET_BIT_EPHY);
cpmac_mii.reset(&cpmac_mii); cpmac_mii->reset(cpmac_mii);
for (i = 0; i < 300000; i++) for (i = 0; i < 300000; i++)
if ((mask = cpmac_read(cpmac_mii.priv, CPMAC_MDIO_ALIVE))) if ((mask = cpmac_read(cpmac_mii->priv, CPMAC_MDIO_ALIVE)))
break; break;
else else
cpu_relax(); cpu_relax();
...@@ -1244,10 +1249,10 @@ int __devinit cpmac_init(void) ...@@ -1244,10 +1249,10 @@ int __devinit cpmac_init(void)
mask = 0; mask = 0;
} }
cpmac_mii.phy_mask = ~(mask | 0x80000000); cpmac_mii->phy_mask = ~(mask | 0x80000000);
snprintf(cpmac_mii.id, MII_BUS_ID_SIZE, "0"); snprintf(cpmac_mii->id, MII_BUS_ID_SIZE, "0");
res = mdiobus_register(&cpmac_mii); res = mdiobus_register(cpmac_mii);
if (res) if (res)
goto fail_mii; goto fail_mii;
...@@ -1258,10 +1263,13 @@ int __devinit cpmac_init(void) ...@@ -1258,10 +1263,13 @@ int __devinit cpmac_init(void)
return 0; return 0;
fail_cpmac: fail_cpmac:
mdiobus_unregister(&cpmac_mii); mdiobus_unregister(cpmac_mii);
fail_mii: fail_mii:
iounmap(cpmac_mii.priv); iounmap(cpmac_mii->priv);
fail_alloc:
mdiobus_free(cpmac_mii);
return res; return res;
} }
...@@ -1269,8 +1277,9 @@ int __devinit cpmac_init(void) ...@@ -1269,8 +1277,9 @@ int __devinit cpmac_init(void)
void __devexit cpmac_exit(void) void __devexit cpmac_exit(void)
{ {
platform_driver_unregister(&cpmac_driver); platform_driver_unregister(&cpmac_driver);
mdiobus_unregister(&cpmac_mii); mdiobus_unregister(cpmac_mii);
iounmap(cpmac_mii.priv); mdiobus_free(cpmac_mii);
iounmap(cpmac_mii->priv);
} }
module_init(cpmac_init); module_init(cpmac_init);
......
...@@ -83,7 +83,7 @@ static int mpc52xx_fec_mdio_probe(struct of_device *of, const struct of_device_i ...@@ -83,7 +83,7 @@ static int mpc52xx_fec_mdio_probe(struct of_device *of, const struct of_device_i
int err; int err;
int i; int i;
bus = kzalloc(sizeof(*bus), GFP_KERNEL); bus = mdiobus_alloc();
if (bus == NULL) if (bus == NULL)
return -ENOMEM; return -ENOMEM;
priv = kzalloc(sizeof(*priv), GFP_KERNEL); priv = kzalloc(sizeof(*priv), GFP_KERNEL);
...@@ -150,7 +150,7 @@ static int mpc52xx_fec_mdio_probe(struct of_device *of, const struct of_device_i ...@@ -150,7 +150,7 @@ static int mpc52xx_fec_mdio_probe(struct of_device *of, const struct of_device_i
irq_dispose_mapping(bus->irq[i]); irq_dispose_mapping(bus->irq[i]);
kfree(bus->irq); kfree(bus->irq);
kfree(priv); kfree(priv);
kfree(bus); mdiobus_free(bus);
return err; return err;
} }
...@@ -171,7 +171,7 @@ static int mpc52xx_fec_mdio_remove(struct of_device *of) ...@@ -171,7 +171,7 @@ static int mpc52xx_fec_mdio_remove(struct of_device *of)
irq_dispose_mapping(bus->irq[i]); irq_dispose_mapping(bus->irq[i]);
kfree(priv); kfree(priv);
kfree(bus->irq); kfree(bus->irq);
kfree(bus); mdiobus_free(bus);
return 0; return 0;
} }
......
...@@ -218,9 +218,9 @@ static int __devinit fs_enet_mdio_probe(struct of_device *ofdev, ...@@ -218,9 +218,9 @@ static int __devinit fs_enet_mdio_probe(struct of_device *ofdev,
out_unmap_regs: out_unmap_regs:
iounmap(bitbang->dir); iounmap(bitbang->dir);
out_free_bus: out_free_bus:
kfree(new_bus);
out_free_priv:
free_mdio_bitbang(new_bus); free_mdio_bitbang(new_bus);
out_free_priv:
kfree(bitbang);
out: out:
return ret; return ret;
} }
...@@ -231,12 +231,11 @@ static int fs_enet_mdio_remove(struct of_device *ofdev) ...@@ -231,12 +231,11 @@ static int fs_enet_mdio_remove(struct of_device *ofdev)
struct bb_info *bitbang = bus->priv; struct bb_info *bitbang = bus->priv;
mdiobus_unregister(bus); mdiobus_unregister(bus);
free_mdio_bitbang(bus);
dev_set_drvdata(&ofdev->dev, NULL); dev_set_drvdata(&ofdev->dev, NULL);
kfree(bus->irq); kfree(bus->irq);
free_mdio_bitbang(bus);
iounmap(bitbang->dir); iounmap(bitbang->dir);
kfree(bitbang); kfree(bitbang);
kfree(bus);
return 0; return 0;
} }
......
...@@ -128,7 +128,7 @@ static int __devinit fs_enet_mdio_probe(struct of_device *ofdev, ...@@ -128,7 +128,7 @@ static int __devinit fs_enet_mdio_probe(struct of_device *ofdev,
struct fec_info *fec; struct fec_info *fec;
int ret = -ENOMEM, i; int ret = -ENOMEM, i;
new_bus = kzalloc(sizeof(struct mii_bus), GFP_KERNEL); new_bus = mdiobus_alloc();
if (!new_bus) if (!new_bus)
goto out; goto out;
...@@ -190,7 +190,7 @@ static int __devinit fs_enet_mdio_probe(struct of_device *ofdev, ...@@ -190,7 +190,7 @@ static int __devinit fs_enet_mdio_probe(struct of_device *ofdev,
out_fec: out_fec:
kfree(fec); kfree(fec);
out_mii: out_mii:
kfree(new_bus); mdiobus_free(new_bus);
out: out:
return ret; return ret;
} }
...@@ -205,7 +205,7 @@ static int fs_enet_mdio_remove(struct of_device *ofdev) ...@@ -205,7 +205,7 @@ static int fs_enet_mdio_remove(struct of_device *ofdev)
kfree(bus->irq); kfree(bus->irq);
iounmap(fec->fecp); iounmap(fec->fecp);
kfree(fec); kfree(fec);
kfree(bus); mdiobus_free(bus);
return 0; return 0;
} }
......
...@@ -164,8 +164,7 @@ static int gfar_mdio_probe(struct device *dev) ...@@ -164,8 +164,7 @@ static int gfar_mdio_probe(struct device *dev)
if (NULL == dev) if (NULL == dev)
return -EINVAL; return -EINVAL;
new_bus = kzalloc(sizeof(struct mii_bus), GFP_KERNEL); new_bus = mdiobus_alloc();
if (NULL == new_bus) if (NULL == new_bus)
return -ENOMEM; return -ENOMEM;
...@@ -242,7 +241,7 @@ static int gfar_mdio_probe(struct device *dev) ...@@ -242,7 +241,7 @@ static int gfar_mdio_probe(struct device *dev)
bus_register_fail: bus_register_fail:
iounmap(regs); iounmap(regs);
reg_map_fail: reg_map_fail:
kfree(new_bus); mdiobus_free(new_bus);
return err; return err;
} }
...@@ -258,7 +257,7 @@ static int gfar_mdio_remove(struct device *dev) ...@@ -258,7 +257,7 @@ static int gfar_mdio_remove(struct device *dev)
iounmap((void __iomem *)bus->priv); iounmap((void __iomem *)bus->priv);
bus->priv = NULL; bus->priv = NULL;
kfree(bus); mdiobus_free(bus);
return 0; return 0;
} }
......
...@@ -195,8 +195,8 @@ static int macb_mii_probe(struct net_device *dev) ...@@ -195,8 +195,8 @@ static int macb_mii_probe(struct net_device *dev)
/* find the first phy */ /* find the first phy */
for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) { for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) {
if (bp->mii_bus.phy_map[phy_addr]) { if (bp->mii_bus->phy_map[phy_addr]) {
phydev = bp->mii_bus.phy_map[phy_addr]; phydev = bp->mii_bus->phy_map[phy_addr];
break; break;
} }
} }
...@@ -244,30 +244,36 @@ static int macb_mii_init(struct macb *bp) ...@@ -244,30 +244,36 @@ static int macb_mii_init(struct macb *bp)
/* Enable managment port */ /* Enable managment port */
macb_writel(bp, NCR, MACB_BIT(MPE)); macb_writel(bp, NCR, MACB_BIT(MPE));
bp->mii_bus.name = "MACB_mii_bus"; bp->mii_bus = mdiobus_alloc();
bp->mii_bus.read = &macb_mdio_read; if (bp->mii_bus == NULL) {
bp->mii_bus.write = &macb_mdio_write; err = -ENOMEM;
bp->mii_bus.reset = &macb_mdio_reset; goto err_out;
snprintf(bp->mii_bus.id, MII_BUS_ID_SIZE, "%x", bp->pdev->id); }
bp->mii_bus.priv = bp;
bp->mii_bus.parent = &bp->dev->dev; bp->mii_bus->name = "MACB_mii_bus";
bp->mii_bus->read = &macb_mdio_read;
bp->mii_bus->write = &macb_mdio_write;
bp->mii_bus->reset = &macb_mdio_reset;
snprintf(bp->mii_bus->id, MII_BUS_ID_SIZE, "%x", bp->pdev->id);
bp->mii_bus->priv = bp;
bp->mii_bus->parent = &bp->dev->dev;
pdata = bp->pdev->dev.platform_data; pdata = bp->pdev->dev.platform_data;
if (pdata) if (pdata)
bp->mii_bus.phy_mask = pdata->phy_mask; bp->mii_bus->phy_mask = pdata->phy_mask;
bp->mii_bus.irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL); bp->mii_bus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL);
if (!bp->mii_bus.irq) { if (!bp->mii_bus->irq) {
err = -ENOMEM; err = -ENOMEM;
goto err_out; goto err_out_free_mdiobus;
} }
for (i = 0; i < PHY_MAX_ADDR; i++) for (i = 0; i < PHY_MAX_ADDR; i++)
bp->mii_bus.irq[i] = PHY_POLL; bp->mii_bus->irq[i] = PHY_POLL;
platform_set_drvdata(bp->dev, &bp->mii_bus); platform_set_drvdata(bp->dev, bp->mii_bus);
if (mdiobus_register(&bp->mii_bus)) if (mdiobus_register(bp->mii_bus))
goto err_out_free_mdio_irq; goto err_out_free_mdio_irq;
if (macb_mii_probe(bp->dev) != 0) { if (macb_mii_probe(bp->dev) != 0) {
...@@ -277,9 +283,11 @@ static int macb_mii_init(struct macb *bp) ...@@ -277,9 +283,11 @@ static int macb_mii_init(struct macb *bp)
return 0; return 0;
err_out_unregister_bus: err_out_unregister_bus:
mdiobus_unregister(&bp->mii_bus); mdiobus_unregister(bp->mii_bus);
err_out_free_mdio_irq: err_out_free_mdio_irq:
kfree(bp->mii_bus.irq); kfree(bp->mii_bus->irq);
err_out_free_mdiobus:
mdiobus_free(bp->mii_bus);
err_out: err_out:
return err; return err;
} }
...@@ -1261,8 +1269,9 @@ static int __exit macb_remove(struct platform_device *pdev) ...@@ -1261,8 +1269,9 @@ static int __exit macb_remove(struct platform_device *pdev)
bp = netdev_priv(dev); bp = netdev_priv(dev);
if (bp->phy_dev) if (bp->phy_dev)
phy_disconnect(bp->phy_dev); phy_disconnect(bp->phy_dev);
mdiobus_unregister(&bp->mii_bus); mdiobus_unregister(bp->mii_bus);
kfree(bp->mii_bus.irq); kfree(bp->mii_bus->irq);
mdiobus_free(bp->mii_bus);
unregister_netdev(dev); unregister_netdev(dev);
free_irq(dev->irq, dev); free_irq(dev->irq, dev);
iounmap(bp->regs); iounmap(bp->regs);
......
...@@ -384,7 +384,7 @@ struct macb { ...@@ -384,7 +384,7 @@ struct macb {
unsigned int rx_pending, tx_pending; unsigned int rx_pending, tx_pending;
struct mii_bus mii_bus; struct mii_bus *mii_bus;
struct phy_device *phy_dev; struct phy_device *phy_dev;
unsigned int link; unsigned int link;
unsigned int speed; unsigned int speed;
......
...@@ -250,7 +250,7 @@ struct mv643xx_eth_shared_private { ...@@ -250,7 +250,7 @@ struct mv643xx_eth_shared_private {
/* /*
* Provides access to local SMI interface. * Provides access to local SMI interface.
*/ */
struct mii_bus smi_bus; struct mii_bus *smi_bus;
/* /*
* If we have access to the error interrupt pin (which is * If we have access to the error interrupt pin (which is
...@@ -2363,15 +2363,19 @@ static int mv643xx_eth_shared_probe(struct platform_device *pdev) ...@@ -2363,15 +2363,19 @@ static int mv643xx_eth_shared_probe(struct platform_device *pdev)
* Set up and register SMI bus. * Set up and register SMI bus.
*/ */
if (pd == NULL || pd->shared_smi == NULL) { if (pd == NULL || pd->shared_smi == NULL) {
msp->smi_bus.priv = msp; msp->smi_bus = mdiobus_alloc();
msp->smi_bus.name = "mv643xx_eth smi"; if (msp->smi_bus == NULL)
msp->smi_bus.read = smi_bus_read;
msp->smi_bus.write = smi_bus_write,
snprintf(msp->smi_bus.id, MII_BUS_ID_SIZE, "%d", pdev->id);
msp->smi_bus.parent = &pdev->dev;
msp->smi_bus.phy_mask = 0xffffffff;
if (mdiobus_register(&msp->smi_bus) < 0)
goto out_unmap; goto out_unmap;
msp->smi_bus->priv = msp;
msp->smi_bus->name = "mv643xx_eth smi";
msp->smi_bus->read = smi_bus_read;
msp->smi_bus->write = smi_bus_write,
snprintf(msp->smi_bus->id, MII_BUS_ID_SIZE, "%d", pdev->id);
msp->smi_bus->parent = &pdev->dev;
msp->smi_bus->phy_mask = 0xffffffff;
if (mdiobus_register(msp->smi_bus) < 0)
goto out_free_mii_bus;
msp->smi = msp; msp->smi = msp;
} else { } else {
msp->smi = platform_get_drvdata(pd->shared_smi); msp->smi = platform_get_drvdata(pd->shared_smi);
...@@ -2411,6 +2415,8 @@ static int mv643xx_eth_shared_probe(struct platform_device *pdev) ...@@ -2411,6 +2415,8 @@ static int mv643xx_eth_shared_probe(struct platform_device *pdev)
return 0; return 0;
out_free_mii_bus:
mdiobus_free(msp->smi_bus);
out_unmap: out_unmap:
iounmap(msp->base); iounmap(msp->base);
out_free: out_free:
...@@ -2424,8 +2430,10 @@ static int mv643xx_eth_shared_remove(struct platform_device *pdev) ...@@ -2424,8 +2430,10 @@ static int mv643xx_eth_shared_remove(struct platform_device *pdev)
struct mv643xx_eth_shared_private *msp = platform_get_drvdata(pdev); struct mv643xx_eth_shared_private *msp = platform_get_drvdata(pdev);
struct mv643xx_eth_shared_platform_data *pd = pdev->dev.platform_data; struct mv643xx_eth_shared_platform_data *pd = pdev->dev.platform_data;
if (pd == NULL || pd->shared_smi == NULL) if (pd == NULL || pd->shared_smi == NULL) {
mdiobus_unregister(&msp->smi_bus); mdiobus_free(msp->smi_bus);
mdiobus_unregister(msp->smi_bus);
}
if (msp->err_interrupt != NO_IRQ) if (msp->err_interrupt != NO_IRQ)
free_irq(msp->err_interrupt, msp); free_irq(msp->err_interrupt, msp);
iounmap(msp->base); iounmap(msp->base);
...@@ -2493,7 +2501,7 @@ static void set_params(struct mv643xx_eth_private *mp, ...@@ -2493,7 +2501,7 @@ static void set_params(struct mv643xx_eth_private *mp,
static struct phy_device *phy_scan(struct mv643xx_eth_private *mp, static struct phy_device *phy_scan(struct mv643xx_eth_private *mp,
int phy_addr) int phy_addr)
{ {
struct mii_bus *bus = &mp->shared->smi->smi_bus; struct mii_bus *bus = mp->shared->smi->smi_bus;
struct phy_device *phydev; struct phy_device *phydev;
int start; int start;
int num; int num;
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
struct fixed_mdio_bus { struct fixed_mdio_bus {
int irqs[PHY_MAX_ADDR]; int irqs[PHY_MAX_ADDR];
struct mii_bus mii_bus; struct mii_bus *mii_bus;
struct list_head phys; struct list_head phys;
}; };
...@@ -213,19 +213,27 @@ static int __init fixed_mdio_bus_init(void) ...@@ -213,19 +213,27 @@ static int __init fixed_mdio_bus_init(void)
goto err_pdev; goto err_pdev;
} }
snprintf(fmb->mii_bus.id, MII_BUS_ID_SIZE, "0"); fmb->mii_bus = mdiobus_alloc();
fmb->mii_bus.name = "Fixed MDIO Bus"; if (fmb->mii_bus == NULL) {
fmb->mii_bus.parent = &pdev->dev; ret = -ENOMEM;
fmb->mii_bus.read = &fixed_mdio_read; goto err_mdiobus_reg;
fmb->mii_bus.write = &fixed_mdio_write; }
fmb->mii_bus.irq = fmb->irqs;
ret = mdiobus_register(&fmb->mii_bus); snprintf(fmb->mii_bus->id, MII_BUS_ID_SIZE, "0");
fmb->mii_bus->name = "Fixed MDIO Bus";
fmb->mii_bus->parent = &pdev->dev;
fmb->mii_bus->read = &fixed_mdio_read;
fmb->mii_bus->write = &fixed_mdio_write;
fmb->mii_bus->irq = fmb->irqs;
ret = mdiobus_register(fmb->mii_bus);
if (ret) if (ret)
goto err_mdiobus_reg; goto err_mdiobus_alloc;
return 0; return 0;
err_mdiobus_alloc:
mdiobus_free(fmb->mii_bus);
err_mdiobus_reg: err_mdiobus_reg:
platform_device_unregister(pdev); platform_device_unregister(pdev);
err_pdev: err_pdev:
...@@ -238,7 +246,8 @@ static void __exit fixed_mdio_bus_exit(void) ...@@ -238,7 +246,8 @@ static void __exit fixed_mdio_bus_exit(void)
struct fixed_mdio_bus *fmb = &platform_fmb; struct fixed_mdio_bus *fmb = &platform_fmb;
struct fixed_phy *fp, *tmp; struct fixed_phy *fp, *tmp;
mdiobus_unregister(&fmb->mii_bus); mdiobus_unregister(fmb->mii_bus);
mdiobus_free(fmb->mii_bus);
platform_device_unregister(pdev); platform_device_unregister(pdev);
list_for_each_entry_safe(fp, tmp, &fmb->phys, node) { list_for_each_entry_safe(fp, tmp, &fmb->phys, node) {
......
...@@ -165,7 +165,7 @@ struct mii_bus *alloc_mdio_bitbang(struct mdiobb_ctrl *ctrl) ...@@ -165,7 +165,7 @@ struct mii_bus *alloc_mdio_bitbang(struct mdiobb_ctrl *ctrl)
{ {
struct mii_bus *bus; struct mii_bus *bus;
bus = kzalloc(sizeof(struct mii_bus), GFP_KERNEL); bus = mdiobus_alloc();
if (!bus) if (!bus)
return NULL; return NULL;
...@@ -184,7 +184,7 @@ void free_mdio_bitbang(struct mii_bus *bus) ...@@ -184,7 +184,7 @@ void free_mdio_bitbang(struct mii_bus *bus)
struct mdiobb_ctrl *ctrl = bus->priv; struct mdiobb_ctrl *ctrl = bus->priv;
module_put(ctrl->ops->owner); module_put(ctrl->ops->owner);
kfree(bus); mdiobus_free(bus);
} }
EXPORT_SYMBOL(free_mdio_bitbang); EXPORT_SYMBOL(free_mdio_bitbang);
......
...@@ -122,7 +122,7 @@ static int __devinit mdio_ofgpio_probe(struct of_device *ofdev, ...@@ -122,7 +122,7 @@ static int __devinit mdio_ofgpio_probe(struct of_device *ofdev,
new_bus = alloc_mdio_bitbang(&bitbang->ctrl); new_bus = alloc_mdio_bitbang(&bitbang->ctrl);
if (!new_bus) if (!new_bus)
goto out_free_priv; goto out_free_bitbang;
new_bus->name = "GPIO Bitbanged MII", new_bus->name = "GPIO Bitbanged MII",
...@@ -155,9 +155,9 @@ static int __devinit mdio_ofgpio_probe(struct of_device *ofdev, ...@@ -155,9 +155,9 @@ static int __devinit mdio_ofgpio_probe(struct of_device *ofdev,
dev_set_drvdata(&ofdev->dev, NULL); dev_set_drvdata(&ofdev->dev, NULL);
kfree(new_bus->irq); kfree(new_bus->irq);
out_free_bus: out_free_bus:
kfree(new_bus);
out_free_priv:
free_mdio_bitbang(new_bus); free_mdio_bitbang(new_bus);
out_free_bitbang:
kfree(bitbang);
out: out:
return ret; return ret;
} }
...@@ -168,11 +168,10 @@ static int mdio_ofgpio_remove(struct of_device *ofdev) ...@@ -168,11 +168,10 @@ static int mdio_ofgpio_remove(struct of_device *ofdev)
struct mdio_gpio_info *bitbang = bus->priv; struct mdio_gpio_info *bitbang = bus->priv;
mdiobus_unregister(bus); mdiobus_unregister(bus);
kfree(bus->irq);
free_mdio_bitbang(bus); free_mdio_bitbang(bus);
dev_set_drvdata(&ofdev->dev, NULL); dev_set_drvdata(&ofdev->dev, NULL);
kfree(bus->irq);
kfree(bitbang); kfree(bitbang);
kfree(bus);
return 0; return 0;
} }
......
...@@ -35,6 +35,18 @@ ...@@ -35,6 +35,18 @@
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
/**
* mdiobus_alloc - allocate a mii_bus structure
*
* Description: called by a bus driver to allocate an mii_bus
* structure to fill in.
*/
struct mii_bus *mdiobus_alloc(void)
{
return kzalloc(sizeof(struct mii_bus), GFP_KERNEL);
}
EXPORT_SYMBOL(mdiobus_alloc);
/** /**
* mdiobus_register - bring up all the PHYs on a given bus and attach them to bus * mdiobus_register - bring up all the PHYs on a given bus and attach them to bus
* @bus: target mii_bus * @bus: target mii_bus
...@@ -87,6 +99,18 @@ void mdiobus_unregister(struct mii_bus *bus) ...@@ -87,6 +99,18 @@ void mdiobus_unregister(struct mii_bus *bus)
} }
EXPORT_SYMBOL(mdiobus_unregister); EXPORT_SYMBOL(mdiobus_unregister);
/**
* mdiobus_free - free a struct mii_bus
* @bus: mii_bus to free
*
* This function frees the mii_bus.
*/
void mdiobus_free(struct mii_bus *bus)
{
kfree(bus);
}
EXPORT_SYMBOL(mdiobus_free);
struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr) struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr)
{ {
struct phy_device *phydev; struct phy_device *phydev;
......
...@@ -256,7 +256,7 @@ struct sbmac_softc { ...@@ -256,7 +256,7 @@ struct sbmac_softc {
struct net_device *sbm_dev; /* pointer to linux device */ struct net_device *sbm_dev; /* pointer to linux device */
struct napi_struct napi; struct napi_struct napi;
struct phy_device *phy_dev; /* the associated PHY device */ struct phy_device *phy_dev; /* the associated PHY device */
struct mii_bus mii_bus; /* the MII bus */ struct mii_bus *mii_bus; /* the MII bus */
int phy_irq[PHY_MAX_ADDR]; int phy_irq[PHY_MAX_ADDR];
spinlock_t sbm_lock; /* spin lock */ spinlock_t sbm_lock; /* spin lock */
int sbm_devflags; /* current device flags */ int sbm_devflags; /* current device flags */
...@@ -2348,10 +2348,17 @@ static int sbmac_init(struct platform_device *pldev, long long base) ...@@ -2348,10 +2348,17 @@ static int sbmac_init(struct platform_device *pldev, long long base)
/* This is needed for PASS2 for Rx H/W checksum feature */ /* This is needed for PASS2 for Rx H/W checksum feature */
sbmac_set_iphdr_offset(sc); sbmac_set_iphdr_offset(sc);
sc->mii_bus = mdiobus_alloc();
if (sc->mii_bus == NULL) {
sbmac_uninitctx(sc);
return -ENOMEM;
}
err = register_netdev(dev); err = register_netdev(dev);
if (err) { if (err) {
printk(KERN_ERR "%s.%d: unable to register netdev\n", printk(KERN_ERR "%s.%d: unable to register netdev\n",
sbmac_string, idx); sbmac_string, idx);
mdiobus_free(sc->mii_bus);
sbmac_uninitctx(sc); sbmac_uninitctx(sc);
return err; return err;
} }
...@@ -2369,17 +2376,17 @@ static int sbmac_init(struct platform_device *pldev, long long base) ...@@ -2369,17 +2376,17 @@ static int sbmac_init(struct platform_device *pldev, long long base)
pr_info("%s: SiByte Ethernet at 0x%08Lx, address: %s\n", pr_info("%s: SiByte Ethernet at 0x%08Lx, address: %s\n",
dev->name, base, print_mac(mac, eaddr)); dev->name, base, print_mac(mac, eaddr));
sc->mii_bus.name = sbmac_mdio_string; sc->mii_bus->name = sbmac_mdio_string;
snprintf(sc->mii_bus.id, MII_BUS_ID_SIZE, "%x", idx); snprintf(sc->mii_bus->id, MII_BUS_ID_SIZE, "%x", idx);
sc->mii_bus.priv = sc; sc->mii_bus->priv = sc;
sc->mii_bus.read = sbmac_mii_read; sc->mii_bus->read = sbmac_mii_read;
sc->mii_bus.write = sbmac_mii_write; sc->mii_bus->write = sbmac_mii_write;
sc->mii_bus.irq = sc->phy_irq; sc->mii_bus->irq = sc->phy_irq;
for (i = 0; i < PHY_MAX_ADDR; ++i) for (i = 0; i < PHY_MAX_ADDR; ++i)
sc->mii_bus.irq[i] = SBMAC_PHY_INT; sc->mii_bus->irq[i] = SBMAC_PHY_INT;
sc->mii_bus.parent = &pldev->dev; sc->mii_bus->parent = &pldev->dev;
dev_set_drvdata(&pldev->dev, &sc->mii_bus); dev_set_drvdata(&pldev->dev, sc->mii_bus);
return 0; return 0;
} }
...@@ -2410,7 +2417,7 @@ static int sbmac_open(struct net_device *dev) ...@@ -2410,7 +2417,7 @@ static int sbmac_open(struct net_device *dev)
/* /*
* Probe PHY address * Probe PHY address
*/ */
err = mdiobus_register(&sc->mii_bus); err = mdiobus_register(sc->mii_bus);
if (err) { if (err) {
printk(KERN_ERR "%s: unable to register MDIO bus\n", printk(KERN_ERR "%s: unable to register MDIO bus\n",
dev->name); dev->name);
...@@ -2447,7 +2454,7 @@ static int sbmac_open(struct net_device *dev) ...@@ -2447,7 +2454,7 @@ static int sbmac_open(struct net_device *dev)
return 0; return 0;
out_unregister: out_unregister:
mdiobus_unregister(&sc->mii_bus); mdiobus_unregister(sc->mii_bus);
out_unirq: out_unirq:
free_irq(dev->irq, dev); free_irq(dev->irq, dev);
...@@ -2463,7 +2470,7 @@ static int sbmac_mii_probe(struct net_device *dev) ...@@ -2463,7 +2470,7 @@ static int sbmac_mii_probe(struct net_device *dev)
int i; int i;
for (i = 0; i < PHY_MAX_ADDR; i++) { for (i = 0; i < PHY_MAX_ADDR; i++) {
phy_dev = sc->mii_bus.phy_map[i]; phy_dev = sc->mii_bus->phy_map[i];
if (phy_dev) if (phy_dev)
break; break;
} }
...@@ -2641,7 +2648,7 @@ static int sbmac_close(struct net_device *dev) ...@@ -2641,7 +2648,7 @@ static int sbmac_close(struct net_device *dev)
phy_disconnect(sc->phy_dev); phy_disconnect(sc->phy_dev);
sc->phy_dev = NULL; sc->phy_dev = NULL;
mdiobus_unregister(&sc->mii_bus); mdiobus_unregister(sc->mii_bus);
free_irq(dev->irq, dev); free_irq(dev->irq, dev);
...@@ -2750,6 +2757,7 @@ static int __exit sbmac_remove(struct platform_device *pldev) ...@@ -2750,6 +2757,7 @@ static int __exit sbmac_remove(struct platform_device *pldev)
unregister_netdev(dev); unregister_netdev(dev);
sbmac_uninitctx(sc); sbmac_uninitctx(sc);
mdiobus_free(sc->mii_bus);
iounmap(sc->sbm_base); iounmap(sc->sbm_base);
free_netdev(dev); free_netdev(dev);
......
...@@ -1166,7 +1166,7 @@ static int sh_mdio_init(struct net_device *ndev, int id) ...@@ -1166,7 +1166,7 @@ static int sh_mdio_init(struct net_device *ndev, int id)
kfree(mdp->mii_bus->irq); kfree(mdp->mii_bus->irq);
out_free_bus: out_free_bus:
kfree(mdp->mii_bus); free_mdio_bitbang(mdp->mii_bus);
out_free_bitbang: out_free_bitbang:
kfree(bitbang); kfree(bitbang);
......
...@@ -424,7 +424,7 @@ struct tc35815_local { ...@@ -424,7 +424,7 @@ struct tc35815_local {
*/ */
spinlock_t lock; spinlock_t lock;
struct mii_bus mii_bus; struct mii_bus *mii_bus;
struct phy_device *phy_dev; struct phy_device *phy_dev;
int duplex; int duplex;
int speed; int speed;
...@@ -704,13 +704,13 @@ static int tc_mii_probe(struct net_device *dev) ...@@ -704,13 +704,13 @@ static int tc_mii_probe(struct net_device *dev)
/* find the first phy */ /* find the first phy */
for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) { for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) {
if (lp->mii_bus.phy_map[phy_addr]) { if (lp->mii_bus->phy_map[phy_addr]) {
if (phydev) { if (phydev) {
printk(KERN_ERR "%s: multiple PHYs found\n", printk(KERN_ERR "%s: multiple PHYs found\n",
dev->name); dev->name);
return -EINVAL; return -EINVAL;
} }
phydev = lp->mii_bus.phy_map[phy_addr]; phydev = lp->mii_bus->phy_map[phy_addr];
break; break;
} }
} }
...@@ -762,23 +762,29 @@ static int tc_mii_init(struct net_device *dev) ...@@ -762,23 +762,29 @@ static int tc_mii_init(struct net_device *dev)
int err; int err;
int i; int i;
lp->mii_bus.name = "tc35815_mii_bus"; lp->mii_bus = mdiobus_alloc();
lp->mii_bus.read = tc_mdio_read; if (lp->mii_bus == NULL) {
lp->mii_bus.write = tc_mdio_write;
snprintf(lp->mii_bus.id, MII_BUS_ID_SIZE, "%x",
(lp->pci_dev->bus->number << 8) | lp->pci_dev->devfn);
lp->mii_bus.priv = dev;
lp->mii_bus.parent = &lp->pci_dev->dev;
lp->mii_bus.irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
if (!lp->mii_bus.irq) {
err = -ENOMEM; err = -ENOMEM;
goto err_out; goto err_out;
} }
lp->mii_bus->name = "tc35815_mii_bus";
lp->mii_bus->read = tc_mdio_read;
lp->mii_bus->write = tc_mdio_write;
snprintf(lp->mii_bus->id, MII_BUS_ID_SIZE, "%x",
(lp->pci_dev->bus->number << 8) | lp->pci_dev->devfn);
lp->mii_bus->priv = dev;
lp->mii_bus->parent = &lp->pci_dev->dev;
lp->mii_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
if (!lp->mii_bus->irq) {
err = -ENOMEM;
goto err_out_free_mii_bus;
}
for (i = 0; i < PHY_MAX_ADDR; i++) for (i = 0; i < PHY_MAX_ADDR; i++)
lp->mii_bus.irq[i] = PHY_POLL; lp->mii_bus->irq[i] = PHY_POLL;
err = mdiobus_register(&lp->mii_bus); err = mdiobus_register(lp->mii_bus);
if (err) if (err)
goto err_out_free_mdio_irq; goto err_out_free_mdio_irq;
err = tc_mii_probe(dev); err = tc_mii_probe(dev);
...@@ -787,9 +793,11 @@ static int tc_mii_init(struct net_device *dev) ...@@ -787,9 +793,11 @@ static int tc_mii_init(struct net_device *dev)
return 0; return 0;
err_out_unregister_bus: err_out_unregister_bus:
mdiobus_unregister(&lp->mii_bus); mdiobus_unregister(lp->mii_bus);
err_out_free_mdio_irq: err_out_free_mdio_irq:
kfree(lp->mii_bus.irq); kfree(lp->mii_bus->irq);
err_out_free_mii_bus;
mdiobus_free(lp->mii_bus);
err_out: err_out:
return err; return err;
} }
...@@ -961,8 +969,9 @@ static void __devexit tc35815_remove_one(struct pci_dev *pdev) ...@@ -961,8 +969,9 @@ static void __devexit tc35815_remove_one(struct pci_dev *pdev)
struct tc35815_local *lp = netdev_priv(dev); struct tc35815_local *lp = netdev_priv(dev);
phy_disconnect(lp->phy_dev); phy_disconnect(lp->phy_dev);
mdiobus_unregister(&lp->mii_bus); mdiobus_unregister(lp->mii_bus);
kfree(lp->mii_bus.irq); kfree(lp->mii_bus->irq);
mdiobus_free(lp->mii_bus);
unregister_netdev(dev); unregister_netdev(dev);
free_netdev(dev); free_netdev(dev);
pci_set_drvdata(pdev, NULL); pci_set_drvdata(pdev, NULL);
......
...@@ -876,7 +876,7 @@ static void tg3_mdio_config(struct tg3 *tp) ...@@ -876,7 +876,7 @@ static void tg3_mdio_config(struct tg3 *tp)
{ {
u32 val; u32 val;
if (tp->mdio_bus.phy_map[PHY_ADDR]->interface != if (tp->mdio_bus->phy_map[PHY_ADDR]->interface !=
PHY_INTERFACE_MODE_RGMII) PHY_INTERFACE_MODE_RGMII)
return; return;
...@@ -920,9 +920,9 @@ static void tg3_mdio_config(struct tg3 *tp) ...@@ -920,9 +920,9 @@ static void tg3_mdio_config(struct tg3 *tp)
static void tg3_mdio_start(struct tg3 *tp) static void tg3_mdio_start(struct tg3 *tp)
{ {
if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_INITED) { if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_INITED) {
mutex_lock(&tp->mdio_bus.mdio_lock); mutex_lock(&tp->mdio_bus->mdio_lock);
tp->tg3_flags3 &= ~TG3_FLG3_MDIOBUS_PAUSED; tp->tg3_flags3 &= ~TG3_FLG3_MDIOBUS_PAUSED;
mutex_unlock(&tp->mdio_bus.mdio_lock); mutex_unlock(&tp->mdio_bus->mdio_lock);
} }
tp->mi_mode &= ~MAC_MI_MODE_AUTO_POLL; tp->mi_mode &= ~MAC_MI_MODE_AUTO_POLL;
...@@ -936,9 +936,9 @@ static void tg3_mdio_start(struct tg3 *tp) ...@@ -936,9 +936,9 @@ static void tg3_mdio_start(struct tg3 *tp)
static void tg3_mdio_stop(struct tg3 *tp) static void tg3_mdio_stop(struct tg3 *tp)
{ {
if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_INITED) { if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_INITED) {
mutex_lock(&tp->mdio_bus.mdio_lock); mutex_lock(&tp->mdio_bus->mdio_lock);
tp->tg3_flags3 |= TG3_FLG3_MDIOBUS_PAUSED; tp->tg3_flags3 |= TG3_FLG3_MDIOBUS_PAUSED;
mutex_unlock(&tp->mdio_bus.mdio_lock); mutex_unlock(&tp->mdio_bus->mdio_lock);
} }
} }
...@@ -947,7 +947,6 @@ static int tg3_mdio_init(struct tg3 *tp) ...@@ -947,7 +947,6 @@ static int tg3_mdio_init(struct tg3 *tp)
int i; int i;
u32 reg; u32 reg;
struct phy_device *phydev; struct phy_device *phydev;
struct mii_bus *mdio_bus = &tp->mdio_bus;
tg3_mdio_start(tp); tg3_mdio_start(tp);
...@@ -955,21 +954,23 @@ static int tg3_mdio_init(struct tg3 *tp) ...@@ -955,21 +954,23 @@ static int tg3_mdio_init(struct tg3 *tp)
(tp->tg3_flags3 & TG3_FLG3_MDIOBUS_INITED)) (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_INITED))
return 0; return 0;
memset(mdio_bus, 0, sizeof(*mdio_bus)); tp->mdio_bus = mdiobus_alloc();
if (tp->mdio_bus == NULL)
return -ENOMEM;
mdio_bus->name = "tg3 mdio bus"; tp->mdio_bus->name = "tg3 mdio bus";
snprintf(mdio_bus->id, MII_BUS_ID_SIZE, "%x", snprintf(tp->mdio_bus->id, MII_BUS_ID_SIZE, "%x",
(tp->pdev->bus->number << 8) | tp->pdev->devfn); (tp->pdev->bus->number << 8) | tp->pdev->devfn);
mdio_bus->priv = tp; tp->mdio_bus->priv = tp;
mdio_bus->parent = &tp->pdev->dev; tp->mdio_bus->parent = &tp->pdev->dev;
mdio_bus->read = &tg3_mdio_read; tp->mdio_bus->read = &tg3_mdio_read;
mdio_bus->write = &tg3_mdio_write; tp->mdio_bus->write = &tg3_mdio_write;
mdio_bus->reset = &tg3_mdio_reset; tp->mdio_bus->reset = &tg3_mdio_reset;
mdio_bus->phy_mask = ~(1 << PHY_ADDR); tp->mdio_bus->phy_mask = ~(1 << PHY_ADDR);
mdio_bus->irq = &tp->mdio_irq[0]; tp->mdio_bus->irq = &tp->mdio_irq[0];
for (i = 0; i < PHY_MAX_ADDR; i++) for (i = 0; i < PHY_MAX_ADDR; i++)
mdio_bus->irq[i] = PHY_POLL; tp->mdio_bus->irq[i] = PHY_POLL;
/* The bus registration will look for all the PHYs on the mdio bus. /* The bus registration will look for all the PHYs on the mdio bus.
* Unfortunately, it does not ensure the PHY is powered up before * Unfortunately, it does not ensure the PHY is powered up before
...@@ -979,7 +980,7 @@ static int tg3_mdio_init(struct tg3 *tp) ...@@ -979,7 +980,7 @@ static int tg3_mdio_init(struct tg3 *tp)
if (tg3_readphy(tp, MII_BMCR, &reg) || (reg & BMCR_PDOWN)) if (tg3_readphy(tp, MII_BMCR, &reg) || (reg & BMCR_PDOWN))
tg3_bmcr_reset(tp); tg3_bmcr_reset(tp);
i = mdiobus_register(mdio_bus); i = mdiobus_register(tp->mdio_bus);
if (i) { if (i) {
printk(KERN_WARNING "%s: mdiobus_reg failed (0x%x)\n", printk(KERN_WARNING "%s: mdiobus_reg failed (0x%x)\n",
tp->dev->name, i); tp->dev->name, i);
...@@ -988,7 +989,7 @@ static int tg3_mdio_init(struct tg3 *tp) ...@@ -988,7 +989,7 @@ static int tg3_mdio_init(struct tg3 *tp)
tp->tg3_flags3 |= TG3_FLG3_MDIOBUS_INITED; tp->tg3_flags3 |= TG3_FLG3_MDIOBUS_INITED;
phydev = tp->mdio_bus.phy_map[PHY_ADDR]; phydev = tp->mdio_bus->phy_map[PHY_ADDR];
switch (phydev->phy_id) { switch (phydev->phy_id) {
case TG3_PHY_ID_BCM50610: case TG3_PHY_ID_BCM50610:
...@@ -1014,7 +1015,8 @@ static void tg3_mdio_fini(struct tg3 *tp) ...@@ -1014,7 +1015,8 @@ static void tg3_mdio_fini(struct tg3 *tp)
{ {
if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_INITED) { if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_INITED) {
tp->tg3_flags3 &= ~TG3_FLG3_MDIOBUS_INITED; tp->tg3_flags3 &= ~TG3_FLG3_MDIOBUS_INITED;
mdiobus_unregister(&tp->mdio_bus); mdiobus_unregister(tp->mdio_bus);
mdiobus_free(tp->mdio_bus);
tp->tg3_flags3 &= ~TG3_FLG3_MDIOBUS_PAUSED; tp->tg3_flags3 &= ~TG3_FLG3_MDIOBUS_PAUSED;
} }
} }
...@@ -1220,7 +1222,7 @@ static void tg3_setup_flow_control(struct tg3 *tp, u32 lcladv, u32 rmtadv) ...@@ -1220,7 +1222,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 (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB)
autoneg = tp->mdio_bus.phy_map[PHY_ADDR]->autoneg; autoneg = tp->mdio_bus->phy_map[PHY_ADDR]->autoneg;
else else
autoneg = tp->link_config.autoneg; autoneg = tp->link_config.autoneg;
...@@ -1257,7 +1259,7 @@ static void tg3_adjust_link(struct net_device *dev) ...@@ -1257,7 +1259,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[PHY_ADDR]; struct phy_device *phydev = tp->mdio_bus->phy_map[PHY_ADDR];
spin_lock(&tp->lock); spin_lock(&tp->lock);
...@@ -1334,7 +1336,7 @@ static int tg3_phy_init(struct tg3 *tp) ...@@ -1334,7 +1336,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[PHY_ADDR]; phydev = tp->mdio_bus->phy_map[PHY_ADDR];
/* Attach the MAC to the PHY. */ /* Attach the MAC to the PHY. */
phydev = phy_connect(tp->dev, phydev->dev.bus_id, tg3_adjust_link, phydev = phy_connect(tp->dev, phydev->dev.bus_id, tg3_adjust_link,
...@@ -1367,7 +1369,7 @@ static void tg3_phy_start(struct tg3 *tp) ...@@ -1367,7 +1369,7 @@ static void tg3_phy_start(struct tg3 *tp)
if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED)) if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED))
return; return;
phydev = tp->mdio_bus.phy_map[PHY_ADDR]; phydev = tp->mdio_bus->phy_map[PHY_ADDR];
if (tp->link_config.phy_is_low_power) { if (tp->link_config.phy_is_low_power) {
tp->link_config.phy_is_low_power = 0; tp->link_config.phy_is_low_power = 0;
...@@ -1387,13 +1389,13 @@ static void tg3_phy_stop(struct tg3 *tp) ...@@ -1387,13 +1389,13 @@ static void tg3_phy_stop(struct tg3 *tp)
if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED)) if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED))
return; return;
phy_stop(tp->mdio_bus.phy_map[PHY_ADDR]); phy_stop(tp->mdio_bus->phy_map[PHY_ADDR]);
} }
static void tg3_phy_fini(struct tg3 *tp) static void tg3_phy_fini(struct tg3 *tp)
{ {
if (tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED) { if (tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED) {
phy_disconnect(tp->mdio_bus.phy_map[PHY_ADDR]); phy_disconnect(tp->mdio_bus->phy_map[PHY_ADDR]);
tp->tg3_flags3 &= ~TG3_FLG3_PHY_CONNECTED; tp->tg3_flags3 &= ~TG3_FLG3_PHY_CONNECTED;
} }
} }
...@@ -2049,7 +2051,7 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state) ...@@ -2049,7 +2051,7 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
struct phy_device *phydev; struct phy_device *phydev;
u32 advertising; u32 advertising;
phydev = tp->mdio_bus.phy_map[PHY_ADDR]; phydev = tp->mdio_bus->phy_map[PHY_ADDR];
tp->link_config.phy_is_low_power = 1; tp->link_config.phy_is_low_power = 1;
...@@ -8954,7 +8956,7 @@ static int tg3_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) ...@@ -8954,7 +8956,7 @@ static int tg3_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) { if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED)) if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED))
return -EAGAIN; return -EAGAIN;
return phy_ethtool_gset(tp->mdio_bus.phy_map[PHY_ADDR], cmd); return phy_ethtool_gset(tp->mdio_bus->phy_map[PHY_ADDR], cmd);
} }
cmd->supported = (SUPPORTED_Autoneg); cmd->supported = (SUPPORTED_Autoneg);
...@@ -8995,7 +8997,7 @@ static int tg3_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) ...@@ -8995,7 +8997,7 @@ static int tg3_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) { if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED)) if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED))
return -EAGAIN; return -EAGAIN;
return phy_ethtool_sset(tp->mdio_bus.phy_map[PHY_ADDR], cmd); return phy_ethtool_sset(tp->mdio_bus->phy_map[PHY_ADDR], cmd);
} }
if (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES) { if (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES) {
...@@ -9143,7 +9145,7 @@ static int tg3_nway_reset(struct net_device *dev) ...@@ -9143,7 +9145,7 @@ static int tg3_nway_reset(struct net_device *dev)
if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) { if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED)) if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED))
return -EAGAIN; return -EAGAIN;
r = phy_start_aneg(tp->mdio_bus.phy_map[PHY_ADDR]); r = phy_start_aneg(tp->mdio_bus->phy_map[PHY_ADDR]);
} else { } else {
u32 bmcr; u32 bmcr;
...@@ -9260,7 +9262,7 @@ static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam ...@@ -9260,7 +9262,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[PHY_ADDR]; phydev = tp->mdio_bus->phy_map[PHY_ADDR];
if (epause->rx_pause) { if (epause->rx_pause) {
if (epause->tx_pause) if (epause->tx_pause)
...@@ -10242,7 +10244,7 @@ static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) ...@@ -10242,7 +10244,7 @@ static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) { if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED)) if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED))
return -EAGAIN; return -EAGAIN;
return phy_mii_ioctl(tp->mdio_bus.phy_map[PHY_ADDR], data, cmd); return phy_mii_ioctl(tp->mdio_bus->phy_map[PHY_ADDR], data, cmd);
} }
switch(cmd) { switch(cmd) {
......
...@@ -2556,7 +2556,7 @@ struct tg3 { ...@@ -2556,7 +2556,7 @@ struct tg3 {
int msi_cap; int msi_cap;
int pcix_cap; int pcix_cap;
struct mii_bus mdio_bus; struct mii_bus *mdio_bus;
int mdio_irq[PHY_MAX_ADDR]; int mdio_irq[PHY_MAX_ADDR];
/* PHY info */ /* PHY info */
......
...@@ -141,8 +141,7 @@ static int uec_mdio_probe(struct of_device *ofdev, const struct of_device_id *ma ...@@ -141,8 +141,7 @@ static int uec_mdio_probe(struct of_device *ofdev, const struct of_device_id *ma
struct resource res; struct resource res;
int k, err = 0; int k, err = 0;
new_bus = kzalloc(sizeof(struct mii_bus), GFP_KERNEL); new_bus = mdiobus_alloc();
if (NULL == new_bus) if (NULL == new_bus)
return -ENOMEM; return -ENOMEM;
...@@ -235,7 +234,7 @@ static int uec_mdio_probe(struct of_device *ofdev, const struct of_device_id *ma ...@@ -235,7 +234,7 @@ static int uec_mdio_probe(struct of_device *ofdev, const struct of_device_id *ma
ioremap_fail: ioremap_fail:
kfree(new_bus->irq); kfree(new_bus->irq);
reg_map_fail: reg_map_fail:
kfree(new_bus); mdiobus_free(new_bus);
return err; return err;
} }
...@@ -251,7 +250,7 @@ static int uec_mdio_remove(struct of_device *ofdev) ...@@ -251,7 +250,7 @@ static int uec_mdio_remove(struct of_device *ofdev)
iounmap((void __iomem *)bus->priv); iounmap((void __iomem *)bus->priv);
bus->priv = NULL; bus->priv = NULL;
kfree(bus); mdiobus_free(bus);
return 0; return 0;
} }
......
...@@ -408,8 +408,10 @@ void phy_start(struct phy_device *phydev); ...@@ -408,8 +408,10 @@ void phy_start(struct phy_device *phydev);
void phy_stop(struct phy_device *phydev); void phy_stop(struct phy_device *phydev);
int phy_start_aneg(struct phy_device *phydev); int phy_start_aneg(struct phy_device *phydev);
struct mii_bus *mdiobus_alloc(void);
int mdiobus_register(struct mii_bus *bus); int mdiobus_register(struct mii_bus *bus);
void mdiobus_unregister(struct mii_bus *bus); void mdiobus_unregister(struct mii_bus *bus);
void mdiobus_free(struct mii_bus *bus);
struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr); struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr);
void phy_sanitize_settings(struct phy_device *phydev); void phy_sanitize_settings(struct phy_device *phydev);
......
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