diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-04-18 13:34:24 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-04-18 13:34:24 -0400 |
commit | 6fbe85f914ad08cc43408a40ad18a561222e1b93 (patch) | |
tree | 320da01ba20dcbf6d31d80d35b1217193d663814 /arch/powerpc/kernel | |
parent | a9a5cd5d2a57fb76dbae2115450f777b69beccf7 (diff) | |
parent | f39224a8c1828bdd327539da72a53d8a13595838 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc-merge
* git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc-merge:
powerpc: Use correct sequence for putting CPU into nap mode
[PATCH] spufs: fix context-switch decrementer code
[PATCH] powerpc32: Set cpu explicitly in kernel compiles
[PATCH] powerpc/pseries: bugfix: balance calls to pci_device_put
[PATCH] powerpc: Fix machine detection in prom_init.c
[PATCH] ppc32: Fix string comparing in platform_notify_map
[PATCH] powerpc: Avoid __initcall warnings
[PATCH] powerpc: Ensure runlatch is off in the idle loop
powerpc: Fix CHRP booting - needs a define_machine call
powerpc: iSeries has only 256 IRQs
Diffstat (limited to 'arch/powerpc/kernel')
-rw-r--r-- | arch/powerpc/kernel/Makefile | 2 | ||||
-rw-r--r-- | arch/powerpc/kernel/asm-offsets.c | 1 | ||||
-rw-r--r-- | arch/powerpc/kernel/entry_32.S | 35 | ||||
-rw-r--r-- | arch/powerpc/kernel/head_64.S | 49 | ||||
-rw-r--r-- | arch/powerpc/kernel/idle.c | 4 | ||||
-rw-r--r-- | arch/powerpc/kernel/idle_6xx.S | 63 | ||||
-rw-r--r-- | arch/powerpc/kernel/idle_power4.S | 10 | ||||
-rw-r--r-- | arch/powerpc/kernel/irq.c | 36 | ||||
-rw-r--r-- | arch/powerpc/kernel/prom_init.c | 5 | ||||
-rw-r--r-- | arch/powerpc/kernel/rtas-proc.c | 4 |
10 files changed, 123 insertions, 86 deletions
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 0cc0995b81b0..803858e86160 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile | |||
@@ -20,7 +20,7 @@ obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \ | |||
20 | firmware.o sysfs.o | 20 | firmware.o sysfs.o |
21 | obj-$(CONFIG_PPC64) += vdso64/ | 21 | obj-$(CONFIG_PPC64) += vdso64/ |
22 | obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o | 22 | obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o |
23 | obj-$(CONFIG_POWER4) += idle_power4.o | 23 | obj-$(CONFIG_PPC_970_NAP) += idle_power4.o |
24 | obj-$(CONFIG_PPC_OF) += of_device.o prom_parse.o | 24 | obj-$(CONFIG_PPC_OF) += of_device.o prom_parse.o |
25 | procfs-$(CONFIG_PPC64) := proc_ppc64.o | 25 | procfs-$(CONFIG_PPC64) := proc_ppc64.o |
26 | obj-$(CONFIG_PROC_FS) += $(procfs-y) | 26 | obj-$(CONFIG_PROC_FS) += $(procfs-y) |
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 54b48f330051..8f85c5e8a55a 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c | |||
@@ -91,6 +91,7 @@ int main(void) | |||
91 | #endif /* CONFIG_PPC64 */ | 91 | #endif /* CONFIG_PPC64 */ |
92 | 92 | ||
93 | DEFINE(TI_FLAGS, offsetof(struct thread_info, flags)); | 93 | DEFINE(TI_FLAGS, offsetof(struct thread_info, flags)); |
94 | DEFINE(TI_LOCAL_FLAGS, offsetof(struct thread_info, local_flags)); | ||
94 | DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count)); | 95 | DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count)); |
95 | DEFINE(TI_TASK, offsetof(struct thread_info, task)); | 96 | DEFINE(TI_TASK, offsetof(struct thread_info, task)); |
96 | #ifdef CONFIG_PPC32 | 97 | #ifdef CONFIG_PPC32 |
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S index b3a979467225..8866fd26c6b9 100644 --- a/arch/powerpc/kernel/entry_32.S +++ b/arch/powerpc/kernel/entry_32.S | |||
@@ -128,37 +128,36 @@ transfer_to_handler: | |||
128 | stw r12,4(r11) | 128 | stw r12,4(r11) |
129 | #endif | 129 | #endif |
130 | b 3f | 130 | b 3f |
131 | |||
131 | 2: /* if from kernel, check interrupted DOZE/NAP mode and | 132 | 2: /* if from kernel, check interrupted DOZE/NAP mode and |
132 | * check for stack overflow | 133 | * check for stack overflow |
133 | */ | 134 | */ |
135 | lwz r9,THREAD_INFO-THREAD(r12) | ||
136 | cmplw r1,r9 /* if r1 <= current->thread_info */ | ||
137 | ble- stack_ovf /* then the kernel stack overflowed */ | ||
138 | 5: | ||
134 | #ifdef CONFIG_6xx | 139 | #ifdef CONFIG_6xx |
135 | mfspr r11,SPRN_HID0 | 140 | tophys(r9,r9) /* check local flags */ |
136 | mtcr r11 | 141 | lwz r12,TI_LOCAL_FLAGS(r9) |
137 | BEGIN_FTR_SECTION | 142 | mtcrf 0x01,r12 |
138 | bt- 8,4f /* Check DOZE */ | 143 | bt- 31-TLF_NAPPING,4f |
139 | END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE) | ||
140 | BEGIN_FTR_SECTION | ||
141 | bt- 9,4f /* Check NAP */ | ||
142 | END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP) | ||
143 | #endif /* CONFIG_6xx */ | 144 | #endif /* CONFIG_6xx */ |
144 | .globl transfer_to_handler_cont | 145 | .globl transfer_to_handler_cont |
145 | transfer_to_handler_cont: | 146 | transfer_to_handler_cont: |
146 | lwz r11,THREAD_INFO-THREAD(r12) | ||
147 | cmplw r1,r11 /* if r1 <= current->thread_info */ | ||
148 | ble- stack_ovf /* then the kernel stack overflowed */ | ||
149 | 3: | 147 | 3: |
150 | mflr r9 | 148 | mflr r9 |
151 | lwz r11,0(r9) /* virtual address of handler */ | 149 | lwz r11,0(r9) /* virtual address of handler */ |
152 | lwz r9,4(r9) /* where to go when done */ | 150 | lwz r9,4(r9) /* where to go when done */ |
153 | FIX_SRR1(r10,r12) | ||
154 | mtspr SPRN_SRR0,r11 | 151 | mtspr SPRN_SRR0,r11 |
155 | mtspr SPRN_SRR1,r10 | 152 | mtspr SPRN_SRR1,r10 |
156 | mtlr r9 | 153 | mtlr r9 |
157 | SYNC | 154 | SYNC |
158 | RFI /* jump to handler, enable MMU */ | 155 | RFI /* jump to handler, enable MMU */ |
159 | 156 | ||
160 | #ifdef CONFIG_6xx | 157 | #ifdef CONFIG_6xx |
161 | 4: b power_save_6xx_restore | 158 | 4: rlwinm r12,r12,0,~_TLF_NAPPING |
159 | stw r12,TI_LOCAL_FLAGS(r9) | ||
160 | b power_save_6xx_restore | ||
162 | #endif | 161 | #endif |
163 | 162 | ||
164 | /* | 163 | /* |
@@ -167,10 +166,10 @@ transfer_to_handler_cont: | |||
167 | */ | 166 | */ |
168 | stack_ovf: | 167 | stack_ovf: |
169 | /* sometimes we use a statically-allocated stack, which is OK. */ | 168 | /* sometimes we use a statically-allocated stack, which is OK. */ |
170 | lis r11,_end@h | 169 | lis r12,_end@h |
171 | ori r11,r11,_end@l | 170 | ori r12,r12,_end@l |
172 | cmplw r1,r11 | 171 | cmplw r1,r12 |
173 | ble 3b /* r1 <= &_end is OK */ | 172 | ble 5b /* r1 <= &_end is OK */ |
174 | SAVE_NVGPRS(r11) | 173 | SAVE_NVGPRS(r11) |
175 | addi r3,r1,STACK_FRAME_OVERHEAD | 174 | addi r3,r1,STACK_FRAME_OVERHEAD |
176 | lis r1,init_thread_union@ha | 175 | lis r1,init_thread_union@ha |
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index a5ae04a57c78..b7d140430a41 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S | |||
@@ -376,11 +376,28 @@ label##_common: \ | |||
376 | bl hdlr; \ | 376 | bl hdlr; \ |
377 | b .ret_from_except | 377 | b .ret_from_except |
378 | 378 | ||
379 | /* | ||
380 | * Like STD_EXCEPTION_COMMON, but for exceptions that can occur | ||
381 | * in the idle task and therefore need the special idle handling. | ||
382 | */ | ||
383 | #define STD_EXCEPTION_COMMON_IDLE(trap, label, hdlr) \ | ||
384 | .align 7; \ | ||
385 | .globl label##_common; \ | ||
386 | label##_common: \ | ||
387 | EXCEPTION_PROLOG_COMMON(trap, PACA_EXGEN); \ | ||
388 | FINISH_NAP; \ | ||
389 | DISABLE_INTS; \ | ||
390 | bl .save_nvgprs; \ | ||
391 | addi r3,r1,STACK_FRAME_OVERHEAD; \ | ||
392 | bl hdlr; \ | ||
393 | b .ret_from_except | ||
394 | |||
379 | #define STD_EXCEPTION_COMMON_LITE(trap, label, hdlr) \ | 395 | #define STD_EXCEPTION_COMMON_LITE(trap, label, hdlr) \ |
380 | .align 7; \ | 396 | .align 7; \ |
381 | .globl label##_common; \ | 397 | .globl label##_common; \ |
382 | label##_common: \ | 398 | label##_common: \ |
383 | EXCEPTION_PROLOG_COMMON(trap, PACA_EXGEN); \ | 399 | EXCEPTION_PROLOG_COMMON(trap, PACA_EXGEN); \ |
400 | FINISH_NAP; \ | ||
384 | DISABLE_INTS; \ | 401 | DISABLE_INTS; \ |
385 | bl .ppc64_runlatch_on; \ | 402 | bl .ppc64_runlatch_on; \ |
386 | addi r3,r1,STACK_FRAME_OVERHEAD; \ | 403 | addi r3,r1,STACK_FRAME_OVERHEAD; \ |
@@ -388,6 +405,25 @@ label##_common: \ | |||
388 | b .ret_from_except_lite | 405 | b .ret_from_except_lite |
389 | 406 | ||
390 | /* | 407 | /* |
408 | * When the idle code in power4_idle puts the CPU into NAP mode, | ||
409 | * it has to do so in a loop, and relies on the external interrupt | ||
410 | * and decrementer interrupt entry code to get it out of the loop. | ||
411 | * It sets the _TLF_NAPPING bit in current_thread_info()->local_flags | ||
412 | * to signal that it is in the loop and needs help to get out. | ||
413 | */ | ||
414 | #ifdef CONFIG_PPC_970_NAP | ||
415 | #define FINISH_NAP \ | ||
416 | BEGIN_FTR_SECTION \ | ||
417 | clrrdi r11,r1,THREAD_SHIFT; \ | ||
418 | ld r9,TI_LOCAL_FLAGS(r11); \ | ||
419 | andi. r10,r9,_TLF_NAPPING; \ | ||
420 | bnel power4_fixup_nap; \ | ||
421 | END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP) | ||
422 | #else | ||
423 | #define FINISH_NAP | ||
424 | #endif | ||
425 | |||
426 | /* | ||
391 | * Start of pSeries system interrupt routines | 427 | * Start of pSeries system interrupt routines |
392 | */ | 428 | */ |
393 | . = 0x100 | 429 | . = 0x100 |
@@ -772,6 +808,7 @@ hardware_interrupt_iSeries_masked: | |||
772 | .globl machine_check_common | 808 | .globl machine_check_common |
773 | machine_check_common: | 809 | machine_check_common: |
774 | EXCEPTION_PROLOG_COMMON(0x200, PACA_EXMC) | 810 | EXCEPTION_PROLOG_COMMON(0x200, PACA_EXMC) |
811 | FINISH_NAP | ||
775 | DISABLE_INTS | 812 | DISABLE_INTS |
776 | bl .save_nvgprs | 813 | bl .save_nvgprs |
777 | addi r3,r1,STACK_FRAME_OVERHEAD | 814 | addi r3,r1,STACK_FRAME_OVERHEAD |
@@ -783,7 +820,7 @@ machine_check_common: | |||
783 | STD_EXCEPTION_COMMON(0xb00, trap_0b, .unknown_exception) | 820 | STD_EXCEPTION_COMMON(0xb00, trap_0b, .unknown_exception) |
784 | STD_EXCEPTION_COMMON(0xd00, single_step, .single_step_exception) | 821 | STD_EXCEPTION_COMMON(0xd00, single_step, .single_step_exception) |
785 | STD_EXCEPTION_COMMON(0xe00, trap_0e, .unknown_exception) | 822 | STD_EXCEPTION_COMMON(0xe00, trap_0e, .unknown_exception) |
786 | STD_EXCEPTION_COMMON(0xf00, performance_monitor, .performance_monitor_exception) | 823 | STD_EXCEPTION_COMMON_IDLE(0xf00, performance_monitor, .performance_monitor_exception) |
787 | STD_EXCEPTION_COMMON(0x1300, instruction_breakpoint, .instruction_breakpoint_exception) | 824 | STD_EXCEPTION_COMMON(0x1300, instruction_breakpoint, .instruction_breakpoint_exception) |
788 | #ifdef CONFIG_ALTIVEC | 825 | #ifdef CONFIG_ALTIVEC |
789 | STD_EXCEPTION_COMMON(0x1700, altivec_assist, .altivec_assist_exception) | 826 | STD_EXCEPTION_COMMON(0x1700, altivec_assist, .altivec_assist_exception) |
@@ -1034,6 +1071,7 @@ unrecov_slb: | |||
1034 | .globl hardware_interrupt_entry | 1071 | .globl hardware_interrupt_entry |
1035 | hardware_interrupt_common: | 1072 | hardware_interrupt_common: |
1036 | EXCEPTION_PROLOG_COMMON(0x500, PACA_EXGEN) | 1073 | EXCEPTION_PROLOG_COMMON(0x500, PACA_EXGEN) |
1074 | FINISH_NAP | ||
1037 | hardware_interrupt_entry: | 1075 | hardware_interrupt_entry: |
1038 | DISABLE_INTS | 1076 | DISABLE_INTS |
1039 | bl .ppc64_runlatch_on | 1077 | bl .ppc64_runlatch_on |
@@ -1041,6 +1079,15 @@ hardware_interrupt_entry: | |||
1041 | bl .do_IRQ | 1079 | bl .do_IRQ |
1042 | b .ret_from_except_lite | 1080 | b .ret_from_except_lite |
1043 | 1081 | ||
1082 | #ifdef CONFIG_PPC_970_NAP | ||
1083 | power4_fixup_nap: | ||
1084 | andc r9,r9,r10 | ||
1085 | std r9,TI_LOCAL_FLAGS(r11) | ||
1086 | ld r10,_LINK(r1) /* make idle task do the */ | ||
1087 | std r10,_NIP(r1) /* equivalent of a blr */ | ||
1088 | blr | ||
1089 | #endif | ||
1090 | |||
1044 | .align 7 | 1091 | .align 7 |
1045 | .globl alignment_common | 1092 | .globl alignment_common |
1046 | alignment_common: | 1093 | alignment_common: |
diff --git a/arch/powerpc/kernel/idle.c b/arch/powerpc/kernel/idle.c index e9f321d74d85..d491052c8e0c 100644 --- a/arch/powerpc/kernel/idle.c +++ b/arch/powerpc/kernel/idle.c | |||
@@ -50,9 +50,9 @@ void cpu_idle(void) | |||
50 | 50 | ||
51 | set_thread_flag(TIF_POLLING_NRFLAG); | 51 | set_thread_flag(TIF_POLLING_NRFLAG); |
52 | while (1) { | 52 | while (1) { |
53 | ppc64_runlatch_off(); | ||
54 | |||
55 | while (!need_resched() && !cpu_should_die()) { | 53 | while (!need_resched() && !cpu_should_die()) { |
54 | ppc64_runlatch_off(); | ||
55 | |||
56 | if (ppc_md.power_save) { | 56 | if (ppc_md.power_save) { |
57 | clear_thread_flag(TIF_POLLING_NRFLAG); | 57 | clear_thread_flag(TIF_POLLING_NRFLAG); |
58 | /* | 58 | /* |
diff --git a/arch/powerpc/kernel/idle_6xx.S b/arch/powerpc/kernel/idle_6xx.S index 12a4efbaa08f..b45fa0e37212 100644 --- a/arch/powerpc/kernel/idle_6xx.S +++ b/arch/powerpc/kernel/idle_6xx.S | |||
@@ -22,8 +22,6 @@ | |||
22 | #include <asm/ppc_asm.h> | 22 | #include <asm/ppc_asm.h> |
23 | #include <asm/asm-offsets.h> | 23 | #include <asm/asm-offsets.h> |
24 | 24 | ||
25 | #undef DEBUG | ||
26 | |||
27 | .text | 25 | .text |
28 | 26 | ||
29 | /* | 27 | /* |
@@ -109,12 +107,6 @@ BEGIN_FTR_SECTION | |||
109 | dcbf 0,r4 | 107 | dcbf 0,r4 |
110 | dcbf 0,r4 | 108 | dcbf 0,r4 |
111 | END_FTR_SECTION_IFSET(CPU_FTR_NAP_DISABLE_L2_PR) | 109 | END_FTR_SECTION_IFSET(CPU_FTR_NAP_DISABLE_L2_PR) |
112 | #ifdef DEBUG | ||
113 | lis r6,nap_enter_count@ha | ||
114 | lwz r4,nap_enter_count@l(r6) | ||
115 | addi r4,r4,1 | ||
116 | stw r4,nap_enter_count@l(r6) | ||
117 | #endif | ||
118 | 2: | 110 | 2: |
119 | BEGIN_FTR_SECTION | 111 | BEGIN_FTR_SECTION |
120 | /* Go to low speed mode on some 750FX */ | 112 | /* Go to low speed mode on some 750FX */ |
@@ -144,48 +136,42 @@ BEGIN_FTR_SECTION | |||
144 | DSSALL | 136 | DSSALL |
145 | sync | 137 | sync |
146 | END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) | 138 | END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) |
139 | rlwinm r9,r1,0,0,31-THREAD_SHIFT /* current thread_info */ | ||
140 | lwz r8,TI_LOCAL_FLAGS(r9) /* set napping bit */ | ||
141 | ori r8,r8,_TLF_NAPPING /* so when we take an exception */ | ||
142 | stw r8,TI_LOCAL_FLAGS(r9) /* it will return to our caller */ | ||
147 | mfmsr r7 | 143 | mfmsr r7 |
148 | ori r7,r7,MSR_EE | 144 | ori r7,r7,MSR_EE |
149 | oris r7,r7,MSR_POW@h | 145 | oris r7,r7,MSR_POW@h |
150 | sync | 146 | 1: sync |
151 | isync | ||
152 | mtmsr r7 | 147 | mtmsr r7 |
153 | isync | 148 | isync |
154 | sync | 149 | b 1b |
155 | blr | 150 | |
156 | |||
157 | /* | 151 | /* |
158 | * Return from NAP/DOZE mode, restore some CPU specific registers, | 152 | * Return from NAP/DOZE mode, restore some CPU specific registers, |
159 | * we are called with DR/IR still off and r2 containing physical | 153 | * we are called with DR/IR still off and r2 containing physical |
160 | * address of current. | 154 | * address of current. R11 points to the exception frame (physical |
155 | * address). We have to preserve r10. | ||
161 | */ | 156 | */ |
162 | _GLOBAL(power_save_6xx_restore) | 157 | _GLOBAL(power_save_6xx_restore) |
163 | mfspr r11,SPRN_HID0 | 158 | lwz r9,_LINK(r11) /* interrupted in ppc6xx_idle: */ |
164 | rlwinm. r11,r11,0,10,8 /* Clear NAP & copy NAP bit !state to cr1 EQ */ | 159 | stw r9,_NIP(r11) /* make it do a blr */ |
165 | cror 4*cr1+eq,4*cr0+eq,4*cr0+eq | ||
166 | BEGIN_FTR_SECTION | ||
167 | rlwinm r11,r11,0,9,7 /* Clear DOZE */ | ||
168 | END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE) | ||
169 | mtspr SPRN_HID0, r11 | ||
170 | 160 | ||
171 | #ifdef DEBUG | 161 | #ifdef CONFIG_SMP |
172 | beq cr1,1f | 162 | mfspr r12,SPRN_SPRG3 |
173 | lis r11,(nap_return_count-KERNELBASE)@ha | 163 | lwz r11,TI_CPU(r12) /* get cpu number * 4 */ |
174 | lwz r9,nap_return_count@l(r11) | ||
175 | addi r9,r9,1 | ||
176 | stw r9,nap_return_count@l(r11) | ||
177 | 1: | ||
178 | #endif | ||
179 | |||
180 | rlwinm r9,r1,0,0,18 | ||
181 | tophys(r9,r9) | ||
182 | lwz r11,TI_CPU(r9) | ||
183 | slwi r11,r11,2 | 164 | slwi r11,r11,2 |
165 | #else | ||
166 | li r11,0 | ||
167 | #endif | ||
184 | /* Todo make sure all these are in the same page | 168 | /* Todo make sure all these are in the same page |
185 | * and load r22 (@ha part + CPU offset) only once | 169 | * and load r11 (@ha part + CPU offset) only once |
186 | */ | 170 | */ |
187 | BEGIN_FTR_SECTION | 171 | BEGIN_FTR_SECTION |
188 | beq cr1,1f | 172 | mfspr r9,SPRN_HID0 |
173 | andis. r9,r9,HID0_NAP@h | ||
174 | beq 1f | ||
189 | addis r9,r11,(nap_save_msscr0-KERNELBASE)@ha | 175 | addis r9,r11,(nap_save_msscr0-KERNELBASE)@ha |
190 | lwz r9,nap_save_msscr0@l(r9) | 176 | lwz r9,nap_save_msscr0@l(r9) |
191 | mtspr SPRN_MSSCR0, r9 | 177 | mtspr SPRN_MSSCR0, r9 |
@@ -210,10 +196,3 @@ _GLOBAL(nap_save_hid1) | |||
210 | 196 | ||
211 | _GLOBAL(powersave_lowspeed) | 197 | _GLOBAL(powersave_lowspeed) |
212 | .long 0 | 198 | .long 0 |
213 | |||
214 | #ifdef DEBUG | ||
215 | _GLOBAL(nap_enter_count) | ||
216 | .space 4 | ||
217 | _GLOBAL(nap_return_count) | ||
218 | .space 4 | ||
219 | #endif | ||
diff --git a/arch/powerpc/kernel/idle_power4.S b/arch/powerpc/kernel/idle_power4.S index 6dad1c02496e..d85c7c938eed 100644 --- a/arch/powerpc/kernel/idle_power4.S +++ b/arch/powerpc/kernel/idle_power4.S | |||
@@ -35,12 +35,16 @@ BEGIN_FTR_SECTION | |||
35 | DSSALL | 35 | DSSALL |
36 | sync | 36 | sync |
37 | END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) | 37 | END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) |
38 | clrrdi r9,r1,THREAD_SHIFT /* current thread_info */ | ||
39 | ld r8,TI_LOCAL_FLAGS(r9) /* set napping bit */ | ||
40 | ori r8,r8,_TLF_NAPPING /* so when we take an exception */ | ||
41 | std r8,TI_LOCAL_FLAGS(r9) /* it will return to our caller */ | ||
38 | mfmsr r7 | 42 | mfmsr r7 |
39 | ori r7,r7,MSR_EE | 43 | ori r7,r7,MSR_EE |
40 | oris r7,r7,MSR_POW@h | 44 | oris r7,r7,MSR_POW@h |
41 | sync | 45 | 1: sync |
42 | isync | 46 | isync |
43 | mtmsrd r7 | 47 | mtmsrd r7 |
44 | isync | 48 | isync |
45 | sync | 49 | b 1b |
46 | blr | 50 | |
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index bb5c9501234c..57d560c68897 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c | |||
@@ -272,18 +272,26 @@ unsigned int virt_irq_to_real_map[NR_IRQS]; | |||
272 | * Don't use virtual irqs 0, 1, 2 for devices. | 272 | * Don't use virtual irqs 0, 1, 2 for devices. |
273 | * The pcnet32 driver considers interrupt numbers < 2 to be invalid, | 273 | * The pcnet32 driver considers interrupt numbers < 2 to be invalid, |
274 | * and 2 is the XICS IPI interrupt. | 274 | * and 2 is the XICS IPI interrupt. |
275 | * We limit virtual irqs to 17 less than NR_IRQS so that when we | 275 | * We limit virtual irqs to __irq_offet_value less than virt_irq_max so |
276 | * offset them by 16 (to reserve the first 16 for ISA interrupts) | 276 | * that when we offset them we don't end up with an interrupt |
277 | * we don't end up with an interrupt number >= NR_IRQS. | 277 | * number >= virt_irq_max. |
278 | */ | 278 | */ |
279 | #define MIN_VIRT_IRQ 3 | 279 | #define MIN_VIRT_IRQ 3 |
280 | #define MAX_VIRT_IRQ (NR_IRQS - NUM_ISA_INTERRUPTS - 1) | 280 | |
281 | #define NR_VIRT_IRQS (MAX_VIRT_IRQ - MIN_VIRT_IRQ + 1) | 281 | unsigned int virt_irq_max; |
282 | static unsigned int max_virt_irq; | ||
283 | static unsigned int nr_virt_irqs; | ||
282 | 284 | ||
283 | void | 285 | void |
284 | virt_irq_init(void) | 286 | virt_irq_init(void) |
285 | { | 287 | { |
286 | int i; | 288 | int i; |
289 | |||
290 | if ((virt_irq_max == 0) || (virt_irq_max > (NR_IRQS - 1))) | ||
291 | virt_irq_max = NR_IRQS - 1; | ||
292 | max_virt_irq = virt_irq_max - __irq_offset_value; | ||
293 | nr_virt_irqs = max_virt_irq - MIN_VIRT_IRQ + 1; | ||
294 | |||
287 | for (i = 0; i < NR_IRQS; i++) | 295 | for (i = 0; i < NR_IRQS; i++) |
288 | virt_irq_to_real_map[i] = UNDEFINED_IRQ; | 296 | virt_irq_to_real_map[i] = UNDEFINED_IRQ; |
289 | } | 297 | } |
@@ -308,17 +316,17 @@ int virt_irq_create_mapping(unsigned int real_irq) | |||
308 | return real_irq; | 316 | return real_irq; |
309 | } | 317 | } |
310 | 318 | ||
311 | /* map to a number between MIN_VIRT_IRQ and MAX_VIRT_IRQ */ | 319 | /* map to a number between MIN_VIRT_IRQ and max_virt_irq */ |
312 | virq = real_irq; | 320 | virq = real_irq; |
313 | if (virq > MAX_VIRT_IRQ) | 321 | if (virq > max_virt_irq) |
314 | virq = (virq % NR_VIRT_IRQS) + MIN_VIRT_IRQ; | 322 | virq = (virq % nr_virt_irqs) + MIN_VIRT_IRQ; |
315 | 323 | ||
316 | /* search for this number or a free slot */ | 324 | /* search for this number or a free slot */ |
317 | first_virq = virq; | 325 | first_virq = virq; |
318 | while (virt_irq_to_real_map[virq] != UNDEFINED_IRQ) { | 326 | while (virt_irq_to_real_map[virq] != UNDEFINED_IRQ) { |
319 | if (virt_irq_to_real_map[virq] == real_irq) | 327 | if (virt_irq_to_real_map[virq] == real_irq) |
320 | return virq; | 328 | return virq; |
321 | if (++virq > MAX_VIRT_IRQ) | 329 | if (++virq > max_virt_irq) |
322 | virq = MIN_VIRT_IRQ; | 330 | virq = MIN_VIRT_IRQ; |
323 | if (virq == first_virq) | 331 | if (virq == first_virq) |
324 | goto nospace; /* oops, no free slots */ | 332 | goto nospace; /* oops, no free slots */ |
@@ -330,8 +338,8 @@ int virt_irq_create_mapping(unsigned int real_irq) | |||
330 | nospace: | 338 | nospace: |
331 | if (!warned) { | 339 | if (!warned) { |
332 | printk(KERN_CRIT "Interrupt table is full\n"); | 340 | printk(KERN_CRIT "Interrupt table is full\n"); |
333 | printk(KERN_CRIT "Increase NR_IRQS (currently %d) " | 341 | printk(KERN_CRIT "Increase virt_irq_max (currently %d) " |
334 | "in your kernel sources and rebuild.\n", NR_IRQS); | 342 | "in your kernel sources and rebuild.\n", virt_irq_max); |
335 | warned = 1; | 343 | warned = 1; |
336 | } | 344 | } |
337 | return NO_IRQ; | 345 | return NO_IRQ; |
@@ -349,8 +357,8 @@ unsigned int real_irq_to_virt_slowpath(unsigned int real_irq) | |||
349 | 357 | ||
350 | virq = real_irq; | 358 | virq = real_irq; |
351 | 359 | ||
352 | if (virq > MAX_VIRT_IRQ) | 360 | if (virq > max_virt_irq) |
353 | virq = (virq % NR_VIRT_IRQS) + MIN_VIRT_IRQ; | 361 | virq = (virq % nr_virt_irqs) + MIN_VIRT_IRQ; |
354 | 362 | ||
355 | first_virq = virq; | 363 | first_virq = virq; |
356 | 364 | ||
@@ -360,7 +368,7 @@ unsigned int real_irq_to_virt_slowpath(unsigned int real_irq) | |||
360 | 368 | ||
361 | virq++; | 369 | virq++; |
362 | 370 | ||
363 | if (virq >= MAX_VIRT_IRQ) | 371 | if (virq >= max_virt_irq) |
364 | virq = 0; | 372 | virq = 0; |
365 | 373 | ||
366 | } while (first_virq != virq); | 374 | } while (first_virq != virq); |
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index d66c5e77fcff..7e4d54821a07 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c | |||
@@ -1528,12 +1528,11 @@ static int __init prom_find_machine_type(void) | |||
1528 | * non-IBM designs ! | 1528 | * non-IBM designs ! |
1529 | * - it has /rtas | 1529 | * - it has /rtas |
1530 | */ | 1530 | */ |
1531 | len = prom_getprop(_prom->root, "model", | 1531 | len = prom_getprop(_prom->root, "device_type", |
1532 | compat, sizeof(compat)-1); | 1532 | compat, sizeof(compat)-1); |
1533 | if (len <= 0) | 1533 | if (len <= 0) |
1534 | return PLATFORM_GENERIC; | 1534 | return PLATFORM_GENERIC; |
1535 | compat[len] = 0; | 1535 | if (strncmp(compat, RELOC("chrp"), 4)) |
1536 | if (strcmp(compat, "chrp")) | ||
1537 | return PLATFORM_GENERIC; | 1536 | return PLATFORM_GENERIC; |
1538 | 1537 | ||
1539 | /* Default to pSeries. We need to know if we are running LPAR */ | 1538 | /* Default to pSeries. We need to know if we are running LPAR */ |
diff --git a/arch/powerpc/kernel/rtas-proc.c b/arch/powerpc/kernel/rtas-proc.c index 456286cf1d14..9c9ad1fa9cce 100644 --- a/arch/powerpc/kernel/rtas-proc.c +++ b/arch/powerpc/kernel/rtas-proc.c | |||
@@ -258,11 +258,11 @@ static int __init proc_rtas_init(void) | |||
258 | struct proc_dir_entry *entry; | 258 | struct proc_dir_entry *entry; |
259 | 259 | ||
260 | if (!machine_is(pseries)) | 260 | if (!machine_is(pseries)) |
261 | return 1; | 261 | return -ENODEV; |
262 | 262 | ||
263 | rtas_node = of_find_node_by_name(NULL, "rtas"); | 263 | rtas_node = of_find_node_by_name(NULL, "rtas"); |
264 | if (rtas_node == NULL) | 264 | if (rtas_node == NULL) |
265 | return 1; | 265 | return -ENODEV; |
266 | 266 | ||
267 | entry = create_proc_entry("ppc64/rtas/progress", S_IRUGO|S_IWUSR, NULL); | 267 | entry = create_proc_entry("ppc64/rtas/progress", S_IRUGO|S_IWUSR, NULL); |
268 | if (entry) | 268 | if (entry) |