Hi Felipe,
so I'll put most of my comments here.
On Tue, 7 Oct 2008, Felipe Balbi wrote:
> Introduce a new mechanism to omap's clk implementation to
> associate the device with its clock during platform_device
> registration. Also gives the clock a function name (like
> mmc_fck, uart_fck, ehci_fck, etc) so drivers won't have to
> care about clk names any longer.
Let's make the function names shorter, like "fclk" and "iclk". That
should make them even easier to use in situations where the device name
itself changes, e.g., "mmc"/"hsmmc" etc. Plus the linker will be able to
merge many them together into single constant strings. For a device with
multiple fclks like DSS, we can use "tv_fclk" also, etc.
> With this mechanism we can also be sure drivers won't be able
> to clk_get the wrong clk (only true when we move all drivers
> to this new mechanism and drop the old ones).
>
> Clk's function names will be defined as they come necessary
> but let's try to keep it as simple as possible.
>
> Signed-off-by: Felipe Balbi <[EMAIL PROTECTED]>
> ---
> arch/arm/plat-omap/clock.c | 38 +++++++++++++++++++++++++++++-
> arch/arm/plat-omap/include/mach/clock.h | 6 +++++
> 2 files changed, 42 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm/plat-omap/clock.c b/arch/arm/plat-omap/clock.c
> index 7bbfba2..c090f23 100644
> --- a/arch/arm/plat-omap/clock.c
> +++ b/arch/arm/plat-omap/clock.c
> @@ -43,7 +43,7 @@ static struct clk_functions *arch_clock;
> */
> struct clk * clk_get(struct device *dev, const char *id)
> {
> - struct clk *p, *clk = ERR_PTR(-ENOENT);
> + struct clk *p, *clk;
> int idno;
>
> if (dev == NULL || dev->bus != &platform_bus_type)
> @@ -53,6 +53,15 @@ struct clk * clk_get(struct device *dev, const char *id)
>
> mutex_lock(&clocks_mutex);
>
> + list_for_each_entry(clk, &clocks, node) {
> + if (clk->function && (dev == clk->dev) &&
> + strcmp(id, clk->function) == 0)
> + goto found;
Please avoid the gotos and use the previously-used form for returning
success, e.g., iterate on p; if found, then assign to clk, and break.
Also, is there some reason why there are two list_for_each_entry() blocks?
Those should be merged into one.
> +
> + if (strcmp(id, clk->name) == 0)
> + goto found;
Doesn't the following code already handle the above case?
> + }
> +
> list_for_each_entry(p, &clocks, node) {
> if (p->id == idno &&
> strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
> @@ -64,10 +73,14 @@ struct clk * clk_get(struct device *dev, const char *id)
> list_for_each_entry(p, &clocks, node) {
> if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
> clk = p;
> - break;
> + goto found;
> }
> }
>
> + mutex_unlock(&clocks_mutex);
> +
> + return ERR_PTR(-ENOENT);
the above two lines will then become unnecessary.
> +
> found:
> mutex_unlock(&clocks_mutex);
>
> @@ -75,6 +88,27 @@ found:
> }
> EXPORT_SYMBOL(clk_get);
>
> +/**
First, thank you for using kerneldoc. But ...
> + * omap_clk_associate - associates a user to a clock so device drivers don't
> + * have to care about clock names
... Documentation/kernel-doc-nano-HOWTO.txt requires the short function
description to fit on one line. If you need more room, please put the
larger description after a blank line after the last argument
documentation line (e.g., line beginning with '@').
> + *
This blank line needs to be removed per kerneldoc - "The @argument
descriptions must begin on the very next line ..."
> + * @id: clock id as defined in arch/arm/mach-omapX/clkxxxx.h
> + * @dev: device pointer for the clock user
> + * @f: a function for the clock (uart_[if]ck, musb_ick, ehci_[if]ck, etc)
> + */
> +void __init omap_clk_associate(const char *id, struct device *dev, const
> char *f)
> +{
> + struct clk *clk = clk_get(NULL, id);
> +
> + if (!dev || !clk || !IS_ERR(clk_get(dev, f)))
> + return;
Please break the clk_get() test above out into its own statement, and
clk_put() it before returning.
> +
> + clk->function = f;
> + clk->dev = dev;
There needs to be a test before these lines to ensure that some driver has
not already associated a function with this clock, or a device with this
clock, and to WARN_ON(1) if it has.
But there seems to be a deeper problem. What happens when multiple device
drivers want to associate to the same clock? osc_ck is the pathological
case. Seems like you'll need a different data structure, like a list, to
store in the struct clk.
> +
> + clk_put(clk);
> +};
> +
> int clk_enable(struct clk *clk)
> {
> unsigned long flags;
> diff --git a/arch/arm/plat-omap/include/mach/clock.h
> b/arch/arm/plat-omap/include/mach/clock.h
> index 9088925..21f18ca 100644
> --- a/arch/arm/plat-omap/include/mach/clock.h
> +++ b/arch/arm/plat-omap/include/mach/clock.h
> @@ -13,6 +13,8 @@
> #ifndef __ARCH_ARM_OMAP_CLOCK_H
> #define __ARCH_ARM_OMAP_CLOCK_H
>
> +#include <linux/device.h>
> +
> struct module;
> struct clk;
> struct clockdomain;
> @@ -61,8 +63,10 @@ struct dpll_data {
>
> struct clk {
> struct list_head node;
> + struct device *dev;
> struct module *owner;
> const char *name;
> + const char *function;
> int id;
> struct clk *parent;
> unsigned long rate;
> @@ -116,6 +120,8 @@ struct clk_functions {
>
> extern unsigned int mpurate;
>
> +extern void omap_clk_associate(const char *id,
> + struct device *dev, const char *func);
> extern int clk_init(struct clk_functions *custom_clocks);
> extern int clk_register(struct clk *clk);
> extern void clk_unregister(struct clk *clk);
> --
> 1.6.0.1.196.g01914
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to [EMAIL PROTECTED]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
- Paul
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at http://vger.kernel.org/majordomo-info.html