[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-12 16:55:49
|
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 |