if (!xpcs)
                return ERR_PTR(-ENOMEM);
 
+       mdio_device_get(mdiodev);
        xpcs->mdiodev = mdiodev;
 
        xpcs_id = xpcs_get_id(xpcs);
        ret = -ENODEV;
 
 out:
+       mdio_device_put(mdiodev);
        kfree(xpcs);
 
        return ERR_PTR(ret);
 
 void xpcs_destroy(struct dw_xpcs *xpcs)
 {
+       if (xpcs)
+               mdio_device_put(xpcs->mdiodev);
        kfree(xpcs);
 }
 EXPORT_SYMBOL_GPL(xpcs_destroy);
 
+struct dw_xpcs *xpcs_create_mdiodev(struct mii_bus *bus, int addr,
+                                   phy_interface_t interface)
+{
+       struct mdio_device *mdiodev;
+       struct dw_xpcs *xpcs;
+
+       mdiodev = mdio_device_create(bus, addr);
+       if (IS_ERR(mdiodev))
+               return ERR_CAST(mdiodev);
+
+       xpcs = xpcs_create(mdiodev, interface);
+
+       /* xpcs_create() has taken a refcount on the mdiodev if it was
+        * successful. If xpcs_create() fails, this will free the mdio
+        * device here. In any case, we don't need to hold our reference
+        * anymore, and putting it here will allow mdio_device_put() in
+        * xpcs_destroy() to automatically free the mdio device.
+        */
+       mdio_device_put(mdiodev);
+
+       return xpcs;
+}
+EXPORT_SYMBOL_GPL(xpcs_create_mdiodev);
+
 MODULE_LICENSE("GPL v2");
 
                    int enable);
 struct dw_xpcs *xpcs_create(struct mdio_device *mdiodev,
                            phy_interface_t interface);
+struct dw_xpcs *xpcs_create_mdiodev(struct mii_bus *bus, int addr,
+                                   phy_interface_t interface);
 void xpcs_destroy(struct dw_xpcs *xpcs);
 
 #endif /* __LINUX_PCS_XPCS_H */