aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/sparc64/kernel/chmc.c69
1 files changed, 25 insertions, 44 deletions
diff --git a/arch/sparc64/kernel/chmc.c b/arch/sparc64/kernel/chmc.c
index 97cf912f0853..259f37e516f5 100644
--- a/arch/sparc64/kernel/chmc.c
+++ b/arch/sparc64/kernel/chmc.c
@@ -17,6 +17,7 @@
17#include <asm/spitfire.h> 17#include <asm/spitfire.h>
18#include <asm/chmctrl.h> 18#include <asm/chmctrl.h>
19#include <asm/oplib.h> 19#include <asm/oplib.h>
20#include <asm/prom.h>
20#include <asm/io.h> 21#include <asm/io.h>
21 22
22#define CHMCTRL_NDGRPS 2 23#define CHMCTRL_NDGRPS 2
@@ -67,7 +68,6 @@ struct bank_info {
67struct mctrl_info { 68struct mctrl_info {
68 struct list_head list; 69 struct list_head list;
69 int portid; 70 int portid;
70 int index;
71 71
72 struct obp_mem_layout layout_prop; 72 struct obp_mem_layout layout_prop;
73 int layout_size; 73 int layout_size;
@@ -339,12 +339,13 @@ static void fetch_decode_regs(struct mctrl_info *mp)
339 read_mcreg(mp, CHMCTRL_DECODE4)); 339 read_mcreg(mp, CHMCTRL_DECODE4));
340} 340}
341 341
342static int init_one_mctrl(int node, int index) 342static int init_one_mctrl(struct device_node *dp)
343{ 343{
344 struct mctrl_info *mp = kmalloc(sizeof(*mp), GFP_KERNEL); 344 struct mctrl_info *mp = kmalloc(sizeof(*mp), GFP_KERNEL);
345 int portid = prom_getintdefault(node, "portid", -1); 345 int portid = of_getintprop_default(dp, "portid", -1);
346 struct linux_prom64_registers p_reg_prop; 346 struct linux_prom64_registers *regs;
347 int t; 347 void *pval;
348 int len;
348 349
349 if (!mp) 350 if (!mp)
350 return -1; 351 return -1;
@@ -353,24 +354,21 @@ static int init_one_mctrl(int node, int index)
353 goto fail; 354 goto fail;
354 355
355 mp->portid = portid; 356 mp->portid = portid;
356 mp->layout_size = prom_getproplen(node, "memory-layout"); 357 pval = of_get_property(dp, "memory-layout", &len);
357 if (mp->layout_size < 0) 358 mp->layout_size = len;
359 if (!pval)
358 mp->layout_size = 0; 360 mp->layout_size = 0;
359 if (mp->layout_size > sizeof(mp->layout_prop)) 361 else {
360 goto fail; 362 if (mp->layout_size > sizeof(mp->layout_prop))
361 363 goto fail;
362 if (mp->layout_size > 0) 364 memcpy(&mp->layout_prop, pval, len);
363 prom_getproperty(node, "memory-layout", 365 }
364 (char *) &mp->layout_prop,
365 mp->layout_size);
366 366
367 t = prom_getproperty(node, "reg", 367 regs = of_get_property(dp, "reg", NULL);
368 (char *) &p_reg_prop, 368 if (!regs || regs->reg_size != 0x48)
369 sizeof(p_reg_prop));
370 if (t < 0 || p_reg_prop.reg_size != 0x48)
371 goto fail; 369 goto fail;
372 370
373 mp->regs = ioremap(p_reg_prop.phys_addr, p_reg_prop.reg_size); 371 mp->regs = ioremap(regs->phys_addr, regs->reg_size);
374 if (mp->regs == NULL) 372 if (mp->regs == NULL)
375 goto fail; 373 goto fail;
376 374
@@ -384,13 +382,11 @@ static int init_one_mctrl(int node, int index)
384 382
385 fetch_decode_regs(mp); 383 fetch_decode_regs(mp);
386 384
387 mp->index = index;
388
389 list_add(&mp->list, &mctrl_list); 385 list_add(&mp->list, &mctrl_list);
390 386
391 /* Report the device. */ 387 /* Report the device. */
392 printk(KERN_INFO "chmc%d: US3 memory controller at %p [%s]\n", 388 printk(KERN_INFO "%s: US3 memory controller at %p [%s]\n",
393 mp->index, 389 dp->full_name,
394 mp->regs, (mp->layout_size ? "ACTIVE" : "INACTIVE")); 390 mp->regs, (mp->layout_size ? "ACTIVE" : "INACTIVE"));
395 391
396 return 0; 392 return 0;
@@ -404,34 +400,19 @@ fail:
404 return -1; 400 return -1;
405} 401}
406 402
407static int __init probe_for_string(char *name, int index)
408{
409 int node = prom_getchild(prom_root_node);
410
411 while ((node = prom_searchsiblings(node, name)) != 0) {
412 int ret = init_one_mctrl(node, index);
413
414 if (!ret)
415 index++;
416
417 node = prom_getsibling(node);
418 if (!node)
419 break;
420 }
421
422 return index;
423}
424
425static int __init chmc_init(void) 403static int __init chmc_init(void)
426{ 404{
427 int index; 405 struct device_node *dp;
428 406
429 /* This driver is only for cheetah platforms. */ 407 /* This driver is only for cheetah platforms. */
430 if (tlb_type != cheetah && tlb_type != cheetah_plus) 408 if (tlb_type != cheetah && tlb_type != cheetah_plus)
431 return -ENODEV; 409 return -ENODEV;
432 410
433 index = probe_for_string("memory-controller", 0); 411 for_each_node_by_name(dp, "memory-controller")
434 index = probe_for_string("mc-us3", index); 412 init_one_mctrl(dp);
413
414 for_each_node_by_name(dp, "mc-us3")
415 init_one_mctrl(dp);
435 416
436 return 0; 417 return 0;
437} 418}