Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee13...
[pandora-kernel.git] / arch / powerpc / platforms / cell / ras.c
1 #define DEBUG
2
3 #include <linux/types.h>
4 #include <linux/kernel.h>
5 #include <linux/smp.h>
6
7 #include <asm/reg.h>
8 #include <asm/io.h>
9 #include <asm/prom.h>
10 #include <asm/machdep.h>
11
12 #include "ras.h"
13 #include "cbe_regs.h"
14
15
16 static void dump_fir(int cpu)
17 {
18         struct cbe_pmd_regs __iomem *pregs = cbe_get_cpu_pmd_regs(cpu);
19         struct cbe_iic_regs __iomem *iregs = cbe_get_cpu_iic_regs(cpu);
20
21         if (pregs == NULL)
22                 return;
23
24         /* Todo: do some nicer parsing of bits and based on them go down
25          * to other sub-units FIRs and not only IIC
26          */
27         printk(KERN_ERR "Global Checkstop FIR    : 0x%016lx\n",
28                in_be64(&pregs->checkstop_fir));
29         printk(KERN_ERR "Global Recoverable FIR  : 0x%016lx\n",
30                in_be64(&pregs->checkstop_fir));
31         printk(KERN_ERR "Global MachineCheck FIR : 0x%016lx\n",
32                in_be64(&pregs->spec_att_mchk_fir));
33
34         if (iregs == NULL)
35                 return;
36         printk(KERN_ERR "IOC FIR                 : 0x%016lx\n",
37                in_be64(&iregs->ioc_fir));
38
39 }
40
41 void cbe_system_error_exception(struct pt_regs *regs)
42 {
43         int cpu = smp_processor_id();
44
45         printk(KERN_ERR "System Error Interrupt on CPU %d !\n", cpu);
46         dump_fir(cpu);
47         dump_stack();
48 }
49
50 void cbe_maintenance_exception(struct pt_regs *regs)
51 {
52         int cpu = smp_processor_id();
53
54         /*
55          * Nothing implemented for the maintenance interrupt at this point
56          */
57
58         printk(KERN_ERR "Unhandled Maintenance interrupt on CPU %d !\n", cpu);
59         dump_stack();
60 }
61
62 void cbe_thermal_exception(struct pt_regs *regs)
63 {
64         int cpu = smp_processor_id();
65
66         /*
67          * Nothing implemented for the thermal interrupt at this point
68          */
69
70         printk(KERN_ERR "Unhandled Thermal interrupt on CPU %d !\n", cpu);
71         dump_stack();
72 }
73
74 static int cbe_machine_check_handler(struct pt_regs *regs)
75 {
76         int cpu = smp_processor_id();
77
78         printk(KERN_ERR "Machine Check Interrupt on CPU %d !\n", cpu);
79         dump_fir(cpu);
80
81         /* No recovery from this code now, lets continue */
82         return 0;
83 }
84
85 void __init cbe_ras_init(void)
86 {
87         unsigned long hid0;
88
89         /*
90          * Enable System Error & thermal interrupts and wakeup conditions
91          */
92
93         hid0 = mfspr(SPRN_HID0);
94         hid0 |= HID0_CBE_THERM_INT_EN | HID0_CBE_THERM_WAKEUP |
95                 HID0_CBE_SYSERR_INT_EN | HID0_CBE_SYSERR_WAKEUP;
96         mtspr(SPRN_HID0, hid0);
97         mb();
98
99         /*
100          * Install machine check handler. Leave setting of precise mode to
101          * what the firmware did for now
102          */
103         ppc_md.machine_check_exception = cbe_machine_check_handler;
104         mb();
105
106         /*
107          * For now, we assume that IOC_FIR is already set to forward some
108          * error conditions to the System Error handler. If that is not true
109          * then it will have to be fixed up here.
110          */
111 }