diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/sparc64/kernel/chmc.c | 69 |
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 { | |||
67 | struct mctrl_info { | 68 | struct 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 | ||
342 | static int init_one_mctrl(int node, int index) | 342 | static 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 | ||
407 | static 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 | |||
425 | static int __init chmc_init(void) | 403 | static 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 | } |