diff options
Diffstat (limited to 'arch/powerpc/platforms/cell/pervasive.c')
-rw-r--r-- | arch/powerpc/platforms/cell/pervasive.c | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/arch/powerpc/platforms/cell/pervasive.c b/arch/powerpc/platforms/cell/pervasive.c index 812bf563ed65..4ede22d363fa 100644 --- a/arch/powerpc/platforms/cell/pervasive.c +++ b/arch/powerpc/platforms/cell/pervasive.c | |||
@@ -38,6 +38,8 @@ | |||
38 | #include "pervasive.h" | 38 | #include "pervasive.h" |
39 | #include "cbe_regs.h" | 39 | #include "cbe_regs.h" |
40 | 40 | ||
41 | static int sysreset_hack; | ||
42 | |||
41 | static void cbe_power_save(void) | 43 | static void cbe_power_save(void) |
42 | { | 44 | { |
43 | unsigned long ctrl, thread_switch_control; | 45 | unsigned long ctrl, thread_switch_control; |
@@ -85,6 +87,9 @@ static void cbe_power_save(void) | |||
85 | 87 | ||
86 | static int cbe_system_reset_exception(struct pt_regs *regs) | 88 | static int cbe_system_reset_exception(struct pt_regs *regs) |
87 | { | 89 | { |
90 | int cpu; | ||
91 | struct cbe_pmd_regs __iomem *pmd; | ||
92 | |||
88 | switch (regs->msr & SRR1_WAKEMASK) { | 93 | switch (regs->msr & SRR1_WAKEMASK) { |
89 | case SRR1_WAKEEE: | 94 | case SRR1_WAKEEE: |
90 | do_IRQ(regs); | 95 | do_IRQ(regs); |
@@ -93,6 +98,18 @@ static int cbe_system_reset_exception(struct pt_regs *regs) | |||
93 | timer_interrupt(regs); | 98 | timer_interrupt(regs); |
94 | break; | 99 | break; |
95 | case SRR1_WAKEMT: | 100 | case SRR1_WAKEMT: |
101 | /* | ||
102 | * The BMC can inject user triggered system reset exceptions, | ||
103 | * but cannot set the system reset reason in srr1, | ||
104 | * so check an extra register here. | ||
105 | */ | ||
106 | if (sysreset_hack && (cpu = smp_processor_id()) == 0) { | ||
107 | pmd = cbe_get_cpu_pmd_regs(cpu); | ||
108 | if (in_be64(&pmd->ras_esc_0) & 0xffff) { | ||
109 | out_be64(&pmd->ras_esc_0, 0); | ||
110 | return 0; | ||
111 | } | ||
112 | } | ||
96 | break; | 113 | break; |
97 | #ifdef CONFIG_CBE_RAS | 114 | #ifdef CONFIG_CBE_RAS |
98 | case SRR1_WAKESYSERR: | 115 | case SRR1_WAKESYSERR: |
@@ -113,9 +130,12 @@ static int cbe_system_reset_exception(struct pt_regs *regs) | |||
113 | void __init cbe_pervasive_init(void) | 130 | void __init cbe_pervasive_init(void) |
114 | { | 131 | { |
115 | int cpu; | 132 | int cpu; |
133 | |||
116 | if (!cpu_has_feature(CPU_FTR_PAUSE_ZERO)) | 134 | if (!cpu_has_feature(CPU_FTR_PAUSE_ZERO)) |
117 | return; | 135 | return; |
118 | 136 | ||
137 | sysreset_hack = machine_is_compatible("IBM,CBPLUS-1.0"); | ||
138 | |||
119 | for_each_possible_cpu(cpu) { | 139 | for_each_possible_cpu(cpu) { |
120 | struct cbe_pmd_regs __iomem *regs = cbe_get_cpu_pmd_regs(cpu); | 140 | struct cbe_pmd_regs __iomem *regs = cbe_get_cpu_pmd_regs(cpu); |
121 | if (!regs) | 141 | if (!regs) |
@@ -124,6 +144,12 @@ void __init cbe_pervasive_init(void) | |||
124 | /* Enable Pause(0) control bit */ | 144 | /* Enable Pause(0) control bit */ |
125 | out_be64(®s->pmcr, in_be64(®s->pmcr) | | 145 | out_be64(®s->pmcr, in_be64(®s->pmcr) | |
126 | CBE_PMD_PAUSE_ZERO_CONTROL); | 146 | CBE_PMD_PAUSE_ZERO_CONTROL); |
147 | |||
148 | /* Enable JTAG system-reset hack */ | ||
149 | if (sysreset_hack) | ||
150 | out_be32(®s->fir_mode_reg, | ||
151 | in_be32(®s->fir_mode_reg) | | ||
152 | CBE_PMD_FIR_MODE_M8); | ||
127 | } | 153 | } |
128 | 154 | ||
129 | ppc_md.power_save = cbe_power_save; | 155 | ppc_md.power_save = cbe_power_save; |