summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRussell King (Oracle) <rmk+kernel@armlinux.org.uk>2021-12-04 20:13:11 +0000
committerRussell King (Oracle) <rmk+kernel@armlinux.org.uk>2025-04-04 14:39:55 +0100
commit6cd49bb42a3a7325e66a19d690bf79f26ef0d84e (patch)
tree35911fca09ad3f4cd4f1d251c8a93382852d2c23
parent7ac2d25f3152509a5ce231025b9cc2b00aa8917d (diff)
net: phy: generate PHY mdio modalias
The modalias string provided in the uevent sysfs file does not conform to the format used in PHY driver modules. One of the reasons is that udev loading of PHY driver modules has not been an expected use case. This patch changes the MODALIAS entry for only PHY devices from: MODALIAS=of:Nethernet-phyT(null) to: MODALIAS=mdio:00000000001000100001010100010011 Other MDIO devices (such as DSA) remain as before. However, having udev automatically load the module has the advantage of making use of existing functionality to have the module loaded before the device is bound to the driver, thus taking advantage of multithreaded boot systems, potentially decreasing the boot time. However, this patch will not solve any issues with the driver module not being loaded prior to the network device needing to use the PHY. This is something that is completely out of control of any patch to change the uevent mechanism. Reported-by: Yinbo Zhu <zhuyinbo@loongson.cn> Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-rw-r--r--drivers/net/phy/mdio_bus.c8
-rw-r--r--drivers/net/phy/phy_device.c14
-rw-r--r--include/linux/mdio.h2
3 files changed, 24 insertions, 0 deletions
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
index 7e2f10182c0c..fada095a778e 100644
--- a/drivers/net/phy/mdio_bus.c
+++ b/drivers/net/phy/mdio_bus.c
@@ -1396,8 +1396,16 @@ static int mdio_bus_match(struct device *dev, const struct device_driver *drv)
static int mdio_uevent(const struct device *dev, struct kobj_uevent_env *env)
{
+ struct mdio_device *mdio = to_mdio_device(dev);
int rc;
+ /* Use the device-specific uevent if specified */
+ if (mdio->bus_uevent) {
+ rc = mdio->bus_uevent(mdio, env);
+ if (rc != -ENODEV)
+ return rc;
+ }
+
/* Some devices have extra OF data and an OF-style MODALIAS */
rc = of_device_uevent_modalias(dev, env);
if (rc != -ENODEV)
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 46713d27412b..d5c71308b966 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -609,6 +609,19 @@ static int phy_request_driver_module(struct phy_device *dev, u32 phy_id)
return 0;
}
+static int phy_bus_uevent(struct mdio_device *mdiodev,
+ struct kobj_uevent_env *env)
+{
+ struct phy_device *phydev;
+
+ phydev = container_of(mdiodev, struct phy_device, mdio);
+
+ add_uevent_var(env, "MODALIAS=" MDIO_MODULE_PREFIX MDIO_ID_FMT,
+ MDIO_ID_ARGS(phydev->phy_id));
+
+ return 0;
+}
+
struct phy_device *phy_device_create(struct mii_bus *bus, int addr, u32 phy_id,
bool is_c45,
struct phy_c45_device_ids *c45_ids)
@@ -628,6 +641,7 @@ struct phy_device *phy_device_create(struct mii_bus *bus, int addr, u32 phy_id,
mdiodev->dev.type = &mdio_bus_phy_type;
mdiodev->bus = bus;
mdiodev->bus_match = phy_bus_match;
+ mdiodev->bus_uevent = phy_bus_uevent;
mdiodev->addr = addr;
mdiodev->flags = MDIO_DEVICE_FLAG_PHY;
mdiodev->device_free = phy_mdio_device_free;
diff --git a/include/linux/mdio.h b/include/linux/mdio.h
index 3c3deac57894..00d3a8cc6f96 100644
--- a/include/linux/mdio.h
+++ b/include/linux/mdio.h
@@ -32,6 +32,8 @@ struct mdio_device {
char modalias[MDIO_NAME_SIZE];
int (*bus_match)(struct device *dev, const struct device_driver *drv);
+ int (*bus_uevent)(struct mdio_device *mdiodev,
+ struct kobj_uevent_env *env);
void (*device_free)(struct mdio_device *mdiodev);
void (*device_remove)(struct mdio_device *mdiodev);