Re: [PATCH v3 7/8] clk: Make clk API return per-user struct clk instances
From: Kodiak Furr
Date: Thu Oct 09 2014 - 19:43:17 EST
Kodiak Furr liked your message with Boxer for Android.
On Oct 9, 2014 6:22 PM, Stephen Boyd <sboyd@xxxxxxxxxxxxxx> wrote:
>
> On 10/09, Tomeu Vizoso wrote:
> >Â arch/arm/mach-omap2/cclock3xxx_data.cÂÂ | 108 ++++--
> >Â arch/arm/mach-omap2/clock.hÂÂÂÂÂÂÂÂÂÂÂÂ |Â 11 +-
> >Â arch/arm/mach-omap2/clock_common_data.c |ÂÂ 5 +-
> >Â drivers/clk/clk.cÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ | 630 ++++++++++++++++++++------------
> >Â drivers/clk/clk.hÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ |ÂÂ 5 +
> >Â drivers/clk/clkdev.cÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ |Â 24 +-
> >Â include/linux/clk-private.hÂÂÂÂÂÂÂÂÂÂÂÂ |Â 35 +-
> >Â include/linux/clk-provider.hÂÂÂÂÂÂÂÂÂÂÂ |Â 22 +-
> >Â 8 files changed, 549 insertions(+), 291 deletions(-)
>
> The difstat looks good.
>
> >
> > diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
> > index fb820bf..4db918a 100644
> > --- a/drivers/clk/clk.c
> > +++ b/drivers/clk/clk.c
> > @@ -695,6 +731,13 @@ struct clk *__clk_lookup(const char *name)
> >Â return NULL;
> >Â }
> >Â
> > +struct clk *__clk_lookup(const char *name)
> > +{
> > + struct clk_core *clk = clk_core_lookup(name);
> > +
> > + return !clk ? NULL : clk->hw->clk;
>
> This just looks weird with clk->hw->clk. I know we're trying to
> keep the diff small by not renaming clk to core when it's used
> extensively throughout the code, but for small little additions
> like this I would prefer we use core for clk_core pointers and
> clk for clk pointers. Then a patch at the end can rename
> everything to be consistent. This thing also threw me off because
> I searched for kfree(core) but couldn't find it so I thought we
> leaked the clk_core structure.
>
> > +}
> > +
> >Â /*
> >ÂÂ * Helper for finding best parent to provide a given frequency. This can be used
> >ÂÂ * directly as a determine_rate callback (e.g. for a mux), or from a more
> > @@ -2175,24 +2298,24 @@ void clk_unregister(struct clk *clk)
> >Â * a reference to this clock.
> >Â */
> >Â flags = clk_enable_lock();
> > - clk->ops = &clk_nodrv_ops;
> > + clk->core->ops = &clk_nodrv_ops;
> >Â clk_enable_unlock(flags);
> >Â
> > - if (!hlist_empty(&clk->children)) {
> > - struct clk *child;
> > + if (!hlist_empty(&clk->core->children)) {
> > + struct clk_core *child;
> >Â struct hlist_node *t;
> >Â
> >Â /* Reparent all children to the orphan list. */
> > - hlist_for_each_entry_safe(child, t, &clk->children, child_node)
> > - clk_set_parent(child, NULL);
> > + hlist_for_each_entry_safe(child, t, &clk->core->children, child_node)
> > + clk_core_set_parent(child, NULL);
> >Â }
> >Â
> > - hlist_del_init(&clk->child_node);
> > + hlist_del_init(&clk->core->child_node);
> >Â
> > - if (clk->prepare_count)
> > + if (clk->core->prepare_count)
> >Â pr_warn("%s: unregistering prepared clock: %s\n",
> > - __func__, clk->name);
> > - kref_put(&clk->ref, __clk_release);
> > + __func__, clk->core->name);
> > + kref_put(&clk->core->ref, __clk_release);
> >Â
> >Â clk_prepare_unlock();
>
> It might be worth it to make a "core" local variable in this
> function.
>
> >Â }
> > @@ -2255,32 +2378,38 @@ void devm_clk_unregister(struct device *dev, struct clk *clk)
> >Â }
> >Â EXPORT_SYMBOL_GPL(devm_clk_unregister);
> >Â
> > +static void clk_core_put(struct clk_core *clk)
> > +{
> > + struct module *owner;
> > +
> > + if (!clk || WARN_ON_ONCE(IS_ERR(clk)))
> > + return;
> > +
> > + clk_prepare_lock();
> > + owner = clk->owner;
>
> Same here too, we don't need to protect the access to owner so it
> can move outside the lock.
>
> > + kref_put(&clk->ref, __clk_release);
> > + module_put(owner);
> > + clk_prepare_unlock();
> > +}
> > +
> >Â /*
> >ÂÂ * clkdev helpers
> >ÂÂ */
> >Â int __clk_get(struct clk *clk)
> >Â {
> >Â if (clk) {
> > - if (!try_module_get(clk->owner))
> > + if (!try_module_get(clk->core->owner))
> >Â return 0;
> >Â
> > - kref_get(&clk->ref);
> > + kref_get(&clk->core->ref);
> >Â }
> >Â return 1;
>
> Grow a core pointer?
>
> >Â }
> > @@ -2391,6 +2520,31 @@ int clk_notifier_unregister(struct clk *clk, struct notifier_block *nb)
> >Â }
> >Â EXPORT_SYMBOL_GPL(clk_notifier_unregister);
> >Â
> > +struct clk *__clk_create_clk(struct clk_hw *hw, const char *dev_id,
>
> Curious, why the underscore?
>
> > + ÂÂÂÂ const char *con_id)
> > +{
> > + struct clk *clk;
> > +
> > + /* This is to allow this function to be chained to others */
> > + if (!hw || IS_ERR(hw))
> > + return (struct clk *) hw;
> > +
> > + clk = kzalloc(sizeof(*clk), GFP_KERNEL);
> > + if (!clk)
> > + return ERR_PTR(-ENOMEM);
> > +
> > + clk->core = hw->core;
> > + clk->dev_id = dev_id;
> > + clk->con_id = con_id;
> > +
> > + return clk;
> > +}
> > diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c
> > index da4bda8..4411db6 100644
> > --- a/drivers/clk/clkdev.c
> > +++ b/drivers/clk/clkdev.c
> > @@ -69,6 +70,10 @@ struct clk *of_clk_get(struct device_node *np, int index)
> >Â
> >Â clk = of_clk_get_by_clkspec(&clkspec);
> >Â of_node_put(clkspec.np);
> > +
> > + if (!IS_ERR(clk))
> > + clk = __clk_create_clk(__clk_get_hw(clk), np->full_name, NULL);
>
> We lost the debugging information here about the device
> requesting this clock and the name they called it. We get the
> device node name but that might not match the device name. We
> probably need to make private functions in here that allow such
> information to be passed without changing the API for
> of_clk_get(), of_clk_get_by_name(), etc.
>
> > +
> >Â return clk;
> >Â }
> >Â EXPORT_SYMBOL(of_clk_get);
> > @@ -168,14 +173,29 @@ static struct clk_lookup *clk_find(const char *dev_id, const char *con_id)
> >Â struct clk *clk_get_sys(const char *dev_id, const char *con_id)
> >Â {
> >Â struct clk_lookup *cl;
> > + struct clk *clk = NULL;
> >Â
> >Â mutex_lock(&clocks_mutex);
> > +
> >Â cl = clk_find(dev_id, con_id);
> > - if (cl && !__clk_get(cl->clk))
> > + if (!cl)
> > + goto out;
> > +
> > + if (!__clk_get(cl->clk)) {
> >Â cl = NULL;
> > + goto out;
> > + }
> > +
> > +#if defined(CONFIG_COMMON_CLK)
> > + clk = __clk_create_clk(__clk_get_hw(cl->clk), dev_id, con_id);
>
> I was hoping we could put the clk_hw pointer next to the clk
> pointer in the lookup structure. Then providers don't have to
> deal with clk pointers at all and can just assign their clk_hw
> pointer in the lookup. This would make most of the omap usage of
> struct clk unnecessary. It doesn't seem necessary though so I
> guess we can do that in another series?
>
> > +#else
> > + clk = cl->clk;
> > +#endif
> > +
> > +out:
> >Â mutex_unlock(&clocks_mutex);
> >Â
> > - return cl ? cl->clk : ERR_PTR(-ENOENT);
> > + return cl ? clk : ERR_PTR(-ENOENT);
> >Â }
> >Â EXPORT_SYMBOL(clk_get_sys);
> >Â
> > @@ -554,6 +559,19 @@ long __clk_mux_determine_rate(struct clk_hw *hw, unsigned long rate,
> >Â ÂÂÂÂÂ unsigned long *best_parent_rate,
> >Â ÂÂÂÂÂ struct clk_hw **best_parent_p);
> >Â
> > +/**
> > + * __clk_core_to_clk - return per-user clk
> > + * @clk: struct clk_core for which we want a per-user clk
> > + *
> > + * Returns a per-user clock that is owned by its provider. The caller shall not
> > + * call clk_get() on it.
> > + *
> > + * This function should be only needed by implementors of
> > + * clk_ops.determine_rate() and should be dropped once all have moved to a
> > + * variant that returns **clk_core instead.
> > + */
> > +struct clk *__clk_core_to_clk(struct clk_core *clk);
> > +
>
> We can drop this now right?
>
> --
> 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/