]> git.ipfire.org Git - thirdparty/openwrt.git/commitdiff
realtek: mdio: add mutex for multiple busses
authorMarkus Stockhausen <markus.stockhausen@gmx.de>
Wed, 1 Apr 2026 15:43:11 +0000 (17:43 +0200)
committerRobert Marko <robimarko@gmail.com>
Mon, 6 Apr 2026 09:24:23 +0000 (11:24 +0200)
When the mdio driver gets enhanced for multiple busses it must
snchronize reads/writes to the single controller. Add a lock
to the control structure and guard the critical operations.

Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
Link: https://github.com/openwrt/openwrt/pull/22731
Signed-off-by: Robert Marko <robimarko@gmail.com>
target/linux/realtek/files-6.18/drivers/net/mdio/mdio-realtek-otto.c

index d53e447c45b4c9724075f3da5b6fc9a02b6e216e..379952fda47e025f3a16d4e0b974e341907bcc2d 100644 (file)
@@ -188,6 +188,7 @@ struct rtmdio_bus {
 };
 
 struct rtmdio_ctrl {
+       struct mutex lock;
        struct regmap *map;
        const struct rtmdio_config *cfg;
        struct rtmdio_port port[RTMDIO_MAX_PHY];
@@ -508,9 +509,11 @@ static int rtmdio_read_c45(struct mii_bus *bus, int addr, int devnum, int regnum
        if (addr >= ctrl->cfg->num_phys)
                return -ENODEV;
 
+       guard(mutex)(&ctrl->lock);
        err = (*ctrl->cfg->read_mmd_phy)(bus, addr, devnum, regnum, &val);
        pr_debug("rd_MMD(adr=%d, dev=%d, reg=%d) = %d, err = %d\n",
                 addr, devnum, regnum, val, err);
+
        return err ? err : val;
 }
 
@@ -522,6 +525,7 @@ static int rtmdio_read(struct mii_bus *bus, int addr, int regnum)
        if (addr >= ctrl->cfg->num_phys)
                return -ENODEV;
 
+       guard(mutex)(&ctrl->lock);
        if (regnum == RTMDIO_PAGE_SELECT && ctrl->port[addr].page != ctrl->cfg->raw_page)
                return ctrl->port[addr].page;
 
@@ -530,6 +534,7 @@ static int rtmdio_read(struct mii_bus *bus, int addr, int regnum)
        err = (*ctrl->cfg->read_phy)(bus, addr, ctrl->port[addr].page, regnum, &val);
        pr_debug("rd_PHY(adr=%d, pag=%d, reg=%d) = %d, err = %d\n",
                 addr, ctrl->port[addr].page, regnum, val, err);
+
        return err ? err : val;
 }
 
@@ -541,9 +546,11 @@ static int rtmdio_write_c45(struct mii_bus *bus, int addr, int devnum, int regnu
        if (addr >= ctrl->cfg->num_phys)
                return -ENODEV;
 
+       guard(mutex)(&ctrl->lock);
        err = (*ctrl->cfg->write_mmd_phy)(bus, addr, devnum, regnum, val);
        pr_debug("wr_MMD(adr=%d, dev=%d, reg=%d, val=%d) err = %d\n",
                 addr, devnum, regnum, val, err);
+
        return err;
 }
 
@@ -555,6 +562,7 @@ static int rtmdio_write(struct mii_bus *bus, int addr, int regnum, u16 val)
        if (addr >= ctrl->cfg->num_phys)
                return -ENODEV;
 
+       guard(mutex)(&ctrl->lock);
        page = ctrl->port[addr].page;
 
        if (regnum == RTMDIO_PAGE_SELECT)
@@ -571,6 +579,7 @@ static int rtmdio_write(struct mii_bus *bus, int addr, int regnum, u16 val)
        }
 
        ctrl->port[addr].raw = false;
+
        return 0;
 }
 
@@ -966,6 +975,10 @@ static int rtmdio_probe(struct platform_device *pdev)
        if (!ctrl)
                return -ENOMEM;
 
+       ret = devm_mutex_init(dev, &ctrl->lock);
+       if (ret)
+               return ret;
+
        platform_set_drvdata(pdev, ctrl);
        ctrl->cfg = (const struct rtmdio_config *)device_get_match_data(dev);
        ctrl->map = syscon_node_to_regmap(pdev->dev.of_node->parent);