diff options
author | Tang Yuantian <Yuantian.Tang@freescale.com> | 2015-01-21 06:45:47 (GMT) |
---|---|---|
committer | Zhengxiong Jin <Jason.Jin@freescale.com> | 2015-02-05 08:12:24 (GMT) |
commit | 885df91947e29649eb4836001e7f7779ffdcb2a9 (patch) | |
tree | 17692d1ba1ba90915a363934424f672ee6cee715 | |
parent | 5d425486f5e6780a5c2655558d319ffe97bac525 (diff) | |
download | linux-fsl-qoriq-885df91947e29649eb4836001e7f7779ffdcb2a9.tar.xz |
cpufreq: qoriq: optimize the CPU frequency switching time
Each time the CPU switches its frequency, the clock nodes in
DTS are walked through to find proper clock source. This is
very time-consuming. Besides, switching time varies from clock
to clock. To optimize this by buffering all the input clock of CPU.
Since for each CPU each input clock takes 4 bytes memory and
normally there are several input clocks per CPU, that will not
take much memory as well.
Signed-off-by: Tang Yuantian <Yuantian.Tang@freescale.com>
Change-Id: Iff017474e04abc00c4f33cd78153baca88829716
Reviewed-on: http://git.am.freescale.net:8181/28854
Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com>
Reviewed-by: Zhuoyu Zhang <Zhuoyu.Zhang@freescale.com>
Reviewed-by: Zhengxiong Jin <Jason.Jin@freescale.com>
-rw-r--r-- | drivers/cpufreq/qoriq-cpufreq.c | 32 |
1 files changed, 21 insertions, 11 deletions
diff --git a/drivers/cpufreq/qoriq-cpufreq.c b/drivers/cpufreq/qoriq-cpufreq.c index 76a8e25..36b2e6e 100644 --- a/drivers/cpufreq/qoriq-cpufreq.c +++ b/drivers/cpufreq/qoriq-cpufreq.c @@ -25,12 +25,12 @@ /** * struct cpu_data - per CPU data struct * @clk: the clk of CPU - * @parent: the parent node of cpu clock + * @pclk: the parent clock of cpu * @table: frequency table */ struct cpu_data { struct clk *clk; - struct device_node *parent; + struct clk **pclk; struct cpufreq_frequency_table *table; }; @@ -205,7 +205,7 @@ static void set_affected_cpus(struct cpufreq_policy *policy) static int qoriq_cpufreq_cpu_init(struct cpufreq_policy *policy) { - struct device_node *np; + struct device_node *np, *pnode; int i, count, ret; u32 freq, mask; struct clk *clk; @@ -230,17 +230,23 @@ static int qoriq_cpufreq_cpu_init(struct cpufreq_policy *policy) goto err_nomem2; } - data->parent = of_parse_phandle(np, "clocks", 0); - if (!data->parent) { + pnode = of_parse_phandle(np, "clocks", 0); + if (!pnode) { pr_err("%s: could not get clock information\n", __func__); goto err_nomem2; } - count = of_property_count_strings(data->parent, "clock-names"); + count = of_property_count_strings(pnode, "clock-names"); + data->pclk = kcalloc(count, sizeof(struct clk *), GFP_KERNEL); + if (!data->pclk) { + pr_err("%s: no memory\n", __func__); + goto err_node; + } + table = kcalloc(count + 1, sizeof(*table), GFP_KERNEL); if (!table) { pr_err("%s: no memory\n", __func__); - goto err_node; + goto err_pclk; } if (fmask) @@ -249,7 +255,8 @@ static int qoriq_cpufreq_cpu_init(struct cpufreq_policy *policy) mask = 0x0; for (i = 0; i < count; i++) { - clk = of_clk_get(data->parent, i); + clk = of_clk_get(pnode, i); + data->pclk[i] = clk; freq = clk_get_rate(clk); /* * the clock is valid if its frequency is not masked @@ -288,13 +295,16 @@ static int qoriq_cpufreq_cpu_init(struct cpufreq_policy *policy) cpufreq_frequency_table_get_attr(table, cpu); of_node_put(np); + of_node_put(pnode); return 0; err_nomem1: kfree(table); +err_pclk: + kfree(data->pclk); err_node: - of_node_put(data->parent); + of_node_put(pnode); err_nomem2: per_cpu(cpu_data, cpu) = NULL; kfree(data); @@ -309,7 +319,7 @@ static int __exit qoriq_cpufreq_cpu_exit(struct cpufreq_policy *policy) struct cpu_data *data = per_cpu(cpu_data, policy->cpu); cpufreq_frequency_table_put_attr(policy->cpu); - of_node_put(data->parent); + kfree(data->pclk); kfree(data->table); kfree(data); @@ -417,7 +427,7 @@ static int qoriq_cpufreq_target(struct cpufreq_policy *policy, mutex_lock(&cpufreq_lock); cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); - parent = of_clk_get(data->parent, data->table[new].driver_data); + parent = data->pclk[data->table[new].driver_data]; #if (defined(CONFIG_PPC) && defined(CONFIG_HOTPLUG_CPU)) if (workaround == 1) { |