diff options
-rw-r--r-- | arch/arm/kernel/topology.c | 61 |
1 files changed, 19 insertions, 42 deletions
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, |