aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-02-08 13:04:20 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-02-08 13:04:20 -0500
commit21eb4fa1700112d1420d72e1de708af671a251c8 (patch)
tree3afd9f526da50108c27e05ac69826be5e7c2ad6e /arch/powerpc/kernel
parent0c0e8caf9fd6c9a49fb9fbdba14a8b7b4239adde (diff)
parentd003e7a1a569501cbe9a5ca14748177498c4893a (diff)
Merge master.kernel.org:/pub/scm/linux/kernel/git/paulus/powerpc
* master.kernel.org:/pub/scm/linux/kernel/git/paulus/powerpc: (116 commits) [POWERPC] Add export of vgacon_remap_base [POWERPC] Remove bogus comment about page_is_ram [POWERPC] windfarm: don't die on suspend thread signal [POWERPC] Fix comment in kernel/irq.c [POWERPC] ppc: Fix booke watchdog initialization [POWERPC] PPC: Use ARRAY_SIZE macro when appropriate [POWERPC] Use ARRAY_SIZE macro when appropriate [POWERPC] Fix ppc64's writing to struct file_operations [POWERPC] ppc: use syslog macro for the printk log level [POWERPC] ppc: cs4218_tdm remove extra brace [POWERPC] Add mpc52xx/lite5200 PCI support [POWERPC] Only use H_BULK_REMOVE if the firmware supports it [POWERPC] Fixup error handling when emulating a floating point instruction [POWERPC] Enable interrupts if we are doing fp math emulation [POWERPC] Added kprobes support to ppc32 [POWERPC] Make pSeries use the H_BULK_REMOVE hypervisor call [POWERPC] Clear RI bit in MSR before restoring r13 when returning to userspace [POWERPC] Fix performance monitor exception [POWERPC] Compile fixes for arch/powerpc dcr code [POWERPC] Maple: use mmio nvram ...
Diffstat (limited to 'arch/powerpc/kernel')
-rw-r--r--arch/powerpc/kernel/Makefile1
-rw-r--r--arch/powerpc/kernel/cpu_setup_pa6t.S44
-rw-r--r--arch/powerpc/kernel/cputable.c21
-rw-r--r--arch/powerpc/kernel/entry_64.S59
-rw-r--r--arch/powerpc/kernel/head_32.S5
-rw-r--r--arch/powerpc/kernel/head_64.S2
-rw-r--r--arch/powerpc/kernel/iomap.c20
-rw-r--r--arch/powerpc/kernel/irq.c8
-rw-r--r--arch/powerpc/kernel/kprobes.c8
-rw-r--r--arch/powerpc/kernel/lparcfg.c11
-rw-r--r--arch/powerpc/kernel/misc_64.S40
-rw-r--r--arch/powerpc/kernel/module_32.c7
-rw-r--r--arch/powerpc/kernel/pci_32.c1
-rw-r--r--arch/powerpc/kernel/pci_64.c1
-rw-r--r--arch/powerpc/kernel/pmc.c37
-rw-r--r--arch/powerpc/kernel/ppc_ksyms.c1
-rw-r--r--arch/powerpc/kernel/prom.c18
-rw-r--r--arch/powerpc/kernel/ptrace.c24
-rw-r--r--arch/powerpc/kernel/setup_32.c1
-rw-r--r--arch/powerpc/kernel/sysfs.c141
-rw-r--r--arch/powerpc/kernel/traps.c111
-rw-r--r--arch/powerpc/kernel/udbg.c4
-rw-r--r--arch/powerpc/kernel/udbg_16550.c24
-rw-r--r--arch/powerpc/kernel/vio.c6
24 files changed, 405 insertions, 190 deletions
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index d2ded19e4064..8120d428ebfd 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -17,6 +17,7 @@ obj-y += vdso32/
17obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \ 17obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \
18 signal_64.o ptrace32.o \ 18 signal_64.o ptrace32.o \
19 paca.o cpu_setup_ppc970.o \ 19 paca.o cpu_setup_ppc970.o \
20 cpu_setup_pa6t.o \
20 firmware.o sysfs.o nvram_64.o 21 firmware.o sysfs.o nvram_64.o
21obj-$(CONFIG_PPC64) += vdso64/ 22obj-$(CONFIG_PPC64) += vdso64/
22obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o 23obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o
diff --git a/arch/powerpc/kernel/cpu_setup_pa6t.S b/arch/powerpc/kernel/cpu_setup_pa6t.S
new file mode 100644
index 000000000000..4047be25c4d2
--- /dev/null
+++ b/arch/powerpc/kernel/cpu_setup_pa6t.S
@@ -0,0 +1,44 @@
1/*
2 * Copyright (C) 2006-2007 PA Semi, Inc
3 *
4 * Maintained by: Olof Johansson <olof@lixom.net>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 */
20
21#include <asm/processor.h>
22#include <asm/page.h>
23#include <asm/cputable.h>
24#include <asm/ppc_asm.h>
25#include <asm/asm-offsets.h>
26#include <asm/cache.h>
27
28/* Right now, restore and setup are the same thing */
29_GLOBAL(__restore_cpu_pa6t)
30_GLOBAL(__setup_cpu_pa6t)
31 /* Do nothing if not running in HV mode */
32 mfmsr r0
33 rldicl. r0,r0,4,63
34 beqlr
35
36 mfspr r0,SPRN_HID5
37 ori r0,r0,0x30
38 mtspr SPRN_HID5,r0
39
40 mfspr r0,SPRN_LPCR
41 ori r0,r0,0x7000
42 mtspr SPRN_LPCR,r0
43
44 blr
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index b742013bb9da..dd17dffbf058 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -43,6 +43,8 @@ extern void __setup_cpu_745x(unsigned long offset, struct cpu_spec* spec);
43#ifdef CONFIG_PPC64 43#ifdef CONFIG_PPC64
44extern void __setup_cpu_ppc970(unsigned long offset, struct cpu_spec* spec); 44extern void __setup_cpu_ppc970(unsigned long offset, struct cpu_spec* spec);
45extern void __setup_cpu_ppc970MP(unsigned long offset, struct cpu_spec* spec); 45extern void __setup_cpu_ppc970MP(unsigned long offset, struct cpu_spec* spec);
46extern void __setup_cpu_pa6t(unsigned long offset, struct cpu_spec* spec);
47extern void __restore_cpu_pa6t(unsigned long offset, struct cpu_spec* spec);
46extern void __restore_cpu_ppc970(void); 48extern void __restore_cpu_ppc970(void);
47#endif /* CONFIG_PPC64 */ 49#endif /* CONFIG_PPC64 */
48 50
@@ -86,6 +88,7 @@ static struct cpu_spec cpu_specs[] = {
86 .icache_bsize = 128, 88 .icache_bsize = 128,
87 .dcache_bsize = 128, 89 .dcache_bsize = 128,
88 .num_pmcs = 8, 90 .num_pmcs = 8,
91 .pmc_type = PPC_PMC_IBM,
89 .oprofile_cpu_type = "ppc64/power3", 92 .oprofile_cpu_type = "ppc64/power3",
90 .oprofile_type = PPC_OPROFILE_RS64, 93 .oprofile_type = PPC_OPROFILE_RS64,
91 .platform = "power3", 94 .platform = "power3",
@@ -99,6 +102,7 @@ static struct cpu_spec cpu_specs[] = {
99 .icache_bsize = 128, 102 .icache_bsize = 128,
100 .dcache_bsize = 128, 103 .dcache_bsize = 128,
101 .num_pmcs = 8, 104 .num_pmcs = 8,
105 .pmc_type = PPC_PMC_IBM,
102 .oprofile_cpu_type = "ppc64/power3", 106 .oprofile_cpu_type = "ppc64/power3",
103 .oprofile_type = PPC_OPROFILE_RS64, 107 .oprofile_type = PPC_OPROFILE_RS64,
104 .platform = "power3", 108 .platform = "power3",
@@ -112,6 +116,7 @@ static struct cpu_spec cpu_specs[] = {
112 .icache_bsize = 128, 116 .icache_bsize = 128,
113 .dcache_bsize = 128, 117 .dcache_bsize = 128,
114 .num_pmcs = 8, 118 .num_pmcs = 8,
119 .pmc_type = PPC_PMC_IBM,
115 .oprofile_cpu_type = "ppc64/rs64", 120 .oprofile_cpu_type = "ppc64/rs64",
116 .oprofile_type = PPC_OPROFILE_RS64, 121 .oprofile_type = PPC_OPROFILE_RS64,
117 .platform = "rs64", 122 .platform = "rs64",
@@ -125,6 +130,7 @@ static struct cpu_spec cpu_specs[] = {
125 .icache_bsize = 128, 130 .icache_bsize = 128,
126 .dcache_bsize = 128, 131 .dcache_bsize = 128,
127 .num_pmcs = 8, 132 .num_pmcs = 8,
133 .pmc_type = PPC_PMC_IBM,
128 .oprofile_cpu_type = "ppc64/rs64", 134 .oprofile_cpu_type = "ppc64/rs64",
129 .oprofile_type = PPC_OPROFILE_RS64, 135 .oprofile_type = PPC_OPROFILE_RS64,
130 .platform = "rs64", 136 .platform = "rs64",
@@ -138,6 +144,7 @@ static struct cpu_spec cpu_specs[] = {
138 .icache_bsize = 128, 144 .icache_bsize = 128,
139 .dcache_bsize = 128, 145 .dcache_bsize = 128,
140 .num_pmcs = 8, 146 .num_pmcs = 8,
147 .pmc_type = PPC_PMC_IBM,
141 .oprofile_cpu_type = "ppc64/rs64", 148 .oprofile_cpu_type = "ppc64/rs64",
142 .oprofile_type = PPC_OPROFILE_RS64, 149 .oprofile_type = PPC_OPROFILE_RS64,
143 .platform = "rs64", 150 .platform = "rs64",
@@ -151,6 +158,7 @@ static struct cpu_spec cpu_specs[] = {
151 .icache_bsize = 128, 158 .icache_bsize = 128,
152 .dcache_bsize = 128, 159 .dcache_bsize = 128,
153 .num_pmcs = 8, 160 .num_pmcs = 8,
161 .pmc_type = PPC_PMC_IBM,
154 .oprofile_cpu_type = "ppc64/rs64", 162 .oprofile_cpu_type = "ppc64/rs64",
155 .oprofile_type = PPC_OPROFILE_RS64, 163 .oprofile_type = PPC_OPROFILE_RS64,
156 .platform = "rs64", 164 .platform = "rs64",
@@ -164,6 +172,7 @@ static struct cpu_spec cpu_specs[] = {
164 .icache_bsize = 128, 172 .icache_bsize = 128,
165 .dcache_bsize = 128, 173 .dcache_bsize = 128,
166 .num_pmcs = 8, 174 .num_pmcs = 8,
175 .pmc_type = PPC_PMC_IBM,
167 .oprofile_cpu_type = "ppc64/power4", 176 .oprofile_cpu_type = "ppc64/power4",
168 .oprofile_type = PPC_OPROFILE_POWER4, 177 .oprofile_type = PPC_OPROFILE_POWER4,
169 .platform = "power4", 178 .platform = "power4",
@@ -177,6 +186,7 @@ static struct cpu_spec cpu_specs[] = {
177 .icache_bsize = 128, 186 .icache_bsize = 128,
178 .dcache_bsize = 128, 187 .dcache_bsize = 128,
179 .num_pmcs = 8, 188 .num_pmcs = 8,
189 .pmc_type = PPC_PMC_IBM,
180 .oprofile_cpu_type = "ppc64/power4", 190 .oprofile_cpu_type = "ppc64/power4",
181 .oprofile_type = PPC_OPROFILE_POWER4, 191 .oprofile_type = PPC_OPROFILE_POWER4,
182 .platform = "power4", 192 .platform = "power4",
@@ -191,6 +201,7 @@ static struct cpu_spec cpu_specs[] = {
191 .icache_bsize = 128, 201 .icache_bsize = 128,
192 .dcache_bsize = 128, 202 .dcache_bsize = 128,
193 .num_pmcs = 8, 203 .num_pmcs = 8,
204 .pmc_type = PPC_PMC_IBM,
194 .cpu_setup = __setup_cpu_ppc970, 205 .cpu_setup = __setup_cpu_ppc970,
195 .cpu_restore = __restore_cpu_ppc970, 206 .cpu_restore = __restore_cpu_ppc970,
196 .oprofile_cpu_type = "ppc64/970", 207 .oprofile_cpu_type = "ppc64/970",
@@ -207,6 +218,7 @@ static struct cpu_spec cpu_specs[] = {
207 .icache_bsize = 128, 218 .icache_bsize = 128,
208 .dcache_bsize = 128, 219 .dcache_bsize = 128,
209 .num_pmcs = 8, 220 .num_pmcs = 8,
221 .pmc_type = PPC_PMC_IBM,
210 .cpu_setup = __setup_cpu_ppc970, 222 .cpu_setup = __setup_cpu_ppc970,
211 .cpu_restore = __restore_cpu_ppc970, 223 .cpu_restore = __restore_cpu_ppc970,
212 .oprofile_cpu_type = "ppc64/970", 224 .oprofile_cpu_type = "ppc64/970",
@@ -239,6 +251,7 @@ static struct cpu_spec cpu_specs[] = {
239 .icache_bsize = 128, 251 .icache_bsize = 128,
240 .dcache_bsize = 128, 252 .dcache_bsize = 128,
241 .num_pmcs = 8, 253 .num_pmcs = 8,
254 .pmc_type = PPC_PMC_IBM,
242 .cpu_setup = __setup_cpu_ppc970, 255 .cpu_setup = __setup_cpu_ppc970,
243 .oprofile_cpu_type = "ppc64/970", 256 .oprofile_cpu_type = "ppc64/970",
244 .oprofile_type = PPC_OPROFILE_POWER4, 257 .oprofile_type = PPC_OPROFILE_POWER4,
@@ -253,6 +266,7 @@ static struct cpu_spec cpu_specs[] = {
253 .icache_bsize = 128, 266 .icache_bsize = 128,
254 .dcache_bsize = 128, 267 .dcache_bsize = 128,
255 .num_pmcs = 6, 268 .num_pmcs = 6,
269 .pmc_type = PPC_PMC_IBM,
256 .oprofile_cpu_type = "ppc64/power5", 270 .oprofile_cpu_type = "ppc64/power5",
257 .oprofile_type = PPC_OPROFILE_POWER4, 271 .oprofile_type = PPC_OPROFILE_POWER4,
258 /* SIHV / SIPR bits are implemented on POWER4+ (GQ) 272 /* SIHV / SIPR bits are implemented on POWER4+ (GQ)
@@ -271,6 +285,7 @@ static struct cpu_spec cpu_specs[] = {
271 .icache_bsize = 128, 285 .icache_bsize = 128,
272 .dcache_bsize = 128, 286 .dcache_bsize = 128,
273 .num_pmcs = 6, 287 .num_pmcs = 6,
288 .pmc_type = PPC_PMC_IBM,
274 .oprofile_cpu_type = "ppc64/power5+", 289 .oprofile_cpu_type = "ppc64/power5+",
275 .oprofile_type = PPC_OPROFILE_POWER4, 290 .oprofile_type = PPC_OPROFILE_POWER4,
276 .oprofile_mmcra_sihv = MMCRA_SIHV, 291 .oprofile_mmcra_sihv = MMCRA_SIHV,
@@ -321,6 +336,7 @@ static struct cpu_spec cpu_specs[] = {
321 .icache_bsize = 128, 336 .icache_bsize = 128,
322 .dcache_bsize = 128, 337 .dcache_bsize = 128,
323 .num_pmcs = 6, 338 .num_pmcs = 6,
339 .pmc_type = PPC_PMC_IBM,
324 .oprofile_cpu_type = "ppc64/power6", 340 .oprofile_cpu_type = "ppc64/power6",
325 .oprofile_type = PPC_OPROFILE_POWER4, 341 .oprofile_type = PPC_OPROFILE_POWER4,
326 .oprofile_mmcra_sihv = POWER6_MMCRA_SIHV, 342 .oprofile_mmcra_sihv = POWER6_MMCRA_SIHV,
@@ -340,6 +356,7 @@ static struct cpu_spec cpu_specs[] = {
340 .icache_bsize = 128, 356 .icache_bsize = 128,
341 .dcache_bsize = 128, 357 .dcache_bsize = 128,
342 .num_pmcs = 4, 358 .num_pmcs = 4,
359 .pmc_type = PPC_PMC_IBM,
343 .oprofile_cpu_type = "ppc64/cell-be", 360 .oprofile_cpu_type = "ppc64/cell-be",
344 .oprofile_type = PPC_OPROFILE_CELL, 361 .oprofile_type = PPC_OPROFILE_CELL,
345 .platform = "ppc-cell-be", 362 .platform = "ppc-cell-be",
@@ -353,6 +370,9 @@ static struct cpu_spec cpu_specs[] = {
353 .icache_bsize = 64, 370 .icache_bsize = 64,
354 .dcache_bsize = 64, 371 .dcache_bsize = 64,
355 .num_pmcs = 6, 372 .num_pmcs = 6,
373 .pmc_type = PPC_PMC_PA6T,
374 .cpu_setup = __setup_cpu_pa6t,
375 .cpu_restore = __restore_cpu_pa6t,
356 .platform = "pa6t", 376 .platform = "pa6t",
357 }, 377 },
358 { /* default match */ 378 { /* default match */
@@ -364,6 +384,7 @@ static struct cpu_spec cpu_specs[] = {
364 .icache_bsize = 128, 384 .icache_bsize = 128,
365 .dcache_bsize = 128, 385 .dcache_bsize = 128,
366 .num_pmcs = 6, 386 .num_pmcs = 6,
387 .pmc_type = PPC_PMC_IBM,
367 .platform = "power4", 388 .platform = "power4",
368 } 389 }
369#endif /* CONFIG_PPC64 */ 390#endif /* CONFIG_PPC64 */
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index 2551c0884afc..2b66d53dcc55 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -172,13 +172,18 @@ syscall_error_cont:
172 stdcx. r0,0,r1 /* to clear the reservation */ 172 stdcx. r0,0,r1 /* to clear the reservation */
173 andi. r6,r8,MSR_PR 173 andi. r6,r8,MSR_PR
174 ld r4,_LINK(r1) 174 ld r4,_LINK(r1)
175 /*
176 * Clear RI before restoring r13. If we are returning to
177 * userspace and we take an exception after restoring r13,
178 * we end up corrupting the userspace r13 value.
179 */
180 li r12,MSR_RI
181 andc r11,r10,r12
182 mtmsrd r11,1 /* clear MSR.RI */
175 beq- 1f 183 beq- 1f
176 ACCOUNT_CPU_USER_EXIT(r11, r12) 184 ACCOUNT_CPU_USER_EXIT(r11, r12)
177 ld r13,GPR13(r1) /* only restore r13 if returning to usermode */ 185 ld r13,GPR13(r1) /* only restore r13 if returning to usermode */
1781: ld r2,GPR2(r1) 1861: ld r2,GPR2(r1)
179 li r12,MSR_RI
180 andc r11,r10,r12
181 mtmsrd r11,1 /* clear MSR.RI */
182 ld r1,GPR1(r1) 187 ld r1,GPR1(r1)
183 mtlr r4 188 mtlr r4
184 mtcr r5 189 mtcr r5
@@ -488,42 +493,44 @@ END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
488#endif 493#endif
489 stb r5,PACASOFTIRQEN(r13) 494 stb r5,PACASOFTIRQEN(r13)
490 495
496 /* extract EE bit and use it to restore paca->hard_enabled */
491 ld r3,_MSR(r1) 497 ld r3,_MSR(r1)
498 rldicl r4,r3,49,63 /* r0 = (r3 >> 15) & 1 */
499 stb r4,PACAHARDIRQEN(r13)
500
501 ld r4,_CTR(r1)
502 ld r0,_LINK(r1)
503 mtctr r4
504 mtlr r0
505 ld r4,_XER(r1)
506 mtspr SPRN_XER,r4
507
508 REST_8GPRS(5, r1)
509
492 andi. r0,r3,MSR_RI 510 andi. r0,r3,MSR_RI
493 beq- unrecov_restore 511 beq- unrecov_restore
494 512
495 /* extract EE bit and use it to restore paca->hard_enabled */ 513 stdcx. r0,0,r1 /* to clear the reservation */
496 rldicl r4,r3,49,63 /* r0 = (r3 >> 15) & 1 */
497 stb r4,PACAHARDIRQEN(r13)
498 514
499 andi. r0,r3,MSR_PR 515 /*
516 * Clear RI before restoring r13. If we are returning to
517 * userspace and we take an exception after restoring r13,
518 * we end up corrupting the userspace r13 value.
519 */
520 mfmsr r4
521 andc r4,r4,r0 /* r0 contains MSR_RI here */
522 mtmsrd r4,1
500 523
501 /* 524 /*
502 * r13 is our per cpu area, only restore it if we are returning to 525 * r13 is our per cpu area, only restore it if we are returning to
503 * userspace 526 * userspace
504 */ 527 */
528 andi. r0,r3,MSR_PR
505 beq 1f 529 beq 1f
506 ACCOUNT_CPU_USER_EXIT(r3, r4) 530 ACCOUNT_CPU_USER_EXIT(r2, r4)
507 REST_GPR(13, r1) 531 REST_GPR(13, r1)
5081: 5321:
509 ld r3,_CTR(r1) 533 mtspr SPRN_SRR1,r3
510 ld r0,_LINK(r1)
511 mtctr r3
512 mtlr r0
513 ld r3,_XER(r1)
514 mtspr SPRN_XER,r3
515
516 REST_8GPRS(5, r1)
517
518 stdcx. r0,0,r1 /* to clear the reservation */
519
520 mfmsr r0
521 li r2, MSR_RI
522 andc r0,r0,r2
523 mtmsrd r0,1
524
525 ld r0,_MSR(r1)
526 mtspr SPRN_SRR1,r0
527 534
528 ld r2,_CCR(r1) 535 ld r2,_CCR(r1)
529 mtcrf 0xFF,r2 536 mtcrf 0xFF,r2
diff --git a/arch/powerpc/kernel/head_32.S b/arch/powerpc/kernel/head_32.S
index 9417cf5b4b7e..c897203198b1 100644
--- a/arch/powerpc/kernel/head_32.S
+++ b/arch/powerpc/kernel/head_32.S
@@ -344,12 +344,7 @@ i##n: \
344/* System reset */ 344/* System reset */
345/* core99 pmac starts the seconary here by changing the vector, and 345/* core99 pmac starts the seconary here by changing the vector, and
346 putting it back to what it was (unknown_exception) when done. */ 346 putting it back to what it was (unknown_exception) when done. */
347#if defined(CONFIG_GEMINI) && defined(CONFIG_SMP)
348 . = 0x100
349 b __secondary_start_gemini
350#else
351 EXCEPTION(0x100, Reset, unknown_exception, EXC_XFER_STD) 347 EXCEPTION(0x100, Reset, unknown_exception, EXC_XFER_STD)
352#endif
353 348
354/* Machine check */ 349/* Machine check */
355/* 350/*
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index 71b1fe58e9e4..97cedcd6c9b4 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -613,7 +613,7 @@ system_call_pSeries:
613/*** pSeries interrupt support ***/ 613/*** pSeries interrupt support ***/
614 614
615 /* moved from 0xf00 */ 615 /* moved from 0xf00 */
616 MASKABLE_EXCEPTION_PSERIES(., performance_monitor) 616 STD_EXCEPTION_PSERIES(., performance_monitor)
617 617
618/* 618/*
619 * An interrupt came in while soft-disabled; clear EE in SRR1, 619 * An interrupt came in while soft-disabled; clear EE in SRR1,
diff --git a/arch/powerpc/kernel/iomap.c b/arch/powerpc/kernel/iomap.c
index c68113371050..601ef79a5916 100644
--- a/arch/powerpc/kernel/iomap.c
+++ b/arch/powerpc/kernel/iomap.c
@@ -12,23 +12,23 @@
12 * Here comes the ppc64 implementation of the IOMAP 12 * Here comes the ppc64 implementation of the IOMAP
13 * interfaces. 13 * interfaces.
14 */ 14 */
15unsigned int fastcall ioread8(void __iomem *addr) 15unsigned int ioread8(void __iomem *addr)
16{ 16{
17 return readb(addr); 17 return readb(addr);
18} 18}
19unsigned int fastcall ioread16(void __iomem *addr) 19unsigned int ioread16(void __iomem *addr)
20{ 20{
21 return readw(addr); 21 return readw(addr);
22} 22}
23unsigned int fastcall ioread16be(void __iomem *addr) 23unsigned int ioread16be(void __iomem *addr)
24{ 24{
25 return in_be16(addr); 25 return in_be16(addr);
26} 26}
27unsigned int fastcall ioread32(void __iomem *addr) 27unsigned int ioread32(void __iomem *addr)
28{ 28{
29 return readl(addr); 29 return readl(addr);
30} 30}
31unsigned int fastcall ioread32be(void __iomem *addr) 31unsigned int ioread32be(void __iomem *addr)
32{ 32{
33 return in_be32(addr); 33 return in_be32(addr);
34} 34}
@@ -38,23 +38,23 @@ EXPORT_SYMBOL(ioread16be);
38EXPORT_SYMBOL(ioread32); 38EXPORT_SYMBOL(ioread32);
39EXPORT_SYMBOL(ioread32be); 39EXPORT_SYMBOL(ioread32be);
40 40
41void fastcall iowrite8(u8 val, void __iomem *addr) 41void iowrite8(u8 val, void __iomem *addr)
42{ 42{
43 writeb(val, addr); 43 writeb(val, addr);
44} 44}
45void fastcall iowrite16(u16 val, void __iomem *addr) 45void iowrite16(u16 val, void __iomem *addr)
46{ 46{
47 writew(val, addr); 47 writew(val, addr);
48} 48}
49void fastcall iowrite16be(u16 val, void __iomem *addr) 49void iowrite16be(u16 val, void __iomem *addr)
50{ 50{
51 out_be16(addr, val); 51 out_be16(addr, val);
52} 52}
53void fastcall iowrite32(u32 val, void __iomem *addr) 53void iowrite32(u32 val, void __iomem *addr)
54{ 54{
55 writel(val, addr); 55 writel(val, addr);
56} 56}
57void fastcall iowrite32be(u32 val, void __iomem *addr) 57void iowrite32be(u32 val, void __iomem *addr)
58{ 58{
59 out_be32(addr, val); 59 out_be32(addr, val);
60} 60}
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 0bd8c7665834..919fbf568495 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -281,10 +281,10 @@ void do_IRQ(struct pt_regs *regs)
281 281
282 /* 282 /*
283 * Every platform is required to implement ppc_md.get_irq. 283 * Every platform is required to implement ppc_md.get_irq.
284 * This function will either return an irq number or -1 to 284 * This function will either return an irq number or NO_IRQ to
285 * indicate there are no more pending. 285 * indicate there are no more pending.
286 * The value -2 is for buggy hardware and means that this IRQ 286 * The value NO_IRQ_IGNORE is for buggy hardware and means that this
287 * has already been handled. -- Tom 287 * IRQ has already been handled. -- Tom
288 */ 288 */
289 irq = ppc_md.get_irq(); 289 irq = ppc_md.get_irq();
290 290
@@ -604,6 +604,8 @@ unsigned int irq_create_mapping(struct irq_host *host,
604 */ 604 */
605 virq = irq_find_mapping(host, hwirq); 605 virq = irq_find_mapping(host, hwirq);
606 if (virq != IRQ_NONE) { 606 if (virq != IRQ_NONE) {
607 if (host->ops->remap)
608 host->ops->remap(host, virq, hwirq);
607 pr_debug("irq: -> existing mapping on virq %d\n", virq); 609 pr_debug("irq: -> existing mapping on virq %d\n", virq);
608 return virq; 610 return virq;
609 } 611 }
diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
index 4657563f8813..dd2886f97e98 100644
--- a/arch/powerpc/kernel/kprobes.c
+++ b/arch/powerpc/kernel/kprobes.c
@@ -46,8 +46,8 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
46 if ((unsigned long)p->addr & 0x03) { 46 if ((unsigned long)p->addr & 0x03) {
47 printk("Attempt to register kprobe at an unaligned address\n"); 47 printk("Attempt to register kprobe at an unaligned address\n");
48 ret = -EINVAL; 48 ret = -EINVAL;
49 } else if (IS_MTMSRD(insn) || IS_RFID(insn)) { 49 } else if (IS_MTMSRD(insn) || IS_RFID(insn) || IS_RFI(insn)) {
50 printk("Cannot register a kprobe on rfid or mtmsrd\n"); 50 printk("Cannot register a kprobe on rfi/rfid or mtmsr[d]\n");
51 ret = -EINVAL; 51 ret = -EINVAL;
52 } 52 }
53 53
@@ -483,8 +483,12 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
483 memcpy(&kcb->jprobe_saved_regs, regs, sizeof(struct pt_regs)); 483 memcpy(&kcb->jprobe_saved_regs, regs, sizeof(struct pt_regs));
484 484
485 /* setup return addr to the jprobe handler routine */ 485 /* setup return addr to the jprobe handler routine */
486#ifdef CONFIG_PPC64
486 regs->nip = (unsigned long)(((func_descr_t *)jp->entry)->entry); 487 regs->nip = (unsigned long)(((func_descr_t *)jp->entry)->entry);
487 regs->gpr[2] = (unsigned long)(((func_descr_t *)jp->entry)->toc); 488 regs->gpr[2] = (unsigned long)(((func_descr_t *)jp->entry)->toc);
489#else
490 regs->nip = (unsigned long)jp->entry;
491#endif
488 492
489 return 1; 493 return 1;
490} 494}
diff --git a/arch/powerpc/kernel/lparcfg.c b/arch/powerpc/kernel/lparcfg.c
index 41c05dcd68f4..0de5a08cf9b0 100644
--- a/arch/powerpc/kernel/lparcfg.c
+++ b/arch/powerpc/kernel/lparcfg.c
@@ -439,6 +439,10 @@ static ssize_t lparcfg_write(struct file *file, const char __user * buf,
439 439
440 ssize_t retval = -ENOMEM; 440 ssize_t retval = -ENOMEM;
441 441
442 if (!firmware_has_feature(FW_FEATURE_SPLPAR) ||
443 firmware_has_feature(FW_FEATURE_ISERIES))
444 return -EINVAL;
445
442 kbuf = kmalloc(count, GFP_KERNEL); 446 kbuf = kmalloc(count, GFP_KERNEL);
443 if (!kbuf) 447 if (!kbuf)
444 goto out; 448 goto out;
@@ -517,7 +521,7 @@ static int pseries_lparcfg_data(struct seq_file *m, void *v)
517static ssize_t lparcfg_write(struct file *file, const char __user * buf, 521static ssize_t lparcfg_write(struct file *file, const char __user * buf,
518 size_t count, loff_t * off) 522 size_t count, loff_t * off)
519{ 523{
520 return count; 524 return -EINVAL;
521} 525}
522 526
523#endif /* CONFIG_PPC_PSERIES */ 527#endif /* CONFIG_PPC_PSERIES */
@@ -570,6 +574,7 @@ static int lparcfg_open(struct inode *inode, struct file *file)
570struct file_operations lparcfg_fops = { 574struct file_operations lparcfg_fops = {
571 .owner = THIS_MODULE, 575 .owner = THIS_MODULE,
572 .read = seq_read, 576 .read = seq_read,
577 .write = lparcfg_write,
573 .open = lparcfg_open, 578 .open = lparcfg_open,
574 .release = single_release, 579 .release = single_release,
575}; 580};
@@ -581,10 +586,8 @@ int __init lparcfg_init(void)
581 586
582 /* Allow writing if we have FW_FEATURE_SPLPAR */ 587 /* Allow writing if we have FW_FEATURE_SPLPAR */
583 if (firmware_has_feature(FW_FEATURE_SPLPAR) && 588 if (firmware_has_feature(FW_FEATURE_SPLPAR) &&
584 !firmware_has_feature(FW_FEATURE_ISERIES)) { 589 !firmware_has_feature(FW_FEATURE_ISERIES))
585 lparcfg_fops.write = lparcfg_write;
586 mode |= S_IWUSR; 590 mode |= S_IWUSR;
587 }
588 591
589 ent = create_proc_entry("ppc64/lparcfg", mode, NULL); 592 ent = create_proc_entry("ppc64/lparcfg", mode, NULL);
590 if (ent) { 593 if (ent) {
diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S
index 21fd2c662a99..519861da0423 100644
--- a/arch/powerpc/kernel/misc_64.S
+++ b/arch/powerpc/kernel/misc_64.S
@@ -311,6 +311,46 @@ _GLOBAL(real_writeb)
311 blr 311 blr
312#endif /* defined(CONFIG_PPC_PMAC) || defined(CONFIG_PPC_MAPLE) */ 312#endif /* defined(CONFIG_PPC_PMAC) || defined(CONFIG_PPC_MAPLE) */
313 313
314#ifdef CONFIG_PPC_PASEMI
315
316/* No support in all binutils for these yet, so use defines */
317#define LBZCIX(RT,RA,RB) .long (0x7c0006aa|(RT<<21)|(RA<<16)|(RB << 11))
318#define STBCIX(RS,RA,RB) .long (0x7c0007aa|(RS<<21)|(RA<<16)|(RB << 11))
319
320
321_GLOBAL(real_205_readb)
322 mfmsr r7
323 ori r0,r7,MSR_DR
324 xori r0,r0,MSR_DR
325 sync
326 mtmsrd r0
327 sync
328 isync
329 LBZCIX(r3,0,r3)
330 isync
331 mtmsrd r7
332 sync
333 isync
334 blr
335
336_GLOBAL(real_205_writeb)
337 mfmsr r7
338 ori r0,r7,MSR_DR
339 xori r0,r0,MSR_DR
340 sync
341 mtmsrd r0
342 sync
343 isync
344 STBCIX(r3,0,r4)
345 isync
346 mtmsrd r7
347 sync
348 isync
349 blr
350
351#endif /* CONFIG_PPC_PASEMI */
352
353
314#ifdef CONFIG_CPU_FREQ_PMAC64 354#ifdef CONFIG_CPU_FREQ_PMAC64
315/* 355/*
316 * SCOM access functions for 970 (FX only for now) 356 * SCOM access functions for 970 (FX only for now)
diff --git a/arch/powerpc/kernel/module_32.c b/arch/powerpc/kernel/module_32.c
index 8339fd609de0..07a89a398639 100644
--- a/arch/powerpc/kernel/module_32.c
+++ b/arch/powerpc/kernel/module_32.c
@@ -224,7 +224,12 @@ int apply_relocate_add(Elf32_Shdr *sechdrs,
224 /* Low half of the symbol */ 224 /* Low half of the symbol */
225 *(uint16_t *)location = value; 225 *(uint16_t *)location = value;
226 break; 226 break;
227 227
228 case R_PPC_ADDR16_HI:
229 /* Higher half of the symbol */
230 *(uint16_t *)location = (value >> 16);
231 break;
232
228 case R_PPC_ADDR16_HA: 233 case R_PPC_ADDR16_HA:
229 /* Sign-adjusted lower 16 bits: PPC ELF ABI says: 234 /* Sign-adjusted lower 16 bits: PPC ELF ABI says:
230 (((x >> 16) + ((x & 0x8000) ? 1 : 0))) & 0xFFFF. 235 (((x >> 16) + ((x & 0x8000) ? 1 : 0))) & 0xFFFF.
diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c
index c54f3639c5ad..d8ef2e100505 100644
--- a/arch/powerpc/kernel/pci_32.c
+++ b/arch/powerpc/kernel/pci_32.c
@@ -1450,7 +1450,6 @@ int pci_read_irq_line(struct pci_dev *pci_dev)
1450 return -1; 1450 return -1;
1451 } 1451 }
1452 pci_dev->irq = virq; 1452 pci_dev->irq = virq;
1453 pci_write_config_byte(pci_dev, PCI_INTERRUPT_LINE, virq);
1454 1453
1455 return 0; 1454 return 0;
1456} 1455}
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
index 2b52b087aaa8..7e97d71a5f8f 100644
--- a/arch/powerpc/kernel/pci_64.c
+++ b/arch/powerpc/kernel/pci_64.c
@@ -1323,7 +1323,6 @@ int pci_read_irq_line(struct pci_dev *pci_dev)
1323 DBG(" -> mapped to linux irq %d\n", virq); 1323 DBG(" -> mapped to linux irq %d\n", virq);
1324 1324
1325 pci_dev->irq = virq; 1325 pci_dev->irq = virq;
1326 pci_write_config_byte(pci_dev, PCI_INTERRUPT_LINE, virq);
1327 1326
1328 return 0; 1327 return 0;
1329} 1328}
diff --git a/arch/powerpc/kernel/pmc.c b/arch/powerpc/kernel/pmc.c
index 3d8f6f44641e..24d7b7c99bb9 100644
--- a/arch/powerpc/kernel/pmc.c
+++ b/arch/powerpc/kernel/pmc.c
@@ -17,40 +17,25 @@
17#include <linux/module.h> 17#include <linux/module.h>
18 18
19#include <asm/processor.h> 19#include <asm/processor.h>
20#include <asm/cputable.h>
20#include <asm/pmc.h> 21#include <asm/pmc.h>
21 22
22#if defined(CONFIG_FSL_BOOKE) && !defined(CONFIG_E200) 23#ifndef MMCR0_PMA0
23static void dummy_perf(struct pt_regs *regs) 24#define MMCR0_PMA0 0
24{
25 unsigned int pmgc0 = mfpmr(PMRN_PMGC0);
26
27 pmgc0 &= ~PMGC0_PMIE;
28 mtpmr(PMRN_PMGC0, pmgc0);
29}
30#elif defined(CONFIG_PPC64) || defined(CONFIG_6xx)
31
32#ifndef MMCR0_PMAO
33#define MMCR0_PMAO 0
34#endif 25#endif
35 26
36/* Ensure exceptions are disabled */
37static void dummy_perf(struct pt_regs *regs) 27static void dummy_perf(struct pt_regs *regs)
38{ 28{
39 unsigned int mmcr0 = mfspr(SPRN_MMCR0); 29#if defined(CONFIG_FSL_BOOKE) && !defined(CONFIG_E200)
40 30 mtpmr(PMRN_PMGC0, mfpmr(PMRN_PMGC0) & ~PMGC0_PMIE);
41 mmcr0 &= ~(MMCR0_PMXE|MMCR0_PMAO); 31#elif defined(CONFIG_PPC64) || defined(CONFIG_6xx)
42 mtspr(SPRN_MMCR0, mmcr0); 32 if (cur_cpu_spec->pmc_type == PPC_PMC_IBM)
43} 33 mtspr(SPRN_MMCR0, mfspr(SPRN_MMCR0) & ~(MMCR0_PMXE|MMCR0_PMA0));
44#else 34#else
45/* Ensure exceptions are disabled */ 35 mtspr(SPRN_MMCR0, mfspr(SPRN_MMCR0) & ~MMCR0_PMXE);
46static void dummy_perf(struct pt_regs *regs)
47{
48 unsigned int mmcr0 = mfspr(SPRN_MMCR0);
49
50 mmcr0 &= ~(MMCR0_PMXE);
51 mtspr(SPRN_MMCR0, mmcr0);
52}
53#endif 36#endif
37}
38
54 39
55static DEFINE_SPINLOCK(pmc_owner_lock); 40static DEFINE_SPINLOCK(pmc_owner_lock);
56static void *pmc_owner_caller; /* mostly for debugging */ 41static void *pmc_owner_caller; /* mostly for debugging */
diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c
index 95776b6af4e2..ecee596d28f6 100644
--- a/arch/powerpc/kernel/ppc_ksyms.c
+++ b/arch/powerpc/kernel/ppc_ksyms.c
@@ -44,6 +44,7 @@
44#include <asm/btext.h> 44#include <asm/btext.h>
45#include <asm/div64.h> 45#include <asm/div64.h>
46#include <asm/signal.h> 46#include <asm/signal.h>
47#include <asm/dcr.h>
47 48
48#ifdef CONFIG_8xx 49#ifdef CONFIG_8xx
49#include <asm/commproc.h> 50#include <asm/commproc.h>
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index 1fc732a552db..3be52d693eca 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -1221,8 +1221,7 @@ struct device_node *of_find_node_by_name(struct device_node *from,
1221 if (np->name != NULL && strcasecmp(np->name, name) == 0 1221 if (np->name != NULL && strcasecmp(np->name, name) == 0
1222 && of_node_get(np)) 1222 && of_node_get(np))
1223 break; 1223 break;
1224 if (from) 1224 of_node_put(from);
1225 of_node_put(from);
1226 read_unlock(&devtree_lock); 1225 read_unlock(&devtree_lock);
1227 return np; 1226 return np;
1228} 1227}
@@ -1250,8 +1249,7 @@ struct device_node *of_find_node_by_type(struct device_node *from,
1250 if (np->type != 0 && strcasecmp(np->type, type) == 0 1249 if (np->type != 0 && strcasecmp(np->type, type) == 0
1251 && of_node_get(np)) 1250 && of_node_get(np))
1252 break; 1251 break;
1253 if (from) 1252 of_node_put(from);
1254 of_node_put(from);
1255 read_unlock(&devtree_lock); 1253 read_unlock(&devtree_lock);
1256 return np; 1254 return np;
1257} 1255}
@@ -1285,8 +1283,7 @@ struct device_node *of_find_compatible_node(struct device_node *from,
1285 if (device_is_compatible(np, compatible) && of_node_get(np)) 1283 if (device_is_compatible(np, compatible) && of_node_get(np))
1286 break; 1284 break;
1287 } 1285 }
1288 if (from) 1286 of_node_put(from);
1289 of_node_put(from);
1290 read_unlock(&devtree_lock); 1287 read_unlock(&devtree_lock);
1291 return np; 1288 return np;
1292} 1289}
@@ -1329,8 +1326,7 @@ struct device_node *of_find_node_by_phandle(phandle handle)
1329 for (np = allnodes; np != 0; np = np->allnext) 1326 for (np = allnodes; np != 0; np = np->allnext)
1330 if (np->linux_phandle == handle) 1327 if (np->linux_phandle == handle)
1331 break; 1328 break;
1332 if (np) 1329 of_node_get(np);
1333 of_node_get(np);
1334 read_unlock(&devtree_lock); 1330 read_unlock(&devtree_lock);
1335 return np; 1331 return np;
1336} 1332}
@@ -1353,8 +1349,7 @@ struct device_node *of_find_all_nodes(struct device_node *prev)
1353 for (; np != 0; np = np->allnext) 1349 for (; np != 0; np = np->allnext)
1354 if (of_node_get(np)) 1350 if (of_node_get(np))
1355 break; 1351 break;
1356 if (prev) 1352 of_node_put(prev);
1357 of_node_put(prev);
1358 read_unlock(&devtree_lock); 1353 read_unlock(&devtree_lock);
1359 return np; 1354 return np;
1360} 1355}
@@ -1399,8 +1394,7 @@ struct device_node *of_get_next_child(const struct device_node *node,
1399 for (; next != 0; next = next->sibling) 1394 for (; next != 0; next = next->sibling)
1400 if (of_node_get(next)) 1395 if (of_node_get(next))
1401 break; 1396 break;
1402 if (prev) 1397 of_node_put(prev);
1403 of_node_put(prev);
1404 read_unlock(&devtree_lock); 1398 read_unlock(&devtree_lock);
1405 return next; 1399 return next;
1406} 1400}
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index 975102a020d9..cc44c7b975aa 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -532,16 +532,22 @@ void do_syscall_trace_enter(struct pt_regs *regs)
532 && (current->ptrace & PT_PTRACED)) 532 && (current->ptrace & PT_PTRACED))
533 do_syscall_trace(); 533 do_syscall_trace();
534 534
535 if (unlikely(current->audit_context)) 535 if (unlikely(current->audit_context)) {
536 audit_syscall_entry( 536#ifdef CONFIG_PPC64
537#ifdef CONFIG_PPC32 537 if (!test_thread_flag(TIF_32BIT))
538 AUDIT_ARCH_PPC, 538 audit_syscall_entry(AUDIT_ARCH_PPC64,
539#else 539 regs->gpr[0],
540 test_thread_flag(TIF_32BIT)?AUDIT_ARCH_PPC:AUDIT_ARCH_PPC64, 540 regs->gpr[3], regs->gpr[4],
541 regs->gpr[5], regs->gpr[6]);
542 else
541#endif 543#endif
542 regs->gpr[0], 544 audit_syscall_entry(AUDIT_ARCH_PPC,
543 regs->gpr[3], regs->gpr[4], 545 regs->gpr[0],
544 regs->gpr[5], regs->gpr[6]); 546 regs->gpr[3] & 0xffffffff,
547 regs->gpr[4] & 0xffffffff,
548 regs->gpr[5] & 0xffffffff,
549 regs->gpr[6] & 0xffffffff);
550 }
545} 551}
546 552
547void do_syscall_trace_leave(struct pt_regs *regs) 553void do_syscall_trace_leave(struct pt_regs *regs)
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c
index 61c65d19ef06..6a19fa40dcee 100644
--- a/arch/powerpc/kernel/setup_32.c
+++ b/arch/powerpc/kernel/setup_32.c
@@ -65,6 +65,7 @@ int have_of = 1;
65 65
66#ifdef CONFIG_VGA_CONSOLE 66#ifdef CONFIG_VGA_CONSOLE
67unsigned long vgacon_remap_base; 67unsigned long vgacon_remap_base;
68EXPORT_SYMBOL(vgacon_remap_base);
68#endif 69#endif
69 70
70/* 71/*
diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c
index 400ab2b946e7..d57818aea081 100644
--- a/arch/powerpc/kernel/sysfs.c
+++ b/arch/powerpc/kernel/sysfs.c
@@ -169,6 +169,11 @@ static ssize_t __attribute_used__ \
169 return count; \ 169 return count; \
170} 170}
171 171
172
173/* Let's define all possible registers, we'll only hook up the ones
174 * that are implemented on the current processor
175 */
176
172SYSFS_PMCSETUP(mmcr0, SPRN_MMCR0); 177SYSFS_PMCSETUP(mmcr0, SPRN_MMCR0);
173SYSFS_PMCSETUP(mmcr1, SPRN_MMCR1); 178SYSFS_PMCSETUP(mmcr1, SPRN_MMCR1);
174SYSFS_PMCSETUP(mmcra, SPRN_MMCRA); 179SYSFS_PMCSETUP(mmcra, SPRN_MMCRA);
@@ -184,55 +189,87 @@ SYSFS_PMCSETUP(purr, SPRN_PURR);
184SYSFS_PMCSETUP(spurr, SPRN_SPURR); 189SYSFS_PMCSETUP(spurr, SPRN_SPURR);
185SYSFS_PMCSETUP(dscr, SPRN_DSCR); 190SYSFS_PMCSETUP(dscr, SPRN_DSCR);
186 191
187static SYSDEV_ATTR(mmcr0, 0600, show_mmcr0, store_mmcr0); 192SYSFS_PMCSETUP(pa6t_pmc0, PA6T_SPRN_PMC0);
188static SYSDEV_ATTR(mmcr1, 0600, show_mmcr1, store_mmcr1); 193SYSFS_PMCSETUP(pa6t_pmc1, PA6T_SPRN_PMC1);
194SYSFS_PMCSETUP(pa6t_pmc2, PA6T_SPRN_PMC2);
195SYSFS_PMCSETUP(pa6t_pmc3, PA6T_SPRN_PMC3);
196SYSFS_PMCSETUP(pa6t_pmc4, PA6T_SPRN_PMC4);
197SYSFS_PMCSETUP(pa6t_pmc5, PA6T_SPRN_PMC5);
198
199
189static SYSDEV_ATTR(mmcra, 0600, show_mmcra, store_mmcra); 200static SYSDEV_ATTR(mmcra, 0600, show_mmcra, store_mmcra);
190static SYSDEV_ATTR(pmc1, 0600, show_pmc1, store_pmc1);
191static SYSDEV_ATTR(pmc2, 0600, show_pmc2, store_pmc2);
192static SYSDEV_ATTR(pmc3, 0600, show_pmc3, store_pmc3);
193static SYSDEV_ATTR(pmc4, 0600, show_pmc4, store_pmc4);
194static SYSDEV_ATTR(pmc5, 0600, show_pmc5, store_pmc5);
195static SYSDEV_ATTR(pmc6, 0600, show_pmc6, store_pmc6);
196static SYSDEV_ATTR(pmc7, 0600, show_pmc7, store_pmc7);
197static SYSDEV_ATTR(pmc8, 0600, show_pmc8, store_pmc8);
198static SYSDEV_ATTR(purr, 0600, show_purr, NULL);
199static SYSDEV_ATTR(spurr, 0600, show_spurr, NULL); 201static SYSDEV_ATTR(spurr, 0600, show_spurr, NULL);
200static SYSDEV_ATTR(dscr, 0600, show_dscr, store_dscr); 202static SYSDEV_ATTR(dscr, 0600, show_dscr, store_dscr);
203static SYSDEV_ATTR(purr, 0600, show_purr, store_purr);
204
205static struct sysdev_attribute ibm_common_attrs[] = {
206 _SYSDEV_ATTR(mmcr0, 0600, show_mmcr0, store_mmcr0),
207 _SYSDEV_ATTR(mmcr1, 0600, show_mmcr1, store_mmcr1),
208};
209
210static struct sysdev_attribute ibm_pmc_attrs[] = {
211 _SYSDEV_ATTR(pmc1, 0600, show_pmc1, store_pmc1),
212 _SYSDEV_ATTR(pmc2, 0600, show_pmc2, store_pmc2),
213 _SYSDEV_ATTR(pmc3, 0600, show_pmc3, store_pmc3),
214 _SYSDEV_ATTR(pmc4, 0600, show_pmc4, store_pmc4),
215 _SYSDEV_ATTR(pmc5, 0600, show_pmc5, store_pmc5),
216 _SYSDEV_ATTR(pmc6, 0600, show_pmc6, store_pmc6),
217 _SYSDEV_ATTR(pmc7, 0600, show_pmc7, store_pmc7),
218 _SYSDEV_ATTR(pmc8, 0600, show_pmc8, store_pmc8),
219};
220
221static struct sysdev_attribute pa6t_attrs[] = {
222 _SYSDEV_ATTR(mmcr0, 0600, show_mmcr0, store_mmcr0),
223 _SYSDEV_ATTR(mmcr1, 0600, show_mmcr1, store_mmcr1),
224 _SYSDEV_ATTR(pmc0, 0600, show_pa6t_pmc0, store_pa6t_pmc0),
225 _SYSDEV_ATTR(pmc1, 0600, show_pa6t_pmc1, store_pa6t_pmc1),
226 _SYSDEV_ATTR(pmc2, 0600, show_pa6t_pmc2, store_pa6t_pmc2),
227 _SYSDEV_ATTR(pmc3, 0600, show_pa6t_pmc3, store_pa6t_pmc3),
228 _SYSDEV_ATTR(pmc4, 0600, show_pa6t_pmc4, store_pa6t_pmc4),
229 _SYSDEV_ATTR(pmc5, 0600, show_pa6t_pmc5, store_pa6t_pmc5),
230};
231
201 232
202static void register_cpu_online(unsigned int cpu) 233static void register_cpu_online(unsigned int cpu)
203{ 234{
204 struct cpu *c = &per_cpu(cpu_devices, cpu); 235 struct cpu *c = &per_cpu(cpu_devices, cpu);
205 struct sys_device *s = &c->sysdev; 236 struct sys_device *s = &c->sysdev;
237 struct sysdev_attribute *attrs, *pmc_attrs;
238 int i, nattrs;
206 239
207 if (!firmware_has_feature(FW_FEATURE_ISERIES) && 240 if (!firmware_has_feature(FW_FEATURE_ISERIES) &&
208 cpu_has_feature(CPU_FTR_SMT)) 241 cpu_has_feature(CPU_FTR_SMT))
209 sysdev_create_file(s, &attr_smt_snooze_delay); 242 sysdev_create_file(s, &attr_smt_snooze_delay);
210 243
211 /* PMC stuff */ 244 /* PMC stuff */
245 switch (cur_cpu_spec->pmc_type) {
246 case PPC_PMC_IBM:
247 attrs = ibm_common_attrs;
248 nattrs = sizeof(ibm_common_attrs) / sizeof(struct sysdev_attribute);
249 pmc_attrs = ibm_pmc_attrs;
250 break;
251 case PPC_PMC_PA6T:
252 /* PA Semi starts counting at PMC0 */
253 attrs = pa6t_attrs;
254 nattrs = sizeof(pa6t_attrs) / sizeof(struct sysdev_attribute);
255 pmc_attrs = NULL;
256 break;
257 default:
258 attrs = NULL;
259 nattrs = 0;
260 pmc_attrs = NULL;
261 }
262
263 for (i = 0; i < nattrs; i++)
264 sysdev_create_file(s, &attrs[i]);
212 265
213 sysdev_create_file(s, &attr_mmcr0); 266 if (pmc_attrs)
214 sysdev_create_file(s, &attr_mmcr1); 267 for (i = 0; i < cur_cpu_spec->num_pmcs; i++)
268 sysdev_create_file(s, &pmc_attrs[i]);
215 269
216 if (cpu_has_feature(CPU_FTR_MMCRA)) 270 if (cpu_has_feature(CPU_FTR_MMCRA))
217 sysdev_create_file(s, &attr_mmcra); 271 sysdev_create_file(s, &attr_mmcra);
218 272
219 if (cur_cpu_spec->num_pmcs >= 1)
220 sysdev_create_file(s, &attr_pmc1);
221 if (cur_cpu_spec->num_pmcs >= 2)
222 sysdev_create_file(s, &attr_pmc2);
223 if (cur_cpu_spec->num_pmcs >= 3)
224 sysdev_create_file(s, &attr_pmc3);
225 if (cur_cpu_spec->num_pmcs >= 4)
226 sysdev_create_file(s, &attr_pmc4);
227 if (cur_cpu_spec->num_pmcs >= 5)
228 sysdev_create_file(s, &attr_pmc5);
229 if (cur_cpu_spec->num_pmcs >= 6)
230 sysdev_create_file(s, &attr_pmc6);
231 if (cur_cpu_spec->num_pmcs >= 7)
232 sysdev_create_file(s, &attr_pmc7);
233 if (cur_cpu_spec->num_pmcs >= 8)
234 sysdev_create_file(s, &attr_pmc8);
235
236 if (cpu_has_feature(CPU_FTR_PURR)) 273 if (cpu_has_feature(CPU_FTR_PURR))
237 sysdev_create_file(s, &attr_purr); 274 sysdev_create_file(s, &attr_purr);
238 275
@@ -248,6 +285,8 @@ static void unregister_cpu_online(unsigned int cpu)
248{ 285{
249 struct cpu *c = &per_cpu(cpu_devices, cpu); 286 struct cpu *c = &per_cpu(cpu_devices, cpu);
250 struct sys_device *s = &c->sysdev; 287 struct sys_device *s = &c->sysdev;
288 struct sysdev_attribute *attrs, *pmc_attrs;
289 int i, nattrs;
251 290
252 BUG_ON(!c->hotpluggable); 291 BUG_ON(!c->hotpluggable);
253 292
@@ -256,30 +295,34 @@ static void unregister_cpu_online(unsigned int cpu)
256 sysdev_remove_file(s, &attr_smt_snooze_delay); 295 sysdev_remove_file(s, &attr_smt_snooze_delay);
257 296
258 /* PMC stuff */ 297 /* PMC stuff */
298 switch (cur_cpu_spec->pmc_type) {
299 case PPC_PMC_IBM:
300 attrs = ibm_common_attrs;
301 nattrs = sizeof(ibm_common_attrs) / sizeof(struct sysdev_attribute);
302 pmc_attrs = ibm_pmc_attrs;
303 break;
304 case PPC_PMC_PA6T:
305 /* PA Semi starts counting at PMC0 */
306 attrs = pa6t_attrs;
307 nattrs = sizeof(pa6t_attrs) / sizeof(struct sysdev_attribute);
308 pmc_attrs = NULL;
309 break;
310 default:
311 attrs = NULL;
312 nattrs = 0;
313 pmc_attrs = NULL;
314 }
259 315
260 sysdev_remove_file(s, &attr_mmcr0); 316 for (i = 0; i < nattrs; i++)
261 sysdev_remove_file(s, &attr_mmcr1); 317 sysdev_remove_file(s, &attrs[i]);
318
319 if (pmc_attrs)
320 for (i = 0; i < cur_cpu_spec->num_pmcs; i++)
321 sysdev_remove_file(s, &pmc_attrs[i]);
262 322
263 if (cpu_has_feature(CPU_FTR_MMCRA)) 323 if (cpu_has_feature(CPU_FTR_MMCRA))
264 sysdev_remove_file(s, &attr_mmcra); 324 sysdev_remove_file(s, &attr_mmcra);
265 325
266 if (cur_cpu_spec->num_pmcs >= 1)
267 sysdev_remove_file(s, &attr_pmc1);
268 if (cur_cpu_spec->num_pmcs >= 2)
269 sysdev_remove_file(s, &attr_pmc2);
270 if (cur_cpu_spec->num_pmcs >= 3)
271 sysdev_remove_file(s, &attr_pmc3);
272 if (cur_cpu_spec->num_pmcs >= 4)
273 sysdev_remove_file(s, &attr_pmc4);
274 if (cur_cpu_spec->num_pmcs >= 5)
275 sysdev_remove_file(s, &attr_pmc5);
276 if (cur_cpu_spec->num_pmcs >= 6)
277 sysdev_remove_file(s, &attr_pmc6);
278 if (cur_cpu_spec->num_pmcs >= 7)
279 sysdev_remove_file(s, &attr_pmc7);
280 if (cur_cpu_spec->num_pmcs >= 8)
281 sysdev_remove_file(s, &attr_pmc8);
282
283 if (cpu_has_feature(CPU_FTR_PURR)) 326 if (cpu_has_feature(CPU_FTR_PURR))
284 sysdev_remove_file(s, &attr_purr); 327 sysdev_remove_file(s, &attr_purr);
285 328
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 535f50665647..dcc6f159fd94 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -174,7 +174,7 @@ void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr)
174 * generate the same exception over and over again and we get 174 * generate the same exception over and over again and we get
175 * nowhere. Better to kill it and let the kernel panic. 175 * nowhere. Better to kill it and let the kernel panic.
176 */ 176 */
177 if (current->pid == 1) { 177 if (is_init(current)) {
178 __sighandler_t handler; 178 __sighandler_t handler;
179 179
180 spin_lock_irq(&current->sighand->siglock); 180 spin_lock_irq(&current->sighand->siglock);
@@ -535,34 +535,40 @@ static void emulate_single_step(struct pt_regs *regs)
535 } 535 }
536} 536}
537 537
538static void parse_fpe(struct pt_regs *regs) 538static inline int __parse_fpscr(unsigned long fpscr)
539{ 539{
540 int code = 0; 540 int ret = 0;
541 unsigned long fpscr;
542
543 flush_fp_to_thread(current);
544
545 fpscr = current->thread.fpscr.val;
546 541
547 /* Invalid operation */ 542 /* Invalid operation */
548 if ((fpscr & FPSCR_VE) && (fpscr & FPSCR_VX)) 543 if ((fpscr & FPSCR_VE) && (fpscr & FPSCR_VX))
549 code = FPE_FLTINV; 544 ret = FPE_FLTINV;
550 545
551 /* Overflow */ 546 /* Overflow */
552 else if ((fpscr & FPSCR_OE) && (fpscr & FPSCR_OX)) 547 else if ((fpscr & FPSCR_OE) && (fpscr & FPSCR_OX))
553 code = FPE_FLTOVF; 548 ret = FPE_FLTOVF;
554 549
555 /* Underflow */ 550 /* Underflow */
556 else if ((fpscr & FPSCR_UE) && (fpscr & FPSCR_UX)) 551 else if ((fpscr & FPSCR_UE) && (fpscr & FPSCR_UX))
557 code = FPE_FLTUND; 552 ret = FPE_FLTUND;
558 553
559 /* Divide by zero */ 554 /* Divide by zero */
560 else if ((fpscr & FPSCR_ZE) && (fpscr & FPSCR_ZX)) 555 else if ((fpscr & FPSCR_ZE) && (fpscr & FPSCR_ZX))
561 code = FPE_FLTDIV; 556 ret = FPE_FLTDIV;
562 557
563 /* Inexact result */ 558 /* Inexact result */
564 else if ((fpscr & FPSCR_XE) && (fpscr & FPSCR_XX)) 559 else if ((fpscr & FPSCR_XE) && (fpscr & FPSCR_XX))
565 code = FPE_FLTRES; 560 ret = FPE_FLTRES;
561
562 return ret;
563}
564
565static void parse_fpe(struct pt_regs *regs)
566{
567 int code = 0;
568
569 flush_fp_to_thread(current);
570
571 code = __parse_fpscr(current->thread.fpscr.val);
566 572
567 _exception(SIGFPE, regs, code, regs->nip); 573 _exception(SIGFPE, regs, code, regs->nip);
568} 574}
@@ -739,20 +745,7 @@ void __kprobes program_check_exception(struct pt_regs *regs)
739 extern int do_mathemu(struct pt_regs *regs); 745 extern int do_mathemu(struct pt_regs *regs);
740 746
741 /* We can now get here via a FP Unavailable exception if the core 747 /* We can now get here via a FP Unavailable exception if the core
742 * has no FPU, in that case no reason flags will be set */ 748 * has no FPU, in that case the reason flags will be 0 */
743#ifdef CONFIG_MATH_EMULATION
744 /* (reason & REASON_ILLEGAL) would be the obvious thing here,
745 * but there seems to be a hardware bug on the 405GP (RevD)
746 * that means ESR is sometimes set incorrectly - either to
747 * ESR_DST (!?) or 0. In the process of chasing this with the
748 * hardware people - not sure if it can happen on any illegal
749 * instruction or only on FP instructions, whether there is a
750 * pattern to occurences etc. -dgibson 31/Mar/2003 */
751 if (!(reason & REASON_TRAP) && do_mathemu(regs) == 0) {
752 emulate_single_step(regs);
753 return;
754 }
755#endif /* CONFIG_MATH_EMULATION */
756 749
757 if (reason & REASON_FP) { 750 if (reason & REASON_FP) {
758 /* IEEE FP exception */ 751 /* IEEE FP exception */
@@ -778,6 +771,31 @@ void __kprobes program_check_exception(struct pt_regs *regs)
778 771
779 local_irq_enable(); 772 local_irq_enable();
780 773
774#ifdef CONFIG_MATH_EMULATION
775 /* (reason & REASON_ILLEGAL) would be the obvious thing here,
776 * but there seems to be a hardware bug on the 405GP (RevD)
777 * that means ESR is sometimes set incorrectly - either to
778 * ESR_DST (!?) or 0. In the process of chasing this with the
779 * hardware people - not sure if it can happen on any illegal
780 * instruction or only on FP instructions, whether there is a
781 * pattern to occurences etc. -dgibson 31/Mar/2003 */
782 switch (do_mathemu(regs)) {
783 case 0:
784 emulate_single_step(regs);
785 return;
786 case 1: {
787 int code = 0;
788 code = __parse_fpscr(current->thread.fpscr.val);
789 _exception(SIGFPE, regs, code, regs->nip);
790 return;
791 }
792 case -EFAULT:
793 _exception(SIGSEGV, regs, SEGV_MAPERR, regs->nip);
794 return;
795 }
796 /* fall through on any other errors */
797#endif /* CONFIG_MATH_EMULATION */
798
781 /* Try to emulate it if we should. */ 799 /* Try to emulate it if we should. */
782 if (reason & (REASON_ILLEGAL | REASON_PRIVILEGED)) { 800 if (reason & (REASON_ILLEGAL | REASON_PRIVILEGED)) {
783 switch (emulate_instruction(regs)) { 801 switch (emulate_instruction(regs)) {
@@ -891,18 +909,39 @@ void SoftwareEmulation(struct pt_regs *regs)
891 909
892#ifdef CONFIG_MATH_EMULATION 910#ifdef CONFIG_MATH_EMULATION
893 errcode = do_mathemu(regs); 911 errcode = do_mathemu(regs);
912
913 switch (errcode) {
914 case 0:
915 emulate_single_step(regs);
916 return;
917 case 1: {
918 int code = 0;
919 code = __parse_fpscr(current->thread.fpscr.val);
920 _exception(SIGFPE, regs, code, regs->nip);
921 return;
922 }
923 case -EFAULT:
924 _exception(SIGSEGV, regs, SEGV_MAPERR, regs->nip);
925 return;
926 default:
927 _exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
928 return;
929 }
930
894#else 931#else
895 errcode = Soft_emulate_8xx(regs); 932 errcode = Soft_emulate_8xx(regs);
896#endif 933 switch (errcode) {
897 if (errcode) { 934 case 0:
898 if (errcode > 0)
899 _exception(SIGFPE, regs, 0, 0);
900 else if (errcode == -EFAULT)
901 _exception(SIGSEGV, regs, 0, 0);
902 else
903 _exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
904 } else
905 emulate_single_step(regs); 935 emulate_single_step(regs);
936 return;
937 case 1:
938 _exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
939 return;
940 case -EFAULT:
941 _exception(SIGSEGV, regs, SEGV_MAPERR, regs->nip);
942 return;
943 }
944#endif
906} 945}
907#endif /* CONFIG_8xx */ 946#endif /* CONFIG_8xx */
908 947
diff --git a/arch/powerpc/kernel/udbg.c b/arch/powerpc/kernel/udbg.c
index 5730906b23d5..8f5afdbad0d5 100644
--- a/arch/powerpc/kernel/udbg.c
+++ b/arch/powerpc/kernel/udbg.c
@@ -45,6 +45,10 @@ void __init udbg_early_init(void)
45#elif defined(CONFIG_PPC_EARLY_DEBUG_ISERIES) 45#elif defined(CONFIG_PPC_EARLY_DEBUG_ISERIES)
46 /* For iSeries - hit Ctrl-x Ctrl-x to see the output */ 46 /* For iSeries - hit Ctrl-x Ctrl-x to see the output */
47 udbg_init_iseries(); 47 udbg_init_iseries();
48#elif defined(CONFIG_PPC_EARLY_DEBUG_BEAT)
49 udbg_init_debug_beat();
50#elif defined(CONFIG_PPC_EARLY_DEBUG_PAS_REALMODE)
51 udbg_init_pas_realmode();
48#endif 52#endif
49} 53}
50 54
diff --git a/arch/powerpc/kernel/udbg_16550.c b/arch/powerpc/kernel/udbg_16550.c
index 2d17f2b8eda7..e738f93b42fe 100644
--- a/arch/powerpc/kernel/udbg_16550.c
+++ b/arch/powerpc/kernel/udbg_16550.c
@@ -14,6 +14,8 @@
14 14
15extern u8 real_readb(volatile u8 __iomem *addr); 15extern u8 real_readb(volatile u8 __iomem *addr);
16extern void real_writeb(u8 data, volatile u8 __iomem *addr); 16extern void real_writeb(u8 data, volatile u8 __iomem *addr);
17extern u8 real_205_readb(volatile u8 __iomem *addr);
18extern void real_205_writeb(u8 data, volatile u8 __iomem *addr);
17 19
18struct NS16550 { 20struct NS16550 {
19 /* this struct must be packed */ 21 /* this struct must be packed */
@@ -167,3 +169,25 @@ void __init udbg_init_maple_realmode(void)
167 udbg_getc_poll = NULL; 169 udbg_getc_poll = NULL;
168} 170}
169#endif /* CONFIG_PPC_MAPLE */ 171#endif /* CONFIG_PPC_MAPLE */
172
173#ifdef CONFIG_PPC_PASEMI
174void udbg_pas_real_putc(char c)
175{
176 if (udbg_comport) {
177 while ((real_205_readb(&udbg_comport->lsr) & LSR_THRE) == 0)
178 /* wait for idle */;
179 real_205_writeb(c, &udbg_comport->thr); eieio();
180 if (c == '\n')
181 udbg_pas_real_putc('\r');
182 }
183}
184
185void udbg_init_pas_realmode(void)
186{
187 udbg_comport = (volatile struct NS16550 __iomem *)0xfcff03f8;
188
189 udbg_putc = udbg_pas_real_putc;
190 udbg_getc = NULL;
191 udbg_getc_poll = NULL;
192}
193#endif /* CONFIG_PPC_MAPLE */
diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c
index a80f8f1d2e5d..2968ffeafdb6 100644
--- a/arch/powerpc/kernel/vio.c
+++ b/arch/powerpc/kernel/vio.c
@@ -199,10 +199,8 @@ EXPORT_SYMBOL(vio_unregister_driver);
199/* vio_dev refcount hit 0 */ 199/* vio_dev refcount hit 0 */
200static void __devinit vio_dev_release(struct device *dev) 200static void __devinit vio_dev_release(struct device *dev)
201{ 201{
202 if (dev->archdata.of_node) { 202 /* XXX should free TCE table */
203 /* XXX should free TCE table */ 203 of_node_put(dev->archdata.of_node);
204 of_node_put(dev->archdata.of_node);
205 }
206 kfree(to_vio_dev(dev)); 204 kfree(to_vio_dev(dev));
207} 205}
208 206