Re: [PATCH v13 3/6] clk: Make clk API return per-user struct clk instances

From: Mike Turquette
Date: Thu Feb 19 2015 - 16:32:53 EST


Quoting Stephen Boyd (2015-02-06 11:30:18)
> On 02/06/15 05:39, Russell King - ARM Linux wrote:
> > On Thu, Feb 05, 2015 at 05:35:28PM -0800, Stephen Boyd wrote:
> >
> >> From what I can tell this code is
> >> now broken because we made all clk getting functions (there's quite a
> >> few...) return unique pointers every time they're called. It seems that
> >> the driver wants to know if extclk and clk are the same so it can do
> >> something differently in kirkwood_set_rate(). Do we need some sort of
> >> clk_equal(struct clk *a, struct clk *b) function for drivers like this?
> > Well, the clocks in question are the SoC internal clock (which is more or
> > less fixed, but has a programmable divider) and an externally supplied
> > clock, and the IP has a multiplexer on its input which allows us to select
> > between those two sources.
> >
> > If it were possible to bind both to the same clock, it wouldn't be a
> > useful configuration - nothing would be gained from doing so in terms of
> > available rates.
> >
> > What the comparison is there for is to catch the case with legacy lookups
> > where a clkdev lookup entry with a NULL connection ID results in matching
> > any connection ID passed to clk_get(). If the patch changes this, then
> > we will have a regression - and this is something which needs fixing
> > _before_ we do this "return unique clocks".
> >
>
> Ok. It seems that we might need a clk_equal() or similar API after all.
> My understanding is that this driver is calling clk_get() twice with
> NULL for the con_id and then "extclk" in attempts to get the SoC
> internal clock and the externally supplied clock. If we're using legacy
> lookups then both clk_get() calls may map to the same clk_lookup entry
> and before Tomeu's patch that returns unique clocks the driver could
> detect this case and know that there isn't an external clock. Looking at
> arch/arm/mach-dove/common.c it seems that there is only one lookup per
> device and it has a wildcard NULL for con_id so both clk_get() calls
> here are going to find the same lookup and get a unique struct clk pointer.
>
> Why don't we make the legacy lookup more specific and actually indicate
> "internal" for the con_id? Then the external clock would fail to be
> found, but we can detect that case and figure out that it's not due to
> probe defer, but instead due to the fact that there really isn't any
> mapping. It looks like the code is already prepared for this anyway.
>
> ----8<----
>
> From: Stephen Boyd <sboyd@xxxxxxxxxxxxxx>
> Subject: [PATCH] ARM: dove: Remove wildcard from mvebu-audio device clk lookup
>
> This i2s driver is using the wildcard nature of clkdev lookups to
> figure out if there's an external clock or not. It does this by
> calling clk_get() twice with NULL for the con_id first and then
> "external" for the con_id the second time around and then
> compares the two pointers. With DT the wildcard feature of
> clk_get() is gone and so the driver has to handle an error from
> the second clk_get() call as meaning "no external clock
> specified". Let's use that logic even with clk lookups to
> simplify the code and remove the struct clk pointer comparisons
> which may not work in the future when clk_get() returns unique
> pointers.
>
> Signed-off-by: Stephen Boyd <sboyd@xxxxxxxxxxxxxx>

Russell et al,

I'm happy to take this patch through the clock tree (where the problem
shows up) with an ack.

Regards,
Mike

> ---
> arch/arm/mach-dove/common.c | 4 ++--
> sound/soc/kirkwood/kirkwood-i2s.c | 13 ++++---------
> 2 files changed, 6 insertions(+), 11 deletions(-)
>
> diff --git a/arch/arm/mach-dove/common.c b/arch/arm/mach-dove/common.c
> index 0d1a89298ece..f290fc944cc1 100644
> --- a/arch/arm/mach-dove/common.c
> +++ b/arch/arm/mach-dove/common.c
> @@ -124,8 +124,8 @@ static void __init dove_clk_init(void)
> orion_clkdev_add(NULL, "sdhci-dove.1", sdio1);
> orion_clkdev_add(NULL, "orion_nand", nand);
> orion_clkdev_add(NULL, "cafe1000-ccic.0", camera);
> - orion_clkdev_add(NULL, "mvebu-audio.0", i2s0);
> - orion_clkdev_add(NULL, "mvebu-audio.1", i2s1);
> + orion_clkdev_add("internal", "mvebu-audio.0", i2s0);
> + orion_clkdev_add("internal", "mvebu-audio.1", i2s1);
> orion_clkdev_add(NULL, "mv_crypto", crypto);
> orion_clkdev_add(NULL, "dove-ac97", ac97);
> orion_clkdev_add(NULL, "dove-pdma", pdma);
> diff --git a/sound/soc/kirkwood/kirkwood-i2s.c b/sound/soc/kirkwood/kirkwood-i2s.c
> index def7d8260c4e..0bfeb712a997 100644
> --- a/sound/soc/kirkwood/kirkwood-i2s.c
> +++ b/sound/soc/kirkwood/kirkwood-i2s.c
> @@ -564,7 +564,7 @@ static int kirkwood_i2s_dev_probe(struct platform_device *pdev)
> return -EINVAL;
> }
>
> - priv->clk = devm_clk_get(&pdev->dev, np ? "internal" : NULL);
> + priv->clk = devm_clk_get(&pdev->dev, "internal");
> if (IS_ERR(priv->clk)) {
> dev_err(&pdev->dev, "no clock\n");
> return PTR_ERR(priv->clk);
> @@ -579,14 +579,9 @@ static int kirkwood_i2s_dev_probe(struct platform_device *pdev)
> if (PTR_ERR(priv->extclk) == -EPROBE_DEFER)
> return -EPROBE_DEFER;
> } else {
> - if (priv->extclk == priv->clk) {
> - devm_clk_put(&pdev->dev, priv->extclk);
> - priv->extclk = ERR_PTR(-EINVAL);
> - } else {
> - dev_info(&pdev->dev, "found external clock\n");
> - clk_prepare_enable(priv->extclk);
> - soc_dai = kirkwood_i2s_dai_extclk;
> - }
> + dev_info(&pdev->dev, "found external clock\n");
> + clk_prepare_enable(priv->extclk);
> + soc_dai = kirkwood_i2s_dai_extclk;
> }
>
> /* Some sensible defaults - this reflects the powerup values */
>
> --
> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
> a Linux Foundation Collaborative Project
>
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/