Commit d41ad6df authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc

* 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc: (34 commits)
  powerpc/mpic: Fix mask/unmask timeout message
  powerpc/pseries: Add BNX2=m to defconfig
  powerpc: Enable 64kB pages and 1024 threads in pseries config
  powerpc: Disable mcount tracers in pseries defconfig
  powerpc/boot/dts: Install dts from the right directory
  powerpc: machine_check_generic is wrong on 64bit
  powerpc: Check RTAS extended log flag before checking length
  powerpc: Fix corruption when grabbing FWNMI data
  powerpc: Rework pseries machine check handler
  powerpc: Don't silently handle machine checks from userspace
  powerpc: Remove duplicate debugger hook in machine_check_exception
  powerpc: Never halt RTAS error logging after receiving an unrecoverable machine check
  powerpc: Don't force MSR_RI in machine_check_exception
  powerpc: Print 32 bits of DSISR in show_regs
  powerpc/kdump: Disable ftrace during kexec
  powerpc/kdump: Move crash_kexec_stop_spus to kdump crash handler
  powerpc/kexec: Remove empty ppc_md.machine_kexec_prepare
  powerpc/kexec: Don't initialise kexec hooks to default handlers
  powerpc/kdump: Remove ppc_md.machine_crash_shutdown
  powerpc/kexec: Remove ppc_md.machine_kexec
  ...
parents 3dece370 8bfc5e36
...@@ -368,7 +368,7 @@ INSTALL := install ...@@ -368,7 +368,7 @@ INSTALL := install
extra-installed := $(patsubst $(obj)/%, $(DESTDIR)$(WRAPPER_OBJDIR)/%, $(extra-y)) extra-installed := $(patsubst $(obj)/%, $(DESTDIR)$(WRAPPER_OBJDIR)/%, $(extra-y))
hostprogs-installed := $(patsubst %, $(DESTDIR)$(WRAPPER_BINDIR)/%, $(hostprogs-y)) hostprogs-installed := $(patsubst %, $(DESTDIR)$(WRAPPER_BINDIR)/%, $(hostprogs-y))
wrapper-installed := $(DESTDIR)$(WRAPPER_BINDIR)/wrapper wrapper-installed := $(DESTDIR)$(WRAPPER_BINDIR)/wrapper
dts-installed := $(patsubst $(obj)/dts/%, $(DESTDIR)$(WRAPPER_DTSDIR)/%, $(wildcard $(obj)/dts/*.dts)) dts-installed := $(patsubst $(dtstree)/%, $(DESTDIR)$(WRAPPER_DTSDIR)/%, $(wildcard $(dtstree)/*.dts))
all-installed := $(extra-installed) $(hostprogs-installed) $(wrapper-installed) $(dts-installed) all-installed := $(extra-installed) $(hostprogs-installed) $(wrapper-installed) $(dts-installed)
......
...@@ -109,7 +109,7 @@ immr@e0000000 { ...@@ -109,7 +109,7 @@ immr@e0000000 {
#address-cells = <1>; #address-cells = <1>;
#size-cells = <1>; #size-cells = <1>;
device_type = "soc"; device_type = "soc";
compatible = "fsl,mpc8315-immr", "simple-bus"; compatible = "fsl,mpc8308-immr", "simple-bus";
ranges = <0 0xe0000000 0x00100000>; ranges = <0 0xe0000000 0x00100000>;
reg = <0xe0000000 0x00000200>; reg = <0xe0000000 0x00000200>;
bus-frequency = <0>; bus-frequency = <0>;
......
...@@ -291,13 +291,13 @@ dma@c300 { ...@@ -291,13 +291,13 @@ dma@c300 {
ranges = <0x0 0xc100 0x200>; ranges = <0x0 0xc100 0x200>;
cell-index = <1>; cell-index = <1>;
dma00: dma-channel@0 { dma00: dma-channel@0 {
compatible = "fsl,eloplus-dma-channel"; compatible = "fsl,ssi-dma-channel";
reg = <0x0 0x80>; reg = <0x0 0x80>;
cell-index = <0>; cell-index = <0>;
interrupts = <76 2>; interrupts = <76 2>;
}; };
dma01: dma-channel@80 { dma01: dma-channel@80 {
compatible = "fsl,eloplus-dma-channel"; compatible = "fsl,ssi-dma-channel";
reg = <0x80 0x80>; reg = <0x80 0x80>;
cell-index = <1>; cell-index = <1>;
interrupts = <77 2>; interrupts = <77 2>;
......
...@@ -2,7 +2,7 @@ CONFIG_PPC64=y ...@@ -2,7 +2,7 @@ CONFIG_PPC64=y
CONFIG_ALTIVEC=y CONFIG_ALTIVEC=y
CONFIG_VSX=y CONFIG_VSX=y
CONFIG_SMP=y CONFIG_SMP=y
CONFIG_NR_CPUS=128 CONFIG_NR_CPUS=1024
CONFIG_EXPERIMENTAL=y CONFIG_EXPERIMENTAL=y
CONFIG_SYSVIPC=y CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y CONFIG_POSIX_MQUEUE=y
...@@ -45,6 +45,8 @@ CONFIG_KEXEC=y ...@@ -45,6 +45,8 @@ CONFIG_KEXEC=y
CONFIG_IRQ_ALL_CPUS=y CONFIG_IRQ_ALL_CPUS=y
CONFIG_MEMORY_HOTPLUG=y CONFIG_MEMORY_HOTPLUG=y
CONFIG_MEMORY_HOTREMOVE=y CONFIG_MEMORY_HOTREMOVE=y
CONFIG_PPC_64K_PAGES=y
CONFIG_PPC_SUBPAGE_PROT=y
CONFIG_SCHED_SMT=y CONFIG_SCHED_SMT=y
CONFIG_HOTPLUG_PCI=m CONFIG_HOTPLUG_PCI=m
CONFIG_HOTPLUG_PCI_RPA=m CONFIG_HOTPLUG_PCI_RPA=m
...@@ -184,6 +186,7 @@ CONFIG_ACENIC_OMIT_TIGON_I=y ...@@ -184,6 +186,7 @@ CONFIG_ACENIC_OMIT_TIGON_I=y
CONFIG_E1000=y CONFIG_E1000=y
CONFIG_E1000E=y CONFIG_E1000E=y
CONFIG_TIGON3=y CONFIG_TIGON3=y
CONFIG_BNX2=m
CONFIG_CHELSIO_T1=m CONFIG_CHELSIO_T1=m
CONFIG_CHELSIO_T3=m CONFIG_CHELSIO_T3=m
CONFIG_EHEA=y CONFIG_EHEA=y
...@@ -311,9 +314,7 @@ CONFIG_DEBUG_KERNEL=y ...@@ -311,9 +314,7 @@ CONFIG_DEBUG_KERNEL=y
# CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set
CONFIG_LATENCYTOP=y CONFIG_LATENCYTOP=y
CONFIG_SYSCTL_SYSCALL_CHECK=y CONFIG_SYSCTL_SYSCALL_CHECK=y
CONFIG_IRQSOFF_TRACER=y
CONFIG_SCHED_TRACER=y CONFIG_SCHED_TRACER=y
CONFIG_STACK_TRACER=y
CONFIG_BLK_DEV_IO_TRACE=y CONFIG_BLK_DEV_IO_TRACE=y
CONFIG_DEBUG_STACKOVERFLOW=y CONFIG_DEBUG_STACKOVERFLOW=y
CONFIG_DEBUG_STACK_USAGE=y CONFIG_DEBUG_STACK_USAGE=y
......
...@@ -37,18 +37,21 @@ label##2: \ ...@@ -37,18 +37,21 @@ label##2: \
.align 2; \ .align 2; \
label##3: label##3:
#define MAKE_FTR_SECTION_ENTRY(msk, val, label, sect) \ #define MAKE_FTR_SECTION_ENTRY(msk, val, label, sect) \
label##4: \ label##4: \
.popsection; \ .popsection; \
.pushsection sect,"a"; \ .pushsection sect,"a"; \
.align 3; \ .align 3; \
label##5: \ label##5: \
FTR_ENTRY_LONG msk; \ FTR_ENTRY_LONG msk; \
FTR_ENTRY_LONG val; \ FTR_ENTRY_LONG val; \
FTR_ENTRY_OFFSET label##1b-label##5b; \ FTR_ENTRY_OFFSET label##1b-label##5b; \
FTR_ENTRY_OFFSET label##2b-label##5b; \ FTR_ENTRY_OFFSET label##2b-label##5b; \
FTR_ENTRY_OFFSET label##3b-label##5b; \ FTR_ENTRY_OFFSET label##3b-label##5b; \
FTR_ENTRY_OFFSET label##4b-label##5b; \ FTR_ENTRY_OFFSET label##4b-label##5b; \
.ifgt (label##4b-label##3b)-(label##2b-label##1b); \
.error "Feature section else case larger than body"; \
.endif; \
.popsection; .popsection;
......
...@@ -467,13 +467,22 @@ struct qe_immap { ...@@ -467,13 +467,22 @@ struct qe_immap {
extern struct qe_immap __iomem *qe_immr; extern struct qe_immap __iomem *qe_immr;
extern phys_addr_t get_qe_base(void); extern phys_addr_t get_qe_base(void);
static inline unsigned long immrbar_virt_to_phys(void *address) /*
* Returns the offset within the QE address space of the given pointer.
*
* Note that the QE does not support 36-bit physical addresses, so if
* get_qe_base() returns a number above 4GB, the caller will probably fail.
*/
static inline phys_addr_t immrbar_virt_to_phys(void *address)
{ {
if ( ((u32)address >= (u32)qe_immr) && void *q = (void *)qe_immr;
((u32)address < ((u32)qe_immr + QE_IMMAP_SIZE)) )
return (unsigned long)(address - (u32)qe_immr + /* Is it a MURAM address? */
(u32)get_qe_base()); if ((address >= q) && (address < (q + QE_IMMAP_SIZE)))
return (unsigned long)virt_to_phys(address); return get_qe_base() + (address - q);
/* It's an address returned by kmalloc */
return virt_to_phys(address);
} }
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
......
...@@ -12,24 +12,44 @@ ...@@ -12,24 +12,44 @@
#else #else
#ifdef CONFIG_TRACE_IRQFLAGS #ifdef CONFIG_TRACE_IRQFLAGS
#ifdef CONFIG_IRQSOFF_TRACER
/*
* Since the ftrace irqsoff latency trace checks CALLER_ADDR1,
* which is the stack frame here, we need to force a stack frame
* in case we came from user space.
*/
#define TRACE_WITH_FRAME_BUFFER(func) \
mflr r0; \
stdu r1, -32(r1); \
std r0, 16(r1); \
stdu r1, -32(r1); \
bl func; \
ld r1, 0(r1); \
ld r1, 0(r1);
#else
#define TRACE_WITH_FRAME_BUFFER(func) \
bl func;
#endif
/* /*
* Most of the CPU's IRQ-state tracing is done from assembly code; we * Most of the CPU's IRQ-state tracing is done from assembly code; we
* have to call a C function so call a wrapper that saves all the * have to call a C function so call a wrapper that saves all the
* C-clobbered registers. * C-clobbered registers.
*/ */
#define TRACE_ENABLE_INTS bl .trace_hardirqs_on #define TRACE_ENABLE_INTS TRACE_WITH_FRAME_BUFFER(.trace_hardirqs_on)
#define TRACE_DISABLE_INTS bl .trace_hardirqs_off #define TRACE_DISABLE_INTS TRACE_WITH_FRAME_BUFFER(.trace_hardirqs_off)
#define TRACE_AND_RESTORE_IRQ_PARTIAL(en,skip) \
cmpdi en,0; \ #define TRACE_AND_RESTORE_IRQ_PARTIAL(en,skip) \
bne 95f; \ cmpdi en,0; \
stb en,PACASOFTIRQEN(r13); \ bne 95f; \
bl .trace_hardirqs_off; \ stb en,PACASOFTIRQEN(r13); \
b skip; \ TRACE_WITH_FRAME_BUFFER(.trace_hardirqs_off) \
95: bl .trace_hardirqs_on; \ b skip; \
95: TRACE_WITH_FRAME_BUFFER(.trace_hardirqs_on) \
li en,1; li en,1;
#define TRACE_AND_RESTORE_IRQ(en) \ #define TRACE_AND_RESTORE_IRQ(en) \
TRACE_AND_RESTORE_IRQ_PARTIAL(en,96f); \ TRACE_AND_RESTORE_IRQ_PARTIAL(en,96f); \
stb en,PACASOFTIRQEN(r13); \ stb en,PACASOFTIRQEN(r13); \
96: 96:
#else #else
#define TRACE_ENABLE_INTS #define TRACE_ENABLE_INTS
......
...@@ -116,9 +116,6 @@ struct machdep_calls { ...@@ -116,9 +116,6 @@ struct machdep_calls {
* If for some reason there is no irq, but the interrupt * If for some reason there is no irq, but the interrupt
* shouldn't be counted as spurious, return NO_IRQ_IGNORE. */ * shouldn't be counted as spurious, return NO_IRQ_IGNORE. */
unsigned int (*get_irq)(void); unsigned int (*get_irq)(void);
#ifdef CONFIG_KEXEC
void (*kexec_cpu_down)(int crash_shutdown, int secondary);
#endif
/* PCI stuff */ /* PCI stuff */
/* Called after scanning the bus, before allocating resources */ /* Called after scanning the bus, before allocating resources */
...@@ -235,11 +232,7 @@ struct machdep_calls { ...@@ -235,11 +232,7 @@ struct machdep_calls {
void (*machine_shutdown)(void); void (*machine_shutdown)(void);
#ifdef CONFIG_KEXEC #ifdef CONFIG_KEXEC
/* Called to do the minimal shutdown needed to run a kexec'd kernel void (*kexec_cpu_down)(int crash_shutdown, int secondary);
* to run successfully.
* XXX Should we move this one out of kexec scope?
*/
void (*machine_crash_shutdown)(struct pt_regs *regs);
/* Called to do what every setup is needed on image and the /* Called to do what every setup is needed on image and the
* reboot code buffer. Returns 0 on success. * reboot code buffer. Returns 0 on success.
...@@ -247,15 +240,6 @@ struct machdep_calls { ...@@ -247,15 +240,6 @@ struct machdep_calls {
* claims to support kexec. * claims to support kexec.
*/ */
int (*machine_kexec_prepare)(struct kimage *image); int (*machine_kexec_prepare)(struct kimage *image);
/* Called to handle any machine specific cleanup on image */
void (*machine_kexec_cleanup)(struct kimage *image);
/* Called to perform the _real_ kexec.
* Do NOT allocate memory or fail here. We are past the point of
* no return.
*/
void (*machine_kexec)(struct kimage *image);
#endif /* CONFIG_KEXEC */ #endif /* CONFIG_KEXEC */
#ifdef CONFIG_SUSPEND #ifdef CONFIG_SUSPEND
......
...@@ -283,6 +283,7 @@ ...@@ -283,6 +283,7 @@
#define HID0_NOPTI (1<<0) /* No-op dcbt and dcbst instr. */ #define HID0_NOPTI (1<<0) /* No-op dcbt and dcbst instr. */
#define SPRN_HID1 0x3F1 /* Hardware Implementation Register 1 */ #define SPRN_HID1 0x3F1 /* Hardware Implementation Register 1 */
#ifdef CONFIG_6xx
#define HID1_EMCP (1<<31) /* 7450 Machine Check Pin Enable */ #define HID1_EMCP (1<<31) /* 7450 Machine Check Pin Enable */
#define HID1_DFS (1<<22) /* 7447A Dynamic Frequency Scaling */ #define HID1_DFS (1<<22) /* 7447A Dynamic Frequency Scaling */
#define HID1_PC0 (1<<16) /* 7450 PLL_CFG[0] */ #define HID1_PC0 (1<<16) /* 7450 PLL_CFG[0] */
...@@ -292,6 +293,7 @@ ...@@ -292,6 +293,7 @@
#define HID1_SYNCBE (1<<11) /* 7450 ABE for sync, eieio */ #define HID1_SYNCBE (1<<11) /* 7450 ABE for sync, eieio */
#define HID1_ABE (1<<10) /* 7450 Address Broadcast Enable */ #define HID1_ABE (1<<10) /* 7450 Address Broadcast Enable */
#define HID1_PS (1<<16) /* 750FX PLL selection */ #define HID1_PS (1<<16) /* 750FX PLL selection */
#endif
#define SPRN_HID2 0x3F8 /* Hardware Implementation Register 2 */ #define SPRN_HID2 0x3F8 /* Hardware Implementation Register 2 */
#define SPRN_HID2_GEKKO 0x398 /* Gekko HID2 Register */ #define SPRN_HID2_GEKKO 0x398 /* Gekko HID2 Register */
#define SPRN_IABR 0x3F2 /* Instruction Address Breakpoint Register */ #define SPRN_IABR 0x3F2 /* Instruction Address Breakpoint Register */
......
...@@ -246,6 +246,20 @@ ...@@ -246,6 +246,20 @@
store or cache line push */ store or cache line push */
#endif #endif
/* Bit definitions for the HID1 */
#ifdef CONFIG_E500
/* e500v1/v2 */
#define HID1_PLL_CFG_MASK 0xfc000000 /* PLL_CFG input pins */
#define HID1_RFXE 0x00020000 /* Read fault exception enable */
#define HID1_R1DPE 0x00008000 /* R1 data bus parity enable */
#define HID1_R2DPE 0x00004000 /* R2 data bus parity enable */
#define HID1_ASTME 0x00002000 /* Address bus streaming mode enable */
#define HID1_ABE 0x00001000 /* Address broadcast enable */
#define HID1_MPXTT 0x00000400 /* MPX re-map transfer type */
#define HID1_ATS 0x00000080 /* Atomic status */
#define HID1_MID_MASK 0x0000000f /* MID input pins */
#endif
/* Bit definitions for the DBSR. */ /* Bit definitions for the DBSR. */
/* /*
* DBSR bits which have conflicting definitions on true Book E versus IBM 40x. * DBSR bits which have conflicting definitions on true Book E versus IBM 40x.
......
...@@ -203,14 +203,6 @@ void spu_irq_setaffinity(struct spu *spu, int cpu); ...@@ -203,14 +203,6 @@ void spu_irq_setaffinity(struct spu *spu, int cpu);
void spu_setup_kernel_slbs(struct spu *spu, struct spu_lscsa *lscsa, void spu_setup_kernel_slbs(struct spu *spu, struct spu_lscsa *lscsa,
void *code, int code_size); void *code, int code_size);
#ifdef CONFIG_KEXEC
void crash_register_spus(struct list_head *list);
#else
static inline void crash_register_spus(struct list_head *list)
{
}
#endif
extern void spu_invalidate_slbs(struct spu *spu); extern void spu_invalidate_slbs(struct spu *spu);
extern void spu_associate_mm(struct spu *spu, struct mm_struct *mm); extern void spu_associate_mm(struct spu *spu, struct mm_struct *mm);
int spu_64k_pages_available(void); int spu_64k_pages_available(void);
......
...@@ -64,6 +64,12 @@ _GLOBAL(__setup_cpu_e500v2) ...@@ -64,6 +64,12 @@ _GLOBAL(__setup_cpu_e500v2)
bl __e500_icache_setup bl __e500_icache_setup
bl __e500_dcache_setup bl __e500_dcache_setup
bl __setup_e500_ivors bl __setup_e500_ivors
#ifdef CONFIG_RAPIDIO
/* Ensure that RFXE is set */
mfspr r3,SPRN_HID1
oris r3,r3,HID1_RFXE@h
mtspr SPRN_HID1,r3
#endif
mtlr r4 mtlr r4
blr blr
_GLOBAL(__setup_cpu_e500mc) _GLOBAL(__setup_cpu_e500mc)
......
...@@ -116,7 +116,6 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -116,7 +116,6 @@ static struct cpu_spec __initdata cpu_specs[] = {
.pmc_type = PPC_PMC_IBM, .pmc_type = PPC_PMC_IBM,
.oprofile_cpu_type = "ppc64/power3", .oprofile_cpu_type = "ppc64/power3",
.oprofile_type = PPC_OPROFILE_RS64, .oprofile_type = PPC_OPROFILE_RS64,
.machine_check = machine_check_generic,
.platform = "power3", .platform = "power3",
}, },
{ /* Power3+ */ { /* Power3+ */
...@@ -132,7 +131,6 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -132,7 +131,6 @@ static struct cpu_spec __initdata cpu_specs[] = {
.pmc_type = PPC_PMC_IBM, .pmc_type = PPC_PMC_IBM,
.oprofile_cpu_type = "ppc64/power3", .oprofile_cpu_type = "ppc64/power3",
.oprofile_type = PPC_OPROFILE_RS64, .oprofile_type = PPC_OPROFILE_RS64,
.machine_check = machine_check_generic,
.platform = "power3", .platform = "power3",
}, },
{ /* Northstar */ { /* Northstar */
...@@ -148,7 +146,6 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -148,7 +146,6 @@ static struct cpu_spec __initdata cpu_specs[] = {
.pmc_type = PPC_PMC_IBM, .pmc_type = PPC_PMC_IBM,
.oprofile_cpu_type = "ppc64/rs64", .oprofile_cpu_type = "ppc64/rs64",
.oprofile_type = PPC_OPROFILE_RS64, .oprofile_type = PPC_OPROFILE_RS64,
.machine_check = machine_check_generic,
.platform = "rs64", .platform = "rs64",
}, },
{ /* Pulsar */ { /* Pulsar */
...@@ -164,7 +161,6 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -164,7 +161,6 @@ static struct cpu_spec __initdata cpu_specs[] = {
.pmc_type = PPC_PMC_IBM, .pmc_type = PPC_PMC_IBM,
.oprofile_cpu_type = "ppc64/rs64", .oprofile_cpu_type = "ppc64/rs64",
.oprofile_type = PPC_OPROFILE_RS64, .oprofile_type = PPC_OPROFILE_RS64,
.machine_check = machine_check_generic,
.platform = "rs64", .platform = "rs64",
}, },
{ /* I-star */ { /* I-star */
...@@ -180,7 +176,6 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -180,7 +176,6 @@ static struct cpu_spec __initdata cpu_specs[] = {
.pmc_type = PPC_PMC_IBM, .pmc_type = PPC_PMC_IBM,
.oprofile_cpu_type = "ppc64/rs64", .oprofile_cpu_type = "ppc64/rs64",
.oprofile_type = PPC_OPROFILE_RS64, .oprofile_type = PPC_OPROFILE_RS64,
.machine_check = machine_check_generic,
.platform = "rs64", .platform = "rs64",
}, },
{ /* S-star */ { /* S-star */
...@@ -196,7 +191,6 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -196,7 +191,6 @@ static struct cpu_spec __initdata cpu_specs[] = {
.pmc_type = PPC_PMC_IBM, .pmc_type = PPC_PMC_IBM,
.oprofile_cpu_type = "ppc64/rs64", .oprofile_cpu_type = "ppc64/rs64",
.oprofile_type = PPC_OPROFILE_RS64, .oprofile_type = PPC_OPROFILE_RS64,
.machine_check = machine_check_generic,
.platform = "rs64", .platform = "rs64",
}, },
{ /* Power4 */ { /* Power4 */
...@@ -212,7 +206,6 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -212,7 +206,6 @@ static struct cpu_spec __initdata cpu_specs[] = {
.pmc_type = PPC_PMC_IBM, .pmc_type = PPC_PMC_IBM,
.oprofile_cpu_type = "ppc64/power4", .oprofile_cpu_type = "ppc64/power4",
.oprofile_type = PPC_OPROFILE_POWER4, .oprofile_type = PPC_OPROFILE_POWER4,
.machine_check = machine_check_generic,
.platform = "power4", .platform = "power4",
}, },
{ /* Power4+ */ { /* Power4+ */
...@@ -228,7 +221,6 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -228,7 +221,6 @@ static struct cpu_spec __initdata cpu_specs[] = {
.pmc_type = PPC_PMC_IBM, .pmc_type = PPC_PMC_IBM,
.oprofile_cpu_type = "ppc64/power4", .oprofile_cpu_type = "ppc64/power4",
.oprofile_type = PPC_OPROFILE_POWER4, .oprofile_type = PPC_OPROFILE_POWER4,
.machine_check = machine_check_generic,
.platform = "power4", .platform = "power4",
}, },
{ /* PPC970 */ { /* PPC970 */
...@@ -247,7 +239,6 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -247,7 +239,6 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_restore = __restore_cpu_ppc970, .cpu_restore = __restore_cpu_ppc970,
.oprofile_cpu_type = "ppc64/970", .oprofile_cpu_type = "ppc64/970",
.oprofile_type = PPC_OPROFILE_POWER4, .oprofile_type = PPC_OPROFILE_POWER4,
.machine_check = machine_check_generic,
.platform = "ppc970", .platform = "ppc970",
}, },
{ /* PPC970FX */ { /* PPC970FX */
...@@ -266,7 +257,6 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -266,7 +257,6 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_restore = __restore_cpu_ppc970, .cpu_restore = __restore_cpu_ppc970,
.oprofile_cpu_type = "ppc64/970", .oprofile_cpu_type = "ppc64/970",
.oprofile_type = PPC_OPROFILE_POWER4, .oprofile_type = PPC_OPROFILE_POWER4,
.machine_check = machine_check_generic,
.platform = "ppc970", .platform = "ppc970",
}, },
{ /* PPC970MP DD1.0 - no DEEPNAP, use regular 970 init */ { /* PPC970MP DD1.0 - no DEEPNAP, use regular 970 init */
...@@ -285,7 +275,6 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -285,7 +275,6 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_restore = __restore_cpu_ppc970, .cpu_restore = __restore_cpu_ppc970,
.oprofile_cpu_type = "ppc64/970MP", .oprofile_cpu_type = "ppc64/970MP",
.oprofile_type = PPC_OPROFILE_POWER4, .oprofile_type = PPC_OPROFILE_POWER4,
.machine_check = machine_check_generic,
.platform = "ppc970", .platform = "ppc970",
}, },
{ /* PPC970MP */ { /* PPC970MP */
...@@ -304,7 +293,6 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -304,7 +293,6 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_restore = __restore_cpu_ppc970, .cpu_restore = __restore_cpu_ppc970,
.oprofile_cpu_type = "ppc64/970MP", .oprofile_cpu_type = "ppc64/970MP",
.oprofile_type = PPC_OPROFILE_POWER4, .oprofile_type = PPC_OPROFILE_POWER4,
.machine_check = machine_check_generic,
.platform = "ppc970", .platform = "ppc970",
}, },
{ /* PPC970GX */ { /* PPC970GX */
...@@ -322,7 +310,6 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -322,7 +310,6 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_setup = __setup_cpu_ppc970, .cpu_setup = __setup_cpu_ppc970,
.oprofile_cpu_type = "ppc64/970", .oprofile_cpu_type = "ppc64/970",
.oprofile_type = PPC_OPROFILE_POWER4, .oprofile_type = PPC_OPROFILE_POWER4,
.machine_check = machine_check_generic,
.platform = "ppc970", .platform = "ppc970",
}, },
{ /* Power5 GR */ { /* Power5 GR */
...@@ -343,7 +330,6 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -343,7 +330,6 @@ static struct cpu_spec __initdata cpu_specs[] = {
*/ */
.oprofile_mmcra_sihv = MMCRA_SIHV, .oprofile_mmcra_sihv = MMCRA_SIHV,
.oprofile_mmcra_sipr = MMCRA_SIPR, .oprofile_mmcra_sipr = MMCRA_SIPR,
.machine_check = machine_check_generic,
.platform = "power5", .platform = "power5",
}, },
{ /* Power5++ */ { /* Power5++ */
...@@ -360,7 +346,6 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -360,7 +346,6 @@ static struct cpu_spec __initdata cpu_specs[] = {
.oprofile_type = PPC_OPROFILE_POWER4, .oprofile_type = PPC_OPROFILE_POWER4,
.oprofile_mmcra_sihv = MMCRA_SIHV, .oprofile_mmcra_sihv = MMCRA_SIHV,
.oprofile_mmcra_sipr = MMCRA_SIPR, .oprofile_mmcra_sipr = MMCRA_SIPR,
.machine_check = machine_check_generic,
.platform = "power5+", .platform = "power5+",
}, },
{ /* Power5 GS */ { /* Power5 GS */
...@@ -378,7 +363,6 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -378,7 +363,6 @@ static struct cpu_spec __initdata cpu_specs[] = {
.oprofile_type = PPC_OPROFILE_POWER4, .oprofile_type = PPC_OPROFILE_POWER4,
.oprofile_mmcra_sihv = MMCRA_SIHV, .oprofile_mmcra_sihv = MMCRA_SIHV,
.oprofile_mmcra_sipr = MMCRA_SIPR, .oprofile_mmcra_sipr = MMCRA_SIPR,
.machine_check = machine_check_generic,
.platform = "power5+", .platform = "power5+",
}, },
{ /* POWER6 in P5+ mode; 2.04-compliant processor */ { /* POWER6 in P5+ mode; 2.04-compliant processor */
...@@ -390,7 +374,6 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -390,7 +374,6 @@ static struct cpu_spec __initdata cpu_specs[] = {
.mmu_features = MMU_FTR_HPTE_TABLE, .mmu_features = MMU_FTR_HPTE_TABLE,
.icache_bsize = 128, .icache_bsize = 128,
.dcache_bsize = 128, .dcache_bsize = 128,
.machine_check = machine_check_generic,
.oprofile_cpu_type = "ppc64/ibm-compat-v1", .oprofile_cpu_type = "ppc64/ibm-compat-v1",
.oprofile_type = PPC_OPROFILE_POWER4, .oprofile_type = PPC_OPROFILE_POWER4,
.platform = "power5+", .platform = "power5+",
...@@ -413,7 +396,6 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -413,7 +396,6 @@ static struct cpu_spec __initdata cpu_specs[] = {
.oprofile_mmcra_sipr = POWER6_MMCRA_SIPR, .oprofile_mmcra_sipr = POWER6_MMCRA_SIPR,
.oprofile_mmcra_clear = POWER6_MMCRA_THRM | .oprofile_mmcra_clear = POWER6_MMCRA_THRM |
POWER6_MMCRA_OTHER, POWER6_MMCRA_OTHER,
.machine_check = machine_check_generic,
.platform = "power6x", .platform = "power6x",
}, },
{ /* 2.05-compliant processor, i.e. Power6 "architected" mode */ { /* 2.05-compliant processor, i.e. Power6 "architected" mode */
...@@ -425,7 +407,6 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -425,7 +407,6 @@ static struct cpu_spec __initdata cpu_specs[] = {
.mmu_features = MMU_FTR_HPTE_TABLE, .mmu_features = MMU_FTR_HPTE_TABLE,
.icache_bsize = 128, .icache_bsize = 128,
.dcache_bsize = 128, .dcache_bsize = 128,
.machine_check = machine_check_generic,
.oprofile_cpu_type = "ppc64/ibm-compat-v1", .oprofile_cpu_type = "ppc64/ibm-compat-v1",
.oprofile_type = PPC_OPROFILE_POWER4, .oprofile_type = PPC_OPROFILE_POWER4,
.platform = "power6", .platform = "power6",
...@@ -440,7 +421,6 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -440,7 +421,6 @@ static struct cpu_spec __initdata cpu_specs[] = {
MMU_FTR_TLBIE_206, MMU_FTR_TLBIE_206,
.icache_bsize = 128, .icache_bsize = 128,
.dcache_bsize = 128, .dcache_bsize = 128,
.machine_check = machine_check_generic,
.oprofile_type = PPC_OPROFILE_POWER4, .oprofile_type = PPC_OPROFILE_POWER4,
.oprofile_cpu_type = "ppc64/ibm-compat-v1", .oprofile_cpu_type = "ppc64/ibm-compat-v1",
.platform = "power7", .platform = "power7",
...@@ -492,7 +472,6 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -492,7 +472,6 @@ static struct cpu_spec __initdata cpu_specs[] = {
.pmc_type = PPC_PMC_IBM, .pmc_type = PPC_PMC_IBM,
.oprofile_cpu_type = "ppc64/cell-be", .oprofile_cpu_type = "ppc64/cell-be",
.oprofile_type = PPC_OPROFILE_CELL, .oprofile_type = PPC_OPROFILE_CELL,
.machine_check = machine_check_generic,
.platform = "ppc-cell-be", .platform = "ppc-cell-be",
}, },
{ /* PA Semi PA6T */ { /* PA Semi PA6T */
...@@ -510,7 +489,6 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -510,7 +489,6 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_restore = __restore_cpu_pa6t, .cpu_restore = __restore_cpu_pa6t,
.oprofile_cpu_type = "ppc64/pa6t", .oprofile_cpu_type = "ppc64/pa6t",
.oprofile_type = PPC_OPROFILE_PA6T, .oprofile_type = PPC_OPROFILE_PA6T,
.machine_check = machine_check_generic,
.platform = "pa6t", .platform = "pa6t",
}, },
{ /* default match */ { /* default match */
...@@ -524,7 +502,6 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -524,7 +502,6 @@ static struct cpu_spec __initdata cpu_specs[] = {
.dcache_bsize = 128, .dcache_bsize = 128,
.num_pmcs = 6, .num_pmcs = 6,
.pmc_type = PPC_PMC_IBM, .pmc_type = PPC_PMC_IBM,
.machine_check = machine_check_generic,
.platform = "power4", .platform = "power4",
} }
#endif /* CONFIG_PPC_BOOK3S_64 */ #endif /* CONFIG_PPC_BOOK3S_64 */
......
...@@ -48,7 +48,7 @@ int crashing_cpu = -1; ...@@ -48,7 +48,7 @@ int crashing_cpu = -1;
static cpumask_t cpus_in_crash = CPU_MASK_NONE; static cpumask_t cpus_in_crash = CPU_MASK_NONE;
cpumask_t cpus_in_sr = CPU_MASK_NONE; cpumask_t cpus_in_sr = CPU_MASK_NONE;
#define CRASH_HANDLER_MAX 2 #define CRASH_HANDLER_MAX 3
/* NULL terminated list of shutdown handles */ /* NULL terminated list of shutdown handles */
static crash_shutdown_t crash_shutdown_handles[CRASH_HANDLER_MAX+1]; static crash_shutdown_t crash_shutdown_handles[CRASH_HANDLER_MAX+1];
static DEFINE_SPINLOCK(crash_handlers_lock); static DEFINE_SPINLOCK(crash_handlers_lock);
...@@ -125,7 +125,7 @@ static void crash_kexec_prepare_cpus(int cpu) ...@@ -125,7 +125,7 @@ static void crash_kexec_prepare_cpus(int cpu)
smp_wmb(); smp_wmb();
/* /*
* FIXME: Until we will have the way to stop other CPUSs reliabally, * FIXME: Until we will have the way to stop other CPUs reliably,
* the crash CPU will send an IPI and wait for other CPUs to * the crash CPU will send an IPI and wait for other CPUs to
* respond. * respond.
* Delay of at least 10 seconds. * Delay of at least 10 seconds.
...@@ -254,72 +254,6 @@ void crash_kexec_secondary(struct pt_regs *regs) ...@@ -254,72 +254,6 @@ void crash_kexec_secondary(struct pt_regs *regs)
cpus_in_sr = CPU_MASK_NONE; cpus_in_sr = CPU_MASK_NONE;
} }
#endif #endif
#ifdef CONFIG_SPU_BASE
#include <asm/spu.h>
#include <asm/spu_priv1.h>
struct crash_spu_info {
struct spu *spu;
u32 saved_spu_runcntl_RW;
u32 saved_spu_status_R;
u32 saved_spu_npc_RW;
u64 saved_mfc_sr1_RW;
u64 saved_mfc_dar;
u64 saved_mfc_dsisr;
};
#define CRASH_NUM_SPUS 16 /* Enough for current hardware */
static struct crash_spu_info crash_spu_info[CRASH_NUM_SPUS];
static void crash_kexec_stop_spus(void)
{
struct spu *spu;
int i;
u64 tmp;
for (i = 0; i < CRASH_NUM_SPUS; i++) {
if (!crash_spu_info[i].spu)
continue;
spu = crash_spu_info[i].spu;
crash_spu_info[i].saved_spu_runcntl_RW =
in_be32(&spu->problem->spu_runcntl_RW);
crash_spu_info[i].saved_spu_status_R =
in_be32(&spu->problem->spu_status_R);
crash_spu_info[i].saved_spu_npc_RW =
in_be32(&spu->problem->spu_npc_RW);
crash_spu_info[i].saved_mfc_dar = spu_mfc_dar_get(spu);
crash_spu_info[i].saved_mfc_dsisr = spu_mfc_dsisr_get(spu);
tmp = spu_mfc_sr1_get(spu);
crash_spu_info[i].saved_mfc_sr1_RW = tmp;
tmp &= ~MFC_STATE1_MASTER_RUN_CONTROL_MASK;
spu_mfc_sr1_set(spu, tmp);
__delay(200);
}
}
void crash_register_spus(struct list_head *list)
{
struct spu *spu;
list_for_each_entry(spu, list, full_list) {
if (WARN_ON(spu->number >= CRASH_NUM_SPUS))
continue;
crash_spu_info[spu->number].spu = spu;
}
}
#else
static inline void crash_kexec_stop_spus(void)
{
}
#endif /* CONFIG_SPU_BASE */
/* /*
* Register a function to be called on shutdown. Only use this if you * Register a function to be called on shutdown. Only use this if you
...@@ -439,8 +373,6 @@ void default_machine_crash_shutdown(struct pt_regs *regs) ...@@ -439,8 +373,6 @@ void default_machine_crash_shutdown(struct pt_regs *regs)
crash_shutdown_cpu = -1; crash_shutdown_cpu = -1;
__debugger_fault_handler = old_handler; __debugger_fault_handler = old_handler;
crash_kexec_stop_spus();
if (ppc_md.kexec_cpu_down) if (ppc_md.kexec_cpu_down)
ppc_md.kexec_cpu_down(1, 0); ppc_md.kexec_cpu_down(1, 0);
} }
...@@ -880,7 +880,18 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_TYPE_47x) ...@@ -880,7 +880,18 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_TYPE_47x)
*/ */
andi. r10,r9,MSR_EE andi. r10,r9,MSR_EE
beq 1f beq 1f
/*
* Since the ftrace irqsoff latency trace checks CALLER_ADDR1,
* which is the stack frame here, we need to force a stack frame
* in case we came from user space.
*/
stwu r1,-32(r1)
mflr r0
stw r0,4(r1)
stwu r1,-32(r1)
bl trace_hardirqs_on bl trace_hardirqs_on
lwz r1,0(r1)
lwz r1,0(r1)
lwz r9,_MSR(r1) lwz r9,_MSR(r1)
1: 1:
#endif /* CONFIG_TRACE_IRQFLAGS */ #endif /* CONFIG_TRACE_IRQFLAGS */
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include <linux/memblock.h> #include <linux/memblock.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/ftrace.h>
#include <asm/machdep.h> #include <asm/machdep.h>
#include <asm/prom.h> #include <asm/prom.h>
...@@ -44,10 +45,7 @@ void machine_kexec_mask_interrupts(void) { ...@@ -44,10 +45,7 @@ void machine_kexec_mask_interrupts(void) {
void machine_crash_shutdown(struct pt_regs *regs) void machine_crash_shutdown(struct pt_regs *regs)
{ {
if (ppc_md.machine_crash_shutdown) default_machine_crash_shutdown(regs);
ppc_md.machine_crash_shutdown(regs);
else
default_machine_crash_shutdown(regs);
} }
/* /*
...@@ -65,8 +63,6 @@ int machine_kexec_prepare(struct kimage *image) ...@@ -65,8 +63,6 @@ int machine_kexec_prepare(struct kimage *image)
void machine_kexec_cleanup(struct kimage *image) void machine_kexec_cleanup(struct kimage *image)
{ {
if (ppc_md.machine_kexec_cleanup)
ppc_md.machine_kexec_cleanup(image);
} }
void arch_crash_save_vmcoreinfo(void) void arch_crash_save_vmcoreinfo(void)
...@@ -87,10 +83,13 @@ void arch_crash_save_vmcoreinfo(void) ...@@ -87,10 +83,13 @@ void arch_crash_save_vmcoreinfo(void)
*/ */
void machine_kexec(struct kimage *image) void machine_kexec(struct kimage *image)
{ {
if (ppc_md.machine_kexec) int save_ftrace_enabled;
ppc_md.machine_kexec(image);
else save_ftrace_enabled = __ftrace_enabled_save();
default_machine_kexec(image);
default_machine_kexec(image);
__ftrace_enabled_restore(save_ftrace_enabled);
/* Fall back to normal restart if we're still alive. */ /* Fall back to normal restart if we're still alive. */
machine_restart(NULL); machine_restart(NULL);
......
...@@ -631,7 +631,7 @@ void show_regs(struct pt_regs * regs) ...@@ -631,7 +631,7 @@ void show_regs(struct pt_regs * regs)
#ifdef CONFIG_PPC_ADV_DEBUG_REGS #ifdef CONFIG_PPC_ADV_DEBUG_REGS
printk("DEAR: "REG", ESR: "REG"\n", regs->dar, regs->dsisr); printk("DEAR: "REG", ESR: "REG"\n", regs->dar, regs->dsisr);
#else #else
printk("DAR: "REG", DSISR: "REG"\n", regs->dar, regs->dsisr); printk("DAR: "REG", DSISR: %08lx\n", regs->dar, regs->dsisr);
#endif #endif
printk("TASK = %p[%d] '%s' THREAD: %p", printk("TASK = %p[%d] '%s' THREAD: %p",
current, task_pid_nr(current), current->comm, task_thread_info(current)); current, task_pid_nr(current), current->comm, task_thread_info(current));
......
...@@ -256,31 +256,16 @@ static ssize_t rtas_flash_read(struct file *file, char __user *buf, ...@@ -256,31 +256,16 @@ static ssize_t rtas_flash_read(struct file *file, char __user *buf,
struct proc_dir_entry *dp = PDE(file->f_path.dentry->d_inode); struct proc_dir_entry *dp = PDE(file->f_path.dentry->d_inode);
struct rtas_update_flash_t *uf; struct rtas_update_flash_t *uf;
char msg[RTAS_MSG_MAXLEN]; char msg[RTAS_MSG_MAXLEN];
int msglen;
uf = (struct rtas_update_flash_t *) dp->data; uf = dp->data;
if (!strcmp(dp->name, FIRMWARE_FLASH_NAME)) { if (!strcmp(dp->name, FIRMWARE_FLASH_NAME)) {
get_flash_status_msg(uf->status, msg); get_flash_status_msg(uf->status, msg);
} else { /* FIRMWARE_UPDATE_NAME */ } else { /* FIRMWARE_UPDATE_NAME */
sprintf(msg, "%d\n", uf->status); sprintf(msg, "%d\n", uf->status);
} }
msglen = strlen(msg);
if (msglen > count)
msglen = count;
if (ppos && *ppos != 0)
return 0; /* be cheap */
if (!access_ok(VERIFY_WRITE, buf, msglen))
return -EINVAL;
if (copy_to_user(buf, msg, msglen)) return simple_read_from_buffer(buf, count, ppos, msg, strlen(msg));
return -EFAULT;
if (ppos)
*ppos = msglen;
return msglen;
} }
/* constructor for flash_block_cache */ /* constructor for flash_block_cache */
...@@ -394,26 +379,13 @@ static ssize_t manage_flash_read(struct file *file, char __user *buf, ...@@ -394,26 +379,13 @@ static ssize_t manage_flash_read(struct file *file, char __user *buf,
char msg[RTAS_MSG_MAXLEN]; char msg[RTAS_MSG_MAXLEN];
int msglen; int msglen;
args_buf = (struct rtas_manage_flash_t *) dp->data; args_buf = dp->data;
if (args_buf == NULL) if (args_buf == NULL)
return 0; return 0;
msglen = sprintf(msg, "%d\n", args_buf->status); msglen = sprintf(msg, "%d\n", args_buf->status);
if (msglen > count)
msglen = count;
if (ppos && *ppos != 0) return simple_read_from_buffer(buf, count, ppos, msg, msglen);
return 0; /* be cheap */
if (!access_ok(VERIFY_WRITE, buf, msglen))
return -EINVAL;
if (copy_to_user(buf, msg, msglen))
return -EFAULT;
if (ppos)
*ppos = msglen;
return msglen;
} }
static ssize_t manage_flash_write(struct file *file, const char __user *buf, static ssize_t manage_flash_write(struct file *file, const char __user *buf,
...@@ -495,24 +467,11 @@ static ssize_t validate_flash_read(struct file *file, char __user *buf, ...@@ -495,24 +467,11 @@ static ssize_t validate_flash_read(struct file *file, char __user *buf,
char msg[RTAS_MSG_MAXLEN]; char msg[RTAS_MSG_MAXLEN];
int msglen; int msglen;
args_buf = (struct rtas_validate_flash_t *) dp->data; args_buf = dp->data;
if (ppos && *ppos != 0)
return 0; /* be cheap */
msglen = get_validate_flash_msg(args_buf, msg); msglen = get_validate_flash_msg(args_buf, msg);
if (msglen > count)
msglen = count;
if (!access_ok(VERIFY_WRITE, buf, msglen))
return -EINVAL;
if (copy_to_user(buf, msg, msglen))
return -EFAULT;
if (ppos) return simple_read_from_buffer(buf, count, ppos, msg, msglen);
*ppos = msglen;
return msglen;
} }
static ssize_t validate_flash_write(struct file *file, const char __user *buf, static ssize_t validate_flash_write(struct file *file, const char __user *buf,
......
...@@ -160,7 +160,7 @@ static int log_rtas_len(char * buf) ...@@ -160,7 +160,7 @@ static int log_rtas_len(char * buf)
/* rtas fixed header */ /* rtas fixed header */
len = 8; len = 8;
err = (struct rtas_error_log *)buf; err = (struct rtas_error_log *)buf;
if (err->extended_log_length) { if (err->extended && err->extended_log_length) {
/* extended header */ /* extended header */
len += err->extended_log_length; len += err->extended_log_length;
......
...@@ -265,11 +265,26 @@ void accumulate_stolen_time(void) ...@@ -265,11 +265,26 @@ void accumulate_stolen_time(void)
{ {
u64 sst, ust; u64 sst, ust;
sst = scan_dispatch_log(get_paca()->starttime_user); u8 save_soft_enabled = local_paca->soft_enabled;
ust = scan_dispatch_log(get_paca()->starttime); u8 save_hard_enabled = local_paca->hard_enabled;
get_paca()->system_time -= sst;
get_paca()->user_time -= ust; /* We are called early in the exception entry, before
get_paca()->stolen_time += ust + sst; * soft/hard_enabled are sync'ed to the expected state
* for the exception. We are hard disabled but the PACA
* needs to reflect that so various debug stuff doesn't
* complain
*/
local_paca->soft_enabled = 0;
local_paca->hard_enabled = 0;
sst = scan_dispatch_log(local_paca->starttime_user);
ust = scan_dispatch_log(local_paca->starttime);
local_paca->system_time -= sst;
local_paca->user_time -= ust;
local_paca->stolen_time += ust + sst;
local_paca->soft_enabled = save_soft_enabled;
local_paca->hard_enabled = save_hard_enabled;
} }
static inline u64 calculate_stolen_time(u64 stop_tb) static inline u64 calculate_stolen_time(u64 stop_tb)
......
...@@ -626,12 +626,6 @@ void machine_check_exception(struct pt_regs *regs) ...@@ -626,12 +626,6 @@ void machine_check_exception(struct pt_regs *regs)
if (recover > 0) if (recover > 0)
return; return;
if (user_mode(regs)) {
regs->msr |= MSR_RI;
_exception(SIGBUS, regs, BUS_ADRERR, regs->nip);
return;
}
#if defined(CONFIG_8xx) && defined(CONFIG_PCI) #if defined(CONFIG_8xx) && defined(CONFIG_PCI)
/* the qspan pci read routines can cause machine checks -- Cort /* the qspan pci read routines can cause machine checks -- Cort
* *
...@@ -643,16 +637,12 @@ void machine_check_exception(struct pt_regs *regs) ...@@ -643,16 +637,12 @@ void machine_check_exception(struct pt_regs *regs)
return; return;
#endif #endif
if (debugger_fault_handler(regs)) { if (debugger_fault_handler(regs))
regs->msr |= MSR_RI;
return; return;
}
if (check_io_access(regs)) if (check_io_access(regs))
return; return;
if (debugger_fault_handler(regs))
return;
die("Machine check", regs, SIGBUS); die("Machine check", regs, SIGBUS);
/* Must die if the interrupt is not recoverable */ /* Must die if the interrupt is not recoverable */
......
...@@ -172,6 +172,25 @@ globl(ftr_fixup_test6_expected) ...@@ -172,6 +172,25 @@ globl(ftr_fixup_test6_expected)
3: or 3,3,3 3: or 3,3,3
#if 0
/* Test that if we have a larger else case the assembler spots it and
* reports an error. #if 0'ed so as not to break the build normally.
*/
ftr_fixup_test7:
or 1,1,1
BEGIN_FTR_SECTION
or 2,2,2
or 2,2,2
or 2,2,2
FTR_SECTION_ELSE
or 3,3,3
or 3,3,3
or 3,3,3
or 3,3,3
ALT_FTR_SECTION_END(0, 1)
or 1,1,1
#endif
#define MAKE_MACRO_TEST(TYPE) \ #define MAKE_MACRO_TEST(TYPE) \
globl(ftr_fixup_test_ ##TYPE##_macros) \ globl(ftr_fixup_test_ ##TYPE##_macros) \
or 1,1,1; \ or 1,1,1; \
......
...@@ -35,6 +35,8 @@ ...@@ -35,6 +35,8 @@
/* system i/o configuration register high */ /* system i/o configuration register high */
#define MPC83XX_SICRH_OFFS 0x118 #define MPC83XX_SICRH_OFFS 0x118
#define MPC8308_SICRH_USB_MASK 0x000c0000
#define MPC8308_SICRH_USB_ULPI 0x00040000
#define MPC834X_SICRH_USB_UTMI 0x00020000 #define MPC834X_SICRH_USB_UTMI 0x00020000
#define MPC831X_SICRH_USB_MASK 0x000000e0 #define MPC831X_SICRH_USB_MASK 0x000000e0
#define MPC831X_SICRH_USB_ULPI 0x000000a0 #define MPC831X_SICRH_USB_ULPI 0x000000a0
......
...@@ -127,7 +127,8 @@ int mpc831x_usb_cfg(void) ...@@ -127,7 +127,8 @@ int mpc831x_usb_cfg(void)
/* Configure clock */ /* Configure clock */
immr_node = of_get_parent(np); immr_node = of_get_parent(np);
if (immr_node && of_device_is_compatible(immr_node, "fsl,mpc8315-immr")) if (immr_node && (of_device_is_compatible(immr_node, "fsl,mpc8315-immr") ||
of_device_is_compatible(immr_node, "fsl,mpc8308-immr")))
clrsetbits_be32(immap + MPC83XX_SCCR_OFFS, clrsetbits_be32(immap + MPC83XX_SCCR_OFFS,
MPC8315_SCCR_USB_MASK, MPC8315_SCCR_USB_MASK,
MPC8315_SCCR_USB_DRCM_01); MPC8315_SCCR_USB_DRCM_01);
...@@ -138,7 +139,11 @@ int mpc831x_usb_cfg(void) ...@@ -138,7 +139,11 @@ int mpc831x_usb_cfg(void)
/* Configure pin mux for ULPI. There is no pin mux for UTMI */ /* Configure pin mux for ULPI. There is no pin mux for UTMI */
if (prop && !strcmp(prop, "ulpi")) { if (prop && !strcmp(prop, "ulpi")) {
if (of_device_is_compatible(immr_node, "fsl,mpc8315-immr")) { if (of_device_is_compatible(immr_node, "fsl,mpc8308-immr")) {
clrsetbits_be32(immap + MPC83XX_SICRH_OFFS,
MPC8308_SICRH_USB_MASK,
MPC8308_SICRH_USB_ULPI);
} else if (of_device_is_compatible(immr_node, "fsl,mpc8315-immr")) {
clrsetbits_be32(immap + MPC83XX_SICRL_OFFS, clrsetbits_be32(immap + MPC83XX_SICRL_OFFS,
MPC8315_SICRL_USB_MASK, MPC8315_SICRL_USB_MASK,
MPC8315_SICRL_USB_ULPI); MPC8315_SICRL_USB_ULPI);
...@@ -173,6 +178,9 @@ int mpc831x_usb_cfg(void) ...@@ -173,6 +178,9 @@ int mpc831x_usb_cfg(void)
!strcmp(prop, "utmi"))) { !strcmp(prop, "utmi"))) {
u32 refsel; u32 refsel;
if (of_device_is_compatible(immr_node, "fsl,mpc8308-immr"))
goto out;
if (of_device_is_compatible(immr_node, "fsl,mpc8315-immr")) if (of_device_is_compatible(immr_node, "fsl,mpc8315-immr"))
refsel = CONTROL_REFSEL_24MHZ; refsel = CONTROL_REFSEL_24MHZ;
else else
...@@ -186,9 +194,11 @@ int mpc831x_usb_cfg(void) ...@@ -186,9 +194,11 @@ int mpc831x_usb_cfg(void)
temp = CONTROL_PHY_CLK_SEL_ULPI; temp = CONTROL_PHY_CLK_SEL_ULPI;
#ifdef CONFIG_USB_OTG #ifdef CONFIG_USB_OTG
/* Set OTG_PORT */ /* Set OTG_PORT */
dr_mode = of_get_property(np, "dr_mode", NULL); if (!of_device_is_compatible(immr_node, "fsl,mpc8308-immr")) {
if (dr_mode && !strcmp(dr_mode, "otg")) dr_mode = of_get_property(np, "dr_mode", NULL);
temp |= CONTROL_OTG_PORT; if (dr_mode && !strcmp(dr_mode, "otg"))
temp |= CONTROL_OTG_PORT;
}
#endif /* CONFIG_USB_OTG */ #endif /* CONFIG_USB_OTG */
out_be32(usb_regs + FSL_USB2_CONTROL_OFFS, temp); out_be32(usb_regs + FSL_USB2_CONTROL_OFFS, temp);
} else { } else {
...@@ -196,6 +206,7 @@ int mpc831x_usb_cfg(void) ...@@ -196,6 +206,7 @@ int mpc831x_usb_cfg(void)
ret = -EINVAL; ret = -EINVAL;
} }
out:
iounmap(usb_regs); iounmap(usb_regs);
of_node_put(np); of_node_put(np);
return ret; return ret;
......
...@@ -39,8 +39,6 @@ struct spu_gov_info_struct { ...@@ -39,8 +39,6 @@ struct spu_gov_info_struct {
}; };
static DEFINE_PER_CPU(struct spu_gov_info_struct, spu_gov_info); static DEFINE_PER_CPU(struct spu_gov_info_struct, spu_gov_info);
static struct workqueue_struct *kspugov_wq;
static int calc_freq(struct spu_gov_info_struct *info) static int calc_freq(struct spu_gov_info_struct *info)
{ {
int cpu; int cpu;
...@@ -71,14 +69,14 @@ static void spu_gov_work(struct work_struct *work) ...@@ -71,14 +69,14 @@ static void spu_gov_work(struct work_struct *work)
__cpufreq_driver_target(info->policy, target_freq, CPUFREQ_RELATION_H); __cpufreq_driver_target(info->policy, target_freq, CPUFREQ_RELATION_H);
delay = usecs_to_jiffies(info->poll_int); delay = usecs_to_jiffies(info->poll_int);
queue_delayed_work_on(info->policy->cpu, kspugov_wq, &info->work, delay); schedule_delayed_work_on(info->policy->cpu, &info->work, delay);
} }
static void spu_gov_init_work(struct spu_gov_info_struct *info) static void spu_gov_init_work(struct spu_gov_info_struct *info)
{ {
int delay = usecs_to_jiffies(info->poll_int); int delay = usecs_to_jiffies(info->poll_int);
INIT_DELAYED_WORK_DEFERRABLE(&info->work, spu_gov_work); INIT_DELAYED_WORK_DEFERRABLE(&info->work, spu_gov_work);
queue_delayed_work_on(info->policy->cpu, kspugov_wq, &info->work, delay); schedule_delayed_work_on(info->policy->cpu, &info->work, delay);
} }
static void spu_gov_cancel_work(struct spu_gov_info_struct *info) static void spu_gov_cancel_work(struct spu_gov_info_struct *info)
...@@ -152,27 +150,15 @@ static int __init spu_gov_init(void) ...@@ -152,27 +150,15 @@ static int __init spu_gov_init(void)
{ {
int ret; int ret;
kspugov_wq = create_workqueue("kspugov");
if (!kspugov_wq) {
printk(KERN_ERR "creation of kspugov failed\n");
ret = -EFAULT;
goto out;
}
ret = cpufreq_register_governor(&spu_governor); ret = cpufreq_register_governor(&spu_governor);
if (ret) { if (ret)
printk(KERN_ERR "registration of governor failed\n"); printk(KERN_ERR "registration of governor failed\n");
destroy_workqueue(kspugov_wq);
goto out;
}
out:
return ret; return ret;
} }
static void __exit spu_gov_exit(void) static void __exit spu_gov_exit(void)
{ {
cpufreq_unregister_governor(&spu_governor); cpufreq_unregister_governor(&spu_governor);
destroy_workqueue(kspugov_wq);
} }
......
...@@ -145,9 +145,4 @@ define_machine(qpace) { ...@@ -145,9 +145,4 @@ define_machine(qpace) {
.calibrate_decr = generic_calibrate_decr, .calibrate_decr = generic_calibrate_decr,
.progress = qpace_progress, .progress = qpace_progress,
.init_IRQ = iic_init_IRQ, .init_IRQ = iic_init_IRQ,
#ifdef CONFIG_KEXEC
.machine_kexec = default_machine_kexec,
.machine_kexec_prepare = default_machine_kexec_prepare,
.machine_crash_shutdown = default_machine_crash_shutdown,
#endif
}; };
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
#include <asm/spu_csa.h> #include <asm/spu_csa.h>
#include <asm/xmon.h> #include <asm/xmon.h>
#include <asm/prom.h> #include <asm/prom.h>
#include <asm/kexec.h>
const struct spu_management_ops *spu_management_ops; const struct spu_management_ops *spu_management_ops;
EXPORT_SYMBOL_GPL(spu_management_ops); EXPORT_SYMBOL_GPL(spu_management_ops);
...@@ -727,6 +728,75 @@ static ssize_t spu_stat_show(struct sys_device *sysdev, ...@@ -727,6 +728,75 @@ static ssize_t spu_stat_show(struct sys_device *sysdev,
static SYSDEV_ATTR(stat, 0644, spu_stat_show, NULL); static SYSDEV_ATTR(stat, 0644, spu_stat_show, NULL);
#ifdef CONFIG_KEXEC
struct crash_spu_info {
struct spu *spu;
u32 saved_spu_runcntl_RW;
u32 saved_spu_status_R;
u32 saved_spu_npc_RW;
u64 saved_mfc_sr1_RW;
u64 saved_mfc_dar;
u64 saved_mfc_dsisr;
};
#define CRASH_NUM_SPUS 16 /* Enough for current hardware */
static struct crash_spu_info crash_spu_info[CRASH_NUM_SPUS];
static void crash_kexec_stop_spus(void)
{
struct spu *spu;
int i;
u64 tmp;
for (i = 0; i < CRASH_NUM_SPUS; i++) {
if (!crash_spu_info[i].spu)
continue;
spu = crash_spu_info[i].spu;
crash_spu_info[i].saved_spu_runcntl_RW =
in_be32(&spu->problem->spu_runcntl_RW);
crash_spu_info[i].saved_spu_status_R =
in_be32(&spu->problem->spu_status_R);
crash_spu_info[i].saved_spu_npc_RW =
in_be32(&spu->problem->spu_npc_RW);
crash_spu_info[i].saved_mfc_dar = spu_mfc_dar_get(spu);
crash_spu_info[i].saved_mfc_dsisr = spu_mfc_dsisr_get(spu);
tmp = spu_mfc_sr1_get(spu);
crash_spu_info[i].saved_mfc_sr1_RW = tmp;
tmp &= ~MFC_STATE1_MASTER_RUN_CONTROL_MASK;
spu_mfc_sr1_set(spu, tmp);
__delay(200);
}
}
static void crash_register_spus(struct list_head *list)
{
struct spu *spu;
int ret;
list_for_each_entry(spu, list, full_list) {
if (WARN_ON(spu->number >= CRASH_NUM_SPUS))
continue;
crash_spu_info[spu->number].spu = spu;
}
ret = crash_shutdown_register(&crash_kexec_stop_spus);
if (ret)
printk(KERN_ERR "Could not register SPU crash handler");
}
#else
static inline void crash_register_spus(struct list_head *list)
{
}
#endif
static int __init init_spu_base(void) static int __init init_spu_base(void)
{ {
int i, ret = 0; int i, ret = 0;
......
...@@ -219,24 +219,17 @@ spufs_mem_write(struct file *file, const char __user *buffer, ...@@ -219,24 +219,17 @@ spufs_mem_write(struct file *file, const char __user *buffer,
loff_t pos = *ppos; loff_t pos = *ppos;
int ret; int ret;
if (pos < 0)
return -EINVAL;
if (pos > LS_SIZE) if (pos > LS_SIZE)
return -EFBIG; return -EFBIG;
if (size > LS_SIZE - pos)
size = LS_SIZE - pos;
ret = spu_acquire(ctx); ret = spu_acquire(ctx);
if (ret) if (ret)
return ret; return ret;
local_store = ctx->ops->get_ls(ctx); local_store = ctx->ops->get_ls(ctx);
ret = copy_from_user(local_store + pos, buffer, size); size = simple_write_to_buffer(local_store, LS_SIZE, ppos, buffer, size);
spu_release(ctx); spu_release(ctx);
if (ret)
return -EFAULT;
*ppos = pos + size;
return size; return size;
} }
...@@ -574,18 +567,15 @@ spufs_regs_write(struct file *file, const char __user *buffer, ...@@ -574,18 +567,15 @@ spufs_regs_write(struct file *file, const char __user *buffer,
if (*pos >= sizeof(lscsa->gprs)) if (*pos >= sizeof(lscsa->gprs))
return -EFBIG; return -EFBIG;
size = min_t(ssize_t, sizeof(lscsa->gprs) - *pos, size);
*pos += size;
ret = spu_acquire_saved(ctx); ret = spu_acquire_saved(ctx);
if (ret) if (ret)
return ret; return ret;
ret = copy_from_user((char *)lscsa->gprs + *pos - size, size = simple_write_to_buffer(lscsa->gprs, sizeof(lscsa->gprs), pos,
buffer, size) ? -EFAULT : size; buffer, size);
spu_release_saved(ctx); spu_release_saved(ctx);
return ret; return size;
} }
static const struct file_operations spufs_regs_fops = { static const struct file_operations spufs_regs_fops = {
...@@ -630,18 +620,15 @@ spufs_fpcr_write(struct file *file, const char __user * buffer, ...@@ -630,18 +620,15 @@ spufs_fpcr_write(struct file *file, const char __user * buffer,
if (*pos >= sizeof(lscsa->fpcr)) if (*pos >= sizeof(lscsa->fpcr))
return -EFBIG; return -EFBIG;
size = min_t(ssize_t, sizeof(lscsa->fpcr) - *pos, size);
ret = spu_acquire_saved(ctx); ret = spu_acquire_saved(ctx);
if (ret) if (ret)
return ret; return ret;
*pos += size; size = simple_write_to_buffer(&lscsa->fpcr, sizeof(lscsa->fpcr), pos,
ret = copy_from_user((char *)&lscsa->fpcr + *pos - size, buffer, size);
buffer, size) ? -EFAULT : size;
spu_release_saved(ctx); spu_release_saved(ctx);
return ret; return size;
} }
static const struct file_operations spufs_fpcr_fops = { static const struct file_operations spufs_fpcr_fops = {
......
...@@ -75,14 +75,6 @@ static void gamecube_shutdown(void) ...@@ -75,14 +75,6 @@ static void gamecube_shutdown(void)
flipper_quiesce(); flipper_quiesce();
} }
#ifdef CONFIG_KEXEC
static int gamecube_kexec_prepare(struct kimage *image)
{
return 0;
}
#endif /* CONFIG_KEXEC */
define_machine(gamecube) { define_machine(gamecube) {
.name = "gamecube", .name = "gamecube",
.probe = gamecube_probe, .probe = gamecube_probe,
...@@ -95,9 +87,6 @@ define_machine(gamecube) { ...@@ -95,9 +87,6 @@ define_machine(gamecube) {
.calibrate_decr = generic_calibrate_decr, .calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress, .progress = udbg_progress,
.machine_shutdown = gamecube_shutdown, .machine_shutdown = gamecube_shutdown,
#ifdef CONFIG_KEXEC
.machine_kexec_prepare = gamecube_kexec_prepare,
#endif
}; };
......
...@@ -18,7 +18,6 @@ ...@@ -18,7 +18,6 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/seq_file.h> #include <linux/seq_file.h>
#include <linux/kexec.h>
#include <linux/of_platform.h> #include <linux/of_platform.h>
#include <linux/memblock.h> #include <linux/memblock.h>
#include <mm/mmu_decl.h> #include <mm/mmu_decl.h>
...@@ -226,13 +225,6 @@ static void wii_shutdown(void) ...@@ -226,13 +225,6 @@ static void wii_shutdown(void)
flipper_quiesce(); flipper_quiesce();
} }
#ifdef CONFIG_KEXEC
static int wii_machine_kexec_prepare(struct kimage *image)
{
return 0;
}
#endif /* CONFIG_KEXEC */
define_machine(wii) { define_machine(wii) {
.name = "wii", .name = "wii",
.probe = wii_probe, .probe = wii_probe,
...@@ -246,9 +238,6 @@ define_machine(wii) { ...@@ -246,9 +238,6 @@ define_machine(wii) {
.calibrate_decr = generic_calibrate_decr, .calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress, .progress = udbg_progress,
.machine_shutdown = wii_shutdown, .machine_shutdown = wii_shutdown,
#ifdef CONFIG_KEXEC
.machine_kexec_prepare = wii_machine_kexec_prepare,
#endif
}; };
static struct of_device_id wii_of_bus[] = { static struct of_device_id wii_of_bus[] = {
......
...@@ -61,13 +61,3 @@ void __init setup_kexec_cpu_down_xics(void) ...@@ -61,13 +61,3 @@ void __init setup_kexec_cpu_down_xics(void)
{ {
ppc_md.kexec_cpu_down = pseries_kexec_cpu_down_xics; ppc_md.kexec_cpu_down = pseries_kexec_cpu_down_xics;
} }
static int __init pseries_kexec_setup(void)
{
ppc_md.machine_kexec = default_machine_kexec;
ppc_md.machine_kexec_prepare = default_machine_kexec_prepare;
ppc_md.machine_crash_shutdown = default_machine_crash_shutdown;
return 0;
}
machine_device_initcall(pseries, pseries_kexec_setup);
...@@ -54,7 +54,8 @@ ...@@ -54,7 +54,8 @@
static unsigned char ras_log_buf[RTAS_ERROR_LOG_MAX]; static unsigned char ras_log_buf[RTAS_ERROR_LOG_MAX];
static DEFINE_SPINLOCK(ras_log_buf_lock); static DEFINE_SPINLOCK(ras_log_buf_lock);
static char mce_data_buf[RTAS_ERROR_LOG_MAX]; static char global_mce_data_buf[RTAS_ERROR_LOG_MAX];
static DEFINE_PER_CPU(__u64, mce_data_buf);
static int ras_get_sensor_state_token; static int ras_get_sensor_state_token;
static int ras_check_exception_token; static int ras_check_exception_token;
...@@ -196,12 +197,24 @@ static irqreturn_t ras_error_interrupt(int irq, void *dev_id) ...@@ -196,12 +197,24 @@ static irqreturn_t ras_error_interrupt(int irq, void *dev_id)
return IRQ_HANDLED; return IRQ_HANDLED;
} }
/* Get the error information for errors coming through the /*
* Some versions of FWNMI place the buffer inside the 4kB page starting at
* 0x7000. Other versions place it inside the rtas buffer. We check both.
*/
#define VALID_FWNMI_BUFFER(A) \
((((A) >= 0x7000) && ((A) < 0x7ff0)) || \
(((A) >= rtas.base) && ((A) < (rtas.base + rtas.size - 16))))
/*
* Get the error information for errors coming through the
* FWNMI vectors. The pt_regs' r3 will be updated to reflect * FWNMI vectors. The pt_regs' r3 will be updated to reflect
* the actual r3 if possible, and a ptr to the error log entry * the actual r3 if possible, and a ptr to the error log entry
* will be returned if found. * will be returned if found.
* *
* The mce_data_buf does not have any locks or protection around it, * If the RTAS error is not of the extended type, then we put it in a per
* cpu 64bit buffer. If it is the extended type we use global_mce_data_buf.
*
* The global_mce_data_buf does not have any locks or protection around it,
* if a second machine check comes in, or a system reset is done * if a second machine check comes in, or a system reset is done
* before we have logged the error, then we will get corruption in the * before we have logged the error, then we will get corruption in the
* error log. This is preferable over holding off on calling * error log. This is preferable over holding off on calling
...@@ -210,20 +223,31 @@ static irqreturn_t ras_error_interrupt(int irq, void *dev_id) ...@@ -210,20 +223,31 @@ static irqreturn_t ras_error_interrupt(int irq, void *dev_id)
*/ */
static struct rtas_error_log *fwnmi_get_errinfo(struct pt_regs *regs) static struct rtas_error_log *fwnmi_get_errinfo(struct pt_regs *regs)
{ {
unsigned long errdata = regs->gpr[3];
struct rtas_error_log *errhdr = NULL;
unsigned long *savep; unsigned long *savep;
struct rtas_error_log *h, *errhdr = NULL;
if (!VALID_FWNMI_BUFFER(regs->gpr[3])) {
printk(KERN_ERR "FWNMI: corrupt r3\n");
return NULL;
}
if ((errdata >= 0x7000 && errdata < 0x7fff0) || savep = __va(regs->gpr[3]);
(errdata >= rtas.base && errdata < rtas.base + rtas.size - 16)) { regs->gpr[3] = savep[0]; /* restore original r3 */
savep = __va(errdata);
regs->gpr[3] = savep[0]; /* restore original r3 */ /* If it isn't an extended log we can use the per cpu 64bit buffer */
memset(mce_data_buf, 0, RTAS_ERROR_LOG_MAX); h = (struct rtas_error_log *)&savep[1];
memcpy(mce_data_buf, (char *)(savep + 1), RTAS_ERROR_LOG_MAX); if (!h->extended) {
errhdr = (struct rtas_error_log *)mce_data_buf; memcpy(&__get_cpu_var(mce_data_buf), h, sizeof(__u64));
errhdr = (struct rtas_error_log *)&__get_cpu_var(mce_data_buf);
} else { } else {
printk("FWNMI: corrupt r3\n"); int len;
len = max_t(int, 8+h->extended_log_length, RTAS_ERROR_LOG_MAX);
memset(global_mce_data_buf, 0, RTAS_ERROR_LOG_MAX);
memcpy(global_mce_data_buf, h, len);
errhdr = (struct rtas_error_log *)global_mce_data_buf;
} }
return errhdr; return errhdr;
} }
...@@ -235,7 +259,7 @@ static void fwnmi_release_errinfo(void) ...@@ -235,7 +259,7 @@ static void fwnmi_release_errinfo(void)
{ {
int ret = rtas_call(rtas_token("ibm,nmi-interlock"), 0, 1, NULL); int ret = rtas_call(rtas_token("ibm,nmi-interlock"), 0, 1, NULL);
if (ret != 0) if (ret != 0)
printk("FWNMI: nmi-interlock failed: %d\n", ret); printk(KERN_ERR "FWNMI: nmi-interlock failed: %d\n", ret);
} }
int pSeries_system_reset_exception(struct pt_regs *regs) int pSeries_system_reset_exception(struct pt_regs *regs)
...@@ -259,31 +283,43 @@ int pSeries_system_reset_exception(struct pt_regs *regs) ...@@ -259,31 +283,43 @@ int pSeries_system_reset_exception(struct pt_regs *regs)
* Return 1 if corrected (or delivered a signal). * Return 1 if corrected (or delivered a signal).
* Return 0 if there is nothing we can do. * Return 0 if there is nothing we can do.
*/ */
static int recover_mce(struct pt_regs *regs, struct rtas_error_log * err) static int recover_mce(struct pt_regs *regs, struct rtas_error_log *err)
{ {
int nonfatal = 0; int recovered = 0;
if (err->disposition == RTAS_DISP_FULLY_RECOVERED) { if (!(regs->msr & MSR_RI)) {
/* If MSR_RI isn't set, we cannot recover */
recovered = 0;
} else if (err->disposition == RTAS_DISP_FULLY_RECOVERED) {
/* Platform corrected itself */ /* Platform corrected itself */
nonfatal = 1; recovered = 1;
} else if ((regs->msr & MSR_RI) &&
user_mode(regs) && } else if (err->disposition == RTAS_DISP_LIMITED_RECOVERY) {
err->severity == RTAS_SEVERITY_ERROR_SYNC && /* Platform corrected itself but could be degraded */
err->disposition == RTAS_DISP_NOT_RECOVERED && printk(KERN_ERR "MCE: limited recovery, system may "
err->target == RTAS_TARGET_MEMORY && "be degraded\n");
err->type == RTAS_TYPE_ECC_UNCORR && recovered = 1;
!(current->pid == 0 || is_global_init(current))) {
/* Kill off a user process with an ECC error */ } else if (user_mode(regs) && !is_global_init(current) &&
printk(KERN_ERR "MCE: uncorrectable ecc error for pid %d\n", err->severity == RTAS_SEVERITY_ERROR_SYNC) {
current->pid);
/* XXX something better for ECC error? */ /*
_exception(SIGBUS, regs, BUS_ADRERR, regs->nip); * If we received a synchronous error when in userspace
nonfatal = 1; * kill the task. Firmware may report details of the fail
* asynchronously, so we can't rely on the target and type
* fields being valid here.
*/
printk(KERN_ERR "MCE: uncorrectable error, killing task "
"%s:%d\n", current->comm, current->pid);
_exception(SIGBUS, regs, BUS_MCEERR_AR, regs->nip);
recovered = 1;
} }
log_error((char *)err, ERR_TYPE_RTAS_LOG, !nonfatal); log_error((char *)err, ERR_TYPE_RTAS_LOG, 0);
return nonfatal; return recovered;
} }
/* /*
......
...@@ -1555,8 +1555,6 @@ int fsl_rio_setup(struct platform_device *dev) ...@@ -1555,8 +1555,6 @@ int fsl_rio_setup(struct platform_device *dev)
saved_mcheck_exception = ppc_md.machine_check_exception; saved_mcheck_exception = ppc_md.machine_check_exception;
ppc_md.machine_check_exception = fsl_rio_mcheck_exception; ppc_md.machine_check_exception = fsl_rio_mcheck_exception;
#endif #endif
/* Ensure that RFXE is set */
mtspr(SPRN_HID1, (mfspr(SPRN_HID1) | 0x20000));
return 0; return 0;
err: err:
......
...@@ -674,7 +674,8 @@ void mpic_unmask_irq(unsigned int irq) ...@@ -674,7 +674,8 @@ void mpic_unmask_irq(unsigned int irq)
/* make sure mask gets to controller before we return to user */ /* make sure mask gets to controller before we return to user */
do { do {
if (!loops--) { if (!loops--) {
printk(KERN_ERR "mpic_enable_irq timeout\n"); printk(KERN_ERR "%s: timeout on hwirq %u\n",
__func__, src);
break; break;
} }
} while(mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) & MPIC_VECPRI_MASK); } while(mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) & MPIC_VECPRI_MASK);
...@@ -695,7 +696,8 @@ void mpic_mask_irq(unsigned int irq) ...@@ -695,7 +696,8 @@ void mpic_mask_irq(unsigned int irq)
/* make sure mask gets to controller before we return to user */ /* make sure mask gets to controller before we return to user */
do { do {
if (!loops--) { if (!loops--) {
printk(KERN_ERR "mpic_enable_irq timeout\n"); printk(KERN_ERR "%s: timeout on hwirq %u\n",
__func__, src);
break; break;
} }
} while(!(mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) & MPIC_VECPRI_MASK)); } while(!(mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) & MPIC_VECPRI_MASK));
......
...@@ -443,7 +443,7 @@ static int fan_read_reg(int reg, unsigned char *buf, int nb) ...@@ -443,7 +443,7 @@ static int fan_read_reg(int reg, unsigned char *buf, int nb)
tries = 0; tries = 0;
for (;;) { for (;;) {
nr = i2c_master_recv(fcu, buf, nb); nr = i2c_master_recv(fcu, buf, nb);
if (nr > 0 || (nr < 0 && nr != ENODEV) || tries >= 100) if (nr > 0 || (nr < 0 && nr != -ENODEV) || tries >= 100)
break; break;
msleep(10); msleep(10);
++tries; ++tries;
...@@ -464,7 +464,7 @@ static int fan_write_reg(int reg, const unsigned char *ptr, int nb) ...@@ -464,7 +464,7 @@ static int fan_write_reg(int reg, const unsigned char *ptr, int nb)
tries = 0; tries = 0;
for (;;) { for (;;) {
nw = i2c_master_send(fcu, buf, nb); nw = i2c_master_send(fcu, buf, nb);
if (nw > 0 || (nw < 0 && nw != EIO) || tries >= 100) if (nw > 0 || (nw < 0 && nw != -EIO) || tries >= 100)
break; break;
msleep(10); msleep(10);
++tries; ++tries;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment