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
 |