[PATCH v2 15/24] net: mdio: Add ZTE ZX279128S MDIO controller
Andrew Lunn
andrew at lunn.ch
Wed Oct 14 05:13:38 PDT 2026
> +static int zx279128s_mdio_xfer(struct mii_bus *bus, u32 op, int addr,
> + int regnum, u16 data)
> +{
> + struct zx279128s_mdio *priv = bus->priv;
> + void __iomem *base = priv->base;
> + u32 cmd, val;
> + int ret;
> +
> + /* Clear the previous command and its status */
> + writel(readl(base + ZX_MDIO_CMD) & ~ZX_MDIO_CMD_START,
> + base + ZX_MDIO_CMD);
> + writel(0, base + ZX_MDIO_STATUS);
> +
> + cmd = readl(base + ZX_MDIO_CMD);
> + cmd &= ~(ZX_MDIO_CMD_WR | ZX_MDIO_CMD_RD | ZX_MDIO_CMD_ADDR |
> + ZX_MDIO_CMD_REG);
> + cmd |= op | FIELD_PREP(ZX_MDIO_CMD_ADDR, addr) |
> + FIELD_PREP(ZX_MDIO_CMD_REG, regnum);
> +
> + if (op == ZX_MDIO_CMD_WR)
> + writel(data, base + ZX_MDIO_DATA_WR);
> + writel(cmd | ZX_MDIO_CMD_START, base + ZX_MDIO_CMD);
> +
> + ret = readl_poll_timeout(base + ZX_MDIO_STATUS, val,
> + val & ZX_MDIO_STATUS_DONE, ZX_MDIO_POLL_US,
> + ZX_MDIO_TIMEOUT_US);
> + if (ret) {
> + dev_err_ratelimited(&bus->dev, "timeout (addr %d, reg %d)\n",
> + addr, regnum);
> + return ret;
> + }
> +
> + writel(0, base + ZX_MDIO_STATUS);
> + writel(readl(base + ZX_MDIO_CMD) & ~ZX_MDIO_CMD_START,
> + base + ZX_MDIO_CMD);
This is the same as what you did at the beginning, but in the opposite
order. Is it actually needed, and can the same order be used?
> +static int zx279128s_mdio_probe(struct platform_device *pdev)
> +{
> + struct device *dev = &pdev->dev;
> + struct zx279128s_mdio *priv;
> + struct mii_bus *bus;
> + struct clk *clk;
> + u32 val;
> +
> + bus = devm_mdiobus_alloc_size(dev, sizeof(*priv));
> + if (!bus)
> + return -ENOMEM;
> +
> + priv = bus->priv;
> + priv->base = devm_platform_ioremap_resource(pdev, 0);
> + if (IS_ERR(priv->base))
> + return PTR_ERR(priv->base);
> +
> + clk = devm_clk_get_enabled(dev, "pclk");
> + if (IS_ERR(clk))
> + return dev_err_probe(dev, PTR_ERR(clk),
> + "failed to get the register clock\n");
> + clk = devm_clk_get_enabled(dev, "wclk");
> + if (IS_ERR(clk))
> + return dev_err_probe(dev, PTR_ERR(clk),
> + "failed to get the work clock\n");
> +
Is this the bus clock? Does it need setting to 2.5Mhz?
> +static const struct of_device_id zx279128s_mdio_of_match[] = {
> + { .compatible = "zte,zx279128s-mdio" },
> + { }
It needs a device tree binding. But that is mostly boilerplate.
Andrew
More information about the linux-arm-kernel
mailing list