tbiphy = of_phy_find_device(priv->tbi_node);
        if (!tbiphy) {
                dev_err(&dev->dev, "error: Could not get TBI device\n");
-               put_device(&tbiphy->dev);
                return;
        }
 
         * everything for us?  Resetting it takes the link down and requires
         * several seconds for it to come back.
         */
-       if (phy_read(tbiphy, MII_BMSR) & BMSR_LSTATUS)
+       if (phy_read(tbiphy, MII_BMSR) & BMSR_LSTATUS) {
+               put_device(&tbiphy->dev);
                return;
+       }
 
        /* Single clk mode, mii mode off(for serdes communication) */
        phy_write(tbiphy, MII_TBICON, TBICON_CLK_SELECT);
 
 
 error:
        while (--i >= 0) {
-               if (bus->phy_map[i])
-                       device_unregister(&bus->phy_map[i]->dev);
+               struct phy_device *phydev = bus->phy_map[i];
+               if (phydev) {
+                       phy_device_remove(phydev);
+                       phy_device_free(phydev);
+               }
        }
        device_del(&bus->dev);
        return err;
        bus->state = MDIOBUS_UNREGISTERED;
 
        for (i = 0; i < PHY_MAX_ADDR; i++) {
-               if (bus->phy_map[i])
-                       device_unregister(&bus->phy_map[i]->dev);
-               bus->phy_map[i] = NULL;
+               struct phy_device *phydev = bus->phy_map[i];
+               if (phydev) {
+                       phy_device_remove(phydev);
+                       phy_device_free(phydev);
+               }
        }
        device_del(&bus->dev);
 }
 
 }
 EXPORT_SYMBOL(phy_device_register);
 
+/**
+ * phy_device_remove - Remove a previously registered phy device from the MDIO bus
+ * @phydev: phy_device structure to remove
+ *
+ * This doesn't free the phy_device itself, it merely reverses the effects
+ * of phy_device_register(). Use phy_device_free() to free the device
+ * after calling this function.
+ */
+void phy_device_remove(struct phy_device *phydev)
+{
+       struct mii_bus *bus = phydev->bus;
+       int addr = phydev->addr;
+
+       device_del(&phydev->dev);
+       bus->phy_map[addr] = NULL;
+}
+EXPORT_SYMBOL(phy_device_remove);
+
 /**
  * phy_find_first - finds the first PHY device on the bus
  * @bus: the target MII bus
 
                                     struct phy_c45_device_ids *c45_ids);
 struct phy_device *get_phy_device(struct mii_bus *bus, int addr, bool is_c45);
 int phy_device_register(struct phy_device *phy);
+void phy_device_remove(struct phy_device *phydev);
 int phy_init_hw(struct phy_device *phydev);
 int phy_suspend(struct phy_device *phydev);
 int phy_resume(struct phy_device *phydev);