diff options
Diffstat (limited to 'arch/powerpc/platforms/chrp/setup.c')
-rw-r--r-- | arch/powerpc/platforms/chrp/setup.c | 77 |
1 files changed, 57 insertions, 20 deletions
diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c index 8bf4307e323d..23a201718704 100644 --- a/arch/powerpc/platforms/chrp/setup.c +++ b/arch/powerpc/platforms/chrp/setup.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/root_dev.h> | 35 | #include <linux/root_dev.h> |
36 | #include <linux/initrd.h> | 36 | #include <linux/initrd.h> |
37 | #include <linux/module.h> | 37 | #include <linux/module.h> |
38 | #include <linux/timer.h> | ||
38 | 39 | ||
39 | #include <asm/io.h> | 40 | #include <asm/io.h> |
40 | #include <asm/pgtable.h> | 41 | #include <asm/pgtable.h> |
@@ -61,6 +62,10 @@ EXPORT_SYMBOL(_chrp_type); | |||
61 | 62 | ||
62 | struct mpic *chrp_mpic; | 63 | struct mpic *chrp_mpic; |
63 | 64 | ||
65 | /* Used for doing CHRP event-scans */ | ||
66 | DEFINE_PER_CPU(struct timer_list, heartbeat_timer); | ||
67 | unsigned long event_scan_interval; | ||
68 | |||
64 | /* | 69 | /* |
65 | * XXX this should be in xmon.h, but putting it there means xmon.h | 70 | * XXX this should be in xmon.h, but putting it there means xmon.h |
66 | * has to include <linux/interrupt.h> (to get irqreturn_t), which | 71 | * has to include <linux/interrupt.h> (to get irqreturn_t), which |
@@ -229,8 +234,6 @@ void __init chrp_setup_arch(void) | |||
229 | { | 234 | { |
230 | struct device_node *root = find_path_device ("/"); | 235 | struct device_node *root = find_path_device ("/"); |
231 | char *machine = NULL; | 236 | char *machine = NULL; |
232 | struct device_node *device; | ||
233 | unsigned int *p = NULL; | ||
234 | 237 | ||
235 | /* init to some ~sane value until calibrate_delay() runs */ | 238 | /* init to some ~sane value until calibrate_delay() runs */ |
236 | loops_per_jiffy = 50000000/HZ; | 239 | loops_per_jiffy = 50000000/HZ; |
@@ -287,23 +290,12 @@ void __init chrp_setup_arch(void) | |||
287 | */ | 290 | */ |
288 | sio_init(); | 291 | sio_init(); |
289 | 292 | ||
290 | /* Get the event scan rate for the rtas so we know how | ||
291 | * often it expects a heartbeat. -- Cort | ||
292 | */ | ||
293 | device = find_devices("rtas"); | ||
294 | if (device) | ||
295 | p = (unsigned int *) get_property | ||
296 | (device, "rtas-event-scan-rate", NULL); | ||
297 | if (p && *p) { | ||
298 | ppc_md.heartbeat = chrp_event_scan; | ||
299 | ppc_md.heartbeat_reset = HZ / (*p * 30) - 1; | ||
300 | ppc_md.heartbeat_count = 1; | ||
301 | printk("RTAS Event Scan Rate: %u (%lu jiffies)\n", | ||
302 | *p, ppc_md.heartbeat_reset); | ||
303 | } | ||
304 | |||
305 | pci_create_OF_bus_map(); | 293 | pci_create_OF_bus_map(); |
306 | 294 | ||
295 | #ifdef CONFIG_SMP | ||
296 | smp_ops = &chrp_smp_ops; | ||
297 | #endif /* CONFIG_SMP */ | ||
298 | |||
307 | /* | 299 | /* |
308 | * Print the banner, then scroll down so boot progress | 300 | * Print the banner, then scroll down so boot progress |
309 | * can be printed. -- Cort | 301 | * can be printed. -- Cort |
@@ -312,7 +304,7 @@ void __init chrp_setup_arch(void) | |||
312 | } | 304 | } |
313 | 305 | ||
314 | void | 306 | void |
315 | chrp_event_scan(void) | 307 | chrp_event_scan(unsigned long unused) |
316 | { | 308 | { |
317 | unsigned char log[1024]; | 309 | unsigned char log[1024]; |
318 | int ret = 0; | 310 | int ret = 0; |
@@ -320,7 +312,8 @@ chrp_event_scan(void) | |||
320 | /* XXX: we should loop until the hardware says no more error logs -- Cort */ | 312 | /* XXX: we should loop until the hardware says no more error logs -- Cort */ |
321 | rtas_call(rtas_token("event-scan"), 4, 1, &ret, 0xffffffff, 0, | 313 | rtas_call(rtas_token("event-scan"), 4, 1, &ret, 0xffffffff, 0, |
322 | __pa(log), 1024); | 314 | __pa(log), 1024); |
323 | ppc_md.heartbeat_count = ppc_md.heartbeat_reset; | 315 | mod_timer(&__get_cpu_var(heartbeat_timer), |
316 | jiffies + event_scan_interval); | ||
324 | } | 317 | } |
325 | 318 | ||
326 | /* | 319 | /* |
@@ -465,6 +458,9 @@ void __init chrp_init_IRQ(void) | |||
465 | void __init | 458 | void __init |
466 | chrp_init2(void) | 459 | chrp_init2(void) |
467 | { | 460 | { |
461 | struct device_node *device; | ||
462 | unsigned int *p = NULL; | ||
463 | |||
468 | #ifdef CONFIG_NVRAM | 464 | #ifdef CONFIG_NVRAM |
469 | chrp_nvram_init(); | 465 | chrp_nvram_init(); |
470 | #endif | 466 | #endif |
@@ -476,12 +472,53 @@ chrp_init2(void) | |||
476 | request_region(0x80,0x10,"dma page reg"); | 472 | request_region(0x80,0x10,"dma page reg"); |
477 | request_region(0xc0,0x20,"dma2"); | 473 | request_region(0xc0,0x20,"dma2"); |
478 | 474 | ||
475 | /* Get the event scan rate for the rtas so we know how | ||
476 | * often it expects a heartbeat. -- Cort | ||
477 | */ | ||
478 | device = find_devices("rtas"); | ||
479 | if (device) | ||
480 | p = (unsigned int *) get_property | ||
481 | (device, "rtas-event-scan-rate", NULL); | ||
482 | if (p && *p) { | ||
483 | /* | ||
484 | * Arrange to call chrp_event_scan at least *p times | ||
485 | * per minute. We use 59 rather than 60 here so that | ||
486 | * the rate will be slightly higher than the minimum. | ||
487 | * This all assumes we don't do hotplug CPU on any | ||
488 | * machine that needs the event scans done. | ||
489 | */ | ||
490 | unsigned long interval, offset; | ||
491 | int cpu, ncpus; | ||
492 | struct timer_list *timer; | ||
493 | |||
494 | interval = HZ * 59 / *p; | ||
495 | offset = HZ; | ||
496 | ncpus = num_online_cpus(); | ||
497 | event_scan_interval = ncpus * interval; | ||
498 | for (cpu = 0; cpu < ncpus; ++cpu) { | ||
499 | timer = &per_cpu(heartbeat_timer, cpu); | ||
500 | setup_timer(timer, chrp_event_scan, 0); | ||
501 | timer->expires = jiffies + offset; | ||
502 | add_timer_on(timer, cpu); | ||
503 | offset += interval; | ||
504 | } | ||
505 | printk("RTAS Event Scan Rate: %u (%lu jiffies)\n", | ||
506 | *p, interval); | ||
507 | } | ||
508 | |||
479 | if (ppc_md.progress) | 509 | if (ppc_md.progress) |
480 | ppc_md.progress(" Have fun! ", 0x7777); | 510 | ppc_md.progress(" Have fun! ", 0x7777); |
481 | } | 511 | } |
482 | 512 | ||
483 | void __init chrp_init(void) | 513 | static int __init chrp_probe(void) |
484 | { | 514 | { |
515 | char *dtype = of_get_flat_dt_prop(of_get_flat_dt_root(), | ||
516 | "device_type", NULL); | ||
517 | if (dtype == NULL) | ||
518 | return 0; | ||
519 | if (strcmp(dtype, "chrp")) | ||
520 | return 0; | ||
521 | |||
485 | ISA_DMA_THRESHOLD = ~0L; | 522 | ISA_DMA_THRESHOLD = ~0L; |
486 | DMA_MODE_READ = 0x44; | 523 | DMA_MODE_READ = 0x44; |
487 | DMA_MODE_WRITE = 0x48; | 524 | DMA_MODE_WRITE = 0x48; |