summaryrefslogtreecommitdiff
path: root/drivers/cpufreq
diff options
context:
space:
mode:
authorTang Yuantian <Yuantian.Tang@freescale.com>2015-01-21 06:45:47 (GMT)
committerZhengxiong Jin <Jason.Jin@freescale.com>2015-02-05 08:12:24 (GMT)
commit885df91947e29649eb4836001e7f7779ffdcb2a9 (patch)
tree17692d1ba1ba90915a363934424f672ee6cee715 /drivers/cpufreq
parent5d425486f5e6780a5c2655558d319ffe97bac525 (diff)
downloadlinux-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>
Diffstat (limited to 'drivers/cpufreq')
-rw-r--r--drivers/cpufreq/qoriq-cpufreq.c32
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) {