aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel/devices.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@sunset.davemloft.net>2006-06-22 02:34:02 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2006-06-24 02:15:17 -0400
commit07f8e5f358a0b7240f1dad6b3819f2fd1103f159 (patch)
tree5976cc05de92f27a9cc12a3db31ced5311ac3769 /arch/sparc64/kernel/devices.c
parent6d307724cb6a6b8466cad4fdf13d8a409bc2433f (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.c118
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
136static int get_cpu_mid(int prom_node) 136static 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 *) &reg, 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
153static int check_cpu_node(int nd, int *cur_inst, 161static 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
176static int __cpu_find_by(int (*compare)(int, int, void *), void *compare_arg, 182static 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
202static int cpu_instance_compare(int nd, int instance, void *_arg) 201static 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
211int cpu_find_by_instance(int instance, int *prom_node, int *mid) 210int 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
217static int cpu_mid_compare(int nd, int instance, void *_arg) 216static 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
228int cpu_find_by_mid(int mid, int *prom_node) 227int 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
234void __init device_scan(void) 233void __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)] "