Re: [Tinyx-devel] [PATCH 1/3] GENERIC: CLOCK: Improving generic clock subsystem.
Status: Planning
Brought to you by:
davidcohen
|
From: David C. <da...@gm...> - 2008-01-13 17:05:56
|
Pushing all three patches.
David
On Jan 12, 2008 12:55 PM, David Cohen <da...@gm...> wrote:
> This patch improves generic clock subsystem.
>
> Signed-off-by: David Cohen <da...@gm...>
> ---
> arch/common/clock.c | 89 +++++++++++++++++++++++++++++++-----------
> include/asm-generic/clock.h | 23 +++++++----
> 2 files changed, 80 insertions(+), 32 deletions(-)
>
> diff --git a/arch/common/clock.c b/arch/common/clock.c
> index d92f09e..32296f8 100644
> --- a/arch/common/clock.c
> +++ b/arch/common/clock.c
> @@ -22,54 +22,95 @@
> #include <asm-generic/clock.h>
> #include <tinyx/list.h>
>
> -static struct clock *clk_list;
> -static unsigned int num_clk;
> +static struct clock **clk_list;
>
> -void clk_set_list(struct clock *list, unsigned int num)
> +unsigned int clk_get_rate(unsigned int id)
> {
> - clk_list = list;
> - num_clk = num;
> + struct clock **list = clk_list;
> + struct clock *clk = NULL;
> +
> + while (*list) {
> + clk = *list;
> + if (clk->id == id)
> + break;
> + list++;
> + }
> +
> + return clk ? clk->rate : 0;
> }
>
> -void clk_propagate(struct clock *clk, struct clock *parent)
> +void clk_propagate(struct clock *clk)
> {
> - unsigned int c;
> - struct clock *child;
> + struct clock **list;
>
> if (clk == NULL)
> return;
>
> if (clk->propagate)
> - (*clk->propagate)(clk, parent);
> + (*clk->propagate)(clk);
>
> - c = clk->num_child;
> - child = clk->child;
> + list = clk->child_list;
>
> /* Revisit: fix recursive while */
> - while (c--) {
> - clk_propagate(child, clk);
> - child++;
> + while (*list) {
> + clk_propagate(*list);
> + list++;
> }
> }
>
> -unsigned int clk_set_rate(struct clock *clk, unsigned int rate)
> +unsigned int clk_set_rate(struct clock *clk, unsigned int clk_rate)
> {
> - unsigned int clk_rate = rate;
> - unsigned int c;
> - struct clock *child;
> + unsigned int *rate_list;
> + struct clock **list;
>
> if (clk == NULL)
> return 0;
>
> + rate_list = clk->rate_list;
> + while (*rate_list) {
> + if (clk_rate >= (*rate_list)) {
> + clk_rate = *rate_list;
> + break;
> + }
> + rate_list++;
> + }
> + if (!(*rate_list))
> + clk_rate = 0;
> +
> if (clk->set_rate)
> - clk_rate = (*clk->set_rate)(clk, rate);
> + clk_rate = (*clk->set_rate)(clk, clk_rate);
>
> - c = clk->num_child;
> - child = clk->child;
> - while (c--) {
> - clk_propagate(child, clk);
> - child++;
> + list = clk->child_list;
> + while (*list) {
> + struct clock *child = *list;
> +
> + child = *list;
> + if (!(child->flags & CLK_INITIALIZED)) {
> + clk_set_rate(child, child->rate);
> + child->flags |= CLK_INITIALIZED;
> + } else
> + clk_propagate(child);
> + list++;
> }
>
> return clk_rate;
> }
> +
> +void clk_set_list(struct clock **list, unsigned int num)
> +{
> + clk_list = list;
> +
> + while (*list) {
> + struct clock *clk = *list;
> +
> + if ((clk->flags & CLK_PRIMARY) &&
> + !(clk->flags & CLK_INITIALIZED)) {
> + if (clk->init)
> + (*clk->init)(clk);
> + clk_set_rate(clk, clk->rate);
> + clk->flags |= CLK_INITIALIZED;
> + }
> + list++;
> + }
> +}
> +
> diff --git a/include/asm-generic/clock.h b/include/asm-generic/clock.h
> index 4ac8e7c..6560eb6 100644
> --- a/include/asm-generic/clock.h
> +++ b/include/asm-generic/clock.h
> @@ -22,20 +22,27 @@
> #ifndef __ASM_GENERIC_CLOCK_H
> #define __ASM_GENERIC_CLOCK_H
>
> +#define CLK_ENABLED (1 << 0)
> +#define CLK_INITIALIZED (1 << 1)
> +#define CLK_PRIMARY (1 << 2)
> +
> struct clock {
> unsigned int id;
> unsigned int rate;
> + unsigned int flags;
> struct clock *parent;
> - struct clock *child;
> - unsigned int num_child;
> + struct clock **child_list;
> +
> unsigned int (*set_rate) (struct clock *clk, unsigned int rate);
> - void (*propagate) (struct clock *clk, struct clock *parent);
> -};
> + void (*propagate) (struct clock *clk);
> + void (*init) (struct clock *clk);
>
> -#define clk_get_rate(clk) (clk)->rate
> + unsigned int rate_list[];
> +};
>
> -extern void clk_set_list(struct clock *list, unsigned int num);
> -extern void clk_propagate(struct clock *clk, struct clock *parent);
> -extern unsigned int clk_set_rate(struct clock *clk, unsigned int rate);
> +void clk_set_list(struct clock **list, unsigned int num);
> +unsigned int clk_get_rate(unsigned int id);
> +void clk_propagate(struct clock *clk);
> +unsigned int clk_set_rate(struct clock *clk, unsigned int rate);
>
> #endif /* __ASM_GENERIC_CLOCK_H */
> --
> 1.5.3.7
>
>
--
David Cohen
Instituto Nokia de Tecnologia - INdT
Manaus - Brazil
|