net: macb: Add remove callback
authorWenyou Yang <wenyou.yang@atmel.com>
Fri, 14 Apr 2017 06:36:04 +0000 (14:36 +0800)
committerSimon Glass <sjg@chromium.org>
Tue, 9 May 2017 18:14:15 +0000 (12:14 -0600)
To avoid the failure of mdio_register(), add the remove callback
to unregister the mii_dev when removing the ethernet device.

Signed-off-by: Wenyou Yang <wenyou.yang@atmel.com>
Acked-by: Joe Hershberger <joe.hershberger@ni.com>
Fixed up unused variable warning, e.g. for gurnard:
Signed-off-by: Simon Glass <sjg@chromium.org>
drivers/net/macb.c

index 402e866..08d441c 100644 (file)
@@ -111,6 +111,9 @@ struct macb_device {
 #endif
        unsigned short          phy_addr;
        struct mii_dev          *bus;
+#ifdef CONFIG_PHYLIB
+       struct phy_device       *phydev;
+#endif
 
 #ifdef CONFIG_DM_ETH
 #ifdef CONFIG_CLK
@@ -479,9 +482,6 @@ static int macb_phy_init(struct macb_device *macb, const char *name)
 #ifdef CONFIG_DM_ETH
        struct macb_device *macb = dev_get_priv(dev);
 #endif
-#ifdef CONFIG_PHYLIB
-       struct phy_device *phydev;
-#endif
        u32 ncfgr;
        u16 phy_id, status, adv, lpa;
        int media, speed, duplex;
@@ -503,19 +503,19 @@ static int macb_phy_init(struct macb_device *macb, const char *name)
 
 #ifdef CONFIG_PHYLIB
 #ifdef CONFIG_DM_ETH
-       phydev = phy_connect(macb->bus, macb->phy_addr, dev,
+       macb->phydev = phy_connect(macb->bus, macb->phy_addr, dev,
                             macb->phy_interface);
 #else
        /* need to consider other phy interface mode */
-       phydev = phy_connect(macb->bus, macb->phy_addr, &macb->netdev,
+       macb->phydev = phy_connect(macb->bus, macb->phy_addr, &macb->netdev,
                             PHY_INTERFACE_MODE_RGMII);
 #endif
-       if (!phydev) {
+       if (!macb->phydev) {
                printf("phy_connect failed\n");
                return -ENODEV;
        }
 
-       phy_config(phydev);
+       phy_config(macb->phydev);
 #endif
 
        status = macb_mdio_read(macb, MII_BMSR);
@@ -1035,6 +1035,7 @@ static int macb_eth_probe(struct udevice *dev)
        struct eth_pdata *pdata = dev_get_platdata(dev);
        struct macb_device *macb = dev_get_priv(dev);
        const char *phy_mode;
+       __maybe_unused int ret;
 
        phy_mode = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "phy-mode",
                               NULL);
@@ -1048,7 +1049,7 @@ static int macb_eth_probe(struct udevice *dev)
        macb->regs = (void *)pdata->iobase;
 
 #ifdef CONFIG_CLK
-       int ret = macb_enable_clk(dev);
+       ret = macb_enable_clk(dev);
        if (ret)
                return ret;
 #endif
@@ -1056,23 +1057,35 @@ static int macb_eth_probe(struct udevice *dev)
        _macb_eth_initialize(macb);
 
 #if defined(CONFIG_CMD_MII) || defined(CONFIG_PHYLIB)
-       int retval;
-       struct mii_dev *mdiodev = mdio_alloc();
-       if (!mdiodev)
+       macb->bus = mdio_alloc();
+       if (!macb->bus)
                return -ENOMEM;
-       strncpy(mdiodev->name, dev->name, MDIO_NAME_LEN);
-       mdiodev->read = macb_miiphy_read;
-       mdiodev->write = macb_miiphy_write;
+       strncpy(macb->bus->name, dev->name, MDIO_NAME_LEN);
+       macb->bus->read = macb_miiphy_read;
+       macb->bus->write = macb_miiphy_write;
 
-       retval = mdio_register(mdiodev);
-       if (retval < 0)
-               return retval;
+       ret = mdio_register(macb->bus);
+       if (ret < 0)
+               return ret;
        macb->bus = miiphy_get_dev_by_name(dev->name);
 #endif
 
        return 0;
 }
 
+static int macb_eth_remove(struct udevice *dev)
+{
+       struct macb_device *macb = dev_get_priv(dev);
+
+#ifdef CONFIG_PHYLIB
+       free(macb->phydev);
+#endif
+       mdio_unregister(macb->bus);
+       mdio_free(macb->bus);
+
+       return 0;
+}
+
 static int macb_eth_ofdata_to_platdata(struct udevice *dev)
 {
        struct eth_pdata *pdata = dev_get_platdata(dev);
@@ -1092,6 +1105,7 @@ U_BOOT_DRIVER(eth_macb) = {
        .of_match = macb_eth_ids,
        .ofdata_to_platdata = macb_eth_ofdata_to_platdata,
        .probe  = macb_eth_probe,
+       .remove = macb_eth_remove,
        .ops    = &macb_eth_ops,
        .priv_auto_alloc_size = sizeof(struct macb_device),
        .platdata_auto_alloc_size = sizeof(struct eth_pdata),