diff options
author | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2013-08-26 19:44:40 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2013-08-26 19:44:40 -0400 |
commit | 7a330a5416de9240c93a6987e11cb32b581d3263 (patch) | |
tree | dba692d0b2cf263f85637edf012b1918d7ea08da /arch/arm | |
parent | c7878810f2d3a637bafc4fd55126eb9a5548ec77 (diff) | |
parent | 09198f8feff1fcdf03994f35955292f85b299bd6 (diff) |
Merge branch 'pm-cpufreq'
* pm-cpufreq: (60 commits)
cpufreq: pmac32-cpufreq: remove device tree parsing for cpu nodes
cpufreq: pmac64-cpufreq: remove device tree parsing for cpu nodes
cpufreq: maple-cpufreq: remove device tree parsing for cpu nodes
cpufreq: arm_big_little: remove device tree parsing for cpu nodes
cpufreq: kirkwood-cpufreq: remove device tree parsing for cpu nodes
cpufreq: spear-cpufreq: remove device tree parsing for cpu nodes
cpufreq: highbank-cpufreq: remove device tree parsing for cpu nodes
cpufreq: cpufreq-cpu0: remove device tree parsing for cpu nodes
cpufreq: imx6q-cpufreq: remove device tree parsing for cpu nodes
drivers/bus: arm-cci: avoid parsing DT for cpu device nodes
ARM: mvebu: remove device tree parsing for cpu nodes
ARM: topology: remove hwid/MPIDR dependency from cpu_capacity
of/device: add helper to get cpu device node from logical cpu index
driver/core: cpu: initialize of_node in cpu's device struture
ARM: DT/kernel: define ARM specific arch_match_cpu_phys_id
of: move of_get_cpu_node implementation to DT core library
powerpc: refactor of_get_cpu_node to support other architectures
openrisc: remove undefined of_get_cpu_node declaration
microblaze: remove undefined of_get_cpu_node declaration
cpufreq: fix bad unlock balance on !CONFIG_SMP
...
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/kernel/devtree.c | 5 | ||||
-rw-r--r-- | arch/arm/kernel/topology.c | 61 | ||||
-rw-r--r-- | arch/arm/mach-imx/mach-imx6q.c | 3 | ||||
-rw-r--r-- | arch/arm/mach-mvebu/platsmp.c | 51 |
4 files changed, 48 insertions, 72 deletions
diff --git a/arch/arm/kernel/devtree.c b/arch/arm/kernel/devtree.c index 5859c8bc727c..2ee8a17d2b01 100644 --- a/arch/arm/kernel/devtree.c +++ b/arch/arm/kernel/devtree.c | |||
@@ -169,6 +169,11 @@ void __init arm_dt_init_cpu_maps(void) | |||
169 | } | 169 | } |
170 | } | 170 | } |
171 | 171 | ||
172 | bool arch_match_cpu_phys_id(int cpu, u64 phys_id) | ||
173 | { | ||
174 | return (phys_id & MPIDR_HWID_BITMASK) == cpu_logical_map(cpu); | ||
175 | } | ||
176 | |||
172 | /** | 177 | /** |
173 | * setup_machine_fdt - Machine setup when an dtb was passed to the kernel | 178 | * setup_machine_fdt - Machine setup when an dtb was passed to the kernel |
174 | * @dt_phys: physical address of dt blob | 179 | * @dt_phys: physical address of dt blob |
diff --git a/arch/arm/kernel/topology.c b/arch/arm/kernel/topology.c index c5a59546a256..85a87370f144 100644 --- a/arch/arm/kernel/topology.c +++ b/arch/arm/kernel/topology.c | |||
@@ -74,12 +74,8 @@ struct cpu_efficiency table_efficiency[] = { | |||
74 | {NULL, }, | 74 | {NULL, }, |
75 | }; | 75 | }; |
76 | 76 | ||
77 | struct cpu_capacity { | 77 | unsigned long *__cpu_capacity; |
78 | unsigned long hwid; | 78 | #define cpu_capacity(cpu) __cpu_capacity[cpu] |
79 | unsigned long capacity; | ||
80 | }; | ||
81 | |||
82 | struct cpu_capacity *cpu_capacity; | ||
83 | 79 | ||
84 | unsigned long middle_capacity = 1; | 80 | unsigned long middle_capacity = 1; |
85 | 81 | ||
@@ -100,15 +96,19 @@ static void __init parse_dt_topology(void) | |||
100 | unsigned long capacity = 0; | 96 | unsigned long capacity = 0; |
101 | int alloc_size, cpu = 0; | 97 | int alloc_size, cpu = 0; |
102 | 98 | ||
103 | alloc_size = nr_cpu_ids * sizeof(struct cpu_capacity); | 99 | alloc_size = nr_cpu_ids * sizeof(*__cpu_capacity); |
104 | cpu_capacity = kzalloc(alloc_size, GFP_NOWAIT); | 100 | __cpu_capacity = kzalloc(alloc_size, GFP_NOWAIT); |
105 | 101 | ||
106 | while ((cn = of_find_node_by_type(cn, "cpu"))) { | 102 | for_each_possible_cpu(cpu) { |
107 | const u32 *rate, *reg; | 103 | const u32 *rate; |
108 | int len; | 104 | int len; |
109 | 105 | ||
110 | if (cpu >= num_possible_cpus()) | 106 | /* too early to use cpu->of_node */ |
111 | break; | 107 | cn = of_get_cpu_node(cpu, NULL); |
108 | if (!cn) { | ||
109 | pr_err("missing device node for CPU %d\n", cpu); | ||
110 | continue; | ||
111 | } | ||
112 | 112 | ||
113 | for (cpu_eff = table_efficiency; cpu_eff->compatible; cpu_eff++) | 113 | for (cpu_eff = table_efficiency; cpu_eff->compatible; cpu_eff++) |
114 | if (of_device_is_compatible(cn, cpu_eff->compatible)) | 114 | if (of_device_is_compatible(cn, cpu_eff->compatible)) |
@@ -124,12 +124,6 @@ static void __init parse_dt_topology(void) | |||
124 | continue; | 124 | continue; |
125 | } | 125 | } |
126 | 126 | ||
127 | reg = of_get_property(cn, "reg", &len); | ||
128 | if (!reg || len != 4) { | ||
129 | pr_err("%s missing reg property\n", cn->full_name); | ||
130 | continue; | ||
131 | } | ||
132 | |||
133 | capacity = ((be32_to_cpup(rate)) >> 20) * cpu_eff->efficiency; | 127 | capacity = ((be32_to_cpup(rate)) >> 20) * cpu_eff->efficiency; |
134 | 128 | ||
135 | /* Save min capacity of the system */ | 129 | /* Save min capacity of the system */ |
@@ -140,13 +134,9 @@ static void __init parse_dt_topology(void) | |||
140 | if (capacity > max_capacity) | 134 | if (capacity > max_capacity) |
141 | max_capacity = capacity; | 135 | max_capacity = capacity; |
142 | 136 | ||
143 | cpu_capacity[cpu].capacity = capacity; | 137 | cpu_capacity(cpu) = capacity; |
144 | cpu_capacity[cpu++].hwid = be32_to_cpup(reg); | ||
145 | } | 138 | } |
146 | 139 | ||
147 | if (cpu < num_possible_cpus()) | ||
148 | cpu_capacity[cpu].hwid = (unsigned long)(-1); | ||
149 | |||
150 | /* If min and max capacities are equals, we bypass the update of the | 140 | /* If min and max capacities are equals, we bypass the update of the |
151 | * cpu_scale because all CPUs have the same capacity. Otherwise, we | 141 | * cpu_scale because all CPUs have the same capacity. Otherwise, we |
152 | * compute a middle_capacity factor that will ensure that the capacity | 142 | * compute a middle_capacity factor that will ensure that the capacity |
@@ -154,9 +144,7 @@ static void __init parse_dt_topology(void) | |||
154 | * SCHED_POWER_SCALE, which is the default value, but with the | 144 | * SCHED_POWER_SCALE, which is the default value, but with the |
155 | * constraint explained near table_efficiency[]. | 145 | * constraint explained near table_efficiency[]. |
156 | */ | 146 | */ |
157 | if (min_capacity == max_capacity) | 147 | if (4*max_capacity < (3*(max_capacity + min_capacity))) |
158 | cpu_capacity[0].hwid = (unsigned long)(-1); | ||
159 | else if (4*max_capacity < (3*(max_capacity + min_capacity))) | ||
160 | middle_capacity = (min_capacity + max_capacity) | 148 | middle_capacity = (min_capacity + max_capacity) |
161 | >> (SCHED_POWER_SHIFT+1); | 149 | >> (SCHED_POWER_SHIFT+1); |
162 | else | 150 | else |
@@ -170,23 +158,12 @@ static void __init parse_dt_topology(void) | |||
170 | * boot. The update of all CPUs is in O(n^2) for heteregeneous system but the | 158 | * boot. The update of all CPUs is in O(n^2) for heteregeneous system but the |
171 | * function returns directly for SMP system. | 159 | * function returns directly for SMP system. |
172 | */ | 160 | */ |
173 | void update_cpu_power(unsigned int cpu, unsigned long hwid) | 161 | void update_cpu_power(unsigned int cpu) |
174 | { | 162 | { |
175 | unsigned int idx = 0; | 163 | if (!cpu_capacity(cpu)) |
176 | |||
177 | /* look for the cpu's hwid in the cpu capacity table */ | ||
178 | for (idx = 0; idx < num_possible_cpus(); idx++) { | ||
179 | if (cpu_capacity[idx].hwid == hwid) | ||
180 | break; | ||
181 | |||
182 | if (cpu_capacity[idx].hwid == -1) | ||
183 | return; | ||
184 | } | ||
185 | |||
186 | if (idx == num_possible_cpus()) | ||
187 | return; | 164 | return; |
188 | 165 | ||
189 | set_power_scale(cpu, cpu_capacity[idx].capacity / middle_capacity); | 166 | set_power_scale(cpu, cpu_capacity(cpu) / middle_capacity); |
190 | 167 | ||
191 | printk(KERN_INFO "CPU%u: update cpu_power %lu\n", | 168 | printk(KERN_INFO "CPU%u: update cpu_power %lu\n", |
192 | cpu, arch_scale_freq_power(NULL, cpu)); | 169 | cpu, arch_scale_freq_power(NULL, cpu)); |
@@ -194,7 +171,7 @@ void update_cpu_power(unsigned int cpu, unsigned long hwid) | |||
194 | 171 | ||
195 | #else | 172 | #else |
196 | static inline void parse_dt_topology(void) {} | 173 | static inline void parse_dt_topology(void) {} |
197 | static inline void update_cpu_power(unsigned int cpuid, unsigned int mpidr) {} | 174 | static inline void update_cpu_power(unsigned int cpuid) {} |
198 | #endif | 175 | #endif |
199 | 176 | ||
200 | /* | 177 | /* |
@@ -281,7 +258,7 @@ void store_cpu_topology(unsigned int cpuid) | |||
281 | 258 | ||
282 | update_siblings_masks(cpuid); | 259 | update_siblings_masks(cpuid); |
283 | 260 | ||
284 | update_cpu_power(cpuid, mpidr & MPIDR_HWID_BITMASK); | 261 | update_cpu_power(cpuid); |
285 | 262 | ||
286 | printk(KERN_INFO "CPU%u: thread %d, cpu %d, socket %d, mpidr %x\n", | 263 | printk(KERN_INFO "CPU%u: thread %d, cpu %d, socket %d, mpidr %x\n", |
287 | cpuid, cpu_topology[cpuid].thread_id, | 264 | cpuid, cpu_topology[cpuid].thread_id, |
diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c index 7be13f8e69a0..a02f275a198d 100644 --- a/arch/arm/mach-imx/mach-imx6q.c +++ b/arch/arm/mach-imx/mach-imx6q.c | |||
@@ -254,13 +254,12 @@ static void __init imx6q_opp_init(struct device *cpu_dev) | |||
254 | { | 254 | { |
255 | struct device_node *np; | 255 | struct device_node *np; |
256 | 256 | ||
257 | np = of_find_node_by_path("/cpus/cpu@0"); | 257 | np = of_node_get(cpu_dev->of_node); |
258 | if (!np) { | 258 | if (!np) { |
259 | pr_warn("failed to find cpu0 node\n"); | 259 | pr_warn("failed to find cpu0 node\n"); |
260 | return; | 260 | return; |
261 | } | 261 | } |
262 | 262 | ||
263 | cpu_dev->of_node = np; | ||
264 | if (of_init_opp_table(cpu_dev)) { | 263 | if (of_init_opp_table(cpu_dev)) { |
265 | pr_warn("failed to init OPP table\n"); | 264 | pr_warn("failed to init OPP table\n"); |
266 | goto put_node; | 265 | goto put_node; |
diff --git a/arch/arm/mach-mvebu/platsmp.c b/arch/arm/mach-mvebu/platsmp.c index ce81d3031405..594b63db4215 100644 --- a/arch/arm/mach-mvebu/platsmp.c +++ b/arch/arm/mach-mvebu/platsmp.c | |||
@@ -29,45 +29,40 @@ | |||
29 | #include "pmsu.h" | 29 | #include "pmsu.h" |
30 | #include "coherency.h" | 30 | #include "coherency.h" |
31 | 31 | ||
32 | static struct clk *__init get_cpu_clk(int cpu) | ||
33 | { | ||
34 | struct clk *cpu_clk; | ||
35 | struct device_node *np = of_get_cpu_node(cpu, NULL); | ||
36 | |||
37 | if (WARN(!np, "missing cpu node\n")) | ||
38 | return NULL; | ||
39 | cpu_clk = of_clk_get(np, 0); | ||
40 | if (WARN_ON(IS_ERR(cpu_clk))) | ||
41 | return NULL; | ||
42 | return cpu_clk; | ||
43 | } | ||
44 | |||
32 | void __init set_secondary_cpus_clock(void) | 45 | void __init set_secondary_cpus_clock(void) |
33 | { | 46 | { |
34 | int thiscpu; | 47 | int thiscpu, cpu; |
35 | unsigned long rate; | 48 | unsigned long rate; |
36 | struct clk *cpu_clk = NULL; | 49 | struct clk *cpu_clk; |
37 | struct device_node *np = NULL; | ||
38 | 50 | ||
39 | thiscpu = smp_processor_id(); | 51 | thiscpu = smp_processor_id(); |
40 | for_each_node_by_type(np, "cpu") { | 52 | cpu_clk = get_cpu_clk(thiscpu); |
41 | int err; | 53 | if (!cpu_clk) |
42 | int cpu; | ||
43 | |||
44 | err = of_property_read_u32(np, "reg", &cpu); | ||
45 | if (WARN_ON(err)) | ||
46 | return; | ||
47 | |||
48 | if (cpu == thiscpu) { | ||
49 | cpu_clk = of_clk_get(np, 0); | ||
50 | break; | ||
51 | } | ||
52 | } | ||
53 | if (WARN_ON(IS_ERR(cpu_clk))) | ||
54 | return; | 54 | return; |
55 | clk_prepare_enable(cpu_clk); | 55 | clk_prepare_enable(cpu_clk); |
56 | rate = clk_get_rate(cpu_clk); | 56 | rate = clk_get_rate(cpu_clk); |
57 | 57 | ||
58 | /* set all the other CPU clk to the same rate than the boot CPU */ | 58 | /* set all the other CPU clk to the same rate than the boot CPU */ |
59 | for_each_node_by_type(np, "cpu") { | 59 | for_each_possible_cpu(cpu) { |
60 | int err; | 60 | if (cpu == thiscpu) |
61 | int cpu; | 61 | continue; |
62 | 62 | cpu_clk = get_cpu_clk(cpu); | |
63 | err = of_property_read_u32(np, "reg", &cpu); | 63 | if (!cpu_clk) |
64 | if (WARN_ON(err)) | ||
65 | return; | 64 | return; |
66 | 65 | clk_set_rate(cpu_clk, rate); | |
67 | if (cpu != thiscpu) { | ||
68 | cpu_clk = of_clk_get(np, 0); | ||
69 | clk_set_rate(cpu_clk, rate); | ||
70 | } | ||
71 | } | 66 | } |
72 | } | 67 | } |
73 | 68 | ||