Re: [PATCH] cpufreq: add frequency table to at32ap driver

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 13 August 2013 00:40, Hans-Christian Egtvedt <egtvedt@xxxxxxxxxxxx> wrote:
> This patch adds a dynamically calculated frequency table to the at32ap driver.
> In short the architecture can scale in power of two between a maximum and
> minimum frequency. Min, max, and the steps in between are added to the table.
>
> Signed-off-by: Hans-Christian Egtvedt <egtvedt@xxxxxxxxxxxx>
> ---
>  drivers/cpufreq/at32ap-cpufreq.c | 47 +++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 46 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/cpufreq/at32ap-cpufreq.c b/drivers/cpufreq/at32ap-cpufreq.c
> index 6544887..dbf3f3d 100644
> --- a/drivers/cpufreq/at32ap-cpufreq.c
> +++ b/drivers/cpufreq/at32ap-cpufreq.c
> @@ -19,8 +19,10 @@
>  #include <linux/clk.h>
>  #include <linux/err.h>
>  #include <linux/export.h>
> +#include <linux/slab.h>
>
>  static struct clk *cpuclk;
> +static struct cpufreq_frequency_table *freq_table;
>
>  static int at32_verify_speed(struct cpufreq_policy *policy)
>  {
> @@ -85,13 +87,19 @@ static int at32_set_target(struct cpufreq_policy *policy,
>
>  static int __init at32_cpufreq_driver_init(struct cpufreq_policy *policy)
>  {
> +       unsigned int frequency;
> +       int retval;
> +       int steps;
> +       int i;
> +
>         if (policy->cpu != 0)
>                 return -EINVAL;
>
>         cpuclk = clk_get(NULL, "cpu");
>         if (IS_ERR(cpuclk)) {
>                 pr_debug("cpufreq: could not get CPU clk\n");
> -               return PTR_ERR(cpuclk);
> +               retval = PTR_ERR(cpuclk);
> +               goto out_err;
>         }
>
>         policy->cpuinfo.min_freq = (clk_round_rate(cpuclk, 1) + 500) / 1000;
> @@ -101,9 +109,46 @@ static int __init at32_cpufreq_driver_init(struct cpufreq_policy *policy)
>         policy->min = policy->cpuinfo.min_freq;
>         policy->max = policy->cpuinfo.max_freq;
>
> +       /*
> +        * AVR32 CPU frequency rate scales in power of two between maximum and
> +        * minimum, also add space for the table end marker.
> +        *
> +        * Further validate that the frequency is usable, and append it to the
> +        * frequency table.
> +        */
> +       steps = fls(policy->cpuinfo.max_freq / policy->cpuinfo.min_freq) + 1;
> +       freq_table = kzalloc(steps * sizeof(struct cpufreq_frequency_table),
> +                       GFP_KERNEL);
> +       if (!freq_table) {
> +               retval = -ENOMEM;
> +               goto out_err_put_clk;
> +       }
> +
> +       frequency = policy->cpuinfo.max_freq;
> +       for (i = 0; i < (steps - 1); i++) {
> +               unsigned int rate = clk_round_rate(cpuclk, frequency * 1000);
> +               rate /= 1000;
> +               if (rate != frequency)
> +                       freq_table[i].frequency = CPUFREQ_ENTRY_INVALID;
> +               else
> +                       freq_table[i].frequency = frequency;
> +               frequency /= 2;
> +       }
> +       freq_table[steps - 1].frequency = CPUFREQ_TABLE_END;
> +
> +       retval = cpufreq_frequency_table_cpuinfo(policy, freq_table);
> +       if (retval)
> +               goto out_err_kfree;
> +
>         printk("cpufreq: AT32AP CPU frequency driver\n");
>
>         return 0;
> +out_err_kfree:
> +       kfree(freq_table);
> +out_err_put_clk:
> +       clk_put(cpuclk);
> +out_err:
> +       return retval;
>  }
>
>  static struct cpufreq_driver at32_driver = {

Thanks for your patch, I have folded below patch with your patch while
applying..

diff --git a/drivers/cpufreq/at32ap-cpufreq.c b/drivers/cpufreq/at32ap-cpufreq.c
index eaac7cb..c586d3e 100644
--- a/drivers/cpufreq/at32ap-cpufreq.c
+++ b/drivers/cpufreq/at32ap-cpufreq.c
@@ -87,10 +87,8 @@ static int at32_set_target(struct cpufreq_policy *policy,

 static int __init at32_cpufreq_driver_init(struct cpufreq_policy *policy)
 {
-       unsigned int frequency;
-       int retval;
-       int steps;
-       int i;
+       unsigned int frequency, rate;
+       int retval, steps, i;

        if (policy->cpu != 0)
                return -EINVAL;
@@ -126,20 +124,23 @@ static int __init
at32_cpufreq_driver_init(struct cpufreq_policy *policy)

        frequency = policy->cpuinfo.max_freq;
        for (i = 0; i < (steps - 1); i++) {
-               unsigned int rate = clk_round_rate(cpuclk, frequency * 1000);
-               rate /= 1000;
+               rate = clk_round_rate(cpuclk, frequency * 1000) / 1000;
+
                if (rate != frequency)
                        freq_table[i].frequency = CPUFREQ_ENTRY_INVALID;
                else
                        freq_table[i].frequency = frequency;
+
                frequency /= 2;
        }
+
        freq_table[steps - 1].frequency = CPUFREQ_TABLE_END;

        retval = cpufreq_frequency_table_cpuinfo(policy, freq_table);
        if (retval)
                goto out_err_kfree;

+       cpufreq_frequency_table_get_attr(freq_table, policy->cpu);
        printk("cpufreq: AT32AP CPU frequency driver\n");

        return 0;
--
To unsubscribe from this list: send the line "unsubscribe cpufreq" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux Kernel Devel]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Forum]     [Linux SCSI]

  Powered by Linux