diff options
author | David S. Miller <davem@sunset.davemloft.net> | 2006-06-22 02:34:02 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-06-24 02:15:17 -0400 |
commit | 07f8e5f358a0b7240f1dad6b3819f2fd1103f159 (patch) | |
tree | 5976cc05de92f27a9cc12a3db31ced5311ac3769 /arch/sparc64/kernel/devices.c | |
parent | 6d307724cb6a6b8466cad4fdf13d8a409bc2433f (diff) |
[SPARC64]: Convert cpu_find_by_*() interface to in-kernel PROM device tree.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc64/kernel/devices.c')
-rw-r--r-- | arch/sparc64/kernel/devices.c | 118 |
1 files changed, 57 insertions, 61 deletions
diff --git a/arch/sparc64/kernel/devices.c b/arch/sparc64/kernel/devices.c index 136f872a8a57..389301c95cb2 100644 --- a/arch/sparc64/kernel/devices.c +++ b/arch/sparc64/kernel/devices.c | |||
@@ -133,38 +133,44 @@ static const char *cpu_mid_prop(void) | |||
133 | return "portid"; | 133 | return "portid"; |
134 | } | 134 | } |
135 | 135 | ||
136 | static int get_cpu_mid(int prom_node) | 136 | static int get_cpu_mid(struct device_node *dp) |
137 | { | 137 | { |
138 | struct property *prop; | ||
139 | |||
138 | if (tlb_type == hypervisor) { | 140 | if (tlb_type == hypervisor) { |
139 | struct linux_prom64_registers reg; | 141 | struct linux_prom64_registers *reg; |
142 | int len; | ||
140 | 143 | ||
141 | if (prom_getproplen(prom_node, "cpuid") == 4) | 144 | prop = of_find_property(dp, "cpuid", &len); |
142 | return prom_getintdefault(prom_node, "cpuid", 0); | 145 | if (prop && len == 4) |
146 | return *(int *) prop->value; | ||
143 | 147 | ||
144 | prom_getproperty(prom_node, "reg", (char *) ®, sizeof(reg)); | 148 | prop = of_find_property(dp, "reg", NULL); |
145 | return (reg.phys_addr >> 32) & 0x0fffffffUL; | 149 | reg = prop->value; |
150 | return (reg[0].phys_addr >> 32) & 0x0fffffffUL; | ||
146 | } else { | 151 | } else { |
147 | const char *prop_name = cpu_mid_prop(); | 152 | const char *prop_name = cpu_mid_prop(); |
148 | 153 | ||
149 | return prom_getintdefault(prom_node, prop_name, 0); | 154 | prop = of_find_property(dp, prop_name, NULL); |
155 | if (prop) | ||
156 | return *(int *) prop->value; | ||
157 | return 0; | ||
150 | } | 158 | } |
151 | } | 159 | } |
152 | 160 | ||
153 | static int check_cpu_node(int nd, int *cur_inst, | 161 | static int check_cpu_node(struct device_node *dp, int *cur_inst, |
154 | int (*compare)(int, int, void *), void *compare_arg, | 162 | int (*compare)(struct device_node *, int, void *), |
155 | int *prom_node, int *mid) | 163 | void *compare_arg, |
164 | struct device_node **dev_node, int *mid) | ||
156 | { | 165 | { |
157 | char node_str[128]; | 166 | if (strcmp(dp->type, "cpu")) |
158 | |||
159 | prom_getstring(nd, "device_type", node_str, sizeof(node_str)); | ||
160 | if (strcmp(node_str, "cpu")) | ||
161 | return -ENODEV; | 167 | return -ENODEV; |
162 | 168 | ||
163 | if (!compare(nd, *cur_inst, compare_arg)) { | 169 | if (!compare(dp, *cur_inst, compare_arg)) { |
164 | if (prom_node) | 170 | if (dev_node) |
165 | *prom_node = nd; | 171 | *dev_node = dp; |
166 | if (mid) | 172 | if (mid) |
167 | *mid = get_cpu_mid(nd); | 173 | *mid = get_cpu_mid(dp); |
168 | return 0; | 174 | return 0; |
169 | } | 175 | } |
170 | 176 | ||
@@ -173,25 +179,18 @@ static int check_cpu_node(int nd, int *cur_inst, | |||
173 | return -ENODEV; | 179 | return -ENODEV; |
174 | } | 180 | } |
175 | 181 | ||
176 | static int __cpu_find_by(int (*compare)(int, int, void *), void *compare_arg, | 182 | static int __cpu_find_by(int (*compare)(struct device_node *, int, void *), |
177 | int *prom_node, int *mid) | 183 | void *compare_arg, |
184 | struct device_node **dev_node, int *mid) | ||
178 | { | 185 | { |
179 | int nd, cur_inst, err; | 186 | struct device_node *dp; |
187 | int cur_inst; | ||
180 | 188 | ||
181 | nd = prom_root_node; | ||
182 | cur_inst = 0; | 189 | cur_inst = 0; |
183 | 190 | for_each_node_by_type(dp, "cpu") { | |
184 | err = check_cpu_node(nd, &cur_inst, | 191 | int err = check_cpu_node(dp, &cur_inst, |
185 | compare, compare_arg, | 192 | compare, compare_arg, |
186 | prom_node, mid); | 193 | dev_node, mid); |
187 | if (err == 0) | ||
188 | return 0; | ||
189 | |||
190 | nd = prom_getchild(nd); | ||
191 | while ((nd = prom_getsibling(nd)) != 0) { | ||
192 | err = check_cpu_node(nd, &cur_inst, | ||
193 | compare, compare_arg, | ||
194 | prom_node, mid); | ||
195 | if (err == 0) | 194 | if (err == 0) |
196 | return 0; | 195 | return 0; |
197 | } | 196 | } |
@@ -199,7 +198,7 @@ static int __cpu_find_by(int (*compare)(int, int, void *), void *compare_arg, | |||
199 | return -ENODEV; | 198 | return -ENODEV; |
200 | } | 199 | } |
201 | 200 | ||
202 | static int cpu_instance_compare(int nd, int instance, void *_arg) | 201 | static int cpu_instance_compare(struct device_node *dp, int instance, void *_arg) |
203 | { | 202 | { |
204 | int desired_instance = (int) (long) _arg; | 203 | int desired_instance = (int) (long) _arg; |
205 | 204 | ||
@@ -208,27 +207,27 @@ static int cpu_instance_compare(int nd, int instance, void *_arg) | |||
208 | return -ENODEV; | 207 | return -ENODEV; |
209 | } | 208 | } |
210 | 209 | ||
211 | int cpu_find_by_instance(int instance, int *prom_node, int *mid) | 210 | int cpu_find_by_instance(int instance, struct device_node **dev_node, int *mid) |
212 | { | 211 | { |
213 | return __cpu_find_by(cpu_instance_compare, (void *)(long)instance, | 212 | return __cpu_find_by(cpu_instance_compare, (void *)(long)instance, |
214 | prom_node, mid); | 213 | dev_node, mid); |
215 | } | 214 | } |
216 | 215 | ||
217 | static int cpu_mid_compare(int nd, int instance, void *_arg) | 216 | static int cpu_mid_compare(struct device_node *dp, int instance, void *_arg) |
218 | { | 217 | { |
219 | int desired_mid = (int) (long) _arg; | 218 | int desired_mid = (int) (long) _arg; |
220 | int this_mid; | 219 | int this_mid; |
221 | 220 | ||
222 | this_mid = get_cpu_mid(nd); | 221 | this_mid = get_cpu_mid(dp); |
223 | if (this_mid == desired_mid) | 222 | if (this_mid == desired_mid) |
224 | return 0; | 223 | return 0; |
225 | return -ENODEV; | 224 | return -ENODEV; |
226 | } | 225 | } |
227 | 226 | ||
228 | int cpu_find_by_mid(int mid, int *prom_node) | 227 | int cpu_find_by_mid(int mid, struct device_node **dev_node) |
229 | { | 228 | { |
230 | return __cpu_find_by(cpu_mid_compare, (void *)(long)mid, | 229 | return __cpu_find_by(cpu_mid_compare, (void *)(long)mid, |
231 | prom_node, NULL); | 230 | dev_node, NULL); |
232 | } | 231 | } |
233 | 232 | ||
234 | void __init device_scan(void) | 233 | void __init device_scan(void) |
@@ -240,50 +239,47 @@ void __init device_scan(void) | |||
240 | 239 | ||
241 | #ifndef CONFIG_SMP | 240 | #ifndef CONFIG_SMP |
242 | { | 241 | { |
243 | int err, cpu_node, def; | 242 | struct device_node *dp; |
243 | int err, def; | ||
244 | 244 | ||
245 | err = cpu_find_by_instance(0, &cpu_node, NULL); | 245 | err = cpu_find_by_instance(0, &dp, NULL); |
246 | if (err) { | 246 | if (err) { |
247 | prom_printf("No cpu nodes, cannot continue\n"); | 247 | prom_printf("No cpu nodes, cannot continue\n"); |
248 | prom_halt(); | 248 | prom_halt(); |
249 | } | 249 | } |
250 | cpu_data(0).clock_tick = prom_getintdefault(cpu_node, | 250 | cpu_data(0).clock_tick = |
251 | "clock-frequency", | 251 | of_getintprop_default(dp, "clock-frequency", 0); |
252 | 0); | ||
253 | 252 | ||
254 | def = ((tlb_type == hypervisor) ? | 253 | def = ((tlb_type == hypervisor) ? |
255 | (8 * 1024) : | 254 | (8 * 1024) : |
256 | (16 * 1024)); | 255 | (16 * 1024)); |
257 | cpu_data(0).dcache_size = prom_getintdefault(cpu_node, | 256 | cpu_data(0).dcache_size = of_getintprop_default(dp, |
258 | "dcache-size", | 257 | "dcache-size", |
259 | def); | 258 | def); |
260 | 259 | ||
261 | def = 32; | 260 | def = 32; |
262 | cpu_data(0).dcache_line_size = | 261 | cpu_data(0).dcache_line_size = |
263 | prom_getintdefault(cpu_node, "dcache-line-size", | 262 | of_getintprop_default(dp, "dcache-line-size", def); |
264 | def); | ||
265 | 263 | ||
266 | def = 16 * 1024; | 264 | def = 16 * 1024; |
267 | cpu_data(0).icache_size = prom_getintdefault(cpu_node, | 265 | cpu_data(0).icache_size = of_getintprop_default(dp, |
268 | "icache-size", | 266 | "icache-size", |
269 | def); | 267 | def); |
270 | 268 | ||
271 | def = 32; | 269 | def = 32; |
272 | cpu_data(0).icache_line_size = | 270 | cpu_data(0).icache_line_size = |
273 | prom_getintdefault(cpu_node, "icache-line-size", | 271 | of_getintprop_default(dp, "icache-line-size", def); |
274 | def); | ||
275 | 272 | ||
276 | def = ((tlb_type == hypervisor) ? | 273 | def = ((tlb_type == hypervisor) ? |
277 | (3 * 1024 * 1024) : | 274 | (3 * 1024 * 1024) : |
278 | (4 * 1024 * 1024)); | 275 | (4 * 1024 * 1024)); |
279 | cpu_data(0).ecache_size = prom_getintdefault(cpu_node, | 276 | cpu_data(0).ecache_size = of_getintprop_default(dp, |
280 | "ecache-size", | 277 | "ecache-size", |
281 | def); | 278 | def); |
282 | 279 | ||
283 | def = 64; | 280 | def = 64; |
284 | cpu_data(0).ecache_line_size = | 281 | cpu_data(0).ecache_line_size = |
285 | prom_getintdefault(cpu_node, "ecache-line-size", | 282 | of_getintprop_default(dp, "ecache-line-size", def); |
286 | def); | ||
287 | printk("CPU[0]: Caches " | 283 | printk("CPU[0]: Caches " |
288 | "D[sz(%d):line_sz(%d)] " | 284 | "D[sz(%d):line_sz(%d)] " |
289 | "I[sz(%d):line_sz(%d)] " | 285 | "I[sz(%d):line_sz(%d)] " |