|
@@ -38,6 +38,8 @@
|
|
#include "pervasive.h"
|
|
#include "pervasive.h"
|
|
#include "cbe_regs.h"
|
|
#include "cbe_regs.h"
|
|
|
|
|
|
|
|
+static int sysreset_hack;
|
|
|
|
+
|
|
static void cbe_power_save(void)
|
|
static void cbe_power_save(void)
|
|
{
|
|
{
|
|
unsigned long ctrl, thread_switch_control;
|
|
unsigned long ctrl, thread_switch_control;
|
|
@@ -85,6 +87,9 @@ static void cbe_power_save(void)
|
|
|
|
|
|
static int cbe_system_reset_exception(struct pt_regs *regs)
|
|
static int cbe_system_reset_exception(struct pt_regs *regs)
|
|
{
|
|
{
|
|
|
|
+ int cpu;
|
|
|
|
+ struct cbe_pmd_regs __iomem *pmd;
|
|
|
|
+
|
|
switch (regs->msr & SRR1_WAKEMASK) {
|
|
switch (regs->msr & SRR1_WAKEMASK) {
|
|
case SRR1_WAKEEE:
|
|
case SRR1_WAKEEE:
|
|
do_IRQ(regs);
|
|
do_IRQ(regs);
|
|
@@ -93,6 +98,18 @@ static int cbe_system_reset_exception(struct pt_regs *regs)
|
|
timer_interrupt(regs);
|
|
timer_interrupt(regs);
|
|
break;
|
|
break;
|
|
case SRR1_WAKEMT:
|
|
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;
|
|
break;
|
|
#ifdef CONFIG_CBE_RAS
|
|
#ifdef CONFIG_CBE_RAS
|
|
case SRR1_WAKESYSERR:
|
|
case SRR1_WAKESYSERR:
|
|
@@ -113,9 +130,12 @@ static int cbe_system_reset_exception(struct pt_regs *regs)
|
|
void __init cbe_pervasive_init(void)
|
|
void __init cbe_pervasive_init(void)
|
|
{
|
|
{
|
|
int cpu;
|
|
int cpu;
|
|
|
|
+
|
|
if (!cpu_has_feature(CPU_FTR_PAUSE_ZERO))
|
|
if (!cpu_has_feature(CPU_FTR_PAUSE_ZERO))
|
|
return;
|
|
return;
|
|
|
|
|
|
|
|
+ sysreset_hack = machine_is_compatible("IBM,CBPLUS-1.0");
|
|
|
|
+
|
|
for_each_possible_cpu(cpu) {
|
|
for_each_possible_cpu(cpu) {
|
|
struct cbe_pmd_regs __iomem *regs = cbe_get_cpu_pmd_regs(cpu);
|
|
struct cbe_pmd_regs __iomem *regs = cbe_get_cpu_pmd_regs(cpu);
|
|
if (!regs)
|
|
if (!regs)
|
|
@@ -124,6 +144,12 @@ void __init cbe_pervasive_init(void)
|
|
/* Enable Pause(0) control bit */
|
|
/* Enable Pause(0) control bit */
|
|
out_be64(®s->pmcr, in_be64(®s->pmcr) |
|
|
out_be64(®s->pmcr, in_be64(®s->pmcr) |
|
|
CBE_PMD_PAUSE_ZERO_CONTROL);
|
|
CBE_PMD_PAUSE_ZERO_CONTROL);
|
|
|
|
+
|
|
|
|
+ /* Enable JTAG system-reset hack */
|
|
|
|
+ if (sysreset_hack)
|
|
|
|
+ out_be32(®s->fir_mode_reg,
|
|
|
|
+ in_be32(®s->fir_mode_reg) |
|
|
|
|
+ CBE_PMD_FIR_MODE_M8);
|
|
}
|
|
}
|
|
|
|
|
|
ppc_md.power_save = cbe_power_save;
|
|
ppc_md.power_save = cbe_power_save;
|