Re: [PATCH v1 03/14] clk: Add of_clk_match() for device drivers

From: Tomasz Figa
Date: Thu Jul 25 2013 - 04:12:40 EST


Hi Stephen,

On Wednesday 24 of July 2013 17:43:31 Stephen Boyd wrote:
> In similar fashion as of_regulator_match() add an of_clk_match()
> function that finds an initializes clock init_data structs from
> devicetree. Drivers should use this API to find clocks that their
> device is providing and then iterate over their match table
> registering the clocks with the init data parsed.

I think all you need here is declaring all your clock drivers using
CLK_OF_DECLARE() macro. Then they will be automatically probed by
of_clk_init(). See last lines of drivers/clk/clk-fixed-rate.c for an
example.

Best regards,
Tomasz

> Signed-off-by: Stephen Boyd <sboyd@xxxxxxxxxxxxxx>
> ---
> drivers/clk/clk.c | 64
> ++++++++++++++++++++++++++++++++++++++++++++
> include/linux/clk-provider.h | 16 +++++++++++
> 2 files changed, 80 insertions(+)
>
> diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
> index ea8e951b..1e3e0db 100644
> --- a/drivers/clk/clk.c
> +++ b/drivers/clk/clk.c
> @@ -2289,4 +2289,68 @@ err:
> return -ENOMEM;
> }
> EXPORT_SYMBOL_GPL(of_init_clk_data);
> +
> +/**
> + * of_clk_match() - Scan and match clock providers from the DT node of
> a device + * @dev: device initializing clock providers
> + * @matches: match table of clocks
> + * @num_matches: number of entries in @matches
> + *
> + * This function uses a match table specified by the clock driver to
> parse + * clock init data from the device tree. @dev is expected to be
> a device with + * a 'clocks' child node containing a set of child
> nodes, each providing the + * init data for one clock. The data parsed
> from a child node will be matched + * to a clock based on the child
> node's name. Note that the match table is + * modified in place.
> + *
> + * Returns the number of matches found or a negative error code on
> failure. + */
> +int of_clk_match(struct device *dev, struct of_clk_match *matches,
> + int num_matches)
> +{
> + int count = 0;
> + int err, i;
> + struct device_node *np, *clocks;
> + struct clk_init_data *init;
> +
> + clocks = of_find_node_by_name(dev->of_node, "clocks");
> + if (!clocks)
> + return -EINVAL;
> +
> + for (i = 0; i < num_matches; i++) {
> + struct of_clk_match *match = &matches[i];
> + match->init_data = NULL;
> + match->of_node = NULL;
> + }
> +
> + for_each_available_child_of_node(clocks, np) {
> + for (i = 0; i < num_matches; i++) {
> + struct of_clk_match *match = &matches[i];
> + if (match->of_node)
> + continue;
> +
> + if (strcmp(match->name, np->name))
> + continue;
> +
> + init = devm_kzalloc(dev, sizeof(*init),
GFP_KERNEL);
> + if (!init)
> + return -ENOMEM;
> +
> + err = of_init_clk_data(np, init);
> + if (err) {
> + dev_err(dev,
> + "failed to parse DT for clock
%s\n",
> + np->name);
> + return err;
> + }
> + match->of_node = np;
> + match->init_data = init;
> + count++;
> + break;
> + }
> + }
> +
> + return count;
> +}
> +EXPORT_SYMBOL_GPL(of_clk_match);
> #endif
> diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
> index 18d6362..484f8ad 100644
> --- a/include/linux/clk-provider.h
> +++ b/include/linux/clk-provider.h
> @@ -461,6 +461,13 @@ struct clk_onecell_data {
> __used __section(__clk_of_table) \
> = { .compatible = compat, .data = fn };
>
> +struct of_clk_match {
> + const char *name;
> + void *driver_data;
> + struct clk_init_data *init_data;
> + struct device_node *of_node;
> +};
> +
> #ifdef CONFIG_OF
> int of_clk_add_provider(struct device_node *np,
> struct clk *(*clk_src_get)(struct of_phandle_args
*args,
> @@ -475,6 +482,9 @@ const char *of_clk_get_parent_name(struct
> device_node *np, int index); void of_clk_init(const struct of_device_id
> *matches);
> int of_init_clk_data(struct device_node *np, struct clk_init_data
> *init);
>
> +int of_clk_match(struct device *dev, struct of_clk_match *matches,
> + int num_matches);
> +
> #else /* !CONFIG_OF */
>
> static inline int of_clk_add_provider(struct device_node *np,
> @@ -508,6 +518,12 @@ of_init_clk_data(struct device_node *np, struct
> clk_init_data *init) {
> return 0;
> }
> +static inline int
> +of_clk_match(struct device *dev, struct of_clk_match *matches, int
> num_matches) +{
> +
> + return 0;
> +}
> #endif /* CONFIG_OF */
> #endif /* CONFIG_COMMON_CLK */
> #endif /* CLK_PROVIDER_H */
--
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/