aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/include/asm/machdep.h1
-rw-r--r--arch/powerpc/include/asm/paca.h2
-rw-r--r--arch/powerpc/include/asm/ppc-opcode.h6
-rw-r--r--arch/powerpc/kernel/Makefile1
-rw-r--r--arch/powerpc/kernel/exceptions-64s.S30
-rw-r--r--arch/powerpc/kernel/idle_power7.S97
-rw-r--r--arch/powerpc/platforms/Kconfig4
7 files changed, 139 insertions, 2 deletions
diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h
index e4f01915fbb0..493dbb38e1ba 100644
--- a/arch/powerpc/include/asm/machdep.h
+++ b/arch/powerpc/include/asm/machdep.h
@@ -267,6 +267,7 @@ struct machdep_calls {
267 267
268extern void e500_idle(void); 268extern void e500_idle(void);
269extern void power4_idle(void); 269extern void power4_idle(void);
270extern void power7_idle(void);
270extern void ppc6xx_idle(void); 271extern void ppc6xx_idle(void);
271extern void book3e_idle(void); 272extern void book3e_idle(void);
272 273
diff --git a/arch/powerpc/include/asm/paca.h b/arch/powerpc/include/asm/paca.h
index ec57540cd7af..f6da4f517fca 100644
--- a/arch/powerpc/include/asm/paca.h
+++ b/arch/powerpc/include/asm/paca.h
@@ -125,7 +125,7 @@ struct paca_struct {
125 struct task_struct *__current; /* Pointer to current */ 125 struct task_struct *__current; /* Pointer to current */
126 u64 kstack; /* Saved Kernel stack addr */ 126 u64 kstack; /* Saved Kernel stack addr */
127 u64 stab_rr; /* stab/slb round-robin counter */ 127 u64 stab_rr; /* stab/slb round-robin counter */
128 u64 saved_r1; /* r1 save for RTAS calls */ 128 u64 saved_r1; /* r1 save for RTAS calls or PM */
129 u64 saved_msr; /* MSR saved here by enter_rtas */ 129 u64 saved_msr; /* MSR saved here by enter_rtas */
130 u16 trap_save; /* Used when bad stack is encountered */ 130 u16 trap_save; /* Used when bad stack is encountered */
131 u8 soft_enabled; /* irq soft-enable flag */ 131 u8 soft_enabled; /* irq soft-enable flag */
diff --git a/arch/powerpc/include/asm/ppc-opcode.h b/arch/powerpc/include/asm/ppc-opcode.h
index 1255569387b6..384a96db794a 100644
--- a/arch/powerpc/include/asm/ppc-opcode.h
+++ b/arch/powerpc/include/asm/ppc-opcode.h
@@ -56,6 +56,9 @@
56#define PPC_INST_TLBSRX_DOT 0x7c0006a5 56#define PPC_INST_TLBSRX_DOT 0x7c0006a5
57#define PPC_INST_XXLOR 0xf0000510 57#define PPC_INST_XXLOR 0xf0000510
58 58
59#define PPC_INST_NAP 0x4c000364
60#define PPC_INST_SLEEP 0x4c0003a4
61
59/* macros to insert fields into opcodes */ 62/* macros to insert fields into opcodes */
60#define __PPC_RA(a) (((a) & 0x1f) << 16) 63#define __PPC_RA(a) (((a) & 0x1f) << 16)
61#define __PPC_RB(b) (((b) & 0x1f) << 11) 64#define __PPC_RB(b) (((b) & 0x1f) << 11)
@@ -126,4 +129,7 @@
126#define XXLOR(t, a, b) stringify_in_c(.long PPC_INST_XXLOR | \ 129#define XXLOR(t, a, b) stringify_in_c(.long PPC_INST_XXLOR | \
127 VSX_XX3((t), (a), (b))) 130 VSX_XX3((t), (a), (b)))
128 131
132#define PPC_NAP stringify_in_c(.long PPC_INST_NAP)
133#define PPC_SLEEP stringify_in_c(.long PPC_INST_SLEEP)
134
129#endif /* _ASM_POWERPC_PPC_OPCODE_H */ 135#endif /* _ASM_POWERPC_PPC_OPCODE_H */
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 7c6eb4974f25..0fd6273bb8a9 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -44,6 +44,7 @@ obj-$(CONFIG_PPC_BOOK3E_64) += exceptions-64e.o idle_book3e.o
44obj-$(CONFIG_PPC64) += vdso64/ 44obj-$(CONFIG_PPC64) += vdso64/
45obj-$(CONFIG_ALTIVEC) += vecemu.o 45obj-$(CONFIG_ALTIVEC) += vecemu.o
46obj-$(CONFIG_PPC_970_NAP) += idle_power4.o 46obj-$(CONFIG_PPC_970_NAP) += idle_power4.o
47obj-$(CONFIG_PPC_P7_NAP) += idle_power7.o
47obj-$(CONFIG_PPC_OF) += of_platform.o prom_parse.o 48obj-$(CONFIG_PPC_OF) += of_platform.o prom_parse.o
48obj-$(CONFIG_PPC_CLOCK) += clock.o 49obj-$(CONFIG_PPC_CLOCK) += clock.o
49procfs-y := proc_powerpc.o 50procfs-y := proc_powerpc.o
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index e513c1d35b2a..ad06333631ac 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -37,7 +37,35 @@
37 .globl __start_interrupts 37 .globl __start_interrupts
38__start_interrupts: 38__start_interrupts:
39 39
40 STD_EXCEPTION_PSERIES(0x100, 0x100, system_reset) 40 .globl system_reset_pSeries;
41system_reset_pSeries:
42 HMT_MEDIUM;
43 DO_KVM 0x100;
44 SET_SCRATCH0(r13)
45#ifdef CONFIG_PPC_P7_NAP
46BEGIN_FTR_SECTION
47 /* Running native on arch 2.06 or later, check if we are
48 * waking up from nap. We only handle no state loss and
49 * supervisor state loss. We do -not- handle hypervisor
50 * state loss at this time.
51 */
52 mfspr r13,SPRN_SRR1
53 rlwinm r13,r13,47-31,30,31
54 cmpwi cr0,r13,1
55 bne 1f
56 b .power7_wakeup_noloss
571: cmpwi cr0,r13,2
58 bne 1f
59 b .power7_wakeup_loss
60 /* Total loss of HV state is fatal, we could try to use the
61 * PIR to locate a PACA, then use an emergency stack etc...
62 * but for now, let's just stay stuck here
63 */
641: cmpwi cr0,r13,3
65 beq .
66END_FTR_SECTION_IFSET(CPU_FTR_HVMODE_206)
67#endif /* CONFIG_PPC_P7_NAP */
68 EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common, EXC_STD)
41 69
42 . = 0x200 70 . = 0x200
43_machine_check_pSeries: 71_machine_check_pSeries:
diff --git a/arch/powerpc/kernel/idle_power7.S b/arch/powerpc/kernel/idle_power7.S
new file mode 100644
index 000000000000..f8f0bc7f1d4f
--- /dev/null
+++ b/arch/powerpc/kernel/idle_power7.S
@@ -0,0 +1,97 @@
1/*
2 * This file contains the power_save function for 970-family CPUs.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 */
9
10#include <linux/threads.h>
11#include <asm/processor.h>
12#include <asm/page.h>
13#include <asm/cputable.h>
14#include <asm/thread_info.h>
15#include <asm/ppc_asm.h>
16#include <asm/asm-offsets.h>
17#include <asm/ppc-opcode.h>
18
19#undef DEBUG
20
21 .text
22
23_GLOBAL(power7_idle)
24 /* Now check if user or arch enabled NAP mode */
25 LOAD_REG_ADDRBASE(r3,powersave_nap)
26 lwz r4,ADDROFF(powersave_nap)(r3)
27 cmpwi 0,r4,0
28 beqlr
29
30 /* NAP is a state loss, we create a regs frame on the
31 * stack, fill it up with the state we care about and
32 * stick a pointer to it in PACAR1. We really only
33 * need to save PC, some CR bits and the NV GPRs,
34 * but for now an interrupt frame will do.
35 */
36 mflr r0
37 std r0,16(r1)
38 stdu r1,-INT_FRAME_SIZE(r1)
39 std r0,_LINK(r1)
40 std r0,_NIP(r1)
41
42#ifndef CONFIG_SMP
43 /* Make sure FPU, VSX etc... are flushed as we may lose
44 * state when going to nap mode
45 */
46 bl .discard_lazy_cpu_state
47#endif /* CONFIG_SMP */
48
49 /* Hard disable interrupts */
50 mfmsr r9
51 rldicl r9,r9,48,1
52 rotldi r9,r9,16
53 mtmsrd r9,1 /* hard-disable interrupts */
54 li r0,0
55 stb r0,PACASOFTIRQEN(r13) /* we'll hard-enable shortly */
56 stb r0,PACAHARDIRQEN(r13)
57
58 /* Continue saving state */
59 SAVE_GPR(2, r1)
60 SAVE_NVGPRS(r1)
61 mfcr r3
62 std r3,_CCR(r1)
63 std r9,_MSR(r1)
64 std r1,PACAR1(r13)
65
66 /* Magic NAP mode enter sequence */
67 std r0,0(r1)
68 ptesync
69 ld r0,0(r1)
701: cmp cr0,r0,r0
71 bne 1b
72 PPC_NAP
73 b .
74
75_GLOBAL(power7_wakeup_loss)
76 GET_PACA(r13)
77 ld r1,PACAR1(r13)
78 REST_NVGPRS(r1)
79 REST_GPR(2, r1)
80 ld r3,_CCR(r1)
81 ld r4,_MSR(r1)
82 ld r5,_NIP(r1)
83 addi r1,r1,INT_FRAME_SIZE
84 mtcr r3
85 mtspr SPRN_SRR1,r4
86 mtspr SPRN_SRR0,r5
87 rfid
88
89_GLOBAL(power7_wakeup_noloss)
90 GET_PACA(r13)
91 ld r1,PACAR1(r13)
92 ld r4,_MSR(r1)
93 ld r5,_NIP(r1)
94 addi r1,r1,INT_FRAME_SIZE
95 mtspr SPRN_SRR1,r4
96 mtspr SPRN_SRR0,r5
97 rfid
diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig
index f7b07720aa30..658ffc50493d 100644
--- a/arch/powerpc/platforms/Kconfig
+++ b/arch/powerpc/platforms/Kconfig
@@ -147,6 +147,10 @@ config PPC_970_NAP
147 bool 147 bool
148 default n 148 default n
149 149
150config PPC_P7_NAP
151 bool
152 default n
153
150config PPC_INDIRECT_IO 154config PPC_INDIRECT_IO
151 bool 155 bool
152 select GENERIC_IOMAP 156 select GENERIC_IOMAP