Some newer SoC-s have a separate MDIO clock that needs to be enabled. So lets add support for handling the clocks to the driver. Signed-off-by: Robert Marko <robert.marko@xxxxxxxxxx> --- drivers/net/phy/mdio-ipq4019.c | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/drivers/net/phy/mdio-ipq4019.c b/drivers/net/phy/mdio-ipq4019.c index 0e78830c070b..7660bf006da0 100644 --- a/drivers/net/phy/mdio-ipq4019.c +++ b/drivers/net/phy/mdio-ipq4019.c @@ -9,6 +9,7 @@ #include <linux/iopoll.h> #include <linux/of_address.h> #include <linux/of_mdio.h> +#include <linux/clk.h> #include <linux/phy.h> #include <linux/platform_device.h> @@ -24,8 +25,12 @@ #define IPQ4019_MDIO_TIMEOUT 10000 #define IPQ4019_MDIO_SLEEP 10 +#define QCA_MDIO_CLK_DEFAULT_RATE 100000000 + struct ipq4019_mdio_data { - void __iomem *membase; + void __iomem *membase; + struct clk *mdio_clk; + u32 clk_freq; }; static int ipq4019_mdio_wait_busy(struct mii_bus *bus) @@ -100,6 +105,7 @@ static int ipq4019_mdio_probe(struct platform_device *pdev) { struct ipq4019_mdio_data *priv; struct mii_bus *bus; + struct device_node *np = pdev->dev.of_node; int ret; bus = devm_mdiobus_alloc_size(&pdev->dev, sizeof(*priv)); @@ -112,6 +118,26 @@ static int ipq4019_mdio_probe(struct platform_device *pdev) if (IS_ERR(priv->membase)) return PTR_ERR(priv->membase); + priv->mdio_clk = devm_clk_get_optional(&pdev->dev, "mdio_ahb"); + if (!IS_ERR(priv->mdio_clk)) { + if (of_property_read_u32(np, "clock-frequency", &priv->clk_freq)) { + dev_warn(&pdev->dev, "Cannot find MDIO clock frequency, using default!\n"); + priv->clk_freq = QCA_MDIO_CLK_DEFAULT_RATE; + } + + ret = clk_set_rate(priv->mdio_clk, priv->clk_freq); + if (ret) { + dev_err(&pdev->dev, "Cannot set MDIO clock rate!\n"); + return ret; + } + + ret = clk_prepare_enable(priv->mdio_clk); + if (ret) { + dev_err(&pdev->dev, "Cannot enable MDIO clock!\n"); + return ret; + } + } + bus->name = "ipq4019_mdio"; bus->read = ipq4019_mdio_read; bus->write = ipq4019_mdio_write; -- 2.26.2