Message ID | 20220331151440.3643482-3-michael@walle.cc (mailing list archive) |
---|---|
State | RFC |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | [RFC,net-next,1/3] dt-bindings: net: convert mscc-miim to YAML format | expand |
Context | Check | Description |
---|---|---|
netdev/tree_selection | success | Clearly marked for net-next |
netdev/fixes_present | success | Fixes tag not required for -next series |
netdev/subject_prefix | success | Link |
netdev/cover_letter | warning | Series does not have a cover letter |
netdev/patch_count | success | Link |
netdev/header_inline | success | No static functions without inline keyword in header files |
netdev/build_32bit | success | Errors and warnings before: 0 this patch: 0 |
netdev/cc_maintainers | success | CCed 7 of 7 maintainers |
netdev/build_clang | success | Errors and warnings before: 0 this patch: 0 |
netdev/module_param | success | Was 0 now: 0 |
netdev/verify_signedoff | success | Signed-off-by tag matches author and committer |
netdev/verify_fixes | success | No Fixes tag |
netdev/build_allmodconfig_warn | success | Errors and warnings before: 0 this patch: 0 |
netdev/checkpatch | success | total: 0 errors, 0 warnings, 0 checks, 98 lines checked |
netdev/kdoc | success | Errors and warnings before: 0 this patch: 0 |
netdev/source_inline | success | Was 0 now: 0 |
> @@ -295,21 +323,41 @@ static int mscc_miim_probe(struct platform_device *pdev) > if (!miim->info) > return -EINVAL; > > - ret = of_mdiobus_register(bus, pdev->dev.of_node); > + miim->clk = devm_clk_get_optional(&pdev->dev, NULL); > + if (IS_ERR(miim->clk)) > + return PTR_ERR(miim->clk); > + > + ret = clk_prepare_enable(miim->clk); > + if (ret) > + return ret; > + > + of_property_read_u32(np, "clock-frequency", &miim->clk_freq); The clock is optional if there is no "clock-frequency" property. If the property does exist, the clock should be mandatory. I don't think it should silently fail setting the bus frequency because the clock is missing. Andrew
Am 2022-03-31 18:28, schrieb Andrew Lunn: >> @@ -295,21 +323,41 @@ static int mscc_miim_probe(struct >> platform_device *pdev) >> if (!miim->info) >> return -EINVAL; >> >> - ret = of_mdiobus_register(bus, pdev->dev.of_node); >> + miim->clk = devm_clk_get_optional(&pdev->dev, NULL); >> + if (IS_ERR(miim->clk)) >> + return PTR_ERR(miim->clk); >> + >> + ret = clk_prepare_enable(miim->clk); >> + if (ret) >> + return ret; >> + >> + of_property_read_u32(np, "clock-frequency", &miim->clk_freq); > > The clock is optional if there is no "clock-frequency" property. If > the property does exist, the clock should be mandatory. I don't think > it should silently fail setting the bus frequency because the clock is > missing. Oh yes, agreed. -michael
diff --git a/drivers/net/mdio/mdio-mscc-miim.c b/drivers/net/mdio/mdio-mscc-miim.c index c9efcfa2a1ce..3793c154bd0d 100644 --- a/drivers/net/mdio/mdio-mscc-miim.c +++ b/drivers/net/mdio/mdio-mscc-miim.c @@ -7,6 +7,7 @@ */ #include <linux/bitops.h> +#include <linux/clk.h> #include <linux/io.h> #include <linux/iopoll.h> #include <linux/kernel.h> @@ -30,6 +31,8 @@ #define MSCC_MIIM_CMD_VLD BIT(31) #define MSCC_MIIM_REG_DATA 0xC #define MSCC_MIIM_DATA_ERROR (BIT(16) | BIT(17)) +#define MSCC_MIIM_REG_CFG 0x10 +#define MSCC_MIIM_CFG_PRESCALE_MASK GENMASK(7, 0) #define MSCC_PHY_REG_PHY_CFG 0x0 #define PHY_CFG_PHY_ENA (BIT(0) | BIT(1) | BIT(2) | BIT(3)) @@ -50,6 +53,8 @@ struct mscc_miim_dev { int mii_status_offset; struct regmap *phy_regs; const struct mscc_miim_info *info; + struct clk *clk; + u32 clk_freq; }; /* When high resolution timers aren't built-in: we can't use usleep_range() as @@ -242,9 +247,32 @@ int mscc_miim_setup(struct device *dev, struct mii_bus **pbus, const char *name, } EXPORT_SYMBOL(mscc_miim_setup); +static int mscc_miim_clk_set(struct mii_bus *bus) +{ + struct mscc_miim_dev *miim = bus->priv; + unsigned long rate; + u32 div; + + /* Keep the current settings */ + if (!miim->clk || !miim->clk_freq) + return 0; + + rate = clk_get_rate(miim->clk); + + div = DIV_ROUND_UP(rate, 2 * miim->clk_freq) - 1; + if (div == 0 || div & ~MSCC_MIIM_CFG_PRESCALE_MASK) { + dev_err(&bus->dev, "Incorrect MDIO clock frequency\n"); + return -EINVAL; + } + + return regmap_update_bits(miim->regs, MSCC_MIIM_REG_CFG, + MSCC_MIIM_CFG_PRESCALE_MASK, div); +} + static int mscc_miim_probe(struct platform_device *pdev) { struct regmap *mii_regmap, *phy_regmap = NULL; + struct device_node *np = pdev->dev.of_node; void __iomem *regs, *phy_regs; struct mscc_miim_dev *miim; struct resource *res; @@ -295,21 +323,41 @@ static int mscc_miim_probe(struct platform_device *pdev) if (!miim->info) return -EINVAL; - ret = of_mdiobus_register(bus, pdev->dev.of_node); + miim->clk = devm_clk_get_optional(&pdev->dev, NULL); + if (IS_ERR(miim->clk)) + return PTR_ERR(miim->clk); + + ret = clk_prepare_enable(miim->clk); + if (ret) + return ret; + + of_property_read_u32(np, "clock-frequency", &miim->clk_freq); + + ret = mscc_miim_clk_set(bus); + if (ret) + goto out_disable_clk; + + ret = of_mdiobus_register(bus, np); if (ret < 0) { dev_err(&pdev->dev, "Cannot register MDIO bus (%d)\n", ret); - return ret; + goto out_disable_clk; } platform_set_drvdata(pdev, bus); return 0; + +out_disable_clk: + clk_disable_unprepare(miim->clk); + return ret; } static int mscc_miim_remove(struct platform_device *pdev) { struct mii_bus *bus = platform_get_drvdata(pdev); + struct mscc_miim_dev *miim = bus->priv; + clk_disable_unprepare(miim->clk); mdiobus_unregister(bus); return 0;
Until now, the MDIO bus will have the hardware default bus frequency. Read the desired frequency of the bus from the device tree and configure it. Signed-off-by: Michael Walle <michael@walle.cc> --- drivers/net/mdio/mdio-mscc-miim.c | 52 +++++++++++++++++++++++++++++-- 1 file changed, 50 insertions(+), 2 deletions(-)