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 |