diff options
| -rw-r--r-- | arch/powerpc/platforms/chrp/chrp.h | 2 | ||||
| -rw-r--r-- | arch/powerpc/platforms/chrp/setup.c | 64 | ||||
| -rw-r--r-- | include/asm-powerpc/machdep.h | 4 |
3 files changed, 46 insertions, 24 deletions
diff --git a/arch/powerpc/platforms/chrp/chrp.h b/arch/powerpc/platforms/chrp/chrp.h index 814f54742e0f..63f0aee4c158 100644 --- a/arch/powerpc/platforms/chrp/chrp.h +++ b/arch/powerpc/platforms/chrp/chrp.h | |||
| @@ -8,4 +8,4 @@ extern int chrp_set_rtc_time(struct rtc_time *); | |||
| 8 | extern long chrp_time_init(void); | 8 | extern long chrp_time_init(void); |
| 9 | 9 | ||
| 10 | extern void chrp_find_bridges(void); | 10 | extern void chrp_find_bridges(void); |
| 11 | extern void chrp_event_scan(void); | 11 | extern void chrp_event_scan(unsigned long); |
diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c index 8bf4307e323d..9c718bb2305e 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,21 +290,6 @@ 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 | ||
| 307 | /* | 295 | /* |
| @@ -312,7 +300,7 @@ void __init chrp_setup_arch(void) | |||
| 312 | } | 300 | } |
| 313 | 301 | ||
| 314 | void | 302 | void |
| 315 | chrp_event_scan(void) | 303 | chrp_event_scan(unsigned long unused) |
| 316 | { | 304 | { |
| 317 | unsigned char log[1024]; | 305 | unsigned char log[1024]; |
| 318 | int ret = 0; | 306 | int ret = 0; |
| @@ -320,7 +308,8 @@ chrp_event_scan(void) | |||
| 320 | /* XXX: we should loop until the hardware says no more error logs -- Cort */ | 308 | /* 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, | 309 | rtas_call(rtas_token("event-scan"), 4, 1, &ret, 0xffffffff, 0, |
| 322 | __pa(log), 1024); | 310 | __pa(log), 1024); |
| 323 | ppc_md.heartbeat_count = ppc_md.heartbeat_reset; | 311 | mod_timer(&__get_cpu_var(heartbeat_timer), |
| 312 | jiffies + event_scan_interval); | ||
| 324 | } | 313 | } |
| 325 | 314 | ||
| 326 | /* | 315 | /* |
| @@ -465,6 +454,9 @@ void __init chrp_init_IRQ(void) | |||
| 465 | void __init | 454 | void __init |
| 466 | chrp_init2(void) | 455 | chrp_init2(void) |
| 467 | { | 456 | { |
| 457 | struct device_node *device; | ||
| 458 | unsigned int *p = NULL; | ||
| 459 | |||
| 468 | #ifdef CONFIG_NVRAM | 460 | #ifdef CONFIG_NVRAM |
| 469 | chrp_nvram_init(); | 461 | chrp_nvram_init(); |
| 470 | #endif | 462 | #endif |
| @@ -476,6 +468,40 @@ chrp_init2(void) | |||
| 476 | request_region(0x80,0x10,"dma page reg"); | 468 | request_region(0x80,0x10,"dma page reg"); |
| 477 | request_region(0xc0,0x20,"dma2"); | 469 | request_region(0xc0,0x20,"dma2"); |
| 478 | 470 | ||
| 471 | /* Get the event scan rate for the rtas so we know how | ||
| 472 | * often it expects a heartbeat. -- Cort | ||
| 473 | */ | ||
| 474 | device = find_devices("rtas"); | ||
| 475 | if (device) | ||
| 476 | p = (unsigned int *) get_property | ||
| 477 | (device, "rtas-event-scan-rate", NULL); | ||
| 478 | if (p && *p) { | ||
| 479 | /* | ||
| 480 | * Arrange to call chrp_event_scan at least *p times | ||
| 481 | * per minute. We use 59 rather than 60 here so that | ||
| 482 | * the rate will be slightly higher than the minimum. | ||
| 483 | * This all assumes we don't do hotplug CPU on any | ||
| 484 | * machine that needs the event scans done. | ||
| 485 | */ | ||
| 486 | unsigned long interval, offset; | ||
| 487 | int cpu, ncpus; | ||
| 488 | struct timer_list *timer; | ||
| 489 | |||
| 490 | interval = HZ * 59 / *p; | ||
| 491 | offset = HZ; | ||
| 492 | ncpus = num_online_cpus(); | ||
| 493 | event_scan_interval = ncpus * interval; | ||
| 494 | for (cpu = 0; cpu < ncpus; ++cpu) { | ||
| 495 | timer = &per_cpu(heartbeat_timer, cpu); | ||
| 496 | setup_timer(timer, chrp_event_scan, 0); | ||
| 497 | timer->expires = jiffies + offset; | ||
| 498 | add_timer_on(timer, cpu); | ||
| 499 | offset += interval; | ||
| 500 | } | ||
| 501 | printk("RTAS Event Scan Rate: %u (%lu jiffies)\n", | ||
| 502 | *p, interval); | ||
| 503 | } | ||
| 504 | |||
| 479 | if (ppc_md.progress) | 505 | if (ppc_md.progress) |
| 480 | ppc_md.progress(" Have fun! ", 0x7777); | 506 | ppc_md.progress(" Have fun! ", 0x7777); |
| 481 | } | 507 | } |
diff --git a/include/asm-powerpc/machdep.h b/include/asm-powerpc/machdep.h index 21c8dc90d175..758e47fe8c1e 100644 --- a/include/asm-powerpc/machdep.h +++ b/include/asm-powerpc/machdep.h | |||
| @@ -176,10 +176,6 @@ struct machdep_calls { | |||
| 176 | May be NULL. */ | 176 | May be NULL. */ |
| 177 | void (*init)(void); | 177 | void (*init)(void); |
| 178 | 178 | ||
| 179 | void (*heartbeat)(void); | ||
| 180 | unsigned long heartbeat_reset; | ||
| 181 | unsigned long heartbeat_count; | ||
| 182 | |||
| 183 | void (*setup_io_mappings)(void); | 179 | void (*setup_io_mappings)(void); |
| 184 | 180 | ||
| 185 | void (*early_serial_map)(void); | 181 | void (*early_serial_map)(void); |
