]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/powerpc/platforms/cell/pervasive.c
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc
[linux-2.6-omap-h63xx.git] / arch / powerpc / platforms / cell / pervasive.c
index 8c20f0fb8651f23b204f455bbf75a23581bef746..0304589c0a80550e07be726c6557538f7ee8ae03 100644 (file)
 #include <asm/prom.h>
 #include <asm/pgtable.h>
 #include <asm/reg.h>
+#include <asm/cell-regs.h>
 
 #include "pervasive.h"
-#include "cbe_regs.h"
+
+static int sysreset_hack;
 
 static void cbe_power_save(void)
 {
        unsigned long ctrl, thread_switch_control;
 
        /*
-        * We need to hard disable interrupts, but we also need to mark them
-        * hard disabled in the PACA so that the local_irq_enable() done by
-        * our caller upon return propertly hard enables.
+        * We need to hard disable interrupts, the local_irq_enable() done by
+        * our caller upon return will hard re-enable.
         */
        hard_irq_disable();
-       get_paca()->hard_enabled = 0;
 
        ctrl = mfspr(SPRN_CTRLF);
 
@@ -87,6 +87,9 @@ static void cbe_power_save(void)
 
 static int cbe_system_reset_exception(struct pt_regs *regs)
 {
+       int cpu;
+       struct cbe_pmd_regs __iomem *pmd;
+
        switch (regs->msr & SRR1_WAKEMASK) {
        case SRR1_WAKEEE:
                do_IRQ(regs);
@@ -95,6 +98,18 @@ static int cbe_system_reset_exception(struct pt_regs *regs)
                timer_interrupt(regs);
                break;
        case SRR1_WAKEMT:
+               /*
+                * The BMC can inject user triggered system reset exceptions,
+                * but cannot set the system reset reason in srr1,
+                * so check an extra register here.
+                */
+               if (sysreset_hack && (cpu = smp_processor_id()) == 0) {
+                       pmd = cbe_get_cpu_pmd_regs(cpu);
+                       if (in_be64(&pmd->ras_esc_0) & 0xffff) {
+                               out_be64(&pmd->ras_esc_0, 0);
+                               return 0;
+                       }
+               }
                break;
 #ifdef CONFIG_CBE_RAS
        case SRR1_WAKESYSERR:
@@ -115,9 +130,12 @@ static int cbe_system_reset_exception(struct pt_regs *regs)
 void __init cbe_pervasive_init(void)
 {
        int cpu;
+
        if (!cpu_has_feature(CPU_FTR_PAUSE_ZERO))
                return;
 
+       sysreset_hack = machine_is_compatible("IBM,CBPLUS-1.0");
+
        for_each_possible_cpu(cpu) {
                struct cbe_pmd_regs __iomem *regs = cbe_get_cpu_pmd_regs(cpu);
                if (!regs)
@@ -126,6 +144,12 @@ void __init cbe_pervasive_init(void)
                 /* Enable Pause(0) control bit */
                out_be64(&regs->pmcr, in_be64(&regs->pmcr) |
                                            CBE_PMD_PAUSE_ZERO_CONTROL);
+
+               /* Enable JTAG system-reset hack */
+               if (sysreset_hack)
+                       out_be32(&regs->fir_mode_reg,
+                               in_be32(&regs->fir_mode_reg) |
+                               CBE_PMD_FIR_MODE_M8);
        }
 
        ppc_md.power_save = cbe_power_save;