@@ -658,12 +658,6 @@ struct phy_device *phy_device_create(struct mii_bus *bus, int addr, u32 phy_id,
INIT_DELAYED_WORK(&dev->state_queue, phy_state_machine);
device_initialize(&mdiodev->dev);
- ret = phy_request_driver_module(dev);
- if (ret) {
- phy_device_free(dev);
- dev = ERR_PTR(ret);
- }
-
return dev;
}
EXPORT_SYMBOL(phy_device_create);
@@ -813,30 +807,29 @@ static int get_phy_id(struct mii_bus *bus, int addr, u32 *phy_id,
return 0;
}
+static int phy_device_read_id(struct phy_device *phydev)
+{
+ struct mdio_device *mdiodev = &phydev->mdio;
+
+ phydev->c45_ids.devices_in_package = 0;
+ memset(phydev->c45_ids.device_ids, 0xff,
+ sizeof(phydev->c45_ids.device_ids));
+
+ return get_phy_id(mdiodev->bus, mdiodev->addr, &phydev->phy_id,
+ phydev->is_c45, &phydev->c45_ids);
+}
+
/**
- * get_phy_device - reads the specified PHY device and returns its @phy_device
- * struct
+ * get_phy_device - create a phy_device withoug PHY ID
* @bus: the target MII bus
* @addr: PHY address on the MII bus
* @is_c45: If true the PHY uses the 802.3 clause 45 protocol
*
- * Description: Reads the ID registers of the PHY at @addr on the
- * @bus, then allocates and returns the phy_device to represent it.
+ * Allocates a new phy_device for @addr on the @bus.
*/
struct phy_device *get_phy_device(struct mii_bus *bus, int addr, bool is_c45)
{
- struct phy_c45_device_ids c45_ids;
- u32 phy_id = 0;
- int r;
-
- c45_ids.devices_in_package = 0;
- memset(c45_ids.device_ids, 0xff, sizeof(c45_ids.device_ids));
-
- r = get_phy_id(bus, addr, &phy_id, is_c45, &c45_ids);
- if (r)
- return ERR_PTR(r);
-
- return phy_device_create(bus, addr, phy_id, is_c45, &c45_ids);
+ return phy_device_create(bus, addr, PHY_ID_NONE, is_c45, NULL);
}
EXPORT_SYMBOL(get_phy_device);
@@ -855,6 +848,16 @@ int phy_device_register(struct phy_device *phydev)
/* Deassert the reset signal */
phy_device_reset(phydev, 0);
+ if (phydev->phy_id == PHY_ID_NONE) {
+ err = phy_device_read_id(phydev);
+ if (err)
+ goto err_unregister_mdio;
+ }
+
+ err = phy_request_driver_module(phydev);
+ if (err)
+ goto err_unregister_mdio;
+
/* Run all of the fixups for this PHY */
err = phy_scan_fixups(phydev);
if (err) {
@@ -742,6 +742,7 @@ struct phy_driver {
#define PHY_ANY_ID "MATCH ANY PHY"
#define PHY_ANY_UID 0xffffffff
+#define PHY_ID_NONE 0
#define PHY_ID_MATCH_EXACT(id) .phy_id = (id), .phy_id_mask = GENMASK(31, 0)
#define PHY_ID_MATCH_MODEL(id) .phy_id = (id), .phy_id_mask = GENMASK(31, 4)