aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2009-09-24 15:30:05 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2009-10-30 02:20:53 -0400
commit3d541c4b7f6efd55a98189afd1b2f1c9d048c1b3 (patch)
tree37ea005412feedefe836afd0752051b0c93f4f71
parent188917e183cf9ad0374b571006d0fc6d48a7f447 (diff)
powerpc/chrp: Use the same RTAS daemon as pSeries
The CHRP code has some fishy timer based code to scan the RTAS event log, which uses a 1KB stack buffer and doesn't even use the results. The pSeries code as a nicer daemon that allows userspace to read the event log and basically uses the same RTAS interface This patch moves rtasd.c out of platform/pseries and makes it usable by CHRP, after removing the old crufty event log mechanism in there. The nvram logging part of the daemon is still only available on 64-bit since the underlying nvram management routines aren't currently shared. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
-rw-r--r--arch/powerpc/kernel/Makefile1
-rw-r--r--arch/powerpc/kernel/rtasd.c (renamed from arch/powerpc/platforms/pseries/rtasd.c)48
-rw-r--r--arch/powerpc/platforms/Kconfig5
-rw-r--r--arch/powerpc/platforms/chrp/Kconfig2
-rw-r--r--arch/powerpc/platforms/chrp/setup.c50
-rw-r--r--arch/powerpc/platforms/pseries/Kconfig1
-rw-r--r--arch/powerpc/platforms/pseries/Makefile2
7 files changed, 44 insertions, 65 deletions
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 3faa39114219..c002b0410219 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -46,6 +46,7 @@ procfs-y := proc_powerpc.o
46obj-$(CONFIG_PROC_FS) += $(procfs-y) 46obj-$(CONFIG_PROC_FS) += $(procfs-y)
47rtaspci-$(CONFIG_PPC64)-$(CONFIG_PCI) := rtas_pci.o 47rtaspci-$(CONFIG_PPC64)-$(CONFIG_PCI) := rtas_pci.o
48obj-$(CONFIG_PPC_RTAS) += rtas.o rtas-rtc.o $(rtaspci-y-y) 48obj-$(CONFIG_PPC_RTAS) += rtas.o rtas-rtc.o $(rtaspci-y-y)
49obj-$(CONFIG_PPC_RTAS_DAEMON) += rtasd.o
49obj-$(CONFIG_RTAS_FLASH) += rtas_flash.o 50obj-$(CONFIG_RTAS_FLASH) += rtas_flash.o
50obj-$(CONFIG_RTAS_PROC) += rtas-proc.o 51obj-$(CONFIG_RTAS_PROC) += rtas-proc.o
51obj-$(CONFIG_LPARCFG) += lparcfg.o 52obj-$(CONFIG_LPARCFG) += lparcfg.o
diff --git a/arch/powerpc/platforms/pseries/rtasd.c b/arch/powerpc/kernel/rtasd.c
index b3cbac855924..2e4832ab2108 100644
--- a/arch/powerpc/platforms/pseries/rtasd.c
+++ b/arch/powerpc/kernel/rtasd.c
@@ -39,6 +39,7 @@ static unsigned long rtas_log_start;
39static unsigned long rtas_log_size; 39static unsigned long rtas_log_size;
40 40
41static int surveillance_timeout = -1; 41static int surveillance_timeout = -1;
42
42static unsigned int rtas_error_log_max; 43static unsigned int rtas_error_log_max;
43static unsigned int rtas_error_log_buffer_max; 44static unsigned int rtas_error_log_buffer_max;
44 45
@@ -213,9 +214,11 @@ void pSeries_log_error(char *buf, unsigned int err_type, int fatal)
213 return; 214 return;
214 } 215 }
215 216
217#ifdef CONFIG_PPC64
216 /* Write error to NVRAM */ 218 /* Write error to NVRAM */
217 if (logging_enabled && !(err_type & ERR_FLAG_BOOT)) 219 if (logging_enabled && !(err_type & ERR_FLAG_BOOT))
218 nvram_write_error_log(buf, len, err_type, error_log_cnt); 220 nvram_write_error_log(buf, len, err_type, error_log_cnt);
221#endif /* CONFIG_PPC64 */
219 222
220 /* 223 /*
221 * rtas errors can occur during boot, and we do want to capture 224 * rtas errors can occur during boot, and we do want to capture
@@ -264,7 +267,6 @@ void pSeries_log_error(char *buf, unsigned int err_type, int fatal)
264 267
265} 268}
266 269
267
268static int rtas_log_open(struct inode * inode, struct file * file) 270static int rtas_log_open(struct inode * inode, struct file * file)
269{ 271{
270 return 0; 272 return 0;
@@ -300,6 +302,7 @@ static ssize_t rtas_log_read(struct file * file, char __user * buf,
300 return -ENOMEM; 302 return -ENOMEM;
301 303
302 spin_lock_irqsave(&rtasd_log_lock, s); 304 spin_lock_irqsave(&rtasd_log_lock, s);
305
303 /* if it's 0, then we know we got the last one (the one in NVRAM) */ 306 /* if it's 0, then we know we got the last one (the one in NVRAM) */
304 while (rtas_log_size == 0) { 307 while (rtas_log_size == 0) {
305 if (file->f_flags & O_NONBLOCK) { 308 if (file->f_flags & O_NONBLOCK) {
@@ -313,7 +316,9 @@ static ssize_t rtas_log_read(struct file * file, char __user * buf,
313 error = -ENODATA; 316 error = -ENODATA;
314 goto out; 317 goto out;
315 } 318 }
319#ifdef CONFIG_PPC64
316 nvram_clear_error_log(); 320 nvram_clear_error_log();
321#endif /* CONFIG_PPC64 */
317 322
318 spin_unlock_irqrestore(&rtasd_log_lock, s); 323 spin_unlock_irqrestore(&rtasd_log_lock, s);
319 error = wait_event_interruptible(rtas_log_wait, rtas_log_size); 324 error = wait_event_interruptible(rtas_log_wait, rtas_log_size);
@@ -427,14 +432,11 @@ static void rtas_event_scan(struct work_struct *w)
427 put_online_cpus(); 432 put_online_cpus();
428} 433}
429 434
430static void start_event_scan(void) 435#ifdef CONFIG_PPC64
436static void retreive_nvram_error_log(void)
431{ 437{
432 unsigned int err_type; 438 unsigned int err_type ;
433 int rc; 439 int rc ;
434
435 printk(KERN_DEBUG "RTAS daemon started\n");
436 pr_debug("rtasd: will sleep for %d milliseconds\n",
437 (30000 / rtas_event_scan_rate));
438 440
439 /* See if we have any error stored in NVRAM */ 441 /* See if we have any error stored in NVRAM */
440 memset(logdata, 0, rtas_error_log_max); 442 memset(logdata, 0, rtas_error_log_max);
@@ -442,12 +444,26 @@ static void start_event_scan(void)
442 &err_type, &error_log_cnt); 444 &err_type, &error_log_cnt);
443 /* We can use rtas_log_buf now */ 445 /* We can use rtas_log_buf now */
444 logging_enabled = 1; 446 logging_enabled = 1;
445
446 if (!rc) { 447 if (!rc) {
447 if (err_type != ERR_FLAG_ALREADY_LOGGED) { 448 if (err_type != ERR_FLAG_ALREADY_LOGGED) {
448 pSeries_log_error(logdata, err_type | ERR_FLAG_BOOT, 0); 449 pSeries_log_error(logdata, err_type | ERR_FLAG_BOOT, 0);
449 } 450 }
450 } 451 }
452}
453#else /* CONFIG_PPC64 */
454static void retreive_nvram_error_log(void)
455{
456}
457#endif /* CONFIG_PPC64 */
458
459static void start_event_scan(void)
460{
461 printk(KERN_DEBUG "RTAS daemon started\n");
462 pr_debug("rtasd: will sleep for %d milliseconds\n",
463 (30000 / rtas_event_scan_rate));
464
465 /* Retreive errors from nvram if any */
466 retreive_nvram_error_log();
451 467
452 schedule_delayed_work_on(first_cpu(cpu_online_map), &event_scan_work, 468 schedule_delayed_work_on(first_cpu(cpu_online_map), &event_scan_work,
453 event_scan_delay); 469 event_scan_delay);
@@ -457,13 +473,13 @@ static int __init rtas_init(void)
457{ 473{
458 struct proc_dir_entry *entry; 474 struct proc_dir_entry *entry;
459 475
460 if (!machine_is(pseries)) 476 if (!machine_is(pseries) && !machine_is(chrp))
461 return 0; 477 return 0;
462 478
463 /* No RTAS */ 479 /* No RTAS */
464 event_scan = rtas_token("event-scan"); 480 event_scan = rtas_token("event-scan");
465 if (event_scan == RTAS_UNKNOWN_SERVICE) { 481 if (event_scan == RTAS_UNKNOWN_SERVICE) {
466 printk(KERN_DEBUG "rtasd: no event-scan on system\n"); 482 printk(KERN_INFO "rtasd: No event-scan on system\n");
467 return -ENODEV; 483 return -ENODEV;
468 } 484 }
469 485
@@ -483,7 +499,7 @@ static int __init rtas_init(void)
483 return -ENOMEM; 499 return -ENOMEM;
484 } 500 }
485 501
486 entry = proc_create("ppc64/rtas/error_log", S_IRUSR, NULL, 502 entry = proc_create("powerpc/rtas/error_log", S_IRUSR, NULL,
487 &proc_rtas_log_operations); 503 &proc_rtas_log_operations);
488 if (!entry) 504 if (!entry)
489 printk(KERN_ERR "Failed to create error_log proc entry\n"); 505 printk(KERN_ERR "Failed to create error_log proc entry\n");
@@ -492,11 +508,16 @@ static int __init rtas_init(void)
492 508
493 return 0; 509 return 0;
494} 510}
511__initcall(rtas_init);
495 512
496static int __init surveillance_setup(char *str) 513static int __init surveillance_setup(char *str)
497{ 514{
498 int i; 515 int i;
499 516
517 /* We only do surveillance on pseries */
518 if (!machine_is(pseries))
519 return 0;
520
500 if (get_option(&str,&i)) { 521 if (get_option(&str,&i)) {
501 if (i >= 0 && i <= 255) 522 if (i >= 0 && i <= 255)
502 surveillance_timeout = i; 523 surveillance_timeout = i;
@@ -504,6 +525,7 @@ static int __init surveillance_setup(char *str)
504 525
505 return 1; 526 return 1;
506} 527}
528__setup("surveillance=", surveillance_setup);
507 529
508static int __init rtasmsgs_setup(char *str) 530static int __init rtasmsgs_setup(char *str)
509{ 531{
@@ -514,6 +536,4 @@ static int __init rtasmsgs_setup(char *str)
514 536
515 return 1; 537 return 1;
516} 538}
517__initcall(rtas_init);
518__setup("surveillance=", surveillance_setup);
519__setup("rtasmsgs=", rtasmsgs_setup); 539__setup("rtasmsgs=", rtasmsgs_setup);
diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig
index 04a8061045c4..56bf12692f37 100644
--- a/arch/powerpc/platforms/Kconfig
+++ b/arch/powerpc/platforms/Kconfig
@@ -86,6 +86,11 @@ config RTAS_ERROR_LOGGING
86 depends on PPC_RTAS 86 depends on PPC_RTAS
87 default n 87 default n
88 88
89config PPC_RTAS_DAEMON
90 bool
91 depends on PPC_RTAS
92 default n
93
89config RTAS_PROC 94config RTAS_PROC
90 bool "Proc interface to RTAS" 95 bool "Proc interface to RTAS"
91 depends on PPC_RTAS 96 depends on PPC_RTAS
diff --git a/arch/powerpc/platforms/chrp/Kconfig b/arch/powerpc/platforms/chrp/Kconfig
index 37d438bd5b7a..bc0b0efdc5fe 100644
--- a/arch/powerpc/platforms/chrp/Kconfig
+++ b/arch/powerpc/platforms/chrp/Kconfig
@@ -5,6 +5,8 @@ config PPC_CHRP
5 select PPC_I8259 5 select PPC_I8259
6 select PPC_INDIRECT_PCI 6 select PPC_INDIRECT_PCI
7 select PPC_RTAS 7 select PPC_RTAS
8 select PPC_RTAS_DAEMON
9 select RTAS_ERROR_LOGGING
8 select PPC_MPC106 10 select PPC_MPC106
9 select PPC_UDBG_16550 11 select PPC_UDBG_16550
10 select PPC_NATIVE 12 select PPC_NATIVE
diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c
index cd4ad9aea760..52f3df3b4ca0 100644
--- a/arch/powerpc/platforms/chrp/setup.c
+++ b/arch/powerpc/platforms/chrp/setup.c
@@ -364,19 +364,6 @@ void __init chrp_setup_arch(void)
364 if (ppc_md.progress) ppc_md.progress("Linux/PPC "UTS_RELEASE"\n", 0x0); 364 if (ppc_md.progress) ppc_md.progress("Linux/PPC "UTS_RELEASE"\n", 0x0);
365} 365}
366 366
367void
368chrp_event_scan(unsigned long unused)
369{
370 unsigned char log[1024];
371 int ret = 0;
372
373 /* XXX: we should loop until the hardware says no more error logs -- Cort */
374 rtas_call(rtas_token("event-scan"), 4, 1, &ret, 0xffffffff, 0,
375 __pa(log), 1024);
376 mod_timer(&__get_cpu_var(heartbeat_timer),
377 jiffies + event_scan_interval);
378}
379
380static void chrp_8259_cascade(unsigned int irq, struct irq_desc *desc) 367static void chrp_8259_cascade(unsigned int irq, struct irq_desc *desc)
381{ 368{
382 unsigned int cascade_irq = i8259_irq(); 369 unsigned int cascade_irq = i8259_irq();
@@ -568,9 +555,6 @@ void __init chrp_init_IRQ(void)
568void __init 555void __init
569chrp_init2(void) 556chrp_init2(void)
570{ 557{
571 struct device_node *device;
572 const unsigned int *p = NULL;
573
574#ifdef CONFIG_NVRAM 558#ifdef CONFIG_NVRAM
575 chrp_nvram_init(); 559 chrp_nvram_init();
576#endif 560#endif
@@ -582,40 +566,6 @@ chrp_init2(void)
582 request_region(0x80,0x10,"dma page reg"); 566 request_region(0x80,0x10,"dma page reg");
583 request_region(0xc0,0x20,"dma2"); 567 request_region(0xc0,0x20,"dma2");
584 568
585 /* Get the event scan rate for the rtas so we know how
586 * often it expects a heartbeat. -- Cort
587 */
588 device = of_find_node_by_name(NULL, "rtas");
589 if (device)
590 p = of_get_property(device, "rtas-event-scan-rate", NULL);
591 if (p && *p) {
592 /*
593 * Arrange to call chrp_event_scan at least *p times
594 * per minute. We use 59 rather than 60 here so that
595 * the rate will be slightly higher than the minimum.
596 * This all assumes we don't do hotplug CPU on any
597 * machine that needs the event scans done.
598 */
599 unsigned long interval, offset;
600 int cpu, ncpus;
601 struct timer_list *timer;
602
603 interval = HZ * 59 / *p;
604 offset = HZ;
605 ncpus = num_online_cpus();
606 event_scan_interval = ncpus * interval;
607 for (cpu = 0; cpu < ncpus; ++cpu) {
608 timer = &per_cpu(heartbeat_timer, cpu);
609 setup_timer(timer, chrp_event_scan, 0);
610 timer->expires = jiffies + offset;
611 add_timer_on(timer, cpu);
612 offset += interval;
613 }
614 printk("RTAS Event Scan Rate: %u (%lu jiffies)\n",
615 *p, interval);
616 }
617 of_node_put(device);
618
619 if (ppc_md.progress) 569 if (ppc_md.progress)
620 ppc_md.progress(" Have fun! ", 0x7777); 570 ppc_md.progress(" Have fun! ", 0x7777);
621} 571}
diff --git a/arch/powerpc/platforms/pseries/Kconfig b/arch/powerpc/platforms/pseries/Kconfig
index f0e6f28427bd..26a24bd92623 100644
--- a/arch/powerpc/platforms/pseries/Kconfig
+++ b/arch/powerpc/platforms/pseries/Kconfig
@@ -4,6 +4,7 @@ config PPC_PSERIES
4 select MPIC 4 select MPIC
5 select PPC_I8259 5 select PPC_I8259
6 select PPC_RTAS 6 select PPC_RTAS
7 select PPC_RTAS_DAEMON
7 select RTAS_ERROR_LOGGING 8 select RTAS_ERROR_LOGGING
8 select PPC_UDBG_16550 9 select PPC_UDBG_16550
9 select PPC_NATIVE 10 select PPC_NATIVE
diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile
index 790c0b872d4f..4b1c422b8145 100644
--- a/arch/powerpc/platforms/pseries/Makefile
+++ b/arch/powerpc/platforms/pseries/Makefile
@@ -7,7 +7,7 @@ EXTRA_CFLAGS += -DDEBUG
7endif 7endif
8 8
9obj-y := lpar.o hvCall.o nvram.o reconfig.o \ 9obj-y := lpar.o hvCall.o nvram.o reconfig.o \
10 setup.o iommu.o ras.o rtasd.o \ 10 setup.o iommu.o ras.o \
11 firmware.o power.o 11 firmware.o power.o
12obj-$(CONFIG_SMP) += smp.o 12obj-$(CONFIG_SMP) += smp.o
13obj-$(CONFIG_XICS) += xics.o 13obj-$(CONFIG_XICS) += xics.o