aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/powerpc/Kconfig4
-rw-r--r--arch/powerpc/Kconfig.debug9
-rw-r--r--arch/powerpc/Makefile1
-rw-r--r--arch/powerpc/boot/dts/bamboo.dts3
-rw-r--r--arch/powerpc/boot/dts/canyonlands.dts14
-rw-r--r--arch/powerpc/boot/dts/gef_sbc610.dts11
-rw-r--r--arch/powerpc/boot/dts/kuroboxHD.dts1
-rw-r--r--arch/powerpc/boot/dts/kuroboxHG.dts1
-rw-r--r--arch/powerpc/boot/dts/lite5200.dts1
-rw-r--r--arch/powerpc/boot/dts/lite5200b.dts1
-rw-r--r--arch/powerpc/boot/dts/motionpro.dts1
-rw-r--r--arch/powerpc/boot/dts/mpc8315erdb.dts1
-rw-r--r--arch/powerpc/boot/dts/mpc8349emitx.dts1
-rw-r--r--arch/powerpc/boot/dts/mpc8349emitxgp.dts1
-rw-r--r--arch/powerpc/boot/dts/mpc8377_rdb.dts1
-rw-r--r--arch/powerpc/boot/dts/mpc8378_rdb.dts1
-rw-r--r--arch/powerpc/boot/dts/mpc8379_rdb.dts1
-rw-r--r--arch/powerpc/boot/dts/mpc8572ds.dts113
-rw-r--r--arch/powerpc/boot/dts/mpc8572ds_camp_core0.dts483
-rw-r--r--arch/powerpc/boot/dts/mpc8572ds_camp_core1.dts234
-rw-r--r--arch/powerpc/boot/dts/pcm030.dts2
-rw-r--r--arch/powerpc/boot/dts/tqm5200.dts1
-rw-r--r--arch/powerpc/boot/libfdt-wrapper.c2
-rw-r--r--arch/powerpc/configs/86xx/gef_sbc610_defconfig8
-rw-r--r--arch/powerpc/configs/ppc44x_defconfig12
-rw-r--r--arch/powerpc/include/asm/atomic.h18
-rw-r--r--arch/powerpc/include/asm/bug.h11
-rw-r--r--arch/powerpc/include/asm/byteorder.h38
-rw-r--r--arch/powerpc/include/asm/cputable.h21
-rw-r--r--arch/powerpc/include/asm/device.h12
-rw-r--r--arch/powerpc/include/asm/dma-mapping.h156
-rw-r--r--arch/powerpc/include/asm/eeh.h8
-rw-r--r--arch/powerpc/include/asm/highmem.h4
-rw-r--r--arch/powerpc/include/asm/io.h7
-rw-r--r--arch/powerpc/include/asm/local.h4
-rw-r--r--arch/powerpc/include/asm/lppaca.h3
-rw-r--r--arch/powerpc/include/asm/mmu-fsl-booke.h2
-rw-r--r--arch/powerpc/include/asm/mmu_context.h3
-rw-r--r--arch/powerpc/include/asm/mutex.h135
-rw-r--r--arch/powerpc/include/asm/pci-bridge.h30
-rw-r--r--arch/powerpc/include/asm/pci.h15
-rw-r--r--arch/powerpc/include/asm/pgalloc-32.h11
-rw-r--r--arch/powerpc/include/asm/pgalloc-64.h34
-rw-r--r--arch/powerpc/include/asm/pgalloc.h41
-rw-r--r--arch/powerpc/include/asm/pgtable-ppc64.h2
-rw-r--r--arch/powerpc/include/asm/processor.h8
-rw-r--r--arch/powerpc/include/asm/ps3.h56
-rw-r--r--arch/powerpc/include/asm/ps3av.h4
-rw-r--r--arch/powerpc/include/asm/rtas.h1
-rw-r--r--arch/powerpc/include/asm/sfp-machine.h58
-rw-r--r--arch/powerpc/include/asm/smp.h7
-rw-r--r--arch/powerpc/include/asm/spinlock.h2
-rw-r--r--arch/powerpc/include/asm/synch.h4
-rw-r--r--arch/powerpc/include/asm/system.h24
-rw-r--r--arch/powerpc/include/asm/time.h20
-rw-r--r--arch/powerpc/include/asm/tlbflush.h19
-rw-r--r--arch/powerpc/include/asm/vdso_datapage.h3
-rw-r--r--arch/powerpc/kernel/asm-offsets.c1
-rw-r--r--arch/powerpc/kernel/dma.c26
-rw-r--r--arch/powerpc/kernel/head_fsl_booke.S103
-rw-r--r--arch/powerpc/kernel/ibmebus.c3
-rw-r--r--arch/powerpc/kernel/of_device.c18
-rw-r--r--arch/powerpc/kernel/paca.c1
-rw-r--r--arch/powerpc/kernel/pci-common.c278
-rw-r--r--arch/powerpc/kernel/pci_32.c108
-rw-r--r--arch/powerpc/kernel/pci_64.c134
-rw-r--r--arch/powerpc/kernel/process.c4
-rw-r--r--arch/powerpc/kernel/prom_parse.c5
-rw-r--r--arch/powerpc/kernel/rtas.c26
-rw-r--r--arch/powerpc/kernel/rtas_pci.c48
-rw-r--r--arch/powerpc/kernel/setup_32.c4
-rw-r--r--arch/powerpc/kernel/setup_64.c3
-rw-r--r--arch/powerpc/kernel/smp-tbsync.c12
-rw-r--r--arch/powerpc/kernel/smp.c60
-rw-r--r--arch/powerpc/kernel/time.c36
-rw-r--r--arch/powerpc/kernel/traps.c62
-rw-r--r--arch/powerpc/kernel/vdso32/gettimeofday.S208
-rw-r--r--arch/powerpc/kernel/vdso64/gettimeofday.S141
-rw-r--r--arch/powerpc/kernel/vio.c12
-rw-r--r--arch/powerpc/lib/copyuser_64.S17
-rw-r--r--arch/powerpc/lib/dma-noncoherent.c1
-rw-r--r--arch/powerpc/lib/memcpy_64.S16
-rw-r--r--arch/powerpc/math-emu/Makefile2
-rw-r--r--arch/powerpc/math-emu/fadd.c1
-rw-r--r--arch/powerpc/math-emu/fcmpo.c5
-rw-r--r--arch/powerpc/math-emu/fdiv.c9
-rw-r--r--arch/powerpc/math-emu/fdivs.c9
-rw-r--r--arch/powerpc/math-emu/fmadd.c5
-rw-r--r--arch/powerpc/math-emu/fmadds.c5
-rw-r--r--arch/powerpc/math-emu/fmsub.c5
-rw-r--r--arch/powerpc/math-emu/fmsubs.c5
-rw-r--r--arch/powerpc/math-emu/fmul.c3
-rw-r--r--arch/powerpc/math-emu/fmuls.c3
-rw-r--r--arch/powerpc/math-emu/fnmadd.c5
-rw-r--r--arch/powerpc/math-emu/fnmadds.c5
-rw-r--r--arch/powerpc/math-emu/fnmsub.c5
-rw-r--r--arch/powerpc/math-emu/fnmsubs.c5
-rw-r--r--arch/powerpc/math-emu/fsqrt.c5
-rw-r--r--arch/powerpc/math-emu/fsqrts.c5
-rw-r--r--arch/powerpc/math-emu/fsub.c3
-rw-r--r--arch/powerpc/math-emu/fsubs.c3
-rw-r--r--arch/powerpc/math-emu/math_efp.c720
-rw-r--r--arch/powerpc/mm/Makefile4
-rw-r--r--arch/powerpc/mm/fault.c12
-rw-r--r--arch/powerpc/mm/hash_low_32.S30
-rw-r--r--arch/powerpc/mm/hugetlbpage.c22
-rw-r--r--arch/powerpc/mm/mmu_decl.h17
-rw-r--r--arch/powerpc/mm/pgtable.c117
-rw-r--r--arch/powerpc/mm/pgtable_32.c27
-rw-r--r--arch/powerpc/mm/tlb_hash32.c (renamed from arch/powerpc/mm/tlb_32.c)0
-rw-r--r--arch/powerpc/mm/tlb_hash64.c (renamed from arch/powerpc/mm/tlb_64.c)86
-rw-r--r--arch/powerpc/platforms/40x/ep405.c2
-rw-r--r--arch/powerpc/platforms/40x/kilauea.c2
-rw-r--r--arch/powerpc/platforms/40x/ppc40x_simple.c2
-rw-r--r--arch/powerpc/platforms/44x/ebony.c2
-rw-r--r--arch/powerpc/platforms/44x/ppc44x_simple.c2
-rw-r--r--arch/powerpc/platforms/44x/sam440ep.c2
-rw-r--r--arch/powerpc/platforms/52xx/mpc52xx_pci.c2
-rw-r--r--arch/powerpc/platforms/82xx/pq2.c2
-rw-r--r--arch/powerpc/platforms/85xx/Makefile2
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx_ds.c11
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx_mds.c8
-rw-r--r--arch/powerpc/platforms/85xx/smp.c104
-rw-r--r--arch/powerpc/platforms/86xx/Kconfig2
-rw-r--r--arch/powerpc/platforms/86xx/Makefile3
-rw-r--r--arch/powerpc/platforms/86xx/gef_gpio.c143
-rw-r--r--arch/powerpc/platforms/cell/iommu.c5
-rw-r--r--arch/powerpc/platforms/chrp/pci.c3
-rw-r--r--arch/powerpc/platforms/powermac/pci.c6
-rw-r--r--arch/powerpc/platforms/powermac/setup.c4
-rw-r--r--arch/powerpc/platforms/powermac/smp.c2
-rw-r--r--arch/powerpc/platforms/ps3/device-init.c33
-rw-r--r--arch/powerpc/platforms/ps3/mm.c2
-rw-r--r--arch/powerpc/platforms/ps3/setup.c4
-rw-r--r--arch/powerpc/platforms/ps3/system-bus.c38
-rw-r--r--arch/powerpc/platforms/pseries/eeh.c44
-rw-r--r--arch/powerpc/platforms/pseries/pci_dlpar.c163
-rw-r--r--arch/powerpc/platforms/pseries/xics.c43
-rw-r--r--arch/powerpc/sysdev/fsl_pci.c4
-rw-r--r--arch/powerpc/sysdev/grackle.c2
-rw-r--r--arch/powerpc/sysdev/mpic.c32
-rw-r--r--arch/powerpc/sysdev/ppc4xx_pci.c306
-rw-r--r--arch/powerpc/sysdev/qe_lib/qe.c3
-rw-r--r--arch/powerpc/sysdev/qe_lib/ucc.c4
-rw-r--r--arch/sparc/include/asm/device.h12
145 files changed, 3799 insertions, 1319 deletions
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 525c13a4de93..be4f99b7cbbb 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -285,6 +285,10 @@ config IOMMU_VMERGE
285config IOMMU_HELPER 285config IOMMU_HELPER
286 def_bool PPC64 286 def_bool PPC64
287 287
288config PPC_NEED_DMA_SYNC_OPS
289 def_bool y
290 depends on NOT_COHERENT_CACHE
291
288config HOTPLUG_CPU 292config HOTPLUG_CPU
289 bool "Support for enabling/disabling CPUs" 293 bool "Support for enabling/disabling CPUs"
290 depends on SMP && HOTPLUG && EXPERIMENTAL && (PPC_PSERIES || PPC_PMAC) 294 depends on SMP && HOTPLUG && EXPERIMENTAL && (PPC_PSERIES || PPC_PMAC)
diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug
index 15eb27861fc7..08f7cc0a1953 100644
--- a/arch/powerpc/Kconfig.debug
+++ b/arch/powerpc/Kconfig.debug
@@ -2,6 +2,15 @@ menu "Kernel hacking"
2 2
3source "lib/Kconfig.debug" 3source "lib/Kconfig.debug"
4 4
5config PRINT_STACK_DEPTH
6 int "Stack depth to print" if DEBUG_KERNEL
7 default 64
8 help
9 This option allows you to set the stack depth that the kernel
10 prints in stack traces. This can be useful if your display is
11 too small and stack traces cause important information to
12 scroll off the screen.
13
5config DEBUG_STACKOVERFLOW 14config DEBUG_STACKOVERFLOW
6 bool "Check for stack overflows" 15 bool "Check for stack overflows"
7 depends on DEBUG_KERNEL 16 depends on DEBUG_KERNEL
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
index 1f0667069940..72d17f50e54f 100644
--- a/arch/powerpc/Makefile
+++ b/arch/powerpc/Makefile
@@ -107,7 +107,6 @@ KBUILD_CFLAGS += $(call cc-option,-mno-altivec)
107# (We use all available options to help semi-broken compilers) 107# (We use all available options to help semi-broken compilers)
108KBUILD_CFLAGS += $(call cc-option,-mno-spe) 108KBUILD_CFLAGS += $(call cc-option,-mno-spe)
109KBUILD_CFLAGS += $(call cc-option,-mspe=no) 109KBUILD_CFLAGS += $(call cc-option,-mspe=no)
110KBUILD_CFLAGS += $(call cc-option,-mabi=no-spe)
111 110
112# Enable unit-at-a-time mode when possible. It shrinks the 111# Enable unit-at-a-time mode when possible. It shrinks the
113# kernel considerably. 112# kernel considerably.
diff --git a/arch/powerpc/boot/dts/bamboo.dts b/arch/powerpc/boot/dts/bamboo.dts
index 6ce0cc2c0208..aa68911f6560 100644
--- a/arch/powerpc/boot/dts/bamboo.dts
+++ b/arch/powerpc/boot/dts/bamboo.dts
@@ -269,7 +269,8 @@
269 * later cannot be changed. Chip supports a second 269 * later cannot be changed. Chip supports a second
270 * IO range but we don't use it for now 270 * IO range but we don't use it for now
271 */ 271 */
272 ranges = <0x02000000 0x00000000 0xa0000000 0x00000000 0xa0000000 0x00000000 0x20000000 272 ranges = <0x02000000 0x00000000 0xa0000000 0x00000000 0xa0000000 0x00000000 0x40000000
273 0x02000000 0x00000000 0x00000000 0x00000000 0xe0000000 0x00000000 0x00100000
273 0x01000000 0x00000000 0x00000000 0x00000000 0xe8000000 0x00000000 0x00010000>; 274 0x01000000 0x00000000 0x00000000 0x00000000 0xe8000000 0x00000000 0x00010000>;
274 275
275 /* Inbound 2GB range starting at 0 */ 276 /* Inbound 2GB range starting at 0 */
diff --git a/arch/powerpc/boot/dts/canyonlands.dts b/arch/powerpc/boot/dts/canyonlands.dts
index 79fe412c11c9..8b5ba8261a36 100644
--- a/arch/powerpc/boot/dts/canyonlands.dts
+++ b/arch/powerpc/boot/dts/canyonlands.dts
@@ -40,6 +40,7 @@
40 d-cache-size = <32768>; 40 d-cache-size = <32768>;
41 dcr-controller; 41 dcr-controller;
42 dcr-access-method = "native"; 42 dcr-access-method = "native";
43 next-level-cache = <&L2C0>;
43 }; 44 };
44 }; 45 };
45 46
@@ -104,6 +105,16 @@
104 dcr-reg = <0x00c 0x002>; 105 dcr-reg = <0x00c 0x002>;
105 }; 106 };
106 107
108 L2C0: l2c {
109 compatible = "ibm,l2-cache-460ex", "ibm,l2-cache";
110 dcr-reg = <0x020 0x008 /* Internal SRAM DCR's */
111 0x030 0x008>; /* L2 cache DCR's */
112 cache-line-size = <32>; /* 32 bytes */
113 cache-size = <262144>; /* L2, 256K */
114 interrupt-parent = <&UIC1>;
115 interrupts = <11 1>;
116 };
117
107 plb { 118 plb {
108 compatible = "ibm,plb-460ex", "ibm,plb4"; 119 compatible = "ibm,plb-460ex", "ibm,plb4";
109 #address-cells = <2>; 120 #address-cells = <2>;
@@ -343,6 +354,7 @@
343 * later cannot be changed 354 * later cannot be changed
344 */ 355 */
345 ranges = <0x02000000 0x00000000 0x80000000 0x0000000d 0x80000000 0x00000000 0x80000000 356 ranges = <0x02000000 0x00000000 0x80000000 0x0000000d 0x80000000 0x00000000 0x80000000
357 0x02000000 0x00000000 0x00000000 0x0000000c 0x0ee00000 0x00000000 0x00100000
346 0x01000000 0x00000000 0x00000000 0x0000000c 0x08000000 0x00000000 0x00010000>; 358 0x01000000 0x00000000 0x00000000 0x0000000c 0x08000000 0x00000000 0x00010000>;
347 359
348 /* Inbound 2GB range starting at 0 */ 360 /* Inbound 2GB range starting at 0 */
@@ -373,6 +385,7 @@
373 * later cannot be changed 385 * later cannot be changed
374 */ 386 */
375 ranges = <0x02000000 0x00000000 0x80000000 0x0000000e 0x00000000 0x00000000 0x80000000 387 ranges = <0x02000000 0x00000000 0x80000000 0x0000000e 0x00000000 0x00000000 0x80000000
388 0x02000000 0x00000000 0x00000000 0x0000000f 0x00000000 0x00000000 0x00100000
376 0x01000000 0x00000000 0x00000000 0x0000000f 0x80000000 0x00000000 0x00010000>; 389 0x01000000 0x00000000 0x00000000 0x0000000f 0x80000000 0x00000000 0x00010000>;
377 390
378 /* Inbound 2GB range starting at 0 */ 391 /* Inbound 2GB range starting at 0 */
@@ -414,6 +427,7 @@
414 * later cannot be changed 427 * later cannot be changed
415 */ 428 */
416 ranges = <0x02000000 0x00000000 0x80000000 0x0000000e 0x80000000 0x00000000 0x80000000 429 ranges = <0x02000000 0x00000000 0x80000000 0x0000000e 0x80000000 0x00000000 0x80000000
430 0x02000000 0x00000000 0x00000000 0x0000000f 0x00100000 0x00000000 0x00100000
417 0x01000000 0x00000000 0x00000000 0x0000000f 0x80010000 0x00000000 0x00010000>; 431 0x01000000 0x00000000 0x00000000 0x0000000f 0x80010000 0x00000000 0x00010000>;
418 432
419 /* Inbound 2GB range starting at 0 */ 433 /* Inbound 2GB range starting at 0 */
diff --git a/arch/powerpc/boot/dts/gef_sbc610.dts b/arch/powerpc/boot/dts/gef_sbc610.dts
index e48cfa740c8a..9708b3423bbd 100644
--- a/arch/powerpc/boot/dts/gef_sbc610.dts
+++ b/arch/powerpc/boot/dts/gef_sbc610.dts
@@ -98,6 +98,12 @@
98 interrupt-parent = <&mpic>; 98 interrupt-parent = <&mpic>;
99 99
100 }; 100 };
101 gef_gpio: gpio@7,14000 {
102 #gpio-cells = <2>;
103 compatible = "gef,sbc610-gpio";
104 reg = <0x7 0x14000 0x24>;
105 gpio-controller;
106 };
101 }; 107 };
102 108
103 soc@fef00000 { 109 soc@fef00000 {
@@ -119,6 +125,11 @@
119 interrupt-parent = <&mpic>; 125 interrupt-parent = <&mpic>;
120 dfsrr; 126 dfsrr;
121 127
128 rtc@51 {
129 compatible = "epson,rx8581";
130 reg = <0x00000051>;
131 };
132
122 eti@6b { 133 eti@6b {
123 compatible = "dallas,ds1682"; 134 compatible = "dallas,ds1682";
124 reg = <0x6b>; 135 reg = <0x6b>;
diff --git a/arch/powerpc/boot/dts/kuroboxHD.dts b/arch/powerpc/boot/dts/kuroboxHD.dts
index 2e5a1a1812b6..8d725d10882f 100644
--- a/arch/powerpc/boot/dts/kuroboxHD.dts
+++ b/arch/powerpc/boot/dts/kuroboxHD.dts
@@ -76,7 +76,6 @@ XXXX add flash parts, rtc, ??
76 interrupt-parent = <&mpic>; 76 interrupt-parent = <&mpic>;
77 77
78 rtc@32 { 78 rtc@32 {
79 device_type = "rtc";
80 compatible = "ricoh,rs5c372a"; 79 compatible = "ricoh,rs5c372a";
81 reg = <0x32>; 80 reg = <0x32>;
82 }; 81 };
diff --git a/arch/powerpc/boot/dts/kuroboxHG.dts b/arch/powerpc/boot/dts/kuroboxHG.dts
index e4916e69ad31..b13a11eb81b0 100644
--- a/arch/powerpc/boot/dts/kuroboxHG.dts
+++ b/arch/powerpc/boot/dts/kuroboxHG.dts
@@ -76,7 +76,6 @@ XXXX add flash parts, rtc, ??
76 interrupt-parent = <&mpic>; 76 interrupt-parent = <&mpic>;
77 77
78 rtc@32 { 78 rtc@32 {
79 device_type = "rtc";
80 compatible = "ricoh,rs5c372a"; 79 compatible = "ricoh,rs5c372a";
81 reg = <0x32>; 80 reg = <0x32>;
82 }; 81 };
diff --git a/arch/powerpc/boot/dts/lite5200.dts b/arch/powerpc/boot/dts/lite5200.dts
index 2cf9a8768f44..3f7a5dce8de0 100644
--- a/arch/powerpc/boot/dts/lite5200.dts
+++ b/arch/powerpc/boot/dts/lite5200.dts
@@ -130,7 +130,6 @@
130 130
131 rtc@800 { // Real time clock 131 rtc@800 { // Real time clock
132 compatible = "fsl,mpc5200-rtc"; 132 compatible = "fsl,mpc5200-rtc";
133 device_type = "rtc";
134 reg = <0x800 0x100>; 133 reg = <0x800 0x100>;
135 interrupts = <1 5 0 1 6 0>; 134 interrupts = <1 5 0 1 6 0>;
136 interrupt-parent = <&mpc5200_pic>; 135 interrupt-parent = <&mpc5200_pic>;
diff --git a/arch/powerpc/boot/dts/lite5200b.dts b/arch/powerpc/boot/dts/lite5200b.dts
index 7bd5b9c399b8..63e3bb48e843 100644
--- a/arch/powerpc/boot/dts/lite5200b.dts
+++ b/arch/powerpc/boot/dts/lite5200b.dts
@@ -130,7 +130,6 @@
130 130
131 rtc@800 { // Real time clock 131 rtc@800 { // Real time clock
132 compatible = "fsl,mpc5200b-rtc","fsl,mpc5200-rtc"; 132 compatible = "fsl,mpc5200b-rtc","fsl,mpc5200-rtc";
133 device_type = "rtc";
134 reg = <0x800 0x100>; 133 reg = <0x800 0x100>;
135 interrupts = <1 5 0 1 6 0>; 134 interrupts = <1 5 0 1 6 0>;
136 interrupt-parent = <&mpc5200_pic>; 135 interrupt-parent = <&mpc5200_pic>;
diff --git a/arch/powerpc/boot/dts/motionpro.dts b/arch/powerpc/boot/dts/motionpro.dts
index 9e3c921be164..52ba6f98b273 100644
--- a/arch/powerpc/boot/dts/motionpro.dts
+++ b/arch/powerpc/boot/dts/motionpro.dts
@@ -248,7 +248,6 @@
248 fsl5200-clocking; 248 fsl5200-clocking;
249 249
250 rtc@68 { 250 rtc@68 {
251 device_type = "rtc";
252 compatible = "dallas,ds1339"; 251 compatible = "dallas,ds1339";
253 reg = <0x68>; 252 reg = <0x68>;
254 }; 253 };
diff --git a/arch/powerpc/boot/dts/mpc8315erdb.dts b/arch/powerpc/boot/dts/mpc8315erdb.dts
index 6b850670de1d..d3d3097b873a 100644
--- a/arch/powerpc/boot/dts/mpc8315erdb.dts
+++ b/arch/powerpc/boot/dts/mpc8315erdb.dts
@@ -117,7 +117,6 @@
117 interrupt-parent = <&ipic>; 117 interrupt-parent = <&ipic>;
118 dfsrr; 118 dfsrr;
119 rtc@68 { 119 rtc@68 {
120 device_type = "rtc";
121 compatible = "dallas,ds1339"; 120 compatible = "dallas,ds1339";
122 reg = <0x68>; 121 reg = <0x68>;
123 }; 122 };
diff --git a/arch/powerpc/boot/dts/mpc8349emitx.dts b/arch/powerpc/boot/dts/mpc8349emitx.dts
index 4bdbaf4993a1..5ba5c6633b81 100644
--- a/arch/powerpc/boot/dts/mpc8349emitx.dts
+++ b/arch/powerpc/boot/dts/mpc8349emitx.dts
@@ -85,7 +85,6 @@
85 dfsrr; 85 dfsrr;
86 86
87 rtc@68 { 87 rtc@68 {
88 device_type = "rtc";
89 compatible = "dallas,ds1339"; 88 compatible = "dallas,ds1339";
90 reg = <0x68>; 89 reg = <0x68>;
91 interrupts = <18 0x8>; 90 interrupts = <18 0x8>;
diff --git a/arch/powerpc/boot/dts/mpc8349emitxgp.dts b/arch/powerpc/boot/dts/mpc8349emitxgp.dts
index fa40647ee62e..fd4bbc4cbe30 100644
--- a/arch/powerpc/boot/dts/mpc8349emitxgp.dts
+++ b/arch/powerpc/boot/dts/mpc8349emitxgp.dts
@@ -83,7 +83,6 @@
83 dfsrr; 83 dfsrr;
84 84
85 rtc@68 { 85 rtc@68 {
86 device_type = "rtc";
87 compatible = "dallas,ds1339"; 86 compatible = "dallas,ds1339";
88 reg = <0x68>; 87 reg = <0x68>;
89 interrupts = <18 0x8>; 88 interrupts = <18 0x8>;
diff --git a/arch/powerpc/boot/dts/mpc8377_rdb.dts b/arch/powerpc/boot/dts/mpc8377_rdb.dts
index 435ef3dd022d..9fe8e4c96b18 100644
--- a/arch/powerpc/boot/dts/mpc8377_rdb.dts
+++ b/arch/powerpc/boot/dts/mpc8377_rdb.dts
@@ -117,7 +117,6 @@
117 interrupt-parent = <&ipic>; 117 interrupt-parent = <&ipic>;
118 dfsrr; 118 dfsrr;
119 rtc@68 { 119 rtc@68 {
120 device_type = "rtc";
121 compatible = "dallas,ds1339"; 120 compatible = "dallas,ds1339";
122 reg = <0x68>; 121 reg = <0x68>;
123 }; 122 };
diff --git a/arch/powerpc/boot/dts/mpc8378_rdb.dts b/arch/powerpc/boot/dts/mpc8378_rdb.dts
index b11e68f56a06..3a6d5287539c 100644
--- a/arch/powerpc/boot/dts/mpc8378_rdb.dts
+++ b/arch/powerpc/boot/dts/mpc8378_rdb.dts
@@ -117,7 +117,6 @@
117 interrupt-parent = <&ipic>; 117 interrupt-parent = <&ipic>;
118 dfsrr; 118 dfsrr;
119 rtc@68 { 119 rtc@68 {
120 device_type = "rtc";
121 compatible = "dallas,ds1339"; 120 compatible = "dallas,ds1339";
122 reg = <0x68>; 121 reg = <0x68>;
123 }; 122 };
diff --git a/arch/powerpc/boot/dts/mpc8379_rdb.dts b/arch/powerpc/boot/dts/mpc8379_rdb.dts
index 337af6ea26d3..ee64def19210 100644
--- a/arch/powerpc/boot/dts/mpc8379_rdb.dts
+++ b/arch/powerpc/boot/dts/mpc8379_rdb.dts
@@ -117,7 +117,6 @@
117 interrupt-parent = <&ipic>; 117 interrupt-parent = <&ipic>;
118 dfsrr; 118 dfsrr;
119 rtc@68 { 119 rtc@68 {
120 device_type = "rtc";
121 compatible = "dallas,ds1339"; 120 compatible = "dallas,ds1339";
122 reg = <0x68>; 121 reg = <0x68>;
123 }; 122 };
diff --git a/arch/powerpc/boot/dts/mpc8572ds.dts b/arch/powerpc/boot/dts/mpc8572ds.dts
index 5c69b2fafd32..a10506e6fa27 100644
--- a/arch/powerpc/boot/dts/mpc8572ds.dts
+++ b/arch/powerpc/boot/dts/mpc8572ds.dts
@@ -63,6 +63,119 @@
63 device_type = "memory"; 63 device_type = "memory";
64 }; 64 };
65 65
66 localbus@ffe05000 {
67 #address-cells = <2>;
68 #size-cells = <1>;
69 compatible = "fsl,mpc8572-elbc", "fsl,elbc", "simple-bus";
70 reg = <0 0xffe05000 0 0x1000>;
71 interrupts = <19 2>;
72 interrupt-parent = <&mpic>;
73
74 ranges = <0x0 0x0 0x0 0xe8000000 0x08000000
75 0x1 0x0 0x0 0xe0000000 0x08000000
76 0x2 0x0 0x0 0xffa00000 0x00040000
77 0x3 0x0 0x0 0xffdf0000 0x00008000
78 0x4 0x0 0x0 0xffa40000 0x00040000
79 0x5 0x0 0x0 0xffa80000 0x00040000
80 0x6 0x0 0x0 0xffac0000 0x00040000>;
81
82 nor@0,0 {
83 #address-cells = <1>;
84 #size-cells = <1>;
85 compatible = "cfi-flash";
86 reg = <0x0 0x0 0x8000000>;
87 bank-width = <2>;
88 device-width = <1>;
89
90 ramdisk@0 {
91 reg = <0x0 0x03000000>;
92 readl-only;
93 };
94
95 diagnostic@3000000 {
96 reg = <0x03000000 0x00e00000>;
97 read-only;
98 };
99
100 dink@3e00000 {
101 reg = <0x03e00000 0x00200000>;
102 read-only;
103 };
104
105 kernel@4000000 {
106 reg = <0x04000000 0x00400000>;
107 read-only;
108 };
109
110 jffs2@4400000 {
111 reg = <0x04400000 0x03b00000>;
112 };
113
114 dtb@7f00000 {
115 reg = <0x07f00000 0x00080000>;
116 read-only;
117 };
118
119 u-boot@7f80000 {
120 reg = <0x07f80000 0x00080000>;
121 read-only;
122 };
123 };
124
125 nand@2,0 {
126 #address-cells = <1>;
127 #size-cells = <1>;
128 compatible = "fsl,mpc8572-fcm-nand",
129 "fsl,elbc-fcm-nand";
130 reg = <0x2 0x0 0x40000>;
131
132 u-boot@0 {
133 reg = <0x0 0x02000000>;
134 read-only;
135 };
136
137 jffs2@2000000 {
138 reg = <0x02000000 0x10000000>;
139 };
140
141 ramdisk@12000000 {
142 reg = <0x12000000 0x08000000>;
143 read-only;
144 };
145
146 kernel@1a000000 {
147 reg = <0x1a000000 0x04000000>;
148 };
149
150 dtb@1e000000 {
151 reg = <0x1e000000 0x01000000>;
152 read-only;
153 };
154
155 empty@1f000000 {
156 reg = <0x1f000000 0x21000000>;
157 };
158 };
159
160 nand@4,0 {
161 compatible = "fsl,mpc8572-fcm-nand",
162 "fsl,elbc-fcm-nand";
163 reg = <0x4 0x0 0x40000>;
164 };
165
166 nand@5,0 {
167 compatible = "fsl,mpc8572-fcm-nand",
168 "fsl,elbc-fcm-nand";
169 reg = <0x5 0x0 0x40000>;
170 };
171
172 nand@6,0 {
173 compatible = "fsl,mpc8572-fcm-nand",
174 "fsl,elbc-fcm-nand";
175 reg = <0x6 0x0 0x40000>;
176 };
177 };
178
66 soc8572@ffe00000 { 179 soc8572@ffe00000 {
67 #address-cells = <1>; 180 #address-cells = <1>;
68 #size-cells = <1>; 181 #size-cells = <1>;
diff --git a/arch/powerpc/boot/dts/mpc8572ds_camp_core0.dts b/arch/powerpc/boot/dts/mpc8572ds_camp_core0.dts
new file mode 100644
index 000000000000..c114c4ee9931
--- /dev/null
+++ b/arch/powerpc/boot/dts/mpc8572ds_camp_core0.dts
@@ -0,0 +1,483 @@
1/*
2 * MPC8572 DS Core0 Device Tree Source in CAMP mode.
3 *
4 * In CAMP mode, each core needs to have its own dts. Only mpic and L2 cache
5 * can be shared, all the other devices must be assigned to one core only.
6 * This dts file allows core0 to have memory, l2, i2c, dma1, global-util, eth0,
7 * eth1, crypto, pci0, pci1.
8 *
9 * Copyright 2007, 2008 Freescale Semiconductor Inc.
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your
14 * option) any later version.
15 */
16
17/dts-v1/;
18/ {
19 model = "fsl,MPC8572DS";
20 compatible = "fsl,MPC8572DS", "fsl,MPC8572DS-CAMP";
21 #address-cells = <1>;
22 #size-cells = <1>;
23
24 aliases {
25 ethernet0 = &enet0;
26 ethernet1 = &enet1;
27 serial0 = &serial0;
28 pci0 = &pci0;
29 pci1 = &pci1;
30 };
31
32 cpus {
33 #address-cells = <1>;
34 #size-cells = <0>;
35
36 PowerPC,8572@0 {
37 device_type = "cpu";
38 reg = <0x0>;
39 d-cache-line-size = <32>; // 32 bytes
40 i-cache-line-size = <32>; // 32 bytes
41 d-cache-size = <0x8000>; // L1, 32K
42 i-cache-size = <0x8000>; // L1, 32K
43 timebase-frequency = <0>;
44 bus-frequency = <0>;
45 clock-frequency = <0>;
46 next-level-cache = <&L2>;
47 };
48
49 };
50
51 memory {
52 device_type = "memory";
53 reg = <0x0 0x0>; // Filled by U-Boot
54 };
55
56 soc8572@ffe00000 {
57 #address-cells = <1>;
58 #size-cells = <1>;
59 device_type = "soc";
60 compatible = "simple-bus";
61 ranges = <0x0 0xffe00000 0x100000>;
62 reg = <0xffe00000 0x1000>; // CCSRBAR & soc regs, remove once parse code for immrbase fixed
63 bus-frequency = <0>; // Filled out by uboot.
64
65 memory-controller@2000 {
66 compatible = "fsl,mpc8572-memory-controller";
67 reg = <0x2000 0x1000>;
68 interrupt-parent = <&mpic>;
69 interrupts = <18 2>;
70 };
71
72 memory-controller@6000 {
73 compatible = "fsl,mpc8572-memory-controller";
74 reg = <0x6000 0x1000>;
75 interrupt-parent = <&mpic>;
76 interrupts = <18 2>;
77 };
78
79 L2: l2-cache-controller@20000 {
80 compatible = "fsl,mpc8572-l2-cache-controller";
81 reg = <0x20000 0x1000>;
82 cache-line-size = <32>; // 32 bytes
83 cache-size = <0x80000>; // L2, 512K
84 interrupt-parent = <&mpic>;
85 interrupts = <16 2>;
86 };
87
88 i2c@3000 {
89 #address-cells = <1>;
90 #size-cells = <0>;
91 cell-index = <0>;
92 compatible = "fsl-i2c";
93 reg = <0x3000 0x100>;
94 interrupts = <43 2>;
95 interrupt-parent = <&mpic>;
96 dfsrr;
97 };
98
99 i2c@3100 {
100 #address-cells = <1>;
101 #size-cells = <0>;
102 cell-index = <1>;
103 compatible = "fsl-i2c";
104 reg = <0x3100 0x100>;
105 interrupts = <43 2>;
106 interrupt-parent = <&mpic>;
107 dfsrr;
108 };
109
110 dma@21300 {
111 #address-cells = <1>;
112 #size-cells = <1>;
113 compatible = "fsl,mpc8572-dma", "fsl,eloplus-dma";
114 reg = <0x21300 0x4>;
115 ranges = <0x0 0x21100 0x200>;
116 cell-index = <0>;
117 dma-channel@0 {
118 compatible = "fsl,mpc8572-dma-channel",
119 "fsl,eloplus-dma-channel";
120 reg = <0x0 0x80>;
121 cell-index = <0>;
122 interrupt-parent = <&mpic>;
123 interrupts = <20 2>;
124 };
125 dma-channel@80 {
126 compatible = "fsl,mpc8572-dma-channel",
127 "fsl,eloplus-dma-channel";
128 reg = <0x80 0x80>;
129 cell-index = <1>;
130 interrupt-parent = <&mpic>;
131 interrupts = <21 2>;
132 };
133 dma-channel@100 {
134 compatible = "fsl,mpc8572-dma-channel",
135 "fsl,eloplus-dma-channel";
136 reg = <0x100 0x80>;
137 cell-index = <2>;
138 interrupt-parent = <&mpic>;
139 interrupts = <22 2>;
140 };
141 dma-channel@180 {
142 compatible = "fsl,mpc8572-dma-channel",
143 "fsl,eloplus-dma-channel";
144 reg = <0x180 0x80>;
145 cell-index = <3>;
146 interrupt-parent = <&mpic>;
147 interrupts = <23 2>;
148 };
149 };
150
151 mdio@24520 {
152 #address-cells = <1>;
153 #size-cells = <0>;
154 compatible = "fsl,gianfar-mdio";
155 reg = <0x24520 0x20>;
156
157 phy0: ethernet-phy@0 {
158 interrupt-parent = <&mpic>;
159 interrupts = <10 1>;
160 reg = <0x0>;
161 };
162 phy1: ethernet-phy@1 {
163 interrupt-parent = <&mpic>;
164 interrupts = <10 1>;
165 reg = <0x1>;
166 };
167 };
168
169 enet0: ethernet@24000 {
170 cell-index = <0>;
171 device_type = "network";
172 model = "eTSEC";
173 compatible = "gianfar";
174 reg = <0x24000 0x1000>;
175 local-mac-address = [ 00 00 00 00 00 00 ];
176 interrupts = <29 2 30 2 34 2>;
177 interrupt-parent = <&mpic>;
178 phy-handle = <&phy0>;
179 phy-connection-type = "rgmii-id";
180 };
181
182 enet1: ethernet@25000 {
183 cell-index = <1>;
184 device_type = "network";
185 model = "eTSEC";
186 compatible = "gianfar";
187 reg = <0x25000 0x1000>;
188 local-mac-address = [ 00 00 00 00 00 00 ];
189 interrupts = <35 2 36 2 40 2>;
190 interrupt-parent = <&mpic>;
191 phy-handle = <&phy1>;
192 phy-connection-type = "rgmii-id";
193 };
194
195 serial0: serial@4500 {
196 cell-index = <0>;
197 device_type = "serial";
198 compatible = "ns16550";
199 reg = <0x4500 0x100>;
200 clock-frequency = <0>;
201 };
202
203 global-utilities@e0000 { //global utilities block
204 compatible = "fsl,mpc8572-guts";
205 reg = <0xe0000 0x1000>;
206 fsl,has-rstcr;
207 };
208
209 crypto@30000 {
210 compatible = "fsl,sec3.0", "fsl,sec2.4", "fsl,sec2.2",
211 "fsl,sec2.1", "fsl,sec2.0";
212 reg = <0x30000 0x10000>;
213 interrupts = <45 2 58 2>;
214 interrupt-parent = <&mpic>;
215 fsl,num-channels = <4>;
216 fsl,channel-fifo-len = <24>;
217 fsl,exec-units-mask = <0x9fe>;
218 fsl,descriptor-types-mask = <0x3ab0ebf>;
219 };
220
221 mpic: pic@40000 {
222 interrupt-controller;
223 #address-cells = <0>;
224 #interrupt-cells = <2>;
225 reg = <0x40000 0x40000>;
226 compatible = "chrp,open-pic";
227 device_type = "open-pic";
228 protected-sources = <
229 31 32 33 37 38 39 /* enet2 enet3 */
230 76 77 78 79 27 42 /* dma2 pci2 serial*/
231 0xe0 0xe1 0xe2 0xe3 /* msi */
232 0xe4 0xe5 0xe6 0xe7
233 >;
234 };
235 };
236
237 pci0: pcie@ffe08000 {
238 cell-index = <0>;
239 compatible = "fsl,mpc8548-pcie";
240 device_type = "pci";
241 #interrupt-cells = <1>;
242 #size-cells = <2>;
243 #address-cells = <3>;
244 reg = <0xffe08000 0x1000>;
245 bus-range = <0 255>;
246 ranges = <0x2000000 0x0 0x80000000 0x80000000 0x0 0x20000000
247 0x1000000 0x0 0x0 0xffc00000 0x0 0x10000>;
248 clock-frequency = <33333333>;
249 interrupt-parent = <&mpic>;
250 interrupts = <24 2>;
251 interrupt-map-mask = <0xff00 0x0 0x0 0x7>;
252 interrupt-map = <
253 /* IDSEL 0x11 func 0 - PCI slot 1 */
254 0x8800 0x0 0x0 0x1 &mpic 0x2 0x1
255 0x8800 0x0 0x0 0x2 &mpic 0x3 0x1
256 0x8800 0x0 0x0 0x3 &mpic 0x4 0x1
257 0x8800 0x0 0x0 0x4 &mpic 0x1 0x1
258
259 /* IDSEL 0x11 func 1 - PCI slot 1 */
260 0x8900 0x0 0x0 0x1 &mpic 0x2 0x1
261 0x8900 0x0 0x0 0x2 &mpic 0x3 0x1
262 0x8900 0x0 0x0 0x3 &mpic 0x4 0x1
263 0x8900 0x0 0x0 0x4 &mpic 0x1 0x1
264
265 /* IDSEL 0x11 func 2 - PCI slot 1 */
266 0x8a00 0x0 0x0 0x1 &mpic 0x2 0x1
267 0x8a00 0x0 0x0 0x2 &mpic 0x3 0x1
268 0x8a00 0x0 0x0 0x3 &mpic 0x4 0x1
269 0x8a00 0x0 0x0 0x4 &mpic 0x1 0x1
270
271 /* IDSEL 0x11 func 3 - PCI slot 1 */
272 0x8b00 0x0 0x0 0x1 &mpic 0x2 0x1
273 0x8b00 0x0 0x0 0x2 &mpic 0x3 0x1
274 0x8b00 0x0 0x0 0x3 &mpic 0x4 0x1
275 0x8b00 0x0 0x0 0x4 &mpic 0x1 0x1
276
277 /* IDSEL 0x11 func 4 - PCI slot 1 */
278 0x8c00 0x0 0x0 0x1 &mpic 0x2 0x1
279 0x8c00 0x0 0x0 0x2 &mpic 0x3 0x1
280 0x8c00 0x0 0x0 0x3 &mpic 0x4 0x1
281 0x8c00 0x0 0x0 0x4 &mpic 0x1 0x1
282
283 /* IDSEL 0x11 func 5 - PCI slot 1 */
284 0x8d00 0x0 0x0 0x1 &mpic 0x2 0x1
285 0x8d00 0x0 0x0 0x2 &mpic 0x3 0x1
286 0x8d00 0x0 0x0 0x3 &mpic 0x4 0x1
287 0x8d00 0x0 0x0 0x4 &mpic 0x1 0x1
288
289 /* IDSEL 0x11 func 6 - PCI slot 1 */
290 0x8e00 0x0 0x0 0x1 &mpic 0x2 0x1
291 0x8e00 0x0 0x0 0x2 &mpic 0x3 0x1
292 0x8e00 0x0 0x0 0x3 &mpic 0x4 0x1
293 0x8e00 0x0 0x0 0x4 &mpic 0x1 0x1
294
295 /* IDSEL 0x11 func 7 - PCI slot 1 */
296 0x8f00 0x0 0x0 0x1 &mpic 0x2 0x1
297 0x8f00 0x0 0x0 0x2 &mpic 0x3 0x1
298 0x8f00 0x0 0x0 0x3 &mpic 0x4 0x1
299 0x8f00 0x0 0x0 0x4 &mpic 0x1 0x1
300
301 /* IDSEL 0x12 func 0 - PCI slot 2 */
302 0x9000 0x0 0x0 0x1 &mpic 0x3 0x1
303 0x9000 0x0 0x0 0x2 &mpic 0x4 0x1
304 0x9000 0x0 0x0 0x3 &mpic 0x1 0x1
305 0x9000 0x0 0x0 0x4 &mpic 0x2 0x1
306
307 /* IDSEL 0x12 func 1 - PCI slot 2 */
308 0x9100 0x0 0x0 0x1 &mpic 0x3 0x1
309 0x9100 0x0 0x0 0x2 &mpic 0x4 0x1
310 0x9100 0x0 0x0 0x3 &mpic 0x1 0x1
311 0x9100 0x0 0x0 0x4 &mpic 0x2 0x1
312
313 /* IDSEL 0x12 func 2 - PCI slot 2 */
314 0x9200 0x0 0x0 0x1 &mpic 0x3 0x1
315 0x9200 0x0 0x0 0x2 &mpic 0x4 0x1
316 0x9200 0x0 0x0 0x3 &mpic 0x1 0x1
317 0x9200 0x0 0x0 0x4 &mpic 0x2 0x1
318
319 /* IDSEL 0x12 func 3 - PCI slot 2 */
320 0x9300 0x0 0x0 0x1 &mpic 0x3 0x1
321 0x9300 0x0 0x0 0x2 &mpic 0x4 0x1
322 0x9300 0x0 0x0 0x3 &mpic 0x1 0x1
323 0x9300 0x0 0x0 0x4 &mpic 0x2 0x1
324
325 /* IDSEL 0x12 func 4 - PCI slot 2 */
326 0x9400 0x0 0x0 0x1 &mpic 0x3 0x1
327 0x9400 0x0 0x0 0x2 &mpic 0x4 0x1
328 0x9400 0x0 0x0 0x3 &mpic 0x1 0x1
329 0x9400 0x0 0x0 0x4 &mpic 0x2 0x1
330
331 /* IDSEL 0x12 func 5 - PCI slot 2 */
332 0x9500 0x0 0x0 0x1 &mpic 0x3 0x1
333 0x9500 0x0 0x0 0x2 &mpic 0x4 0x1
334 0x9500 0x0 0x0 0x3 &mpic 0x1 0x1
335 0x9500 0x0 0x0 0x4 &mpic 0x2 0x1
336
337 /* IDSEL 0x12 func 6 - PCI slot 2 */
338 0x9600 0x0 0x0 0x1 &mpic 0x3 0x1
339 0x9600 0x0 0x0 0x2 &mpic 0x4 0x1
340 0x9600 0x0 0x0 0x3 &mpic 0x1 0x1
341 0x9600 0x0 0x0 0x4 &mpic 0x2 0x1
342
343 /* IDSEL 0x12 func 7 - PCI slot 2 */
344 0x9700 0x0 0x0 0x1 &mpic 0x3 0x1
345 0x9700 0x0 0x0 0x2 &mpic 0x4 0x1
346 0x9700 0x0 0x0 0x3 &mpic 0x1 0x1
347 0x9700 0x0 0x0 0x4 &mpic 0x2 0x1
348
349 // IDSEL 0x1c USB
350 0xe000 0x0 0x0 0x1 &i8259 0xc 0x2
351 0xe100 0x0 0x0 0x2 &i8259 0x9 0x2
352 0xe200 0x0 0x0 0x3 &i8259 0xa 0x2
353 0xe300 0x0 0x0 0x4 &i8259 0xb 0x2
354
355 // IDSEL 0x1d Audio
356 0xe800 0x0 0x0 0x1 &i8259 0x6 0x2
357
358 // IDSEL 0x1e Legacy
359 0xf000 0x0 0x0 0x1 &i8259 0x7 0x2
360 0xf100 0x0 0x0 0x1 &i8259 0x7 0x2
361
362 // IDSEL 0x1f IDE/SATA
363 0xf800 0x0 0x0 0x1 &i8259 0xe 0x2
364 0xf900 0x0 0x0 0x1 &i8259 0x5 0x2
365
366 >;
367
368 pcie@0 {
369 reg = <0x0 0x0 0x0 0x0 0x0>;
370 #size-cells = <2>;
371 #address-cells = <3>;
372 device_type = "pci";
373 ranges = <0x2000000 0x0 0x80000000
374 0x2000000 0x0 0x80000000
375 0x0 0x20000000
376
377 0x1000000 0x0 0x0
378 0x1000000 0x0 0x0
379 0x0 0x100000>;
380 uli1575@0 {
381 reg = <0x0 0x0 0x0 0x0 0x0>;
382 #size-cells = <2>;
383 #address-cells = <3>;
384 ranges = <0x2000000 0x0 0x80000000
385 0x2000000 0x0 0x80000000
386 0x0 0x20000000
387
388 0x1000000 0x0 0x0
389 0x1000000 0x0 0x0
390 0x0 0x100000>;
391 isa@1e {
392 device_type = "isa";
393 #interrupt-cells = <2>;
394 #size-cells = <1>;
395 #address-cells = <2>;
396 reg = <0xf000 0x0 0x0 0x0 0x0>;
397 ranges = <0x1 0x0 0x1000000 0x0 0x0
398 0x1000>;
399 interrupt-parent = <&i8259>;
400
401 i8259: interrupt-controller@20 {
402 reg = <0x1 0x20 0x2
403 0x1 0xa0 0x2
404 0x1 0x4d0 0x2>;
405 interrupt-controller;
406 device_type = "interrupt-controller";
407 #address-cells = <0>;
408 #interrupt-cells = <2>;
409 compatible = "chrp,iic";
410 interrupts = <9 2>;
411 interrupt-parent = <&mpic>;
412 };
413
414 i8042@60 {
415 #size-cells = <0>;
416 #address-cells = <1>;
417 reg = <0x1 0x60 0x1 0x1 0x64 0x1>;
418 interrupts = <1 3 12 3>;
419 interrupt-parent =
420 <&i8259>;
421
422 keyboard@0 {
423 reg = <0x0>;
424 compatible = "pnpPNP,303";
425 };
426
427 mouse@1 {
428 reg = <0x1>;
429 compatible = "pnpPNP,f03";
430 };
431 };
432
433 rtc@70 {
434 compatible = "pnpPNP,b00";
435 reg = <0x1 0x70 0x2>;
436 };
437
438 gpio@400 {
439 reg = <0x1 0x400 0x80>;
440 };
441 };
442 };
443 };
444
445 };
446
447 pci1: pcie@ffe09000 {
448 cell-index = <1>;
449 compatible = "fsl,mpc8548-pcie";
450 device_type = "pci";
451 #interrupt-cells = <1>;
452 #size-cells = <2>;
453 #address-cells = <3>;
454 reg = <0xffe09000 0x1000>;
455 bus-range = <0 255>;
456 ranges = <0x2000000 0x0 0xa0000000 0xa0000000 0x0 0x20000000
457 0x1000000 0x0 0x0 0xffc10000 0x0 0x10000>;
458 clock-frequency = <33333333>;
459 interrupt-parent = <&mpic>;
460 interrupts = <26 2>;
461 interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
462 interrupt-map = <
463 /* IDSEL 0x0 */
464 0000 0x0 0x0 0x1 &mpic 0x4 0x1
465 0000 0x0 0x0 0x2 &mpic 0x5 0x1
466 0000 0x0 0x0 0x3 &mpic 0x6 0x1
467 0000 0x0 0x0 0x4 &mpic 0x7 0x1
468 >;
469 pcie@0 {
470 reg = <0x0 0x0 0x0 0x0 0x0>;
471 #size-cells = <2>;
472 #address-cells = <3>;
473 device_type = "pci";
474 ranges = <0x2000000 0x0 0xa0000000
475 0x2000000 0x0 0xa0000000
476 0x0 0x20000000
477
478 0x1000000 0x0 0x0
479 0x1000000 0x0 0x0
480 0x0 0x100000>;
481 };
482 };
483};
diff --git a/arch/powerpc/boot/dts/mpc8572ds_camp_core1.dts b/arch/powerpc/boot/dts/mpc8572ds_camp_core1.dts
new file mode 100644
index 000000000000..04ecda18d206
--- /dev/null
+++ b/arch/powerpc/boot/dts/mpc8572ds_camp_core1.dts
@@ -0,0 +1,234 @@
1/*
2 * MPC8572 DS Core1 Device Tree Source in CAMP mode.
3 *
4 * In CAMP mode, each core needs to have its own dts. Only mpic and L2 cache
5 * can be shared, all the other devices must be assigned to one core only.
6 * This dts allows core1 to have l2, dma2, eth2, eth3, pci2, msi.
7 *
8 * Please note to add "-b 1" for core1's dts compiling.
9 *
10 * Copyright 2007, 2008 Freescale Semiconductor Inc.
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version.
16 */
17
18/dts-v1/;
19/ {
20 model = "fsl,MPC8572DS";
21 compatible = "fsl,MPC8572DS", "fsl,MPC8572DS-CAMP";
22 #address-cells = <1>;
23 #size-cells = <1>;
24
25 aliases {
26 ethernet2 = &enet2;
27 ethernet3 = &enet3;
28 serial0 = &serial0;
29 pci2 = &pci2;
30 };
31
32 cpus {
33 #address-cells = <1>;
34 #size-cells = <0>;
35
36 PowerPC,8572@1 {
37 device_type = "cpu";
38 reg = <0x1>;
39 d-cache-line-size = <32>; // 32 bytes
40 i-cache-line-size = <32>; // 32 bytes
41 d-cache-size = <0x8000>; // L1, 32K
42 i-cache-size = <0x8000>; // L1, 32K
43 timebase-frequency = <0>;
44 bus-frequency = <0>;
45 clock-frequency = <0>;
46 next-level-cache = <&L2>;
47 };
48 };
49
50 memory {
51 device_type = "memory";
52 reg = <0x0 0x0>; // Filled by U-Boot
53 };
54
55 soc8572@ffe00000 {
56 #address-cells = <1>;
57 #size-cells = <1>;
58 device_type = "soc";
59 compatible = "simple-bus";
60 ranges = <0x0 0xffe00000 0x100000>;
61 reg = <0xffe00000 0x1000>; // CCSRBAR & soc regs, remove once parse code for immrbase fixed
62 bus-frequency = <0>; // Filled out by uboot.
63
64 L2: l2-cache-controller@20000 {
65 compatible = "fsl,mpc8572-l2-cache-controller";
66 reg = <0x20000 0x1000>;
67 cache-line-size = <32>; // 32 bytes
68 cache-size = <0x80000>; // L2, 512K
69 interrupt-parent = <&mpic>;
70 };
71
72 dma@c300 {
73 #address-cells = <1>;
74 #size-cells = <1>;
75 compatible = "fsl,mpc8572-dma", "fsl,eloplus-dma";
76 reg = <0xc300 0x4>;
77 ranges = <0x0 0xc100 0x200>;
78 cell-index = <0>;
79 dma-channel@0 {
80 compatible = "fsl,mpc8572-dma-channel",
81 "fsl,eloplus-dma-channel";
82 reg = <0x0 0x80>;
83 cell-index = <0>;
84 interrupt-parent = <&mpic>;
85 interrupts = <76 2>;
86 };
87 dma-channel@80 {
88 compatible = "fsl,mpc8572-dma-channel",
89 "fsl,eloplus-dma-channel";
90 reg = <0x80 0x80>;
91 cell-index = <1>;
92 interrupt-parent = <&mpic>;
93 interrupts = <77 2>;
94 };
95 dma-channel@100 {
96 compatible = "fsl,mpc8572-dma-channel",
97 "fsl,eloplus-dma-channel";
98 reg = <0x100 0x80>;
99 cell-index = <2>;
100 interrupt-parent = <&mpic>;
101 interrupts = <78 2>;
102 };
103 dma-channel@180 {
104 compatible = "fsl,mpc8572-dma-channel",
105 "fsl,eloplus-dma-channel";
106 reg = <0x180 0x80>;
107 cell-index = <3>;
108 interrupt-parent = <&mpic>;
109 interrupts = <79 2>;
110 };
111 };
112
113 mdio@24520 {
114 #address-cells = <1>;
115 #size-cells = <0>;
116 compatible = "fsl,gianfar-mdio";
117 reg = <0x24520 0x20>;
118
119 phy2: ethernet-phy@2 {
120 interrupt-parent = <&mpic>;
121 reg = <0x2>;
122 };
123 phy3: ethernet-phy@3 {
124 interrupt-parent = <&mpic>;
125 reg = <0x3>;
126 };
127 };
128
129 enet2: ethernet@26000 {
130 cell-index = <2>;
131 device_type = "network";
132 model = "eTSEC";
133 compatible = "gianfar";
134 reg = <0x26000 0x1000>;
135 local-mac-address = [ 00 00 00 00 00 00 ];
136 interrupts = <31 2 32 2 33 2>;
137 interrupt-parent = <&mpic>;
138 phy-handle = <&phy2>;
139 phy-connection-type = "rgmii-id";
140 };
141
142 enet3: ethernet@27000 {
143 cell-index = <3>;
144 device_type = "network";
145 model = "eTSEC";
146 compatible = "gianfar";
147 reg = <0x27000 0x1000>;
148 local-mac-address = [ 00 00 00 00 00 00 ];
149 interrupts = <37 2 38 2 39 2>;
150 interrupt-parent = <&mpic>;
151 phy-handle = <&phy3>;
152 phy-connection-type = "rgmii-id";
153 };
154
155 msi@41600 {
156 compatible = "fsl,mpc8572-msi", "fsl,mpic-msi";
157 reg = <0x41600 0x80>;
158 msi-available-ranges = <0 0x100>;
159 interrupts = <
160 0xe0 0
161 0xe1 0
162 0xe2 0
163 0xe3 0
164 0xe4 0
165 0xe5 0
166 0xe6 0
167 0xe7 0>;
168 interrupt-parent = <&mpic>;
169 };
170
171 serial0: serial@4600 {
172 cell-index = <1>;
173 device_type = "serial";
174 compatible = "ns16550";
175 reg = <0x4600 0x100>;
176 clock-frequency = <0>;
177 };
178
179 mpic: pic@40000 {
180 interrupt-controller;
181 #address-cells = <0>;
182 #interrupt-cells = <2>;
183 reg = <0x40000 0x40000>;
184 compatible = "chrp,open-pic";
185 device_type = "open-pic";
186 protected-sources = <
187 18 16 10 42 45 58 /* MEM L2 mdio serial crypto */
188 29 30 34 35 36 40 /* enet0 enet1 */
189 24 26 20 21 22 23 /* pcie0 pcie1 dma1 */
190 43 /* i2c */
191 0x1 0x2 0x3 0x4 /* pci slot */
192 0x9 0xa 0xb 0xc /* usb */
193 0x6 0x7 0xe 0x5 /* Audio elgacy SATA */
194 >;
195 };
196 };
197
198 pci2: pcie@ffe0a000 {
199 cell-index = <2>;
200 compatible = "fsl,mpc8548-pcie";
201 device_type = "pci";
202 #interrupt-cells = <1>;
203 #size-cells = <2>;
204 #address-cells = <3>;
205 reg = <0xffe0a000 0x1000>;
206 bus-range = <0 255>;
207 ranges = <0x2000000 0x0 0xc0000000 0xc0000000 0x0 0x20000000
208 0x1000000 0x0 0x0 0xffc20000 0x0 0x10000>;
209 clock-frequency = <33333333>;
210 interrupt-parent = <&mpic>;
211 interrupts = <27 2>;
212 interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
213 interrupt-map = <
214 /* IDSEL 0x0 */
215 0000 0x0 0x0 0x1 &mpic 0x0 0x1
216 0000 0x0 0x0 0x2 &mpic 0x1 0x1
217 0000 0x0 0x0 0x3 &mpic 0x2 0x1
218 0000 0x0 0x0 0x4 &mpic 0x3 0x1
219 >;
220 pcie@0 {
221 reg = <0x0 0x0 0x0 0x0 0x0>;
222 #size-cells = <2>;
223 #address-cells = <3>;
224 device_type = "pci";
225 ranges = <0x2000000 0x0 0xc0000000
226 0x2000000 0x0 0xc0000000
227 0x0 0x20000000
228
229 0x1000000 0x0 0x0
230 0x1000000 0x0 0x0
231 0x0 0x100000>;
232 };
233 };
234};
diff --git a/arch/powerpc/boot/dts/pcm030.dts b/arch/powerpc/boot/dts/pcm030.dts
index 7c1bb952360c..be2c11ca0594 100644
--- a/arch/powerpc/boot/dts/pcm030.dts
+++ b/arch/powerpc/boot/dts/pcm030.dts
@@ -143,7 +143,6 @@
143 143
144 rtc@800 { // Real time clock 144 rtc@800 { // Real time clock
145 compatible = "fsl,mpc5200b-rtc","fsl,mpc5200-rtc"; 145 compatible = "fsl,mpc5200b-rtc","fsl,mpc5200-rtc";
146 device_type = "rtc";
147 reg = <0x800 0x100>; 146 reg = <0x800 0x100>;
148 interrupts = <0x1 0x5 0x0 0x1 0x6 0x0>; 147 interrupts = <0x1 0x5 0x0 0x1 0x6 0x0>;
149 interrupt-parent = <&mpc5200_pic>; 148 interrupt-parent = <&mpc5200_pic>;
@@ -301,7 +300,6 @@
301 interrupt-parent = <&mpc5200_pic>; 300 interrupt-parent = <&mpc5200_pic>;
302 fsl5200-clocking; 301 fsl5200-clocking;
303 rtc@51 { 302 rtc@51 {
304 device_type = "rtc";
305 compatible = "nxp,pcf8563"; 303 compatible = "nxp,pcf8563";
306 reg = <0x51>; 304 reg = <0x51>;
307 }; 305 };
diff --git a/arch/powerpc/boot/dts/tqm5200.dts b/arch/powerpc/boot/dts/tqm5200.dts
index 3008bf8830c1..906302e26a62 100644
--- a/arch/powerpc/boot/dts/tqm5200.dts
+++ b/arch/powerpc/boot/dts/tqm5200.dts
@@ -181,7 +181,6 @@
181 fsl5200-clocking; 181 fsl5200-clocking;
182 182
183 rtc@68 { 183 rtc@68 {
184 device_type = "rtc";
185 compatible = "dallas,ds1307"; 184 compatible = "dallas,ds1307";
186 reg = <0x68>; 185 reg = <0x68>;
187 }; 186 };
diff --git a/arch/powerpc/boot/libfdt-wrapper.c b/arch/powerpc/boot/libfdt-wrapper.c
index 9276327bc2bb..bb8b9b3505ee 100644
--- a/arch/powerpc/boot/libfdt-wrapper.c
+++ b/arch/powerpc/boot/libfdt-wrapper.c
@@ -185,7 +185,7 @@ void fdt_init(void *blob)
185 185
186 /* Make sure the dt blob is the right version and so forth */ 186 /* Make sure the dt blob is the right version and so forth */
187 fdt = blob; 187 fdt = blob;
188 bufsize = fdt_totalsize(fdt) + 4; 188 bufsize = fdt_totalsize(fdt) + EXPAND_GRANULARITY;
189 buf = malloc(bufsize); 189 buf = malloc(bufsize);
190 if(!buf) 190 if(!buf)
191 fatal("malloc failed. can't relocate the device tree\n\r"); 191 fatal("malloc failed. can't relocate the device tree\n\r");
diff --git a/arch/powerpc/configs/86xx/gef_sbc610_defconfig b/arch/powerpc/configs/86xx/gef_sbc610_defconfig
index 07ccaf89f379..cd1ffa449327 100644
--- a/arch/powerpc/configs/86xx/gef_sbc610_defconfig
+++ b/arch/powerpc/configs/86xx/gef_sbc610_defconfig
@@ -1397,8 +1397,11 @@ CONFIG_USB_STORAGE=y
1397# CONFIG_ACCESSIBILITY is not set 1397# CONFIG_ACCESSIBILITY is not set
1398# CONFIG_INFINIBAND is not set 1398# CONFIG_INFINIBAND is not set
1399# CONFIG_EDAC is not set 1399# CONFIG_EDAC is not set
1400CONFIG_RTC_LIB=m 1400CONFIG_RTC_LIB=y
1401CONFIG_RTC_CLASS=m 1401CONFIG_RTC_CLASS=y
1402CONFIG_RTC_HCTOSYS=y
1403CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
1404# CONFIG_RTC_DEBUG is not set
1402 1405
1403# 1406#
1404# RTC interfaces 1407# RTC interfaces
@@ -1424,6 +1427,7 @@ CONFIG_RTC_INTF_DEV=y
1424# CONFIG_RTC_DRV_M41T80 is not set 1427# CONFIG_RTC_DRV_M41T80 is not set
1425# CONFIG_RTC_DRV_S35390A is not set 1428# CONFIG_RTC_DRV_S35390A is not set
1426# CONFIG_RTC_DRV_FM3130 is not set 1429# CONFIG_RTC_DRV_FM3130 is not set
1430CONFIG_RTC_DRV_RX8581=y
1427 1431
1428# 1432#
1429# SPI RTC drivers 1433# SPI RTC drivers
diff --git a/arch/powerpc/configs/ppc44x_defconfig b/arch/powerpc/configs/ppc44x_defconfig
index cfc94cfcf4cb..034a1fbdc887 100644
--- a/arch/powerpc/configs/ppc44x_defconfig
+++ b/arch/powerpc/configs/ppc44x_defconfig
@@ -267,7 +267,7 @@ CONFIG_PCI_SYSCALL=y
267# CONFIG_PCIEPORTBUS is not set 267# CONFIG_PCIEPORTBUS is not set
268CONFIG_ARCH_SUPPORTS_MSI=y 268CONFIG_ARCH_SUPPORTS_MSI=y
269# CONFIG_PCI_MSI is not set 269# CONFIG_PCI_MSI is not set
270CONFIG_PCI_LEGACY=y 270# CONFIG_PCI_LEGACY is not set
271# CONFIG_PCI_DEBUG is not set 271# CONFIG_PCI_DEBUG is not set
272# CONFIG_PCCARD is not set 272# CONFIG_PCCARD is not set
273# CONFIG_HOTPLUG_PCI is not set 273# CONFIG_HOTPLUG_PCI is not set
@@ -354,7 +354,7 @@ CONFIG_IPV6_NDISC_NODETYPE=y
354# CONFIG_IP_SCTP is not set 354# CONFIG_IP_SCTP is not set
355# CONFIG_TIPC is not set 355# CONFIG_TIPC is not set
356# CONFIG_ATM is not set 356# CONFIG_ATM is not set
357# CONFIG_BRIDGE is not set 357CONFIG_BRIDGE=m
358# CONFIG_NET_DSA is not set 358# CONFIG_NET_DSA is not set
359# CONFIG_VLAN_8021Q is not set 359# CONFIG_VLAN_8021Q is not set
360# CONFIG_DECNET is not set 360# CONFIG_DECNET is not set
@@ -579,7 +579,7 @@ CONFIG_NETDEVICES=y
579# CONFIG_BONDING is not set 579# CONFIG_BONDING is not set
580# CONFIG_MACVLAN is not set 580# CONFIG_MACVLAN is not set
581# CONFIG_EQUALIZER is not set 581# CONFIG_EQUALIZER is not set
582# CONFIG_TUN is not set 582CONFIG_TUN=m
583# CONFIG_VETH is not set 583# CONFIG_VETH is not set
584# CONFIG_ARCNET is not set 584# CONFIG_ARCNET is not set
585# CONFIG_PHYLIB is not set 585# CONFIG_PHYLIB is not set
@@ -1001,11 +1001,11 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
1001# CONFIG_USB_TMC is not set 1001# CONFIG_USB_TMC is not set
1002 1002
1003# 1003#
1004# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' 1004# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
1005# 1005#
1006 1006
1007# 1007#
1008# may also be needed; see USB_STORAGE Help for more information 1008# see USB_STORAGE Help for more information
1009# 1009#
1010CONFIG_USB_STORAGE=m 1010CONFIG_USB_STORAGE=m
1011# CONFIG_USB_STORAGE_DEBUG is not set 1011# CONFIG_USB_STORAGE_DEBUG is not set
@@ -1418,6 +1418,6 @@ CONFIG_CRYPTO_LZO=m
1418# CONFIG_PPC_CLOCK is not set 1418# CONFIG_PPC_CLOCK is not set
1419CONFIG_VIRTUALIZATION=y 1419CONFIG_VIRTUALIZATION=y
1420CONFIG_KVM=y 1420CONFIG_KVM=y
1421CONFIG_KVM_BOOKE_HOST=y 1421CONFIG_KVM_440=y
1422# CONFIG_VIRTIO_PCI is not set 1422# CONFIG_VIRTIO_PCI is not set
1423# CONFIG_VIRTIO_BALLOON is not set 1423# CONFIG_VIRTIO_BALLOON is not set
diff --git a/arch/powerpc/include/asm/atomic.h b/arch/powerpc/include/asm/atomic.h
index f3fc733758f5..499be5bdd6fa 100644
--- a/arch/powerpc/include/asm/atomic.h
+++ b/arch/powerpc/include/asm/atomic.h
@@ -111,7 +111,7 @@ static __inline__ void atomic_inc(atomic_t *v)
111 bne- 1b" 111 bne- 1b"
112 : "=&r" (t), "+m" (v->counter) 112 : "=&r" (t), "+m" (v->counter)
113 : "r" (&v->counter) 113 : "r" (&v->counter)
114 : "cc"); 114 : "cc", "xer");
115} 115}
116 116
117static __inline__ int atomic_inc_return(atomic_t *v) 117static __inline__ int atomic_inc_return(atomic_t *v)
@@ -128,7 +128,7 @@ static __inline__ int atomic_inc_return(atomic_t *v)
128 ISYNC_ON_SMP 128 ISYNC_ON_SMP
129 : "=&r" (t) 129 : "=&r" (t)
130 : "r" (&v->counter) 130 : "r" (&v->counter)
131 : "cc", "memory"); 131 : "cc", "xer", "memory");
132 132
133 return t; 133 return t;
134} 134}
@@ -155,7 +155,7 @@ static __inline__ void atomic_dec(atomic_t *v)
155 bne- 1b" 155 bne- 1b"
156 : "=&r" (t), "+m" (v->counter) 156 : "=&r" (t), "+m" (v->counter)
157 : "r" (&v->counter) 157 : "r" (&v->counter)
158 : "cc"); 158 : "cc", "xer");
159} 159}
160 160
161static __inline__ int atomic_dec_return(atomic_t *v) 161static __inline__ int atomic_dec_return(atomic_t *v)
@@ -172,7 +172,7 @@ static __inline__ int atomic_dec_return(atomic_t *v)
172 ISYNC_ON_SMP 172 ISYNC_ON_SMP
173 : "=&r" (t) 173 : "=&r" (t)
174 : "r" (&v->counter) 174 : "r" (&v->counter)
175 : "cc", "memory"); 175 : "cc", "xer", "memory");
176 176
177 return t; 177 return t;
178} 178}
@@ -346,7 +346,7 @@ static __inline__ void atomic64_inc(atomic64_t *v)
346 bne- 1b" 346 bne- 1b"
347 : "=&r" (t), "+m" (v->counter) 347 : "=&r" (t), "+m" (v->counter)
348 : "r" (&v->counter) 348 : "r" (&v->counter)
349 : "cc"); 349 : "cc", "xer");
350} 350}
351 351
352static __inline__ long atomic64_inc_return(atomic64_t *v) 352static __inline__ long atomic64_inc_return(atomic64_t *v)
@@ -362,7 +362,7 @@ static __inline__ long atomic64_inc_return(atomic64_t *v)
362 ISYNC_ON_SMP 362 ISYNC_ON_SMP
363 : "=&r" (t) 363 : "=&r" (t)
364 : "r" (&v->counter) 364 : "r" (&v->counter)
365 : "cc", "memory"); 365 : "cc", "xer", "memory");
366 366
367 return t; 367 return t;
368} 368}
@@ -388,7 +388,7 @@ static __inline__ void atomic64_dec(atomic64_t *v)
388 bne- 1b" 388 bne- 1b"
389 : "=&r" (t), "+m" (v->counter) 389 : "=&r" (t), "+m" (v->counter)
390 : "r" (&v->counter) 390 : "r" (&v->counter)
391 : "cc"); 391 : "cc", "xer");
392} 392}
393 393
394static __inline__ long atomic64_dec_return(atomic64_t *v) 394static __inline__ long atomic64_dec_return(atomic64_t *v)
@@ -404,7 +404,7 @@ static __inline__ long atomic64_dec_return(atomic64_t *v)
404 ISYNC_ON_SMP 404 ISYNC_ON_SMP
405 : "=&r" (t) 405 : "=&r" (t)
406 : "r" (&v->counter) 406 : "r" (&v->counter)
407 : "cc", "memory"); 407 : "cc", "xer", "memory");
408 408
409 return t; 409 return t;
410} 410}
@@ -431,7 +431,7 @@ static __inline__ long atomic64_dec_if_positive(atomic64_t *v)
431 "\n\ 431 "\n\
4322:" : "=&r" (t) 4322:" : "=&r" (t)
433 : "r" (&v->counter) 433 : "r" (&v->counter)
434 : "cc", "memory"); 434 : "cc", "xer", "memory");
435 435
436 return t; 436 return t;
437} 437}
diff --git a/arch/powerpc/include/asm/bug.h b/arch/powerpc/include/asm/bug.h
index e55d1f66b86f..64e1fdca233e 100644
--- a/arch/powerpc/include/asm/bug.h
+++ b/arch/powerpc/include/asm/bug.h
@@ -3,6 +3,7 @@
3#ifdef __KERNEL__ 3#ifdef __KERNEL__
4 4
5#include <asm/asm-compat.h> 5#include <asm/asm-compat.h>
6
6/* 7/*
7 * Define an illegal instr to trap on the bug. 8 * Define an illegal instr to trap on the bug.
8 * We don't use 0 because that marks the end of a function 9 * We don't use 0 because that marks the end of a function
@@ -14,6 +15,7 @@
14#ifdef CONFIG_BUG 15#ifdef CONFIG_BUG
15 16
16#ifdef __ASSEMBLY__ 17#ifdef __ASSEMBLY__
18#include <asm/asm-offsets.h>
17#ifdef CONFIG_DEBUG_BUGVERBOSE 19#ifdef CONFIG_DEBUG_BUGVERBOSE
18.macro EMIT_BUG_ENTRY addr,file,line,flags 20.macro EMIT_BUG_ENTRY addr,file,line,flags
19 .section __bug_table,"a" 21 .section __bug_table,"a"
@@ -26,7 +28,7 @@
26 .previous 28 .previous
27.endm 29.endm
28#else 30#else
29 .macro EMIT_BUG_ENTRY addr,file,line,flags 31.macro EMIT_BUG_ENTRY addr,file,line,flags
30 .section __bug_table,"a" 32 .section __bug_table,"a"
315001: PPC_LONG \addr 335001: PPC_LONG \addr
32 .short \flags 34 .short \flags
@@ -113,6 +115,13 @@
113#define HAVE_ARCH_BUG_ON 115#define HAVE_ARCH_BUG_ON
114#define HAVE_ARCH_WARN_ON 116#define HAVE_ARCH_WARN_ON
115#endif /* __ASSEMBLY __ */ 117#endif /* __ASSEMBLY __ */
118#else
119#ifdef __ASSEMBLY__
120.macro EMIT_BUG_ENTRY addr,file,line,flags
121.endm
122#else /* !__ASSEMBLY__ */
123#define _EMIT_BUG_ENTRY
124#endif
116#endif /* CONFIG_BUG */ 125#endif /* CONFIG_BUG */
117 126
118#include <asm-generic/bug.h> 127#include <asm-generic/bug.h>
diff --git a/arch/powerpc/include/asm/byteorder.h b/arch/powerpc/include/asm/byteorder.h
index b37752214a16..d5de325472e9 100644
--- a/arch/powerpc/include/asm/byteorder.h
+++ b/arch/powerpc/include/asm/byteorder.h
@@ -11,6 +11,8 @@
11#include <asm/types.h> 11#include <asm/types.h>
12#include <linux/compiler.h> 12#include <linux/compiler.h>
13 13
14#define __BIG_ENDIAN
15
14#ifdef __GNUC__ 16#ifdef __GNUC__
15#ifdef __KERNEL__ 17#ifdef __KERNEL__
16 18
@@ -21,12 +23,19 @@ static __inline__ __u16 ld_le16(const volatile __u16 *addr)
21 __asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (addr), "m" (*addr)); 23 __asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (addr), "m" (*addr));
22 return val; 24 return val;
23} 25}
26#define __arch_swab16p ld_le16
24 27
25static __inline__ void st_le16(volatile __u16 *addr, const __u16 val) 28static __inline__ void st_le16(volatile __u16 *addr, const __u16 val)
26{ 29{
27 __asm__ __volatile__ ("sthbrx %1,0,%2" : "=m" (*addr) : "r" (val), "r" (addr)); 30 __asm__ __volatile__ ("sthbrx %1,0,%2" : "=m" (*addr) : "r" (val), "r" (addr));
28} 31}
29 32
33static inline void __arch_swab16s(__u16 *addr)
34{
35 st_le16(addr, *addr);
36}
37#define __arch_swab16s __arch_swab16s
38
30static __inline__ __u32 ld_le32(const volatile __u32 *addr) 39static __inline__ __u32 ld_le32(const volatile __u32 *addr)
31{ 40{
32 __u32 val; 41 __u32 val;
@@ -34,13 +43,20 @@ static __inline__ __u32 ld_le32(const volatile __u32 *addr)
34 __asm__ __volatile__ ("lwbrx %0,0,%1" : "=r" (val) : "r" (addr), "m" (*addr)); 43 __asm__ __volatile__ ("lwbrx %0,0,%1" : "=r" (val) : "r" (addr), "m" (*addr));
35 return val; 44 return val;
36} 45}
46#define __arch_swab32p ld_le32
37 47
38static __inline__ void st_le32(volatile __u32 *addr, const __u32 val) 48static __inline__ void st_le32(volatile __u32 *addr, const __u32 val)
39{ 49{
40 __asm__ __volatile__ ("stwbrx %1,0,%2" : "=m" (*addr) : "r" (val), "r" (addr)); 50 __asm__ __volatile__ ("stwbrx %1,0,%2" : "=m" (*addr) : "r" (val), "r" (addr));
41} 51}
42 52
43static __inline__ __attribute_const__ __u16 ___arch__swab16(__u16 value) 53static inline void __arch_swab32s(__u32 *addr)
54{
55 st_le32(addr, *addr);
56}
57#define __arch_swab32s __arch_swab32s
58
59static inline __attribute_const__ __u16 __arch_swab16(__u16 value)
44{ 60{
45 __u16 result; 61 __u16 result;
46 62
@@ -49,8 +65,9 @@ static __inline__ __attribute_const__ __u16 ___arch__swab16(__u16 value)
49 : "r" (value), "0" (value >> 8)); 65 : "r" (value), "0" (value >> 8));
50 return result; 66 return result;
51} 67}
68#define __arch_swab16 __arch_swab16
52 69
53static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 value) 70static inline __attribute_const__ __u32 __arch_swab32(__u32 value)
54{ 71{
55 __u32 result; 72 __u32 result;
56 73
@@ -61,29 +78,16 @@ static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 value)
61 : "r" (value), "0" (value >> 24)); 78 : "r" (value), "0" (value >> 24));
62 return result; 79 return result;
63} 80}
64 81#define __arch_swab32 __arch_swab32
65#define __arch__swab16(x) ___arch__swab16(x)
66#define __arch__swab32(x) ___arch__swab32(x)
67
68/* The same, but returns converted value from the location pointer by addr. */
69#define __arch__swab16p(addr) ld_le16(addr)
70#define __arch__swab32p(addr) ld_le32(addr)
71
72/* The same, but do the conversion in situ, ie. put the value back to addr. */
73#define __arch__swab16s(addr) st_le16(addr,*addr)
74#define __arch__swab32s(addr) st_le32(addr,*addr)
75 82
76#endif /* __KERNEL__ */ 83#endif /* __KERNEL__ */
77 84
78#ifndef __STRICT_ANSI__
79#define __BYTEORDER_HAS_U64__
80#ifndef __powerpc64__ 85#ifndef __powerpc64__
81#define __SWAB_64_THRU_32__ 86#define __SWAB_64_THRU_32__
82#endif /* __powerpc64__ */ 87#endif /* __powerpc64__ */
83#endif /* __STRICT_ANSI__ */
84 88
85#endif /* __GNUC__ */ 89#endif /* __GNUC__ */
86 90
87#include <linux/byteorder/big_endian.h> 91#include <linux/byteorder.h>
88 92
89#endif /* _ASM_POWERPC_BYTEORDER_H */ 93#endif /* _ASM_POWERPC_BYTEORDER_H */
diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h
index 1e94b07a020e..f3d9d7417166 100644
--- a/arch/powerpc/include/asm/cputable.h
+++ b/arch/powerpc/include/asm/cputable.h
@@ -163,6 +163,7 @@ extern const char *powerpc_base_platform;
163#define CPU_FTR_SPE ASM_CONST(0x0000000002000000) 163#define CPU_FTR_SPE ASM_CONST(0x0000000002000000)
164#define CPU_FTR_NEED_PAIRED_STWCX ASM_CONST(0x0000000004000000) 164#define CPU_FTR_NEED_PAIRED_STWCX ASM_CONST(0x0000000004000000)
165#define CPU_FTR_LWSYNC ASM_CONST(0x0000000008000000) 165#define CPU_FTR_LWSYNC ASM_CONST(0x0000000008000000)
166#define CPU_FTR_NOEXECUTE ASM_CONST(0x0000000010000000)
166 167
167/* 168/*
168 * Add the 64-bit processor unique features in the top half of the word; 169 * Add the 64-bit processor unique features in the top half of the word;
@@ -177,7 +178,6 @@ extern const char *powerpc_base_platform;
177#define CPU_FTR_SLB LONG_ASM_CONST(0x0000000100000000) 178#define CPU_FTR_SLB LONG_ASM_CONST(0x0000000100000000)
178#define CPU_FTR_16M_PAGE LONG_ASM_CONST(0x0000000200000000) 179#define CPU_FTR_16M_PAGE LONG_ASM_CONST(0x0000000200000000)
179#define CPU_FTR_TLBIEL LONG_ASM_CONST(0x0000000400000000) 180#define CPU_FTR_TLBIEL LONG_ASM_CONST(0x0000000400000000)
180#define CPU_FTR_NOEXECUTE LONG_ASM_CONST(0x0000000800000000)
181#define CPU_FTR_IABR LONG_ASM_CONST(0x0000002000000000) 181#define CPU_FTR_IABR LONG_ASM_CONST(0x0000002000000000)
182#define CPU_FTR_MMCRA LONG_ASM_CONST(0x0000004000000000) 182#define CPU_FTR_MMCRA LONG_ASM_CONST(0x0000004000000000)
183#define CPU_FTR_CTRL LONG_ASM_CONST(0x0000008000000000) 183#define CPU_FTR_CTRL LONG_ASM_CONST(0x0000008000000000)
@@ -194,6 +194,7 @@ extern const char *powerpc_base_platform;
194#define CPU_FTR_VSX LONG_ASM_CONST(0x0010000000000000) 194#define CPU_FTR_VSX LONG_ASM_CONST(0x0010000000000000)
195#define CPU_FTR_SAO LONG_ASM_CONST(0x0020000000000000) 195#define CPU_FTR_SAO LONG_ASM_CONST(0x0020000000000000)
196#define CPU_FTR_CP_USE_DCBTZ LONG_ASM_CONST(0x0040000000000000) 196#define CPU_FTR_CP_USE_DCBTZ LONG_ASM_CONST(0x0040000000000000)
197#define CPU_FTR_UNALIGNED_LD_STD LONG_ASM_CONST(0x0080000000000000)
197 198
198#ifndef __ASSEMBLY__ 199#ifndef __ASSEMBLY__
199 200
@@ -366,19 +367,20 @@ extern const char *powerpc_base_platform;
366#define CPU_FTRS_CLASSIC32 (CPU_FTR_COMMON | \ 367#define CPU_FTRS_CLASSIC32 (CPU_FTR_COMMON | \
367 CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE) 368 CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE)
368#define CPU_FTRS_8XX (CPU_FTR_USE_TB) 369#define CPU_FTRS_8XX (CPU_FTR_USE_TB)
369#define CPU_FTRS_40X (CPU_FTR_USE_TB | CPU_FTR_NODSISRALIGN) 370#define CPU_FTRS_40X (CPU_FTR_USE_TB | CPU_FTR_NODSISRALIGN | CPU_FTR_NOEXECUTE)
370#define CPU_FTRS_44X (CPU_FTR_USE_TB | CPU_FTR_NODSISRALIGN) 371#define CPU_FTRS_44X (CPU_FTR_USE_TB | CPU_FTR_NODSISRALIGN | CPU_FTR_NOEXECUTE)
371#define CPU_FTRS_E200 (CPU_FTR_USE_TB | CPU_FTR_SPE_COMP | \ 372#define CPU_FTRS_E200 (CPU_FTR_USE_TB | CPU_FTR_SPE_COMP | \
372 CPU_FTR_NODSISRALIGN | CPU_FTR_COHERENT_ICACHE | \ 373 CPU_FTR_NODSISRALIGN | CPU_FTR_COHERENT_ICACHE | \
373 CPU_FTR_UNIFIED_ID_CACHE) 374 CPU_FTR_UNIFIED_ID_CACHE | CPU_FTR_NOEXECUTE)
374#define CPU_FTRS_E500 (CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | \ 375#define CPU_FTRS_E500 (CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | \
375 CPU_FTR_SPE_COMP | CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_NODSISRALIGN) 376 CPU_FTR_SPE_COMP | CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_NODSISRALIGN | \
377 CPU_FTR_NOEXECUTE)
376#define CPU_FTRS_E500_2 (CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | \ 378#define CPU_FTRS_E500_2 (CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | \
377 CPU_FTR_SPE_COMP | CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_BIG_PHYS | \ 379 CPU_FTR_SPE_COMP | CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_BIG_PHYS | \
378 CPU_FTR_NODSISRALIGN) 380 CPU_FTR_NODSISRALIGN | CPU_FTR_NOEXECUTE)
379#define CPU_FTRS_E500MC (CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | \ 381#define CPU_FTRS_E500MC (CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | \
380 CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_BIG_PHYS | CPU_FTR_NODSISRALIGN | \ 382 CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_BIG_PHYS | CPU_FTR_NODSISRALIGN | \
381 CPU_FTR_L2CSR | CPU_FTR_LWSYNC) 383 CPU_FTR_L2CSR | CPU_FTR_LWSYNC | CPU_FTR_NOEXECUTE)
382#define CPU_FTRS_GENERIC_32 (CPU_FTR_COMMON | CPU_FTR_NODSISRALIGN) 384#define CPU_FTRS_GENERIC_32 (CPU_FTR_COMMON | CPU_FTR_NODSISRALIGN)
383 385
384/* 64-bit CPUs */ 386/* 64-bit CPUs */
@@ -404,7 +406,7 @@ extern const char *powerpc_base_platform;
404 CPU_FTR_MMCRA | CPU_FTR_SMT | \ 406 CPU_FTR_MMCRA | CPU_FTR_SMT | \
405 CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | \ 407 CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | \
406 CPU_FTR_PURR | CPU_FTR_SPURR | CPU_FTR_REAL_LE | \ 408 CPU_FTR_PURR | CPU_FTR_SPURR | CPU_FTR_REAL_LE | \
407 CPU_FTR_DSCR) 409 CPU_FTR_DSCR | CPU_FTR_UNALIGNED_LD_STD)
408#define CPU_FTRS_POWER7 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \ 410#define CPU_FTRS_POWER7 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
409 CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \ 411 CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
410 CPU_FTR_MMCRA | CPU_FTR_SMT | \ 412 CPU_FTR_MMCRA | CPU_FTR_SMT | \
@@ -415,7 +417,8 @@ extern const char *powerpc_base_platform;
415 CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \ 417 CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
416 CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \ 418 CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \
417 CPU_FTR_PAUSE_ZERO | CPU_FTR_CI_LARGE_PAGE | \ 419 CPU_FTR_PAUSE_ZERO | CPU_FTR_CI_LARGE_PAGE | \
418 CPU_FTR_CELL_TB_BUG | CPU_FTR_CP_USE_DCBTZ) 420 CPU_FTR_CELL_TB_BUG | CPU_FTR_CP_USE_DCBTZ | \
421 CPU_FTR_UNALIGNED_LD_STD)
419#define CPU_FTRS_PA6T (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \ 422#define CPU_FTRS_PA6T (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
420 CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | \ 423 CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | \
421 CPU_FTR_ALTIVEC_COMP | CPU_FTR_CI_LARGE_PAGE | \ 424 CPU_FTR_ALTIVEC_COMP | CPU_FTR_CI_LARGE_PAGE | \
diff --git a/arch/powerpc/include/asm/device.h b/arch/powerpc/include/asm/device.h
index dfd504caccc1..7d2277cef09a 100644
--- a/arch/powerpc/include/asm/device.h
+++ b/arch/powerpc/include/asm/device.h
@@ -18,4 +18,16 @@ struct dev_archdata {
18 void *dma_data; 18 void *dma_data;
19}; 19};
20 20
21static inline void dev_archdata_set_node(struct dev_archdata *ad,
22 struct device_node *np)
23{
24 ad->of_node = np;
25}
26
27static inline struct device_node *
28dev_archdata_get_node(const struct dev_archdata *ad)
29{
30 return ad->of_node;
31}
32
21#endif /* _ASM_POWERPC_DEVICE_H */ 33#endif /* _ASM_POWERPC_DEVICE_H */
diff --git a/arch/powerpc/include/asm/dma-mapping.h b/arch/powerpc/include/asm/dma-mapping.h
index fddb229bd74f..86cef7ddc8d5 100644
--- a/arch/powerpc/include/asm/dma-mapping.h
+++ b/arch/powerpc/include/asm/dma-mapping.h
@@ -60,12 +60,6 @@ struct dma_mapping_ops {
60 dma_addr_t *dma_handle, gfp_t flag); 60 dma_addr_t *dma_handle, gfp_t flag);
61 void (*free_coherent)(struct device *dev, size_t size, 61 void (*free_coherent)(struct device *dev, size_t size,
62 void *vaddr, dma_addr_t dma_handle); 62 void *vaddr, dma_addr_t dma_handle);
63 dma_addr_t (*map_single)(struct device *dev, void *ptr,
64 size_t size, enum dma_data_direction direction,
65 struct dma_attrs *attrs);
66 void (*unmap_single)(struct device *dev, dma_addr_t dma_addr,
67 size_t size, enum dma_data_direction direction,
68 struct dma_attrs *attrs);
69 int (*map_sg)(struct device *dev, struct scatterlist *sg, 63 int (*map_sg)(struct device *dev, struct scatterlist *sg,
70 int nents, enum dma_data_direction direction, 64 int nents, enum dma_data_direction direction,
71 struct dma_attrs *attrs); 65 struct dma_attrs *attrs);
@@ -82,6 +76,22 @@ struct dma_mapping_ops {
82 dma_addr_t dma_address, size_t size, 76 dma_addr_t dma_address, size_t size,
83 enum dma_data_direction direction, 77 enum dma_data_direction direction,
84 struct dma_attrs *attrs); 78 struct dma_attrs *attrs);
79#ifdef CONFIG_PPC_NEED_DMA_SYNC_OPS
80 void (*sync_single_range_for_cpu)(struct device *hwdev,
81 dma_addr_t dma_handle, unsigned long offset,
82 size_t size,
83 enum dma_data_direction direction);
84 void (*sync_single_range_for_device)(struct device *hwdev,
85 dma_addr_t dma_handle, unsigned long offset,
86 size_t size,
87 enum dma_data_direction direction);
88 void (*sync_sg_for_cpu)(struct device *hwdev,
89 struct scatterlist *sg, int nelems,
90 enum dma_data_direction direction);
91 void (*sync_sg_for_device)(struct device *hwdev,
92 struct scatterlist *sg, int nelems,
93 enum dma_data_direction direction);
94#endif
85}; 95};
86 96
87/* 97/*
@@ -149,10 +159,9 @@ static inline int dma_set_mask(struct device *dev, u64 dma_mask)
149} 159}
150 160
151/* 161/*
152 * TODO: map_/unmap_single will ideally go away, to be completely 162 * map_/unmap_single actually call through to map/unmap_page now that all the
153 * replaced by map/unmap_page. Until then, we allow dma_ops to have 163 * dma_mapping_ops have been converted over. We just have to get the page and
154 * one or the other, or both by checking to see if the specific 164 * offset to pass through to map_page
155 * function requested exists; and if not, falling back on the other set.
156 */ 165 */
157static inline dma_addr_t dma_map_single_attrs(struct device *dev, 166static inline dma_addr_t dma_map_single_attrs(struct device *dev,
158 void *cpu_addr, 167 void *cpu_addr,
@@ -164,10 +173,6 @@ static inline dma_addr_t dma_map_single_attrs(struct device *dev,
164 173
165 BUG_ON(!dma_ops); 174 BUG_ON(!dma_ops);
166 175
167 if (dma_ops->map_single)
168 return dma_ops->map_single(dev, cpu_addr, size, direction,
169 attrs);
170
171 return dma_ops->map_page(dev, virt_to_page(cpu_addr), 176 return dma_ops->map_page(dev, virt_to_page(cpu_addr),
172 (unsigned long)cpu_addr % PAGE_SIZE, size, 177 (unsigned long)cpu_addr % PAGE_SIZE, size,
173 direction, attrs); 178 direction, attrs);
@@ -183,11 +188,6 @@ static inline void dma_unmap_single_attrs(struct device *dev,
183 188
184 BUG_ON(!dma_ops); 189 BUG_ON(!dma_ops);
185 190
186 if (dma_ops->unmap_single) {
187 dma_ops->unmap_single(dev, dma_addr, size, direction, attrs);
188 return;
189 }
190
191 dma_ops->unmap_page(dev, dma_addr, size, direction, attrs); 191 dma_ops->unmap_page(dev, dma_addr, size, direction, attrs);
192} 192}
193 193
@@ -201,12 +201,7 @@ static inline dma_addr_t dma_map_page_attrs(struct device *dev,
201 201
202 BUG_ON(!dma_ops); 202 BUG_ON(!dma_ops);
203 203
204 if (dma_ops->map_page) 204 return dma_ops->map_page(dev, page, offset, size, direction, attrs);
205 return dma_ops->map_page(dev, page, offset, size, direction,
206 attrs);
207
208 return dma_ops->map_single(dev, page_address(page) + offset, size,
209 direction, attrs);
210} 205}
211 206
212static inline void dma_unmap_page_attrs(struct device *dev, 207static inline void dma_unmap_page_attrs(struct device *dev,
@@ -219,12 +214,7 @@ static inline void dma_unmap_page_attrs(struct device *dev,
219 214
220 BUG_ON(!dma_ops); 215 BUG_ON(!dma_ops);
221 216
222 if (dma_ops->unmap_page) { 217 dma_ops->unmap_page(dev, dma_address, size, direction, attrs);
223 dma_ops->unmap_page(dev, dma_address, size, direction, attrs);
224 return;
225 }
226
227 dma_ops->unmap_single(dev, dma_address, size, direction, attrs);
228} 218}
229 219
230static inline int dma_map_sg_attrs(struct device *dev, struct scatterlist *sg, 220static inline int dma_map_sg_attrs(struct device *dev, struct scatterlist *sg,
@@ -308,47 +298,107 @@ static inline void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
308 dma_unmap_sg_attrs(dev, sg, nhwentries, direction, NULL); 298 dma_unmap_sg_attrs(dev, sg, nhwentries, direction, NULL);
309} 299}
310 300
301#ifdef CONFIG_PPC_NEED_DMA_SYNC_OPS
311static inline void dma_sync_single_for_cpu(struct device *dev, 302static inline void dma_sync_single_for_cpu(struct device *dev,
312 dma_addr_t dma_handle, size_t size, 303 dma_addr_t dma_handle, size_t size,
313 enum dma_data_direction direction) 304 enum dma_data_direction direction)
314{ 305{
315 BUG_ON(direction == DMA_NONE); 306 struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
316 __dma_sync(bus_to_virt(dma_handle), size, direction); 307
308 BUG_ON(!dma_ops);
309 dma_ops->sync_single_range_for_cpu(dev, dma_handle, 0,
310 size, direction);
317} 311}
318 312
319static inline void dma_sync_single_for_device(struct device *dev, 313static inline void dma_sync_single_for_device(struct device *dev,
320 dma_addr_t dma_handle, size_t size, 314 dma_addr_t dma_handle, size_t size,
321 enum dma_data_direction direction) 315 enum dma_data_direction direction)
322{ 316{
323 BUG_ON(direction == DMA_NONE); 317 struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
324 __dma_sync(bus_to_virt(dma_handle), size, direction); 318
319 BUG_ON(!dma_ops);
320 dma_ops->sync_single_range_for_device(dev, dma_handle,
321 0, size, direction);
325} 322}
326 323
327static inline void dma_sync_sg_for_cpu(struct device *dev, 324static inline void dma_sync_sg_for_cpu(struct device *dev,
328 struct scatterlist *sgl, int nents, 325 struct scatterlist *sgl, int nents,
329 enum dma_data_direction direction) 326 enum dma_data_direction direction)
330{ 327{
331 struct scatterlist *sg; 328 struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
332 int i;
333 329
334 BUG_ON(direction == DMA_NONE); 330 BUG_ON(!dma_ops);
331 dma_ops->sync_sg_for_cpu(dev, sgl, nents, direction);
332}
333
334static inline void dma_sync_sg_for_device(struct device *dev,
335 struct scatterlist *sgl, int nents,
336 enum dma_data_direction direction)
337{
338 struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
339
340 BUG_ON(!dma_ops);
341 dma_ops->sync_sg_for_device(dev, sgl, nents, direction);
342}
343
344static inline void dma_sync_single_range_for_cpu(struct device *dev,
345 dma_addr_t dma_handle, unsigned long offset, size_t size,
346 enum dma_data_direction direction)
347{
348 struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
335 349
336 for_each_sg(sgl, sg, nents, i) 350 BUG_ON(!dma_ops);
337 __dma_sync_page(sg_page(sg), sg->offset, sg->length, direction); 351 dma_ops->sync_single_range_for_cpu(dev, dma_handle,
352 offset, size, direction);
353}
354
355static inline void dma_sync_single_range_for_device(struct device *dev,
356 dma_addr_t dma_handle, unsigned long offset, size_t size,
357 enum dma_data_direction direction)
358{
359 struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
360
361 BUG_ON(!dma_ops);
362 dma_ops->sync_single_range_for_device(dev, dma_handle, offset,
363 size, direction);
364}
365#else /* CONFIG_PPC_NEED_DMA_SYNC_OPS */
366static inline void dma_sync_single_for_cpu(struct device *dev,
367 dma_addr_t dma_handle, size_t size,
368 enum dma_data_direction direction)
369{
370}
371
372static inline void dma_sync_single_for_device(struct device *dev,
373 dma_addr_t dma_handle, size_t size,
374 enum dma_data_direction direction)
375{
376}
377
378static inline void dma_sync_sg_for_cpu(struct device *dev,
379 struct scatterlist *sgl, int nents,
380 enum dma_data_direction direction)
381{
338} 382}
339 383
340static inline void dma_sync_sg_for_device(struct device *dev, 384static inline void dma_sync_sg_for_device(struct device *dev,
341 struct scatterlist *sgl, int nents, 385 struct scatterlist *sgl, int nents,
342 enum dma_data_direction direction) 386 enum dma_data_direction direction)
343{ 387{
344 struct scatterlist *sg; 388}
345 int i;
346 389
347 BUG_ON(direction == DMA_NONE); 390static inline void dma_sync_single_range_for_cpu(struct device *dev,
391 dma_addr_t dma_handle, unsigned long offset, size_t size,
392 enum dma_data_direction direction)
393{
394}
348 395
349 for_each_sg(sgl, sg, nents, i) 396static inline void dma_sync_single_range_for_device(struct device *dev,
350 __dma_sync_page(sg_page(sg), sg->offset, sg->length, direction); 397 dma_addr_t dma_handle, unsigned long offset, size_t size,
398 enum dma_data_direction direction)
399{
351} 400}
401#endif
352 402
353static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) 403static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
354{ 404{
@@ -382,22 +432,6 @@ static inline int dma_get_cache_alignment(void)
382#endif 432#endif
383} 433}
384 434
385static inline void dma_sync_single_range_for_cpu(struct device *dev,
386 dma_addr_t dma_handle, unsigned long offset, size_t size,
387 enum dma_data_direction direction)
388{
389 /* just sync everything for now */
390 dma_sync_single_for_cpu(dev, dma_handle, offset + size, direction);
391}
392
393static inline void dma_sync_single_range_for_device(struct device *dev,
394 dma_addr_t dma_handle, unsigned long offset, size_t size,
395 enum dma_data_direction direction)
396{
397 /* just sync everything for now */
398 dma_sync_single_for_device(dev, dma_handle, offset + size, direction);
399}
400
401static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size, 435static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
402 enum dma_data_direction direction) 436 enum dma_data_direction direction)
403{ 437{
diff --git a/arch/powerpc/include/asm/eeh.h b/arch/powerpc/include/asm/eeh.h
index b886bec67016..66ea9b8b95c5 100644
--- a/arch/powerpc/include/asm/eeh.h
+++ b/arch/powerpc/include/asm/eeh.h
@@ -17,8 +17,8 @@
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */ 18 */
19 19
20#ifndef _PPC64_EEH_H 20#ifndef _POWERPC_EEH_H
21#define _PPC64_EEH_H 21#define _POWERPC_EEH_H
22#ifdef __KERNEL__ 22#ifdef __KERNEL__
23 23
24#include <linux/init.h> 24#include <linux/init.h>
@@ -110,6 +110,7 @@ static inline void eeh_remove_bus_device(struct pci_dev *dev) { }
110#define EEH_IO_ERROR_VALUE(size) (-1UL) 110#define EEH_IO_ERROR_VALUE(size) (-1UL)
111#endif /* CONFIG_EEH */ 111#endif /* CONFIG_EEH */
112 112
113#ifdef CONFIG_PPC64
113/* 114/*
114 * MMIO read/write operations with EEH support. 115 * MMIO read/write operations with EEH support.
115 */ 116 */
@@ -207,5 +208,6 @@ static inline void eeh_readsl(const volatile void __iomem *addr, void * buf,
207 eeh_check_failure(addr, *(u32*)buf); 208 eeh_check_failure(addr, *(u32*)buf);
208} 209}
209 210
211#endif /* CONFIG_PPC64 */
210#endif /* __KERNEL__ */ 212#endif /* __KERNEL__ */
211#endif /* _PPC64_EEH_H */ 213#endif /* _POWERPC_EEH_H */
diff --git a/arch/powerpc/include/asm/highmem.h b/arch/powerpc/include/asm/highmem.h
index 91c589520c0a..7dc52eca8b67 100644
--- a/arch/powerpc/include/asm/highmem.h
+++ b/arch/powerpc/include/asm/highmem.h
@@ -85,7 +85,7 @@ static inline void *kmap_atomic_prot(struct page *page, enum km_type type, pgpro
85 BUG_ON(!pte_none(*(kmap_pte-idx))); 85 BUG_ON(!pte_none(*(kmap_pte-idx)));
86#endif 86#endif
87 __set_pte_at(&init_mm, vaddr, kmap_pte-idx, mk_pte(page, prot)); 87 __set_pte_at(&init_mm, vaddr, kmap_pte-idx, mk_pte(page, prot));
88 flush_tlb_page(NULL, vaddr); 88 local_flush_tlb_page(vaddr);
89 89
90 return (void*) vaddr; 90 return (void*) vaddr;
91} 91}
@@ -113,7 +113,7 @@ static inline void kunmap_atomic(void *kvaddr, enum km_type type)
113 * this pte without first remap it 113 * this pte without first remap it
114 */ 114 */
115 pte_clear(&init_mm, vaddr, kmap_pte-idx); 115 pte_clear(&init_mm, vaddr, kmap_pte-idx);
116 flush_tlb_page(NULL, vaddr); 116 local_flush_tlb_page(vaddr);
117#endif 117#endif
118 pagefault_enable(); 118 pagefault_enable();
119} 119}
diff --git a/arch/powerpc/include/asm/io.h b/arch/powerpc/include/asm/io.h
index 08266d2728b3..494cd8b0a278 100644
--- a/arch/powerpc/include/asm/io.h
+++ b/arch/powerpc/include/asm/io.h
@@ -713,13 +713,6 @@ static inline void * phys_to_virt(unsigned long address)
713 */ 713 */
714#define page_to_phys(page) ((phys_addr_t)page_to_pfn(page) << PAGE_SHIFT) 714#define page_to_phys(page) ((phys_addr_t)page_to_pfn(page) << PAGE_SHIFT)
715 715
716/* We do NOT want virtual merging, it would put too much pressure on
717 * our iommu allocator. Instead, we want drivers to be smart enough
718 * to coalesce sglists that happen to have been mapped in a contiguous
719 * way by the iommu
720 */
721#define BIO_VMERGE_BOUNDARY 0
722
723/* 716/*
724 * 32 bits still uses virt_to_bus() for it's implementation of DMA 717 * 32 bits still uses virt_to_bus() for it's implementation of DMA
725 * mappings se we have to keep it defined here. We also have some old 718 * mappings se we have to keep it defined here. We also have some old
diff --git a/arch/powerpc/include/asm/local.h b/arch/powerpc/include/asm/local.h
index 612d83276653..84b457a3c1bc 100644
--- a/arch/powerpc/include/asm/local.h
+++ b/arch/powerpc/include/asm/local.h
@@ -67,7 +67,7 @@ static __inline__ long local_inc_return(local_t *l)
67 bne- 1b" 67 bne- 1b"
68 : "=&r" (t) 68 : "=&r" (t)
69 : "r" (&(l->a.counter)) 69 : "r" (&(l->a.counter))
70 : "cc", "memory"); 70 : "cc", "xer", "memory");
71 71
72 return t; 72 return t;
73} 73}
@@ -94,7 +94,7 @@ static __inline__ long local_dec_return(local_t *l)
94 bne- 1b" 94 bne- 1b"
95 : "=&r" (t) 95 : "=&r" (t)
96 : "r" (&(l->a.counter)) 96 : "r" (&(l->a.counter))
97 : "cc", "memory"); 97 : "cc", "xer", "memory");
98 98
99 return t; 99 return t;
100} 100}
diff --git a/arch/powerpc/include/asm/lppaca.h b/arch/powerpc/include/asm/lppaca.h
index 2fe268b10333..25aaa97facd8 100644
--- a/arch/powerpc/include/asm/lppaca.h
+++ b/arch/powerpc/include/asm/lppaca.h
@@ -133,7 +133,8 @@ struct lppaca {
133//============================================================================= 133//=============================================================================
134// CACHE_LINE_4-5 0x0180 - 0x027F Contains PMC interrupt data 134// CACHE_LINE_4-5 0x0180 - 0x027F Contains PMC interrupt data
135//============================================================================= 135//=============================================================================
136 u8 pmc_save_area[256]; // PMC interrupt Area x00-xFF 136 u32 page_ins; // CMO Hint - # page ins by OS x00-x04
137 u8 pmc_save_area[252]; // PMC interrupt Area x04-xFF
137} __attribute__((__aligned__(0x400))); 138} __attribute__((__aligned__(0x400)));
138 139
139extern struct lppaca lppaca[]; 140extern struct lppaca lppaca[];
diff --git a/arch/powerpc/include/asm/mmu-fsl-booke.h b/arch/powerpc/include/asm/mmu-fsl-booke.h
index 925d93cf64d8..5588a41f439c 100644
--- a/arch/powerpc/include/asm/mmu-fsl-booke.h
+++ b/arch/powerpc/include/asm/mmu-fsl-booke.h
@@ -40,6 +40,8 @@
40#define MAS2_M 0x00000004 40#define MAS2_M 0x00000004
41#define MAS2_G 0x00000002 41#define MAS2_G 0x00000002
42#define MAS2_E 0x00000001 42#define MAS2_E 0x00000001
43#define MAS2_EPN_MASK(size) (~0 << (2*(size) + 10))
44#define MAS2_VAL(addr, size, flags) ((addr) & MAS2_EPN_MASK(size) | (flags))
43 45
44#define MAS3_RPN 0xFFFFF000 46#define MAS3_RPN 0xFFFFF000
45#define MAS3_U0 0x00000200 47#define MAS3_U0 0x00000200
diff --git a/arch/powerpc/include/asm/mmu_context.h b/arch/powerpc/include/asm/mmu_context.h
index 6b993ef452ff..b570209b71a8 100644
--- a/arch/powerpc/include/asm/mmu_context.h
+++ b/arch/powerpc/include/asm/mmu_context.h
@@ -180,6 +180,9 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
180 180
181 tsk->thread.pgdir = next->pgd; 181 tsk->thread.pgdir = next->pgd;
182 182
183 if (!cpu_isset(smp_processor_id(), next->cpu_vm_mask))
184 cpu_set(smp_processor_id(), next->cpu_vm_mask);
185
183 /* No need to flush userspace segments if the mm doesnt change */ 186 /* No need to flush userspace segments if the mm doesnt change */
184 if (prev == next) 187 if (prev == next)
185 return; 188 return;
diff --git a/arch/powerpc/include/asm/mutex.h b/arch/powerpc/include/asm/mutex.h
index 458c1f7fbc18..dabc01c727b8 100644
--- a/arch/powerpc/include/asm/mutex.h
+++ b/arch/powerpc/include/asm/mutex.h
@@ -1,9 +1,134 @@
1/* 1/*
2 * Pull in the generic implementation for the mutex fastpath. 2 * Optimised mutex implementation of include/asm-generic/mutex-dec.h algorithm
3 */
4#ifndef _ASM_POWERPC_MUTEX_H
5#define _ASM_POWERPC_MUTEX_H
6
7static inline int __mutex_cmpxchg_lock(atomic_t *v, int old, int new)
8{
9 int t;
10
11 __asm__ __volatile__ (
12"1: lwarx %0,0,%1 # mutex trylock\n\
13 cmpw 0,%0,%2\n\
14 bne- 2f\n"
15 PPC405_ERR77(0,%1)
16" stwcx. %3,0,%1\n\
17 bne- 1b"
18 ISYNC_ON_SMP
19 "\n\
202:"
21 : "=&r" (t)
22 : "r" (&v->counter), "r" (old), "r" (new)
23 : "cc", "memory");
24
25 return t;
26}
27
28static inline int __mutex_dec_return_lock(atomic_t *v)
29{
30 int t;
31
32 __asm__ __volatile__(
33"1: lwarx %0,0,%1 # mutex lock\n\
34 addic %0,%0,-1\n"
35 PPC405_ERR77(0,%1)
36" stwcx. %0,0,%1\n\
37 bne- 1b"
38 ISYNC_ON_SMP
39 : "=&r" (t)
40 : "r" (&v->counter)
41 : "cc", "memory");
42
43 return t;
44}
45
46static inline int __mutex_inc_return_unlock(atomic_t *v)
47{
48 int t;
49
50 __asm__ __volatile__(
51 LWSYNC_ON_SMP
52"1: lwarx %0,0,%1 # mutex unlock\n\
53 addic %0,%0,1\n"
54 PPC405_ERR77(0,%1)
55" stwcx. %0,0,%1 \n\
56 bne- 1b"
57 : "=&r" (t)
58 : "r" (&v->counter)
59 : "cc", "memory");
60
61 return t;
62}
63
64/**
65 * __mutex_fastpath_lock - try to take the lock by moving the count
66 * from 1 to a 0 value
67 * @count: pointer of type atomic_t
68 * @fail_fn: function to call if the original value was not 1
69 *
70 * Change the count from 1 to a value lower than 1, and call <fail_fn> if
71 * it wasn't 1 originally. This function MUST leave the value lower than
72 * 1 even when the "1" assertion wasn't true.
73 */
74static inline void
75__mutex_fastpath_lock(atomic_t *count, void (*fail_fn)(atomic_t *))
76{
77 if (unlikely(__mutex_dec_return_lock(count) < 0))
78 fail_fn(count);
79}
80
81/**
82 * __mutex_fastpath_lock_retval - try to take the lock by moving the count
83 * from 1 to a 0 value
84 * @count: pointer of type atomic_t
85 * @fail_fn: function to call if the original value was not 1
86 *
87 * Change the count from 1 to a value lower than 1, and call <fail_fn> if
88 * it wasn't 1 originally. This function returns 0 if the fastpath succeeds,
89 * or anything the slow path function returns.
90 */
91static inline int
92__mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *))
93{
94 if (unlikely(__mutex_dec_return_lock(count) < 0))
95 return fail_fn(count);
96 return 0;
97}
98
99/**
100 * __mutex_fastpath_unlock - try to promote the count from 0 to 1
101 * @count: pointer of type atomic_t
102 * @fail_fn: function to call if the original value was not 0
103 *
104 * Try to promote the count from 0 to 1. If it wasn't 0, call <fail_fn>.
105 * In the failure case, this function is allowed to either set the value to
106 * 1, or to set it to a value lower than 1.
107 */
108static inline void
109__mutex_fastpath_unlock(atomic_t *count, void (*fail_fn)(atomic_t *))
110{
111 if (unlikely(__mutex_inc_return_unlock(count) <= 0))
112 fail_fn(count);
113}
114
115#define __mutex_slowpath_needs_to_unlock() 1
116
117/**
118 * __mutex_fastpath_trylock - try to acquire the mutex, without waiting
119 *
120 * @count: pointer of type atomic_t
121 * @fail_fn: fallback function
3 * 122 *
4 * TODO: implement optimized primitives instead, or leave the generic 123 * Change the count from 1 to 0, and return 1 (success), or if the count
5 * implementation in place, or pick the atomic_xchg() based generic 124 * was not 1, then return 0 (failure).
6 * implementation. (see asm-generic/mutex-xchg.h for details)
7 */ 125 */
126static inline int
127__mutex_fastpath_trylock(atomic_t *count, int (*fail_fn)(atomic_t *))
128{
129 if (likely(__mutex_cmpxchg_lock(count, 1, 0) == 1))
130 return 1;
131 return 0;
132}
8 133
9#include <asm-generic/mutex-dec.h> 134#endif
diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h
index 9047af7baa69..84007afabdb5 100644
--- a/arch/powerpc/include/asm/pci-bridge.h
+++ b/arch/powerpc/include/asm/pci-bridge.h
@@ -13,7 +13,6 @@
13 13
14struct device_node; 14struct device_node;
15 15
16extern unsigned int ppc_pci_flags;
17enum { 16enum {
18 /* Force re-assigning all resources (ignore firmware 17 /* Force re-assigning all resources (ignore firmware
19 * setup completely) 18 * setup completely)
@@ -36,6 +35,31 @@ enum {
36 /* ... except for domain 0 */ 35 /* ... except for domain 0 */
37 PPC_PCI_COMPAT_DOMAIN_0 = 0x00000020, 36 PPC_PCI_COMPAT_DOMAIN_0 = 0x00000020,
38}; 37};
38#ifdef CONFIG_PCI
39extern unsigned int ppc_pci_flags;
40
41static inline void ppc_pci_set_flags(int flags)
42{
43 ppc_pci_flags = flags;
44}
45
46static inline void ppc_pci_add_flags(int flags)
47{
48 ppc_pci_flags |= flags;
49}
50
51static inline int ppc_pci_has_flag(int flag)
52{
53 return (ppc_pci_flags & flag);
54}
55#else
56static inline void ppc_pci_set_flags(int flags) { }
57static inline void ppc_pci_add_flags(int flags) { }
58static inline int ppc_pci_has_flag(int flag)
59{
60 return 0;
61}
62#endif
39 63
40 64
41/* 65/*
@@ -241,9 +265,6 @@ extern void pcibios_remove_pci_devices(struct pci_bus *bus);
241 265
242/** Discover new pci devices under this bus, and add them */ 266/** Discover new pci devices under this bus, and add them */
243extern void pcibios_add_pci_devices(struct pci_bus *bus); 267extern void pcibios_add_pci_devices(struct pci_bus *bus);
244extern void pcibios_fixup_new_pci_devices(struct pci_bus *bus);
245
246extern int pcibios_remove_root_bus(struct pci_controller *phb);
247 268
248static inline struct pci_controller *pci_bus_to_host(const struct pci_bus *bus) 269static inline struct pci_controller *pci_bus_to_host(const struct pci_bus *bus)
249{ 270{
@@ -290,6 +311,7 @@ extern void pci_process_bridge_OF_ranges(struct pci_controller *hose,
290/* Allocate & free a PCI host bridge structure */ 311/* Allocate & free a PCI host bridge structure */
291extern struct pci_controller *pcibios_alloc_controller(struct device_node *dev); 312extern struct pci_controller *pcibios_alloc_controller(struct device_node *dev);
292extern void pcibios_free_controller(struct pci_controller *phb); 313extern void pcibios_free_controller(struct pci_controller *phb);
314extern void pcibios_setup_phb_resources(struct pci_controller *hose);
293 315
294#ifdef CONFIG_PCI 316#ifdef CONFIG_PCI
295extern unsigned long pci_address_to_pio(phys_addr_t address); 317extern unsigned long pci_address_to_pio(phys_addr_t address);
diff --git a/arch/powerpc/include/asm/pci.h b/arch/powerpc/include/asm/pci.h
index 57a2a494886b..3548159a1beb 100644
--- a/arch/powerpc/include/asm/pci.h
+++ b/arch/powerpc/include/asm/pci.h
@@ -38,8 +38,8 @@ struct pci_dev;
38 * Set this to 1 if you want the kernel to re-assign all PCI 38 * Set this to 1 if you want the kernel to re-assign all PCI
39 * bus numbers (don't do that on ppc64 yet !) 39 * bus numbers (don't do that on ppc64 yet !)
40 */ 40 */
41#define pcibios_assign_all_busses() (ppc_pci_flags & \ 41#define pcibios_assign_all_busses() \
42 PPC_PCI_REASSIGN_ALL_BUS) 42 (ppc_pci_has_flag(PPC_PCI_REASSIGN_ALL_BUS))
43#define pcibios_scan_all_fns(a, b) 0 43#define pcibios_scan_all_fns(a, b) 0
44 44
45static inline void pcibios_set_master(struct pci_dev *dev) 45static inline void pcibios_set_master(struct pci_dev *dev)
@@ -204,15 +204,14 @@ static inline struct resource *pcibios_select_root(struct pci_dev *pdev,
204 return root; 204 return root;
205} 205}
206 206
207extern void pcibios_setup_new_device(struct pci_dev *dev);
208
209extern void pcibios_claim_one_bus(struct pci_bus *b); 207extern void pcibios_claim_one_bus(struct pci_bus *b);
210 208
211extern void pcibios_allocate_bus_resources(struct pci_bus *bus); 209extern void pcibios_finish_adding_to_bus(struct pci_bus *bus);
212 210
213extern void pcibios_resource_survey(void); 211extern void pcibios_resource_survey(void);
214 212
215extern struct pci_controller *init_phb_dynamic(struct device_node *dn); 213extern struct pci_controller *init_phb_dynamic(struct device_node *dn);
214extern int remove_phb_dynamic(struct pci_controller *phb);
216 215
217extern struct pci_dev *of_create_pci_dev(struct device_node *node, 216extern struct pci_dev *of_create_pci_dev(struct device_node *node,
218 struct pci_bus *bus, int devfn); 217 struct pci_bus *bus, int devfn);
@@ -221,6 +220,7 @@ extern void of_scan_pci_bridge(struct device_node *node,
221 struct pci_dev *dev); 220 struct pci_dev *dev);
222 221
223extern void of_scan_bus(struct device_node *node, struct pci_bus *bus); 222extern void of_scan_bus(struct device_node *node, struct pci_bus *bus);
223extern void of_rescan_bus(struct device_node *node, struct pci_bus *bus);
224 224
225extern int pci_read_irq_line(struct pci_dev *dev); 225extern int pci_read_irq_line(struct pci_dev *dev);
226 226
@@ -235,9 +235,8 @@ extern void pci_resource_to_user(const struct pci_dev *dev, int bar,
235 const struct resource *rsrc, 235 const struct resource *rsrc,
236 resource_size_t *start, resource_size_t *end); 236 resource_size_t *start, resource_size_t *end);
237 237
238extern void pcibios_do_bus_setup(struct pci_bus *bus); 238extern void pcibios_setup_bus_devices(struct pci_bus *bus);
239extern void pcibios_fixup_of_probed_bus(struct pci_bus *bus); 239extern void pcibios_setup_bus_self(struct pci_bus *bus);
240
241 240
242#endif /* __KERNEL__ */ 241#endif /* __KERNEL__ */
243#endif /* __ASM_POWERPC_PCI_H */ 242#endif /* __ASM_POWERPC_PCI_H */
diff --git a/arch/powerpc/include/asm/pgalloc-32.h b/arch/powerpc/include/asm/pgalloc-32.h
index 58c07147b3ea..0815eb40acae 100644
--- a/arch/powerpc/include/asm/pgalloc-32.h
+++ b/arch/powerpc/include/asm/pgalloc-32.h
@@ -3,6 +3,8 @@
3 3
4#include <linux/threads.h> 4#include <linux/threads.h>
5 5
6#define PTE_NONCACHE_NUM 0 /* dummy for now to share code w/ppc64 */
7
6extern void __bad_pte(pmd_t *pmd); 8extern void __bad_pte(pmd_t *pmd);
7 9
8extern pgd_t *pgd_alloc(struct mm_struct *mm); 10extern pgd_t *pgd_alloc(struct mm_struct *mm);
@@ -33,10 +35,13 @@ extern void pgd_free(struct mm_struct *mm, pgd_t *pgd);
33 35
34extern pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr); 36extern pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr);
35extern pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long addr); 37extern pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long addr);
36extern void pte_free_kernel(struct mm_struct *mm, pte_t *pte);
37extern void pte_free(struct mm_struct *mm, pgtable_t pte);
38 38
39#define __pte_free_tlb(tlb, pte) pte_free((tlb)->mm, (pte)) 39static inline void pgtable_free(pgtable_free_t pgf)
40{
41 void *p = (void *)(pgf.val & ~PGF_CACHENUM_MASK);
42
43 free_page((unsigned long)p);
44}
40 45
41#define check_pgt_cache() do { } while (0) 46#define check_pgt_cache() do { } while (0)
42 47
diff --git a/arch/powerpc/include/asm/pgalloc-64.h b/arch/powerpc/include/asm/pgalloc-64.h
index 812a1d8f35cb..afda2bdd860f 100644
--- a/arch/powerpc/include/asm/pgalloc-64.h
+++ b/arch/powerpc/include/asm/pgalloc-64.h
@@ -7,7 +7,6 @@
7 * 2 of the License, or (at your option) any later version. 7 * 2 of the License, or (at your option) any later version.
8 */ 8 */
9 9
10#include <linux/mm.h>
11#include <linux/slab.h> 10#include <linux/slab.h>
12#include <linux/cpumask.h> 11#include <linux/cpumask.h>
13#include <linux/percpu.h> 12#include <linux/percpu.h>
@@ -108,31 +107,6 @@ static inline pgtable_t pte_alloc_one(struct mm_struct *mm,
108 return page; 107 return page;
109} 108}
110 109
111static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
112{
113 free_page((unsigned long)pte);
114}
115
116static inline void pte_free(struct mm_struct *mm, pgtable_t ptepage)
117{
118 pgtable_page_dtor(ptepage);
119 __free_page(ptepage);
120}
121
122#define PGF_CACHENUM_MASK 0x7
123
124typedef struct pgtable_free {
125 unsigned long val;
126} pgtable_free_t;
127
128static inline pgtable_free_t pgtable_free_cache(void *p, int cachenum,
129 unsigned long mask)
130{
131 BUG_ON(cachenum > PGF_CACHENUM_MASK);
132
133 return (pgtable_free_t){.val = ((unsigned long) p & ~mask) | cachenum};
134}
135
136static inline void pgtable_free(pgtable_free_t pgf) 110static inline void pgtable_free(pgtable_free_t pgf)
137{ 111{
138 void *p = (void *)(pgf.val & ~PGF_CACHENUM_MASK); 112 void *p = (void *)(pgf.val & ~PGF_CACHENUM_MASK);
@@ -144,14 +118,6 @@ static inline void pgtable_free(pgtable_free_t pgf)
144 kmem_cache_free(pgtable_cache[cachenum], p); 118 kmem_cache_free(pgtable_cache[cachenum], p);
145} 119}
146 120
147extern void pgtable_free_tlb(struct mmu_gather *tlb, pgtable_free_t pgf);
148
149#define __pte_free_tlb(tlb,ptepage) \
150do { \
151 pgtable_page_dtor(ptepage); \
152 pgtable_free_tlb(tlb, pgtable_free_cache(page_address(ptepage), \
153 PTE_NONCACHE_NUM, PTE_TABLE_SIZE-1)); \
154} while (0)
155#define __pmd_free_tlb(tlb, pmd) \ 121#define __pmd_free_tlb(tlb, pmd) \
156 pgtable_free_tlb(tlb, pgtable_free_cache(pmd, \ 122 pgtable_free_tlb(tlb, pgtable_free_cache(pmd, \
157 PMD_CACHE_NUM, PMD_TABLE_SIZE-1)) 123 PMD_CACHE_NUM, PMD_TABLE_SIZE-1))
diff --git a/arch/powerpc/include/asm/pgalloc.h b/arch/powerpc/include/asm/pgalloc.h
index b4505ed0f0f2..5d8480265a77 100644
--- a/arch/powerpc/include/asm/pgalloc.h
+++ b/arch/powerpc/include/asm/pgalloc.h
@@ -2,11 +2,52 @@
2#define _ASM_POWERPC_PGALLOC_H 2#define _ASM_POWERPC_PGALLOC_H
3#ifdef __KERNEL__ 3#ifdef __KERNEL__
4 4
5#include <linux/mm.h>
6
7static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
8{
9 free_page((unsigned long)pte);
10}
11
12static inline void pte_free(struct mm_struct *mm, pgtable_t ptepage)
13{
14 pgtable_page_dtor(ptepage);
15 __free_page(ptepage);
16}
17
18typedef struct pgtable_free {
19 unsigned long val;
20} pgtable_free_t;
21
22#define PGF_CACHENUM_MASK 0x7
23
24static inline pgtable_free_t pgtable_free_cache(void *p, int cachenum,
25 unsigned long mask)
26{
27 BUG_ON(cachenum > PGF_CACHENUM_MASK);
28
29 return (pgtable_free_t){.val = ((unsigned long) p & ~mask) | cachenum};
30}
31
5#ifdef CONFIG_PPC64 32#ifdef CONFIG_PPC64
6#include <asm/pgalloc-64.h> 33#include <asm/pgalloc-64.h>
7#else 34#else
8#include <asm/pgalloc-32.h> 35#include <asm/pgalloc-32.h>
9#endif 36#endif
10 37
38extern void pgtable_free_tlb(struct mmu_gather *tlb, pgtable_free_t pgf);
39
40#ifdef CONFIG_SMP
41#define __pte_free_tlb(tlb,ptepage) \
42do { \
43 pgtable_page_dtor(ptepage); \
44 pgtable_free_tlb(tlb, pgtable_free_cache(page_address(ptepage), \
45 PTE_NONCACHE_NUM, PTE_TABLE_SIZE-1)); \
46} while (0)
47#else
48#define __pte_free_tlb(tlb, pte) pte_free((tlb)->mm, (pte))
49#endif
50
51
11#endif /* __KERNEL__ */ 52#endif /* __KERNEL__ */
12#endif /* _ASM_POWERPC_PGALLOC_H */ 53#endif /* _ASM_POWERPC_PGALLOC_H */
diff --git a/arch/powerpc/include/asm/pgtable-ppc64.h b/arch/powerpc/include/asm/pgtable-ppc64.h
index 4c0a8c62859d..1f0a330f03f4 100644
--- a/arch/powerpc/include/asm/pgtable-ppc64.h
+++ b/arch/powerpc/include/asm/pgtable-ppc64.h
@@ -100,7 +100,7 @@
100 100
101#define _PAGE_WRENABLE (_PAGE_RW | _PAGE_DIRTY) 101#define _PAGE_WRENABLE (_PAGE_RW | _PAGE_DIRTY)
102 102
103/* __pgprot defined in arch/powerpc/incliude/asm/page.h */ 103/* __pgprot defined in arch/powerpc/include/asm/page.h */
104#define PAGE_NONE __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED) 104#define PAGE_NONE __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED)
105 105
106#define PAGE_SHARED __pgprot(_PAGE_BASE | _PAGE_RW | _PAGE_USER) 106#define PAGE_SHARED __pgprot(_PAGE_BASE | _PAGE_RW | _PAGE_USER)
diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h
index 101ed87f7d84..d3466490104a 100644
--- a/arch/powerpc/include/asm/processor.h
+++ b/arch/powerpc/include/asm/processor.h
@@ -69,8 +69,6 @@ extern int _prep_type;
69 69
70#ifdef __KERNEL__ 70#ifdef __KERNEL__
71 71
72extern int have_of;
73
74struct task_struct; 72struct task_struct;
75void start_thread(struct pt_regs *regs, unsigned long fdptr, unsigned long sp); 73void start_thread(struct pt_regs *regs, unsigned long fdptr, unsigned long sp);
76void release_thread(struct task_struct *); 74void release_thread(struct task_struct *);
@@ -207,6 +205,11 @@ struct thread_struct {
207#define INIT_SP_LIMIT \ 205#define INIT_SP_LIMIT \
208 (_ALIGN_UP(sizeof(init_thread_info), 16) + (unsigned long) &init_stack) 206 (_ALIGN_UP(sizeof(init_thread_info), 16) + (unsigned long) &init_stack)
209 207
208#ifdef CONFIG_SPE
209#define SPEFSCR_INIT .spefscr = SPEFSCR_FINVE | SPEFSCR_FDBZE | SPEFSCR_FUNFE | SPEFSCR_FOVFE,
210#else
211#define SPEFSCR_INIT
212#endif
210 213
211#ifdef CONFIG_PPC32 214#ifdef CONFIG_PPC32
212#define INIT_THREAD { \ 215#define INIT_THREAD { \
@@ -215,6 +218,7 @@ struct thread_struct {
215 .fs = KERNEL_DS, \ 218 .fs = KERNEL_DS, \
216 .pgdir = swapper_pg_dir, \ 219 .pgdir = swapper_pg_dir, \
217 .fpexc_mode = MSR_FE0 | MSR_FE1, \ 220 .fpexc_mode = MSR_FE0 | MSR_FE1, \
221 SPEFSCR_INIT \
218} 222}
219#else 223#else
220#define INIT_THREAD { \ 224#define INIT_THREAD { \
diff --git a/arch/powerpc/include/asm/ps3.h b/arch/powerpc/include/asm/ps3.h
index f9e34c493cbb..cff30c0ef1ff 100644
--- a/arch/powerpc/include/asm/ps3.h
+++ b/arch/powerpc/include/asm/ps3.h
@@ -305,30 +305,34 @@ static inline const char* ps3_result(int result)
305/* system bus routines */ 305/* system bus routines */
306 306
307enum ps3_match_id { 307enum ps3_match_id {
308 PS3_MATCH_ID_EHCI = 1, 308 PS3_MATCH_ID_EHCI = 1,
309 PS3_MATCH_ID_OHCI = 2, 309 PS3_MATCH_ID_OHCI = 2,
310 PS3_MATCH_ID_GELIC = 3, 310 PS3_MATCH_ID_GELIC = 3,
311 PS3_MATCH_ID_AV_SETTINGS = 4, 311 PS3_MATCH_ID_AV_SETTINGS = 4,
312 PS3_MATCH_ID_SYSTEM_MANAGER = 5, 312 PS3_MATCH_ID_SYSTEM_MANAGER = 5,
313 PS3_MATCH_ID_STOR_DISK = 6, 313 PS3_MATCH_ID_STOR_DISK = 6,
314 PS3_MATCH_ID_STOR_ROM = 7, 314 PS3_MATCH_ID_STOR_ROM = 7,
315 PS3_MATCH_ID_STOR_FLASH = 8, 315 PS3_MATCH_ID_STOR_FLASH = 8,
316 PS3_MATCH_ID_SOUND = 9, 316 PS3_MATCH_ID_SOUND = 9,
317 PS3_MATCH_ID_GRAPHICS = 10, 317 PS3_MATCH_ID_GPU = 10,
318 PS3_MATCH_ID_LPM = 11, 318 PS3_MATCH_ID_LPM = 11,
319}; 319};
320 320
321#define PS3_MODULE_ALIAS_EHCI "ps3:1" 321enum ps3_match_sub_id {
322#define PS3_MODULE_ALIAS_OHCI "ps3:2" 322 PS3_MATCH_SUB_ID_GPU_FB = 1,
323#define PS3_MODULE_ALIAS_GELIC "ps3:3" 323};
324#define PS3_MODULE_ALIAS_AV_SETTINGS "ps3:4" 324
325#define PS3_MODULE_ALIAS_SYSTEM_MANAGER "ps3:5" 325#define PS3_MODULE_ALIAS_EHCI "ps3:1:0"
326#define PS3_MODULE_ALIAS_STOR_DISK "ps3:6" 326#define PS3_MODULE_ALIAS_OHCI "ps3:2:0"
327#define PS3_MODULE_ALIAS_STOR_ROM "ps3:7" 327#define PS3_MODULE_ALIAS_GELIC "ps3:3:0"
328#define PS3_MODULE_ALIAS_STOR_FLASH "ps3:8" 328#define PS3_MODULE_ALIAS_AV_SETTINGS "ps3:4:0"
329#define PS3_MODULE_ALIAS_SOUND "ps3:9" 329#define PS3_MODULE_ALIAS_SYSTEM_MANAGER "ps3:5:0"
330#define PS3_MODULE_ALIAS_GRAPHICS "ps3:10" 330#define PS3_MODULE_ALIAS_STOR_DISK "ps3:6:0"
331#define PS3_MODULE_ALIAS_LPM "ps3:11" 331#define PS3_MODULE_ALIAS_STOR_ROM "ps3:7:0"
332#define PS3_MODULE_ALIAS_STOR_FLASH "ps3:8:0"
333#define PS3_MODULE_ALIAS_SOUND "ps3:9:0"
334#define PS3_MODULE_ALIAS_GPU_FB "ps3:10:1"
335#define PS3_MODULE_ALIAS_LPM "ps3:11:0"
332 336
333enum ps3_system_bus_device_type { 337enum ps3_system_bus_device_type {
334 PS3_DEVICE_TYPE_IOC0 = 1, 338 PS3_DEVICE_TYPE_IOC0 = 1,
@@ -337,11 +341,6 @@ enum ps3_system_bus_device_type {
337 PS3_DEVICE_TYPE_LPM, 341 PS3_DEVICE_TYPE_LPM,
338}; 342};
339 343
340enum ps3_match_sub_id {
341 /* for PS3_MATCH_ID_GRAPHICS */
342 PS3_MATCH_SUB_ID_FB = 1,
343};
344
345/** 344/**
346 * struct ps3_system_bus_device - a device on the system bus 345 * struct ps3_system_bus_device - a device on the system bus
347 */ 346 */
@@ -516,4 +515,7 @@ void ps3_sync_irq(int node);
516u32 ps3_get_hw_thread_id(int cpu); 515u32 ps3_get_hw_thread_id(int cpu);
517u64 ps3_get_spe_id(void *arg); 516u64 ps3_get_spe_id(void *arg);
518 517
518/* mutex synchronizing GPU accesses and video mode changes */
519extern struct mutex ps3_gpu_mutex;
520
519#endif 521#endif
diff --git a/arch/powerpc/include/asm/ps3av.h b/arch/powerpc/include/asm/ps3av.h
index 5aa22cffdbd6..cd24ac16660a 100644
--- a/arch/powerpc/include/asm/ps3av.h
+++ b/arch/powerpc/include/asm/ps3av.h
@@ -740,8 +740,4 @@ extern int ps3av_audio_mute(int);
740extern int ps3av_audio_mute_analog(int); 740extern int ps3av_audio_mute_analog(int);
741extern int ps3av_dev_open(void); 741extern int ps3av_dev_open(void);
742extern int ps3av_dev_close(void); 742extern int ps3av_dev_close(void);
743extern void ps3av_register_flip_ctl(void (*flip_ctl)(int on, void *data),
744 void *flip_data);
745extern void ps3av_flip_ctl(int on);
746
747#endif /* _ASM_POWERPC_PS3AV_H_ */ 743#endif /* _ASM_POWERPC_PS3AV_H_ */
diff --git a/arch/powerpc/include/asm/rtas.h b/arch/powerpc/include/asm/rtas.h
index 8eaa7b28d9d0..e0175beb4462 100644
--- a/arch/powerpc/include/asm/rtas.h
+++ b/arch/powerpc/include/asm/rtas.h
@@ -168,6 +168,7 @@ extern void rtas_os_term(char *str);
168extern int rtas_get_sensor(int sensor, int index, int *state); 168extern int rtas_get_sensor(int sensor, int index, int *state);
169extern int rtas_get_power_level(int powerdomain, int *level); 169extern int rtas_get_power_level(int powerdomain, int *level);
170extern int rtas_set_power_level(int powerdomain, int level, int *setlevel); 170extern int rtas_set_power_level(int powerdomain, int level, int *setlevel);
171extern bool rtas_indicator_present(int token, int *maxindex);
171extern int rtas_set_indicator(int indicator, int index, int new_value); 172extern int rtas_set_indicator(int indicator, int index, int new_value);
172extern int rtas_set_indicator_fast(int indicator, int index, int new_value); 173extern int rtas_set_indicator_fast(int indicator, int index, int new_value);
173extern void rtas_progress(char *s, unsigned short hex); 174extern void rtas_progress(char *s, unsigned short hex);
diff --git a/arch/powerpc/include/asm/sfp-machine.h b/arch/powerpc/include/asm/sfp-machine.h
index ced34f1dc8f8..3d9f831c3c55 100644
--- a/arch/powerpc/include/asm/sfp-machine.h
+++ b/arch/powerpc/include/asm/sfp-machine.h
@@ -82,7 +82,7 @@
82#define _FP_MUL_MEAT_S(R,X,Y) _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S,R,X,Y,umul_ppmm) 82#define _FP_MUL_MEAT_S(R,X,Y) _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S,R,X,Y,umul_ppmm)
83#define _FP_MUL_MEAT_D(R,X,Y) _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm) 83#define _FP_MUL_MEAT_D(R,X,Y) _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm)
84 84
85#define _FP_DIV_MEAT_S(R,X,Y) _FP_DIV_MEAT_1_udiv(S,R,X,Y) 85#define _FP_DIV_MEAT_S(R,X,Y) _FP_DIV_MEAT_1_udiv_norm(S,R,X,Y)
86#define _FP_DIV_MEAT_D(R,X,Y) _FP_DIV_MEAT_2_udiv(D,R,X,Y) 86#define _FP_DIV_MEAT_D(R,X,Y) _FP_DIV_MEAT_2_udiv(D,R,X,Y)
87 87
88/* These macros define what NaN looks like. They're supposed to expand to 88/* These macros define what NaN looks like. They're supposed to expand to
@@ -97,6 +97,20 @@
97 97
98#define _FP_KEEPNANFRACP 1 98#define _FP_KEEPNANFRACP 1
99 99
100#ifdef FP_EX_BOOKE_E500_SPE
101#define FP_EX_INEXACT (1 << 21)
102#define FP_EX_INVALID (1 << 20)
103#define FP_EX_DIVZERO (1 << 19)
104#define FP_EX_UNDERFLOW (1 << 18)
105#define FP_EX_OVERFLOW (1 << 17)
106#define FP_INHIBIT_RESULTS 0
107
108#define __FPU_FPSCR (current->thread.spefscr)
109#define __FPU_ENABLED_EXC \
110({ \
111 (__FPU_FPSCR >> 2) & 0x1f; \
112})
113#else
100/* Exception flags. We use the bit positions of the appropriate bits 114/* Exception flags. We use the bit positions of the appropriate bits
101 in the FPSCR, which also correspond to the FE_* bits. This makes 115 in the FPSCR, which also correspond to the FE_* bits. This makes
102 everything easier ;-). */ 116 everything easier ;-). */
@@ -111,22 +125,6 @@
111#define FP_EX_DIVZERO (1 << (31 - 5)) 125#define FP_EX_DIVZERO (1 << (31 - 5))
112#define FP_EX_INEXACT (1 << (31 - 6)) 126#define FP_EX_INEXACT (1 << (31 - 6))
113 127
114/* This macro appears to be called when both X and Y are NaNs, and
115 * has to choose one and copy it to R. i386 goes for the larger of the
116 * two, sparc64 just picks Y. I don't understand this at all so I'll
117 * go with sparc64 because it's shorter :-> -- PMM
118 */
119#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP) \
120 do { \
121 R##_s = Y##_s; \
122 _FP_FRAC_COPY_##wc(R,Y); \
123 R##_c = FP_CLS_NAN; \
124 } while (0)
125
126
127#include <linux/kernel.h>
128#include <linux/sched.h>
129
130#define __FPU_FPSCR (current->thread.fpscr.val) 128#define __FPU_FPSCR (current->thread.fpscr.val)
131 129
132/* We only actually write to the destination register 130/* We only actually write to the destination register
@@ -137,6 +135,32 @@
137 (__FPU_FPSCR >> 3) & 0x1f; \ 135 (__FPU_FPSCR >> 3) & 0x1f; \
138}) 136})
139 137
138#endif
139
140/*
141 * If one NaN is signaling and the other is not,
142 * we choose that one, otherwise we choose X.
143 */
144#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP) \
145 do { \
146 if ((_FP_FRAC_HIGH_RAW_##fs(Y) & _FP_QNANBIT_##fs) \
147 && !(_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs)) \
148 { \
149 R##_s = X##_s; \
150 _FP_FRAC_COPY_##wc(R,X); \
151 } \
152 else \
153 { \
154 R##_s = Y##_s; \
155 _FP_FRAC_COPY_##wc(R,Y); \
156 } \
157 R##_c = FP_CLS_NAN; \
158 } while (0)
159
160
161#include <linux/kernel.h>
162#include <linux/sched.h>
163
140#define __FPU_TRAP_P(bits) \ 164#define __FPU_TRAP_P(bits) \
141 ((__FPU_ENABLED_EXC & (bits)) != 0) 165 ((__FPU_ENABLED_EXC & (bits)) != 0)
142 166
diff --git a/arch/powerpc/include/asm/smp.h b/arch/powerpc/include/asm/smp.h
index 1866cec4f967..c25f73d1d842 100644
--- a/arch/powerpc/include/asm/smp.h
+++ b/arch/powerpc/include/asm/smp.h
@@ -81,6 +81,13 @@ extern int cpu_to_core_id(int cpu);
81#define PPC_MSG_CALL_FUNC_SINGLE 2 81#define PPC_MSG_CALL_FUNC_SINGLE 2
82#define PPC_MSG_DEBUGGER_BREAK 3 82#define PPC_MSG_DEBUGGER_BREAK 3
83 83
84/*
85 * irq controllers that have dedicated ipis per message and don't
86 * need additional code in the action handler may use this
87 */
88extern int smp_request_message_ipi(int virq, int message);
89extern const char *smp_ipi_name[];
90
84void smp_init_iSeries(void); 91void smp_init_iSeries(void);
85void smp_init_pSeries(void); 92void smp_init_pSeries(void);
86void smp_init_cell(void); 93void smp_init_cell(void);
diff --git a/arch/powerpc/include/asm/spinlock.h b/arch/powerpc/include/asm/spinlock.h
index f56a843f4705..36864364e601 100644
--- a/arch/powerpc/include/asm/spinlock.h
+++ b/arch/powerpc/include/asm/spinlock.h
@@ -277,7 +277,7 @@ static inline void __raw_read_unlock(raw_rwlock_t *rw)
277 bne- 1b" 277 bne- 1b"
278 : "=&r"(tmp) 278 : "=&r"(tmp)
279 : "r"(&rw->lock) 279 : "r"(&rw->lock)
280 : "cr0", "memory"); 280 : "cr0", "xer", "memory");
281} 281}
282 282
283static inline void __raw_write_unlock(raw_rwlock_t *rw) 283static inline void __raw_write_unlock(raw_rwlock_t *rw)
diff --git a/arch/powerpc/include/asm/synch.h b/arch/powerpc/include/asm/synch.h
index 45963e80f557..28f6ddbff4cf 100644
--- a/arch/powerpc/include/asm/synch.h
+++ b/arch/powerpc/include/asm/synch.h
@@ -5,6 +5,10 @@
5#include <linux/stringify.h> 5#include <linux/stringify.h>
6#include <asm/feature-fixups.h> 6#include <asm/feature-fixups.h>
7 7
8#if defined(__powerpc64__) || defined(CONFIG_PPC_E500MC)
9#define __SUBARCH_HAS_LWSYNC
10#endif
11
8#ifndef __ASSEMBLY__ 12#ifndef __ASSEMBLY__
9extern unsigned int __start___lwsync_fixup, __stop___lwsync_fixup; 13extern unsigned int __start___lwsync_fixup, __stop___lwsync_fixup;
10extern void do_lwsync_fixups(unsigned long value, void *fixup_start, 14extern void do_lwsync_fixups(unsigned long value, void *fixup_start,
diff --git a/arch/powerpc/include/asm/system.h b/arch/powerpc/include/asm/system.h
index d6648c143322..2a4be19a92c4 100644
--- a/arch/powerpc/include/asm/system.h
+++ b/arch/powerpc/include/asm/system.h
@@ -23,15 +23,17 @@
23 * read_barrier_depends() prevents data-dependent loads being reordered 23 * read_barrier_depends() prevents data-dependent loads being reordered
24 * across this point (nop on PPC). 24 * across this point (nop on PPC).
25 * 25 *
26 * We have to use the sync instructions for mb(), since lwsync doesn't 26 * *mb() variants without smp_ prefix must order all types of memory
27 * order loads with respect to previous stores. Lwsync is fine for 27 * operations with one another. sync is the only instruction sufficient
28 * rmb(), though. Note that rmb() actually uses a sync on 32-bit 28 * to do this.
29 * architectures.
30 * 29 *
31 * For wmb(), we use sync since wmb is used in drivers to order 30 * For the smp_ barriers, ordering is for cacheable memory operations
32 * stores to system memory with respect to writes to the device. 31 * only. We have to use the sync instruction for smp_mb(), since lwsync
33 * However, smp_wmb() can be a lighter-weight lwsync or eieio barrier 32 * doesn't order loads with respect to previous stores. Lwsync can be
34 * on SMP since it is only used to order updates to system memory. 33 * used for smp_rmb() and smp_wmb().
34 *
35 * However, on CPUs that don't support lwsync, lwsync actually maps to a
36 * heavy-weight sync, so smp_wmb() can be a lighter-weight eieio.
35 */ 37 */
36#define mb() __asm__ __volatile__ ("sync" : : : "memory") 38#define mb() __asm__ __volatile__ ("sync" : : : "memory")
37#define rmb() __asm__ __volatile__ ("sync" : : : "memory") 39#define rmb() __asm__ __volatile__ ("sync" : : : "memory")
@@ -45,14 +47,14 @@
45#ifdef CONFIG_SMP 47#ifdef CONFIG_SMP
46 48
47#ifdef __SUBARCH_HAS_LWSYNC 49#ifdef __SUBARCH_HAS_LWSYNC
48# define SMPWMB lwsync 50# define SMPWMB LWSYNC
49#else 51#else
50# define SMPWMB eieio 52# define SMPWMB eieio
51#endif 53#endif
52 54
53#define smp_mb() mb() 55#define smp_mb() mb()
54#define smp_rmb() rmb() 56#define smp_rmb() __asm__ __volatile__ (stringify_in_c(LWSYNC) : : :"memory")
55#define smp_wmb() __asm__ __volatile__ (__stringify(SMPWMB) : : :"memory") 57#define smp_wmb() __asm__ __volatile__ (stringify_in_c(SMPWMB) : : :"memory")
56#define smp_read_barrier_depends() read_barrier_depends() 58#define smp_read_barrier_depends() read_barrier_depends()
57#else 59#else
58#define smp_mb() barrier() 60#define smp_mb() barrier()
diff --git a/arch/powerpc/include/asm/time.h b/arch/powerpc/include/asm/time.h
index febd581ec9b0..27ccb764fdab 100644
--- a/arch/powerpc/include/asm/time.h
+++ b/arch/powerpc/include/asm/time.h
@@ -48,26 +48,6 @@ extern unsigned long ppc_proc_freq;
48extern unsigned long ppc_tb_freq; 48extern unsigned long ppc_tb_freq;
49#define DEFAULT_TB_FREQ 125000000UL 49#define DEFAULT_TB_FREQ 125000000UL
50 50
51/*
52 * By putting all of this stuff into a single struct we
53 * reduce the number of cache lines touched by do_gettimeofday.
54 * Both by collecting all of the data in one cache line and
55 * by touching only one TOC entry on ppc64.
56 */
57struct gettimeofday_vars {
58 u64 tb_to_xs;
59 u64 stamp_xsec;
60 u64 tb_orig_stamp;
61};
62
63struct gettimeofday_struct {
64 unsigned long tb_ticks_per_sec;
65 struct gettimeofday_vars vars[2];
66 struct gettimeofday_vars * volatile varp;
67 unsigned var_idx;
68 unsigned tb_to_us;
69};
70
71struct div_result { 51struct div_result {
72 u64 result_high; 52 u64 result_high;
73 u64 result_low; 53 u64 result_low;
diff --git a/arch/powerpc/include/asm/tlbflush.h b/arch/powerpc/include/asm/tlbflush.h
index a2c6bfd85fb7..333c24b54379 100644
--- a/arch/powerpc/include/asm/tlbflush.h
+++ b/arch/powerpc/include/asm/tlbflush.h
@@ -6,6 +6,7 @@
6 * 6 *
7 * - flush_tlb_mm(mm) flushes the specified mm context TLB's 7 * - flush_tlb_mm(mm) flushes the specified mm context TLB's
8 * - flush_tlb_page(vma, vmaddr) flushes one page 8 * - flush_tlb_page(vma, vmaddr) flushes one page
9 * - local_flush_tlb_page(vmaddr) flushes one page on the local processor
9 * - flush_tlb_page_nohash(vma, vmaddr) flushes one page if SW loaded TLB 10 * - flush_tlb_page_nohash(vma, vmaddr) flushes one page if SW loaded TLB
10 * - flush_tlb_range(vma, start, end) flushes a range of pages 11 * - flush_tlb_range(vma, start, end) flushes a range of pages
11 * - flush_tlb_kernel_range(start, end) flushes a range of kernel pages 12 * - flush_tlb_kernel_range(start, end) flushes a range of kernel pages
@@ -39,11 +40,21 @@ extern void _tlbil_va(unsigned long address, unsigned int pid);
39extern void _tlbia(void); 40extern void _tlbia(void);
40#endif 41#endif
41 42
43static inline void local_flush_tlb_mm(struct mm_struct *mm)
44{
45 _tlbil_pid(mm->context.id);
46}
47
42static inline void flush_tlb_mm(struct mm_struct *mm) 48static inline void flush_tlb_mm(struct mm_struct *mm)
43{ 49{
44 _tlbil_pid(mm->context.id); 50 _tlbil_pid(mm->context.id);
45} 51}
46 52
53static inline void local_flush_tlb_page(unsigned long vmaddr)
54{
55 _tlbil_va(vmaddr, 0);
56}
57
47static inline void flush_tlb_page(struct vm_area_struct *vma, 58static inline void flush_tlb_page(struct vm_area_struct *vma,
48 unsigned long vmaddr) 59 unsigned long vmaddr)
49{ 60{
@@ -81,6 +92,10 @@ extern void flush_tlb_page_nohash(struct vm_area_struct *vma, unsigned long addr
81extern void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, 92extern void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
82 unsigned long end); 93 unsigned long end);
83extern void flush_tlb_kernel_range(unsigned long start, unsigned long end); 94extern void flush_tlb_kernel_range(unsigned long start, unsigned long end);
95static inline void local_flush_tlb_page(unsigned long vmaddr)
96{
97 flush_tlb_page(NULL, vmaddr);
98}
84 99
85#else 100#else
86/* 101/*
@@ -138,6 +153,10 @@ static inline void flush_tlb_mm(struct mm_struct *mm)
138{ 153{
139} 154}
140 155
156static inline void local_flush_tlb_page(unsigned long vmaddr)
157{
158}
159
141static inline void flush_tlb_page(struct vm_area_struct *vma, 160static inline void flush_tlb_page(struct vm_area_struct *vma,
142 unsigned long vmaddr) 161 unsigned long vmaddr)
143{ 162{
diff --git a/arch/powerpc/include/asm/vdso_datapage.h b/arch/powerpc/include/asm/vdso_datapage.h
index f01393224b52..13c2c283e178 100644
--- a/arch/powerpc/include/asm/vdso_datapage.h
+++ b/arch/powerpc/include/asm/vdso_datapage.h
@@ -39,6 +39,7 @@
39#ifndef __ASSEMBLY__ 39#ifndef __ASSEMBLY__
40 40
41#include <linux/unistd.h> 41#include <linux/unistd.h>
42#include <linux/time.h>
42 43
43#define SYSCALL_MAP_SIZE ((__NR_syscalls + 31) / 32) 44#define SYSCALL_MAP_SIZE ((__NR_syscalls + 31) / 32)
44 45
@@ -83,6 +84,7 @@ struct vdso_data {
83 __u32 icache_log_block_size; /* L1 i-cache log block size */ 84 __u32 icache_log_block_size; /* L1 i-cache log block size */
84 __s32 wtom_clock_sec; /* Wall to monotonic clock */ 85 __s32 wtom_clock_sec; /* Wall to monotonic clock */
85 __s32 wtom_clock_nsec; 86 __s32 wtom_clock_nsec;
87 struct timespec stamp_xtime; /* xtime as at tb_orig_stamp */
86 __u32 syscall_map_64[SYSCALL_MAP_SIZE]; /* map of syscalls */ 88 __u32 syscall_map_64[SYSCALL_MAP_SIZE]; /* map of syscalls */
87 __u32 syscall_map_32[SYSCALL_MAP_SIZE]; /* map of syscalls */ 89 __u32 syscall_map_32[SYSCALL_MAP_SIZE]; /* map of syscalls */
88}; 90};
@@ -102,6 +104,7 @@ struct vdso_data {
102 __u32 tz_dsttime; /* Type of dst correction 0x5C */ 104 __u32 tz_dsttime; /* Type of dst correction 0x5C */
103 __s32 wtom_clock_sec; /* Wall to monotonic clock */ 105 __s32 wtom_clock_sec; /* Wall to monotonic clock */
104 __s32 wtom_clock_nsec; 106 __s32 wtom_clock_nsec;
107 struct timespec stamp_xtime; /* xtime as at tb_orig_stamp */
105 __u32 syscall_map_32[SYSCALL_MAP_SIZE]; /* map of syscalls */ 108 __u32 syscall_map_32[SYSCALL_MAP_SIZE]; /* map of syscalls */
106 __u32 dcache_block_size; /* L1 d-cache block size */ 109 __u32 dcache_block_size; /* L1 d-cache block size */
107 __u32 icache_block_size; /* L1 i-cache block size */ 110 __u32 icache_block_size; /* L1 i-cache block size */
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index 75c5dd0138fd..050abfd5c17c 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -306,6 +306,7 @@ int main(void)
306 DEFINE(CFG_SYSCALL_MAP32, offsetof(struct vdso_data, syscall_map_32)); 306 DEFINE(CFG_SYSCALL_MAP32, offsetof(struct vdso_data, syscall_map_32));
307 DEFINE(WTOM_CLOCK_SEC, offsetof(struct vdso_data, wtom_clock_sec)); 307 DEFINE(WTOM_CLOCK_SEC, offsetof(struct vdso_data, wtom_clock_sec));
308 DEFINE(WTOM_CLOCK_NSEC, offsetof(struct vdso_data, wtom_clock_nsec)); 308 DEFINE(WTOM_CLOCK_NSEC, offsetof(struct vdso_data, wtom_clock_nsec));
309 DEFINE(STAMP_XTIME, offsetof(struct vdso_data, stamp_xtime));
309 DEFINE(CFG_ICACHE_BLOCKSZ, offsetof(struct vdso_data, icache_block_size)); 310 DEFINE(CFG_ICACHE_BLOCKSZ, offsetof(struct vdso_data, icache_block_size));
310 DEFINE(CFG_DCACHE_BLOCKSZ, offsetof(struct vdso_data, dcache_block_size)); 311 DEFINE(CFG_DCACHE_BLOCKSZ, offsetof(struct vdso_data, dcache_block_size));
311 DEFINE(CFG_ICACHE_LOGBLOCKSZ, offsetof(struct vdso_data, icache_log_block_size)); 312 DEFINE(CFG_ICACHE_LOGBLOCKSZ, offsetof(struct vdso_data, icache_log_block_size));
diff --git a/arch/powerpc/kernel/dma.c b/arch/powerpc/kernel/dma.c
index 3a6eaa876ee1..1c5c8a6fc129 100644
--- a/arch/powerpc/kernel/dma.c
+++ b/arch/powerpc/kernel/dma.c
@@ -120,6 +120,26 @@ static inline void dma_direct_unmap_page(struct device *dev,
120{ 120{
121} 121}
122 122
123#ifdef CONFIG_NOT_COHERENT_CACHE
124static inline void dma_direct_sync_sg(struct device *dev,
125 struct scatterlist *sgl, int nents,
126 enum dma_data_direction direction)
127{
128 struct scatterlist *sg;
129 int i;
130
131 for_each_sg(sgl, sg, nents, i)
132 __dma_sync_page(sg_page(sg), sg->offset, sg->length, direction);
133}
134
135static inline void dma_direct_sync_single_range(struct device *dev,
136 dma_addr_t dma_handle, unsigned long offset, size_t size,
137 enum dma_data_direction direction)
138{
139 __dma_sync(bus_to_virt(dma_handle+offset), size, direction);
140}
141#endif
142
123struct dma_mapping_ops dma_direct_ops = { 143struct dma_mapping_ops dma_direct_ops = {
124 .alloc_coherent = dma_direct_alloc_coherent, 144 .alloc_coherent = dma_direct_alloc_coherent,
125 .free_coherent = dma_direct_free_coherent, 145 .free_coherent = dma_direct_free_coherent,
@@ -128,5 +148,11 @@ struct dma_mapping_ops dma_direct_ops = {
128 .dma_supported = dma_direct_dma_supported, 148 .dma_supported = dma_direct_dma_supported,
129 .map_page = dma_direct_map_page, 149 .map_page = dma_direct_map_page,
130 .unmap_page = dma_direct_unmap_page, 150 .unmap_page = dma_direct_unmap_page,
151#ifdef CONFIG_NOT_COHERENT_CACHE
152 .sync_single_range_for_cpu = dma_direct_sync_single_range,
153 .sync_single_range_for_device = dma_direct_sync_single_range,
154 .sync_sg_for_cpu = dma_direct_sync_sg,
155 .sync_sg_for_device = dma_direct_sync_sg,
156#endif
131}; 157};
132EXPORT_SYMBOL(dma_direct_ops); 158EXPORT_SYMBOL(dma_direct_ops);
diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S
index 590304c24dad..9a4639c459e6 100644
--- a/arch/powerpc/kernel/head_fsl_booke.S
+++ b/arch/powerpc/kernel/head_fsl_booke.S
@@ -92,6 +92,7 @@ _ENTRY(_start);
92 * if needed 92 * if needed
93 */ 93 */
94 94
95_ENTRY(__early_start)
95/* 1. Find the index of the entry we're executing in */ 96/* 1. Find the index of the entry we're executing in */
96 bl invstr /* Find our address */ 97 bl invstr /* Find our address */
97invstr: mflr r6 /* Make it accessible */ 98invstr: mflr r6 /* Make it accessible */
@@ -235,36 +236,40 @@ skpinv: addi r6,r6,1 /* Increment */
235 tlbivax 0,r9 236 tlbivax 0,r9
236 TLBSYNC 237 TLBSYNC
237 238
239/* The mapping only needs to be cache-coherent on SMP */
240#ifdef CONFIG_SMP
241#define M_IF_SMP MAS2_M
242#else
243#define M_IF_SMP 0
244#endif
245
238/* 6. Setup KERNELBASE mapping in TLB1[0] */ 246/* 6. Setup KERNELBASE mapping in TLB1[0] */
239 lis r6,0x1000 /* Set MAS0(TLBSEL) = TLB1(1), ESEL = 0 */ 247 lis r6,0x1000 /* Set MAS0(TLBSEL) = TLB1(1), ESEL = 0 */
240 mtspr SPRN_MAS0,r6 248 mtspr SPRN_MAS0,r6
241 lis r6,(MAS1_VALID|MAS1_IPROT)@h 249 lis r6,(MAS1_VALID|MAS1_IPROT)@h
242 ori r6,r6,(MAS1_TSIZE(BOOKE_PAGESZ_64M))@l 250 ori r6,r6,(MAS1_TSIZE(BOOKE_PAGESZ_64M))@l
243 mtspr SPRN_MAS1,r6 251 mtspr SPRN_MAS1,r6
244 li r7,0 252 lis r6,MAS2_VAL(PAGE_OFFSET, BOOKE_PAGESZ_64M, M_IF_SMP)@h
245 lis r6,PAGE_OFFSET@h 253 ori r6,r6,MAS2_VAL(PAGE_OFFSET, BOOKE_PAGESZ_64M, M_IF_SMP)@l
246 ori r6,r6,PAGE_OFFSET@l
247 rlwimi r6,r7,0,20,31
248 mtspr SPRN_MAS2,r6 254 mtspr SPRN_MAS2,r6
249 mtspr SPRN_MAS3,r8 255 mtspr SPRN_MAS3,r8
250 tlbwe 256 tlbwe
251 257
252/* 7. Jump to KERNELBASE mapping */ 258/* 7. Jump to KERNELBASE mapping */
253 lis r6,KERNELBASE@h 259 lis r6,(KERNELBASE & ~0xfff)@h
254 ori r6,r6,KERNELBASE@l 260 ori r6,r6,(KERNELBASE & ~0xfff)@l
255 rlwimi r6,r7,0,20,31
256 lis r7,MSR_KERNEL@h 261 lis r7,MSR_KERNEL@h
257 ori r7,r7,MSR_KERNEL@l 262 ori r7,r7,MSR_KERNEL@l
258 bl 1f /* Find our address */ 263 bl 1f /* Find our address */
2591: mflr r9 2641: mflr r9
260 rlwimi r6,r9,0,20,31 265 rlwimi r6,r9,0,20,31
261 addi r6,r6,24 266 addi r6,r6,(2f - 1b)
262 mtspr SPRN_SRR0,r6 267 mtspr SPRN_SRR0,r6
263 mtspr SPRN_SRR1,r7 268 mtspr SPRN_SRR1,r7
264 rfi /* start execution out of TLB1[0] entry */ 269 rfi /* start execution out of TLB1[0] entry */
265 270
266/* 8. Clear out the temp mapping */ 271/* 8. Clear out the temp mapping */
267 lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */ 2722: lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */
268 rlwimi r7,r5,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r5) */ 273 rlwimi r7,r5,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r5) */
269 mtspr SPRN_MAS0,r7 274 mtspr SPRN_MAS0,r7
270 tlbre 275 tlbre
@@ -344,6 +349,15 @@ skpinv: addi r6,r6,1 /* Increment */
344 mtspr SPRN_DBSR,r2 349 mtspr SPRN_DBSR,r2
345#endif 350#endif
346 351
352#ifdef CONFIG_SMP
353 /* Check to see if we're the second processor, and jump
354 * to the secondary_start code if so
355 */
356 mfspr r24,SPRN_PIR
357 cmpwi r24,0
358 bne __secondary_start
359#endif
360
347 /* 361 /*
348 * This is where the main kernel code starts. 362 * This is where the main kernel code starts.
349 */ 363 */
@@ -685,12 +699,13 @@ interrupt_base:
685 /* SPE Floating Point Data */ 699 /* SPE Floating Point Data */
686#ifdef CONFIG_SPE 700#ifdef CONFIG_SPE
687 EXCEPTION(0x2030, SPEFloatingPointData, SPEFloatingPointException, EXC_XFER_EE); 701 EXCEPTION(0x2030, SPEFloatingPointData, SPEFloatingPointException, EXC_XFER_EE);
688#else
689 EXCEPTION(0x2040, SPEFloatingPointData, unknown_exception, EXC_XFER_EE)
690#endif /* CONFIG_SPE */
691 702
692 /* SPE Floating Point Round */ 703 /* SPE Floating Point Round */
704 EXCEPTION(0x2050, SPEFloatingPointRound, SPEFloatingPointRoundException, EXC_XFER_EE)
705#else
706 EXCEPTION(0x2040, SPEFloatingPointData, unknown_exception, EXC_XFER_EE)
693 EXCEPTION(0x2050, SPEFloatingPointRound, unknown_exception, EXC_XFER_EE) 707 EXCEPTION(0x2050, SPEFloatingPointRound, unknown_exception, EXC_XFER_EE)
708#endif /* CONFIG_SPE */
694 709
695 /* Performance Monitor */ 710 /* Performance Monitor */
696 EXCEPTION(0x2060, PerformanceMonitor, performance_monitor_exception, EXC_XFER_STD) 711 EXCEPTION(0x2060, PerformanceMonitor, performance_monitor_exception, EXC_XFER_STD)
@@ -735,6 +750,9 @@ finish_tlb_load:
735#else 750#else
736 rlwimi r12, r11, 26, 27, 31 /* extract WIMGE from pte */ 751 rlwimi r12, r11, 26, 27, 31 /* extract WIMGE from pte */
737#endif 752#endif
753#ifdef CONFIG_SMP
754 ori r12, r12, MAS2_M
755#endif
738 mtspr SPRN_MAS2, r12 756 mtspr SPRN_MAS2, r12
739 757
740 li r10, (_PAGE_HWEXEC | _PAGE_PRESENT) 758 li r10, (_PAGE_HWEXEC | _PAGE_PRESENT)
@@ -746,7 +764,7 @@ finish_tlb_load:
746 iseleq r12, r12, r10 764 iseleq r12, r12, r10
747 765
748#ifdef CONFIG_PTE_64BIT 766#ifdef CONFIG_PTE_64BIT
7492: rlwimi r12, r13, 24, 0, 7 /* grab RPN[32:39] */ 767 rlwimi r12, r13, 24, 0, 7 /* grab RPN[32:39] */
750 rlwimi r12, r11, 24, 8, 19 /* grab RPN[40:51] */ 768 rlwimi r12, r11, 24, 8, 19 /* grab RPN[40:51] */
751 mtspr SPRN_MAS3, r12 769 mtspr SPRN_MAS3, r12
752BEGIN_FTR_SECTION 770BEGIN_FTR_SECTION
@@ -754,7 +772,7 @@ BEGIN_FTR_SECTION
754 mtspr SPRN_MAS7, r10 772 mtspr SPRN_MAS7, r10
755END_FTR_SECTION_IFSET(CPU_FTR_BIG_PHYS) 773END_FTR_SECTION_IFSET(CPU_FTR_BIG_PHYS)
756#else 774#else
7572: rlwimi r11, r12, 0, 20, 31 /* Extract RPN from PTE and merge with perms */ 775 rlwimi r11, r12, 0, 20, 31 /* Extract RPN from PTE and merge with perms */
758 mtspr SPRN_MAS3, r11 776 mtspr SPRN_MAS3, r11
759#endif 777#endif
760#ifdef CONFIG_E200 778#ifdef CONFIG_E200
@@ -1037,6 +1055,63 @@ _GLOBAL(flush_dcache_L1)
1037 1055
1038 blr 1056 blr
1039 1057
1058#ifdef CONFIG_SMP
1059/* When we get here, r24 needs to hold the CPU # */
1060 .globl __secondary_start
1061__secondary_start:
1062 lis r3,__secondary_hold_acknowledge@h
1063 ori r3,r3,__secondary_hold_acknowledge@l
1064 stw r24,0(r3)
1065
1066 li r3,0
1067 mr r4,r24 /* Why? */
1068 bl call_setup_cpu
1069
1070 lis r3,tlbcam_index@ha
1071 lwz r3,tlbcam_index@l(r3)
1072 mtctr r3
1073 li r26,0 /* r26 safe? */
1074
1075 /* Load each CAM entry */
10761: mr r3,r26
1077 bl loadcam_entry
1078 addi r26,r26,1
1079 bdnz 1b
1080
1081 /* get current_thread_info and current */
1082 lis r1,secondary_ti@ha
1083 lwz r1,secondary_ti@l(r1)
1084 lwz r2,TI_TASK(r1)
1085
1086 /* stack */
1087 addi r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD
1088 li r0,0
1089 stw r0,0(r1)
1090
1091 /* ptr to current thread */
1092 addi r4,r2,THREAD /* address of our thread_struct */
1093 mtspr SPRN_SPRG3,r4
1094
1095 /* Setup the defaults for TLB entries */
1096 li r4,(MAS4_TSIZED(BOOKE_PAGESZ_4K))@l
1097 mtspr SPRN_MAS4,r4
1098
1099 /* Jump to start_secondary */
1100 lis r4,MSR_KERNEL@h
1101 ori r4,r4,MSR_KERNEL@l
1102 lis r3,start_secondary@h
1103 ori r3,r3,start_secondary@l
1104 mtspr SPRN_SRR0,r3
1105 mtspr SPRN_SRR1,r4
1106 sync
1107 rfi
1108 sync
1109
1110 .globl __secondary_hold_acknowledge
1111__secondary_hold_acknowledge:
1112 .long -1
1113#endif
1114
1040/* 1115/*
1041 * We put a few things here that have to be page-aligned. This stuff 1116 * We put a few things here that have to be page-aligned. This stuff
1042 * goes at the beginning of the data segment, which is page-aligned. 1117 * goes at the beginning of the data segment, which is page-aligned.
diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c
index 64299d28f364..6e3f62493659 100644
--- a/arch/powerpc/kernel/ibmebus.c
+++ b/arch/powerpc/kernel/ibmebus.c
@@ -47,7 +47,7 @@
47#include <asm/abs_addr.h> 47#include <asm/abs_addr.h>
48 48
49static struct device ibmebus_bus_device = { /* fake "parent" device */ 49static struct device ibmebus_bus_device = { /* fake "parent" device */
50 .bus_id = "ibmebus", 50 .init_name = "ibmebus",
51}; 51};
52 52
53struct bus_type ibmebus_bus_type; 53struct bus_type ibmebus_bus_type;
@@ -231,6 +231,7 @@ void ibmebus_free_irq(u32 ist, void *dev_id)
231 unsigned int irq = irq_find_mapping(NULL, ist); 231 unsigned int irq = irq_find_mapping(NULL, ist);
232 232
233 free_irq(irq, dev_id); 233 free_irq(irq, dev_id);
234 irq_dispose_mapping(irq);
234} 235}
235EXPORT_SYMBOL(ibmebus_free_irq); 236EXPORT_SYMBOL(ibmebus_free_irq);
236 237
diff --git a/arch/powerpc/kernel/of_device.c b/arch/powerpc/kernel/of_device.c
index f3c9cae01dd5..fa983a59c4ce 100644
--- a/arch/powerpc/kernel/of_device.c
+++ b/arch/powerpc/kernel/of_device.c
@@ -14,7 +14,6 @@ static void of_device_make_bus_id(struct of_device *dev)
14{ 14{
15 static atomic_t bus_no_reg_magic; 15 static atomic_t bus_no_reg_magic;
16 struct device_node *node = dev->node; 16 struct device_node *node = dev->node;
17 char *name = dev->dev.bus_id;
18 const u32 *reg; 17 const u32 *reg;
19 u64 addr; 18 u64 addr;
20 int magic; 19 int magic;
@@ -27,14 +26,12 @@ static void of_device_make_bus_id(struct of_device *dev)
27 reg = of_get_property(node, "dcr-reg", NULL); 26 reg = of_get_property(node, "dcr-reg", NULL);
28 if (reg) { 27 if (reg) {
29#ifdef CONFIG_PPC_DCR_NATIVE 28#ifdef CONFIG_PPC_DCR_NATIVE
30 snprintf(name, BUS_ID_SIZE, "d%x.%s", 29 dev_set_name(&dev->dev, "d%x.%s", *reg, node->name);
31 *reg, node->name);
32#else /* CONFIG_PPC_DCR_NATIVE */ 30#else /* CONFIG_PPC_DCR_NATIVE */
33 addr = of_translate_dcr_address(node, *reg, NULL); 31 addr = of_translate_dcr_address(node, *reg, NULL);
34 if (addr != OF_BAD_ADDR) { 32 if (addr != OF_BAD_ADDR) {
35 snprintf(name, BUS_ID_SIZE, 33 dev_set_name(&dev->dev, "D%llx.%s",
36 "D%llx.%s", (unsigned long long)addr, 34 (unsigned long long)addr, node->name);
37 node->name);
38 return; 35 return;
39 } 36 }
40#endif /* !CONFIG_PPC_DCR_NATIVE */ 37#endif /* !CONFIG_PPC_DCR_NATIVE */
@@ -48,9 +45,8 @@ static void of_device_make_bus_id(struct of_device *dev)
48 if (reg) { 45 if (reg) {
49 addr = of_translate_address(node, reg); 46 addr = of_translate_address(node, reg);
50 if (addr != OF_BAD_ADDR) { 47 if (addr != OF_BAD_ADDR) {
51 snprintf(name, BUS_ID_SIZE, 48 dev_set_name(&dev->dev, "%llx.%s",
52 "%llx.%s", (unsigned long long)addr, 49 (unsigned long long)addr, node->name);
53 node->name);
54 return; 50 return;
55 } 51 }
56 } 52 }
@@ -60,7 +56,7 @@ static void of_device_make_bus_id(struct of_device *dev)
60 * counter (and pray...) 56 * counter (and pray...)
61 */ 57 */
62 magic = atomic_add_return(1, &bus_no_reg_magic); 58 magic = atomic_add_return(1, &bus_no_reg_magic);
63 snprintf(name, BUS_ID_SIZE, "%s.%d", node->name, magic - 1); 59 dev_set_name(&dev->dev, "%s.%d", node->name, magic - 1);
64} 60}
65 61
66struct of_device *of_device_alloc(struct device_node *np, 62struct of_device *of_device_alloc(struct device_node *np,
@@ -80,7 +76,7 @@ struct of_device *of_device_alloc(struct device_node *np,
80 dev->dev.archdata.of_node = np; 76 dev->dev.archdata.of_node = np;
81 77
82 if (bus_id) 78 if (bus_id)
83 strlcpy(dev->dev.bus_id, bus_id, BUS_ID_SIZE); 79 dev_set_name(&dev->dev, bus_id);
84 else 80 else
85 of_device_make_bus_id(dev); 81 of_device_make_bus_id(dev);
86 82
diff --git a/arch/powerpc/kernel/paca.c b/arch/powerpc/kernel/paca.c
index 48a347133f41..c744b327bcab 100644
--- a/arch/powerpc/kernel/paca.c
+++ b/arch/powerpc/kernel/paca.c
@@ -37,6 +37,7 @@ struct lppaca lppaca[] = {
37 .end_of_quantum = 0xfffffffffffffffful, 37 .end_of_quantum = 0xfffffffffffffffful,
38 .slb_count = 64, 38 .slb_count = 64,
39 .vmxregs_in_use = 0, 39 .vmxregs_in_use = 0,
40 .page_ins = 0,
40 }, 41 },
41}; 42};
42 43
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index f36936d9fda3..1a32db331a5c 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -37,13 +37,7 @@
37#include <asm/machdep.h> 37#include <asm/machdep.h>
38#include <asm/ppc-pci.h> 38#include <asm/ppc-pci.h>
39#include <asm/firmware.h> 39#include <asm/firmware.h>
40 40#include <asm/eeh.h>
41#ifdef DEBUG
42#include <asm/udbg.h>
43#define DBG(fmt...) printk(fmt)
44#else
45#define DBG(fmt...)
46#endif
47 41
48static DEFINE_SPINLOCK(hose_spinlock); 42static DEFINE_SPINLOCK(hose_spinlock);
49 43
@@ -53,8 +47,9 @@ static int global_phb_number; /* Global phb counter */
53/* ISA Memory physical address */ 47/* ISA Memory physical address */
54resource_size_t isa_mem_base; 48resource_size_t isa_mem_base;
55 49
56/* Default PCI flags is 0 */ 50/* Default PCI flags is 0 on ppc32, modified at boot on ppc64 */
57unsigned int ppc_pci_flags; 51unsigned int ppc_pci_flags = 0;
52
58 53
59static struct dma_mapping_ops *pci_dma_ops; 54static struct dma_mapping_ops *pci_dma_ops;
60 55
@@ -165,8 +160,6 @@ EXPORT_SYMBOL(pci_domain_nr);
165 */ 160 */
166struct pci_controller* pci_find_hose_for_OF_device(struct device_node* node) 161struct pci_controller* pci_find_hose_for_OF_device(struct device_node* node)
167{ 162{
168 if (!have_of)
169 return NULL;
170 while(node) { 163 while(node) {
171 struct pci_controller *hose, *tmp; 164 struct pci_controller *hose, *tmp;
172 list_for_each_entry_safe(hose, tmp, &hose_list, list_node) 165 list_for_each_entry_safe(hose, tmp, &hose_list, list_node)
@@ -208,26 +201,6 @@ char __devinit *pcibios_setup(char *str)
208 return str; 201 return str;
209} 202}
210 203
211void __devinit pcibios_setup_new_device(struct pci_dev *dev)
212{
213 struct dev_archdata *sd = &dev->dev.archdata;
214
215 sd->of_node = pci_device_to_OF_node(dev);
216
217 DBG("PCI: device %s OF node: %s\n", pci_name(dev),
218 sd->of_node ? sd->of_node->full_name : "<none>");
219
220 sd->dma_ops = pci_dma_ops;
221#ifdef CONFIG_PPC32
222 sd->dma_data = (void *)PCI_DRAM_OFFSET;
223#endif
224 set_dev_node(&dev->dev, pcibus_to_node(dev->bus));
225
226 if (ppc_md.pci_dma_dev_setup)
227 ppc_md.pci_dma_dev_setup(dev);
228}
229EXPORT_SYMBOL(pcibios_setup_new_device);
230
231/* 204/*
232 * Reads the interrupt pin to determine if interrupt is use by card. 205 * Reads the interrupt pin to determine if interrupt is use by card.
233 * If the interrupt is used, then gets the interrupt line from the 206 * If the interrupt is used, then gets the interrupt line from the
@@ -252,7 +225,7 @@ int pci_read_irq_line(struct pci_dev *pci_dev)
252 return -1; 225 return -1;
253#endif 226#endif
254 227
255 DBG("Try to map irq for %s...\n", pci_name(pci_dev)); 228 pr_debug("PCI: Try to map irq for %s...\n", pci_name(pci_dev));
256 229
257#ifdef DEBUG 230#ifdef DEBUG
258 memset(&oirq, 0xff, sizeof(oirq)); 231 memset(&oirq, 0xff, sizeof(oirq));
@@ -276,26 +249,26 @@ int pci_read_irq_line(struct pci_dev *pci_dev)
276 line == 0xff || line == 0) { 249 line == 0xff || line == 0) {
277 return -1; 250 return -1;
278 } 251 }
279 DBG(" -> no map ! Using line %d (pin %d) from PCI config\n", 252 pr_debug(" No map ! Using line %d (pin %d) from PCI config\n",
280 line, pin); 253 line, pin);
281 254
282 virq = irq_create_mapping(NULL, line); 255 virq = irq_create_mapping(NULL, line);
283 if (virq != NO_IRQ) 256 if (virq != NO_IRQ)
284 set_irq_type(virq, IRQ_TYPE_LEVEL_LOW); 257 set_irq_type(virq, IRQ_TYPE_LEVEL_LOW);
285 } else { 258 } else {
286 DBG(" -> got one, spec %d cells (0x%08x 0x%08x...) on %s\n", 259 pr_debug(" Got one, spec %d cells (0x%08x 0x%08x...) on %s\n",
287 oirq.size, oirq.specifier[0], oirq.specifier[1], 260 oirq.size, oirq.specifier[0], oirq.specifier[1],
288 oirq.controller->full_name); 261 oirq.controller->full_name);
289 262
290 virq = irq_create_of_mapping(oirq.controller, oirq.specifier, 263 virq = irq_create_of_mapping(oirq.controller, oirq.specifier,
291 oirq.size); 264 oirq.size);
292 } 265 }
293 if(virq == NO_IRQ) { 266 if(virq == NO_IRQ) {
294 DBG(" -> failed to map !\n"); 267 pr_debug(" Failed to map !\n");
295 return -1; 268 return -1;
296 } 269 }
297 270
298 DBG(" -> mapped to linux irq %d\n", virq); 271 pr_debug(" Mapped to linux irq %d\n", virq);
299 272
300 pci_dev->irq = virq; 273 pci_dev->irq = virq;
301 274
@@ -451,8 +424,8 @@ pgprot_t pci_phys_mem_access_prot(struct file *file,
451 pci_dev_put(pdev); 424 pci_dev_put(pdev);
452 } 425 }
453 426
454 DBG("non-PCI map for %llx, prot: %lx\n", 427 pr_debug("PCI: Non-PCI map for %llx, prot: %lx\n",
455 (unsigned long long)offset, prot); 428 (unsigned long long)offset, prot);
456 429
457 return __pgprot(prot); 430 return __pgprot(prot);
458} 431}
@@ -853,15 +826,12 @@ void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose,
853int pci_proc_domain(struct pci_bus *bus) 826int pci_proc_domain(struct pci_bus *bus)
854{ 827{
855 struct pci_controller *hose = pci_bus_to_host(bus); 828 struct pci_controller *hose = pci_bus_to_host(bus);
856#ifdef CONFIG_PPC64 829
857 return hose->buid != 0;
858#else
859 if (!(ppc_pci_flags & PPC_PCI_ENABLE_PROC_DOMAINS)) 830 if (!(ppc_pci_flags & PPC_PCI_ENABLE_PROC_DOMAINS))
860 return 0; 831 return 0;
861 if (ppc_pci_flags & PPC_PCI_COMPAT_DOMAIN_0) 832 if (ppc_pci_flags & PPC_PCI_COMPAT_DOMAIN_0)
862 return hose->global_number != 0; 833 return hose->global_number != 0;
863 return 1; 834 return 1;
864#endif
865} 835}
866 836
867void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, 837void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
@@ -1083,27 +1053,50 @@ static void __devinit pcibios_fixup_bridge(struct pci_bus *bus)
1083 } 1053 }
1084} 1054}
1085 1055
1086static void __devinit __pcibios_fixup_bus(struct pci_bus *bus) 1056void __devinit pcibios_setup_bus_self(struct pci_bus *bus)
1087{ 1057{
1088 struct pci_dev *dev = bus->self; 1058 /* Fix up the bus resources for P2P bridges */
1089 1059 if (bus->self != NULL)
1090 pr_debug("PCI: Fixup bus %d (%s)\n", bus->number, dev ? pci_name(dev) : "PHB");
1091
1092 /* Fixup PCI<->PCI bridges. Host bridges are handled separately, for
1093 * now differently between 32 and 64 bits.
1094 */
1095 if (dev != NULL)
1096 pcibios_fixup_bridge(bus); 1060 pcibios_fixup_bridge(bus);
1097 1061
1098 /* Additional setup that is different between 32 and 64 bits for now */ 1062 /* Platform specific bus fixups. This is currently only used
1099 pcibios_do_bus_setup(bus); 1063 * by fsl_pci and I'm hoping to get rid of it at some point
1100 1064 */
1101 /* Platform specific bus fixups */
1102 if (ppc_md.pcibios_fixup_bus) 1065 if (ppc_md.pcibios_fixup_bus)
1103 ppc_md.pcibios_fixup_bus(bus); 1066 ppc_md.pcibios_fixup_bus(bus);
1104 1067
1105 /* Read default IRQs and fixup if necessary */ 1068 /* Setup bus DMA mappings */
1069 if (ppc_md.pci_dma_bus_setup)
1070 ppc_md.pci_dma_bus_setup(bus);
1071}
1072
1073void __devinit pcibios_setup_bus_devices(struct pci_bus *bus)
1074{
1075 struct pci_dev *dev;
1076
1077 pr_debug("PCI: Fixup bus devices %d (%s)\n",
1078 bus->number, bus->self ? pci_name(bus->self) : "PHB");
1079
1106 list_for_each_entry(dev, &bus->devices, bus_list) { 1080 list_for_each_entry(dev, &bus->devices, bus_list) {
1081 struct dev_archdata *sd = &dev->dev.archdata;
1082
1083 /* Setup OF node pointer in archdata */
1084 sd->of_node = pci_device_to_OF_node(dev);
1085
1086 /* Fixup NUMA node as it may not be setup yet by the generic
1087 * code and is needed by the DMA init
1088 */
1089 set_dev_node(&dev->dev, pcibus_to_node(dev->bus));
1090
1091 /* Hook up default DMA ops */
1092 sd->dma_ops = pci_dma_ops;
1093 sd->dma_data = (void *)PCI_DRAM_OFFSET;
1094
1095 /* Additional platform DMA/iommu setup */
1096 if (ppc_md.pci_dma_dev_setup)
1097 ppc_md.pci_dma_dev_setup(dev);
1098
1099 /* Read default IRQs and fixup if necessary */
1107 pci_read_irq_line(dev); 1100 pci_read_irq_line(dev);
1108 if (ppc_md.pci_irq_fixup) 1101 if (ppc_md.pci_irq_fixup)
1109 ppc_md.pci_irq_fixup(dev); 1102 ppc_md.pci_irq_fixup(dev);
@@ -1113,22 +1106,19 @@ static void __devinit __pcibios_fixup_bus(struct pci_bus *bus)
1113void __devinit pcibios_fixup_bus(struct pci_bus *bus) 1106void __devinit pcibios_fixup_bus(struct pci_bus *bus)
1114{ 1107{
1115 /* When called from the generic PCI probe, read PCI<->PCI bridge 1108 /* When called from the generic PCI probe, read PCI<->PCI bridge
1116 * bases before proceeding 1109 * bases. This is -not- called when generating the PCI tree from
1110 * the OF device-tree.
1117 */ 1111 */
1118 if (bus->self != NULL) 1112 if (bus->self != NULL)
1119 pci_read_bridge_bases(bus); 1113 pci_read_bridge_bases(bus);
1120 __pcibios_fixup_bus(bus);
1121}
1122EXPORT_SYMBOL(pcibios_fixup_bus);
1123 1114
1124/* When building a bus from the OF tree rather than probing, we need a 1115 /* Now fixup the bus bus */
1125 * slightly different version of the fixup which doesn't read the 1116 pcibios_setup_bus_self(bus);
1126 * bridge bases using config space accesses 1117
1127 */ 1118 /* Now fixup devices on that bus */
1128void __devinit pcibios_fixup_of_probed_bus(struct pci_bus *bus) 1119 pcibios_setup_bus_devices(bus);
1129{
1130 __pcibios_fixup_bus(bus);
1131} 1120}
1121EXPORT_SYMBOL(pcibios_fixup_bus);
1132 1122
1133static int skip_isa_ioresource_align(struct pci_dev *dev) 1123static int skip_isa_ioresource_align(struct pci_dev *dev)
1134{ 1124{
@@ -1198,10 +1188,10 @@ static int __init reparent_resources(struct resource *parent,
1198 *pp = NULL; 1188 *pp = NULL;
1199 for (p = res->child; p != NULL; p = p->sibling) { 1189 for (p = res->child; p != NULL; p = p->sibling) {
1200 p->parent = res; 1190 p->parent = res;
1201 DBG(KERN_INFO "PCI: reparented %s [%llx..%llx] under %s\n", 1191 pr_debug("PCI: Reparented %s [%llx..%llx] under %s\n",
1202 p->name, 1192 p->name,
1203 (unsigned long long)p->start, 1193 (unsigned long long)p->start,
1204 (unsigned long long)p->end, res->name); 1194 (unsigned long long)p->end, res->name);
1205 } 1195 }
1206 return 0; 1196 return 0;
1207} 1197}
@@ -1245,9 +1235,12 @@ void pcibios_allocate_bus_resources(struct pci_bus *bus)
1245 int i; 1235 int i;
1246 struct resource *res, *pr; 1236 struct resource *res, *pr;
1247 1237
1238 pr_debug("PCI: Allocating bus resources for %04x:%02x...\n",
1239 pci_domain_nr(bus), bus->number);
1240
1248 for (i = 0; i < PCI_BUS_NUM_RESOURCES; ++i) { 1241 for (i = 0; i < PCI_BUS_NUM_RESOURCES; ++i) {
1249 if ((res = bus->resource[i]) == NULL || !res->flags 1242 if ((res = bus->resource[i]) == NULL || !res->flags
1250 || res->start > res->end) 1243 || res->start > res->end || res->parent)
1251 continue; 1244 continue;
1252 if (bus->parent == NULL) 1245 if (bus->parent == NULL)
1253 pr = (res->flags & IORESOURCE_IO) ? 1246 pr = (res->flags & IORESOURCE_IO) ?
@@ -1271,14 +1264,14 @@ void pcibios_allocate_bus_resources(struct pci_bus *bus)
1271 } 1264 }
1272 } 1265 }
1273 1266
1274 DBG("PCI: %s (bus %d) bridge rsrc %d: %016llx-%016llx " 1267 pr_debug("PCI: %s (bus %d) bridge rsrc %d: %016llx-%016llx "
1275 "[0x%x], parent %p (%s)\n", 1268 "[0x%x], parent %p (%s)\n",
1276 bus->self ? pci_name(bus->self) : "PHB", 1269 bus->self ? pci_name(bus->self) : "PHB",
1277 bus->number, i, 1270 bus->number, i,
1278 (unsigned long long)res->start, 1271 (unsigned long long)res->start,
1279 (unsigned long long)res->end, 1272 (unsigned long long)res->end,
1280 (unsigned int)res->flags, 1273 (unsigned int)res->flags,
1281 pr, (pr && pr->name) ? pr->name : "nil"); 1274 pr, (pr && pr->name) ? pr->name : "nil");
1282 1275
1283 if (pr && !(pr->flags & IORESOURCE_UNSET)) { 1276 if (pr && !(pr->flags & IORESOURCE_UNSET)) {
1284 if (request_resource(pr, res) == 0) 1277 if (request_resource(pr, res) == 0)
@@ -1305,11 +1298,11 @@ static inline void __devinit alloc_resource(struct pci_dev *dev, int idx)
1305{ 1298{
1306 struct resource *pr, *r = &dev->resource[idx]; 1299 struct resource *pr, *r = &dev->resource[idx];
1307 1300
1308 DBG("PCI: Allocating %s: Resource %d: %016llx..%016llx [%x]\n", 1301 pr_debug("PCI: Allocating %s: Resource %d: %016llx..%016llx [%x]\n",
1309 pci_name(dev), idx, 1302 pci_name(dev), idx,
1310 (unsigned long long)r->start, 1303 (unsigned long long)r->start,
1311 (unsigned long long)r->end, 1304 (unsigned long long)r->end,
1312 (unsigned int)r->flags); 1305 (unsigned int)r->flags);
1313 1306
1314 pr = pci_find_parent_resource(dev, r); 1307 pr = pci_find_parent_resource(dev, r);
1315 if (!pr || (pr->flags & IORESOURCE_UNSET) || 1308 if (!pr || (pr->flags & IORESOURCE_UNSET) ||
@@ -1317,10 +1310,11 @@ static inline void __devinit alloc_resource(struct pci_dev *dev, int idx)
1317 printk(KERN_WARNING "PCI: Cannot allocate resource region %d" 1310 printk(KERN_WARNING "PCI: Cannot allocate resource region %d"
1318 " of device %s, will remap\n", idx, pci_name(dev)); 1311 " of device %s, will remap\n", idx, pci_name(dev));
1319 if (pr) 1312 if (pr)
1320 DBG("PCI: parent is %p: %016llx-%016llx [%x]\n", pr, 1313 pr_debug("PCI: parent is %p: %016llx-%016llx [%x]\n",
1321 (unsigned long long)pr->start, 1314 pr,
1322 (unsigned long long)pr->end, 1315 (unsigned long long)pr->start,
1323 (unsigned int)pr->flags); 1316 (unsigned long long)pr->end,
1317 (unsigned int)pr->flags);
1324 /* We'll assign a new address later */ 1318 /* We'll assign a new address later */
1325 r->flags |= IORESOURCE_UNSET; 1319 r->flags |= IORESOURCE_UNSET;
1326 r->end -= r->start; 1320 r->end -= r->start;
@@ -1358,7 +1352,8 @@ static void __init pcibios_allocate_resources(int pass)
1358 * but keep it unregistered. 1352 * but keep it unregistered.
1359 */ 1353 */
1360 u32 reg; 1354 u32 reg;
1361 DBG("PCI: Switching off ROM of %s\n", pci_name(dev)); 1355 pr_debug("PCI: Switching off ROM of %s\n",
1356 pci_name(dev));
1362 r->flags &= ~IORESOURCE_ROM_ENABLE; 1357 r->flags &= ~IORESOURCE_ROM_ENABLE;
1363 pci_read_config_dword(dev, dev->rom_base_reg, &reg); 1358 pci_read_config_dword(dev, dev->rom_base_reg, &reg);
1364 pci_write_config_dword(dev, dev->rom_base_reg, 1359 pci_write_config_dword(dev, dev->rom_base_reg,
@@ -1383,7 +1378,7 @@ void __init pcibios_resource_survey(void)
1383 } 1378 }
1384 1379
1385 if (!(ppc_pci_flags & PPC_PCI_PROBE_ONLY)) { 1380 if (!(ppc_pci_flags & PPC_PCI_PROBE_ONLY)) {
1386 DBG("PCI: Assigning unassigned resouces...\n"); 1381 pr_debug("PCI: Assigning unassigned resouces...\n");
1387 pci_assign_unassigned_resources(); 1382 pci_assign_unassigned_resources();
1388 } 1383 }
1389 1384
@@ -1393,9 +1388,11 @@ void __init pcibios_resource_survey(void)
1393} 1388}
1394 1389
1395#ifdef CONFIG_HOTPLUG 1390#ifdef CONFIG_HOTPLUG
1396/* This is used by the pSeries hotplug driver to allocate resource 1391
1392/* This is used by the PCI hotplug driver to allocate resource
1397 * of newly plugged busses. We can try to consolidate with the 1393 * of newly plugged busses. We can try to consolidate with the
1398 * rest of the code later, for now, keep it as-is 1394 * rest of the code later, for now, keep it as-is as our main
1395 * resource allocation function doesn't deal with sub-trees yet.
1399 */ 1396 */
1400void __devinit pcibios_claim_one_bus(struct pci_bus *bus) 1397void __devinit pcibios_claim_one_bus(struct pci_bus *bus)
1401{ 1398{
@@ -1410,6 +1407,14 @@ void __devinit pcibios_claim_one_bus(struct pci_bus *bus)
1410 1407
1411 if (r->parent || !r->start || !r->flags) 1408 if (r->parent || !r->start || !r->flags)
1412 continue; 1409 continue;
1410
1411 pr_debug("PCI: Claiming %s: "
1412 "Resource %d: %016llx..%016llx [%x]\n",
1413 pci_name(dev), i,
1414 (unsigned long long)r->start,
1415 (unsigned long long)r->end,
1416 (unsigned int)r->flags);
1417
1413 pci_claim_resource(dev, i); 1418 pci_claim_resource(dev, i);
1414 } 1419 }
1415 } 1420 }
@@ -1418,6 +1423,31 @@ void __devinit pcibios_claim_one_bus(struct pci_bus *bus)
1418 pcibios_claim_one_bus(child_bus); 1423 pcibios_claim_one_bus(child_bus);
1419} 1424}
1420EXPORT_SYMBOL_GPL(pcibios_claim_one_bus); 1425EXPORT_SYMBOL_GPL(pcibios_claim_one_bus);
1426
1427
1428/* pcibios_finish_adding_to_bus
1429 *
1430 * This is to be called by the hotplug code after devices have been
1431 * added to a bus, this include calling it for a PHB that is just
1432 * being added
1433 */
1434void pcibios_finish_adding_to_bus(struct pci_bus *bus)
1435{
1436 pr_debug("PCI: Finishing adding to hotplug bus %04x:%02x\n",
1437 pci_domain_nr(bus), bus->number);
1438
1439 /* Allocate bus and devices resources */
1440 pcibios_allocate_bus_resources(bus);
1441 pcibios_claim_one_bus(bus);
1442
1443 /* Add new devices to global lists. Register in proc, sysfs. */
1444 pci_bus_add_devices(bus);
1445
1446 /* Fixup EEH */
1447 eeh_add_device_tree_late(bus);
1448}
1449EXPORT_SYMBOL_GPL(pcibios_finish_adding_to_bus);
1450
1421#endif /* CONFIG_HOTPLUG */ 1451#endif /* CONFIG_HOTPLUG */
1422 1452
1423int pcibios_enable_device(struct pci_dev *dev, int mask) 1453int pcibios_enable_device(struct pci_dev *dev, int mask)
@@ -1428,3 +1458,61 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
1428 1458
1429 return pci_enable_resources(dev, mask); 1459 return pci_enable_resources(dev, mask);
1430} 1460}
1461
1462void __devinit pcibios_setup_phb_resources(struct pci_controller *hose)
1463{
1464 struct pci_bus *bus = hose->bus;
1465 struct resource *res;
1466 int i;
1467
1468 /* Hookup PHB IO resource */
1469 bus->resource[0] = res = &hose->io_resource;
1470
1471 if (!res->flags) {
1472 printk(KERN_WARNING "PCI: I/O resource not set for host"
1473 " bridge %s (domain %d)\n",
1474 hose->dn->full_name, hose->global_number);
1475#ifdef CONFIG_PPC32
1476 /* Workaround for lack of IO resource only on 32-bit */
1477 res->start = (unsigned long)hose->io_base_virt - isa_io_base;
1478 res->end = res->start + IO_SPACE_LIMIT;
1479 res->flags = IORESOURCE_IO;
1480#endif /* CONFIG_PPC32 */
1481 }
1482
1483 pr_debug("PCI: PHB IO resource = %016llx-%016llx [%lx]\n",
1484 (unsigned long long)res->start,
1485 (unsigned long long)res->end,
1486 (unsigned long)res->flags);
1487
1488 /* Hookup PHB Memory resources */
1489 for (i = 0; i < 3; ++i) {
1490 res = &hose->mem_resources[i];
1491 if (!res->flags) {
1492 if (i > 0)
1493 continue;
1494 printk(KERN_ERR "PCI: Memory resource 0 not set for "
1495 "host bridge %s (domain %d)\n",
1496 hose->dn->full_name, hose->global_number);
1497#ifdef CONFIG_PPC32
1498 /* Workaround for lack of MEM resource only on 32-bit */
1499 res->start = hose->pci_mem_offset;
1500 res->end = (resource_size_t)-1LL;
1501 res->flags = IORESOURCE_MEM;
1502#endif /* CONFIG_PPC32 */
1503 }
1504 bus->resource[i+1] = res;
1505
1506 pr_debug("PCI: PHB MEM resource %d = %016llx-%016llx [%lx]\n", i,
1507 (unsigned long long)res->start,
1508 (unsigned long long)res->end,
1509 (unsigned long)res->flags);
1510 }
1511
1512 pr_debug("PCI: PHB MEM offset = %016llx\n",
1513 (unsigned long long)hose->pci_mem_offset);
1514 pr_debug("PCI: PHB IO offset = %08lx\n",
1515 (unsigned long)hose->io_base_virt - _IO_BASE);
1516
1517}
1518
diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c
index 131b1dfa68c6..132cd80afa21 100644
--- a/arch/powerpc/kernel/pci_32.c
+++ b/arch/powerpc/kernel/pci_32.c
@@ -26,12 +26,6 @@
26 26
27#undef DEBUG 27#undef DEBUG
28 28
29#ifdef DEBUG
30#define DBG(x...) printk(x)
31#else
32#define DBG(x...)
33#endif
34
35unsigned long isa_io_base = 0; 29unsigned long isa_io_base = 0;
36unsigned long pci_dram_offset = 0; 30unsigned long pci_dram_offset = 0;
37int pcibios_assign_bus_offset = 1; 31int pcibios_assign_bus_offset = 1;
@@ -272,17 +266,14 @@ pci_busdev_to_OF_node(struct pci_bus *bus, int devfn)
272{ 266{
273 struct device_node *parent, *np; 267 struct device_node *parent, *np;
274 268
275 if (!have_of) 269 pr_debug("pci_busdev_to_OF_node(%d,0x%x)\n", bus->number, devfn);
276 return NULL;
277
278 DBG("pci_busdev_to_OF_node(%d,0x%x)\n", bus->number, devfn);
279 parent = scan_OF_for_pci_bus(bus); 270 parent = scan_OF_for_pci_bus(bus);
280 if (parent == NULL) 271 if (parent == NULL)
281 return NULL; 272 return NULL;
282 DBG(" parent is %s\n", parent ? parent->full_name : "<NULL>"); 273 pr_debug(" parent is %s\n", parent ? parent->full_name : "<NULL>");
283 np = scan_OF_for_pci_dev(parent, devfn); 274 np = scan_OF_for_pci_dev(parent, devfn);
284 of_node_put(parent); 275 of_node_put(parent);
285 DBG(" result is %s\n", np ? np->full_name : "<NULL>"); 276 pr_debug(" result is %s\n", np ? np->full_name : "<NULL>");
286 277
287 /* XXX most callers don't release the returned node 278 /* XXX most callers don't release the returned node
288 * mostly because ppc64 doesn't increase the refcount, 279 * mostly because ppc64 doesn't increase the refcount,
@@ -315,8 +306,6 @@ pci_device_from_OF_node(struct device_node* node, u8* bus, u8* devfn)
315 struct pci_controller* hose; 306 struct pci_controller* hose;
316 struct pci_dev* dev = NULL; 307 struct pci_dev* dev = NULL;
317 308
318 if (!have_of)
319 return -ENODEV;
320 /* Make sure it's really a PCI device */ 309 /* Make sure it's really a PCI device */
321 hose = pci_find_hose_for_OF_device(node); 310 hose = pci_find_hose_for_OF_device(node);
322 if (!hose || !hose->dn) 311 if (!hose || !hose->dn)
@@ -379,10 +368,41 @@ void pcibios_make_OF_bus_map(void)
379} 368}
380#endif /* CONFIG_PPC_OF */ 369#endif /* CONFIG_PPC_OF */
381 370
371static void __devinit pcibios_scan_phb(struct pci_controller *hose)
372{
373 struct pci_bus *bus;
374 struct device_node *node = hose->dn;
375 unsigned long io_offset;
376 struct resource *res = &hose->io_resource;
377
378 pr_debug("PCI: Scanning PHB %s\n",
379 node ? node->full_name : "<NO NAME>");
380
381 /* Create an empty bus for the toplevel */
382 bus = pci_create_bus(hose->parent, hose->first_busno, hose->ops, hose);
383 if (bus == NULL) {
384 printk(KERN_ERR "Failed to create bus for PCI domain %04x\n",
385 hose->global_number);
386 return;
387 }
388 bus->secondary = hose->first_busno;
389 hose->bus = bus;
390
391 /* Fixup IO space offset */
392 io_offset = (unsigned long)hose->io_base_virt - isa_io_base;
393 res->start = (res->start + io_offset) & 0xffffffffu;
394 res->end = (res->end + io_offset) & 0xffffffffu;
395
396 /* Wire up PHB bus resources */
397 pcibios_setup_phb_resources(hose);
398
399 /* Scan children */
400 hose->last_busno = bus->subordinate = pci_scan_child_bus(bus);
401}
402
382static int __init pcibios_init(void) 403static int __init pcibios_init(void)
383{ 404{
384 struct pci_controller *hose, *tmp; 405 struct pci_controller *hose, *tmp;
385 struct pci_bus *bus;
386 int next_busno = 0; 406 int next_busno = 0;
387 407
388 printk(KERN_INFO "PCI: Probing PCI hardware\n"); 408 printk(KERN_INFO "PCI: Probing PCI hardware\n");
@@ -395,12 +415,8 @@ static int __init pcibios_init(void)
395 if (pci_assign_all_buses) 415 if (pci_assign_all_buses)
396 hose->first_busno = next_busno; 416 hose->first_busno = next_busno;
397 hose->last_busno = 0xff; 417 hose->last_busno = 0xff;
398 bus = pci_scan_bus_parented(hose->parent, hose->first_busno, 418 pcibios_scan_phb(hose);
399 hose->ops, hose); 419 pci_bus_add_devices(hose->bus);
400 if (bus) {
401 pci_bus_add_devices(bus);
402 hose->last_busno = bus->subordinate;
403 }
404 if (pci_assign_all_buses || next_busno <= hose->last_busno) 420 if (pci_assign_all_buses || next_busno <= hose->last_busno)
405 next_busno = hose->last_busno + pcibios_assign_bus_offset; 421 next_busno = hose->last_busno + pcibios_assign_bus_offset;
406 } 422 }
@@ -410,7 +426,7 @@ static int __init pcibios_init(void)
410 * numbers vs. kernel bus numbers since we may have to 426 * numbers vs. kernel bus numbers since we may have to
411 * remap them. 427 * remap them.
412 */ 428 */
413 if (pci_assign_all_buses && have_of) 429 if (pci_assign_all_buses)
414 pcibios_make_OF_bus_map(); 430 pcibios_make_OF_bus_map();
415 431
416 /* Call common code to handle resource allocation */ 432 /* Call common code to handle resource allocation */
@@ -425,54 +441,6 @@ static int __init pcibios_init(void)
425 441
426subsys_initcall(pcibios_init); 442subsys_initcall(pcibios_init);
427 443
428void __devinit pcibios_do_bus_setup(struct pci_bus *bus)
429{
430 struct pci_controller *hose = (struct pci_controller *) bus->sysdata;
431 unsigned long io_offset;
432 struct resource *res;
433 int i;
434 struct pci_dev *dev;
435
436 /* Hookup PHB resources */
437 io_offset = (unsigned long)hose->io_base_virt - isa_io_base;
438 if (bus->parent == NULL) {
439 /* This is a host bridge - fill in its resources */
440 hose->bus = bus;
441
442 bus->resource[0] = res = &hose->io_resource;
443 if (!res->flags) {
444 if (io_offset)
445 printk(KERN_ERR "I/O resource not set for host"
446 " bridge %d\n", hose->global_number);
447 res->start = 0;
448 res->end = IO_SPACE_LIMIT;
449 res->flags = IORESOURCE_IO;
450 }
451 res->start = (res->start + io_offset) & 0xffffffffu;
452 res->end = (res->end + io_offset) & 0xffffffffu;
453
454 for (i = 0; i < 3; ++i) {
455 res = &hose->mem_resources[i];
456 if (!res->flags) {
457 if (i > 0)
458 continue;
459 printk(KERN_ERR "Memory resource not set for "
460 "host bridge %d\n", hose->global_number);
461 res->start = hose->pci_mem_offset;
462 res->end = ~0U;
463 res->flags = IORESOURCE_MEM;
464 }
465 bus->resource[i+1] = res;
466 }
467 }
468
469 if (ppc_md.pci_dma_bus_setup)
470 ppc_md.pci_dma_bus_setup(bus);
471
472 list_for_each_entry(dev, &bus->devices, bus_list)
473 pcibios_setup_new_device(dev);
474}
475
476/* the next one is stolen from the alpha port... */ 444/* the next one is stolen from the alpha port... */
477void __init 445void __init
478pcibios_update_irq(struct pci_dev *dev, int irq) 446pcibios_update_irq(struct pci_dev *dev, int irq)
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
index 3502b9101e6b..39fadc6e1492 100644
--- a/arch/powerpc/kernel/pci_64.c
+++ b/arch/powerpc/kernel/pci_64.c
@@ -32,13 +32,6 @@
32#include <asm/machdep.h> 32#include <asm/machdep.h>
33#include <asm/ppc-pci.h> 33#include <asm/ppc-pci.h>
34 34
35#ifdef DEBUG
36#include <asm/udbg.h>
37#define DBG(fmt...) printk(fmt)
38#else
39#define DBG(fmt...)
40#endif
41
42unsigned long pci_probe_only = 1; 35unsigned long pci_probe_only = 1;
43 36
44/* pci_io_base -- the base address from which io bars are offsets. 37/* pci_io_base -- the base address from which io bars are offsets.
@@ -102,7 +95,7 @@ static void pci_parse_of_addrs(struct device_node *node, struct pci_dev *dev)
102 addrs = of_get_property(node, "assigned-addresses", &proplen); 95 addrs = of_get_property(node, "assigned-addresses", &proplen);
103 if (!addrs) 96 if (!addrs)
104 return; 97 return;
105 DBG(" parse addresses (%d bytes) @ %p\n", proplen, addrs); 98 pr_debug(" parse addresses (%d bytes) @ %p\n", proplen, addrs);
106 for (; proplen >= 20; proplen -= 20, addrs += 5) { 99 for (; proplen >= 20; proplen -= 20, addrs += 5) {
107 flags = pci_parse_of_flags(addrs[0]); 100 flags = pci_parse_of_flags(addrs[0]);
108 if (!flags) 101 if (!flags)
@@ -112,8 +105,9 @@ static void pci_parse_of_addrs(struct device_node *node, struct pci_dev *dev)
112 if (!size) 105 if (!size)
113 continue; 106 continue;
114 i = addrs[0] & 0xff; 107 i = addrs[0] & 0xff;
115 DBG(" base: %llx, size: %llx, i: %x\n", 108 pr_debug(" base: %llx, size: %llx, i: %x\n",
116 (unsigned long long)base, (unsigned long long)size, i); 109 (unsigned long long)base,
110 (unsigned long long)size, i);
117 111
118 if (PCI_BASE_ADDRESS_0 <= i && i <= PCI_BASE_ADDRESS_5) { 112 if (PCI_BASE_ADDRESS_0 <= i && i <= PCI_BASE_ADDRESS_5) {
119 res = &dev->resource[(i - PCI_BASE_ADDRESS_0) >> 2]; 113 res = &dev->resource[(i - PCI_BASE_ADDRESS_0) >> 2];
@@ -144,7 +138,7 @@ struct pci_dev *of_create_pci_dev(struct device_node *node,
144 if (type == NULL) 138 if (type == NULL)
145 type = ""; 139 type = "";
146 140
147 DBG(" create device, devfn: %x, type: %s\n", devfn, type); 141 pr_debug(" create device, devfn: %x, type: %s\n", devfn, type);
148 142
149 dev->bus = bus; 143 dev->bus = bus;
150 dev->sysdata = node; 144 dev->sysdata = node;
@@ -165,8 +159,8 @@ struct pci_dev *of_create_pci_dev(struct device_node *node,
165 dev->class = get_int_prop(node, "class-code", 0); 159 dev->class = get_int_prop(node, "class-code", 0);
166 dev->revision = get_int_prop(node, "revision-id", 0); 160 dev->revision = get_int_prop(node, "revision-id", 0);
167 161
168 DBG(" class: 0x%x\n", dev->class); 162 pr_debug(" class: 0x%x\n", dev->class);
169 DBG(" revision: 0x%x\n", dev->revision); 163 pr_debug(" revision: 0x%x\n", dev->revision);
170 164
171 dev->current_state = 4; /* unknown power state */ 165 dev->current_state = 4; /* unknown power state */
172 dev->error_state = pci_channel_io_normal; 166 dev->error_state = pci_channel_io_normal;
@@ -187,7 +181,7 @@ struct pci_dev *of_create_pci_dev(struct device_node *node,
187 181
188 pci_parse_of_addrs(node, dev); 182 pci_parse_of_addrs(node, dev);
189 183
190 DBG(" adding to system ...\n"); 184 pr_debug(" adding to system ...\n");
191 185
192 pci_device_add(dev, bus); 186 pci_device_add(dev, bus);
193 187
@@ -195,19 +189,20 @@ struct pci_dev *of_create_pci_dev(struct device_node *node,
195} 189}
196EXPORT_SYMBOL(of_create_pci_dev); 190EXPORT_SYMBOL(of_create_pci_dev);
197 191
198void __devinit of_scan_bus(struct device_node *node, 192static void __devinit __of_scan_bus(struct device_node *node,
199 struct pci_bus *bus) 193 struct pci_bus *bus, int rescan_existing)
200{ 194{
201 struct device_node *child; 195 struct device_node *child;
202 const u32 *reg; 196 const u32 *reg;
203 int reglen, devfn; 197 int reglen, devfn;
204 struct pci_dev *dev; 198 struct pci_dev *dev;
205 199
206 DBG("of_scan_bus(%s) bus no %d... \n", node->full_name, bus->number); 200 pr_debug("of_scan_bus(%s) bus no %d... \n",
201 node->full_name, bus->number);
207 202
208 /* Scan direct children */ 203 /* Scan direct children */
209 for_each_child_of_node(node, child) { 204 for_each_child_of_node(node, child) {
210 DBG(" * %s\n", child->full_name); 205 pr_debug(" * %s\n", child->full_name);
211 reg = of_get_property(child, "reg", &reglen); 206 reg = of_get_property(child, "reg", &reglen);
212 if (reg == NULL || reglen < 20) 207 if (reg == NULL || reglen < 20)
213 continue; 208 continue;
@@ -217,11 +212,15 @@ void __devinit of_scan_bus(struct device_node *node,
217 dev = of_create_pci_dev(child, bus, devfn); 212 dev = of_create_pci_dev(child, bus, devfn);
218 if (!dev) 213 if (!dev)
219 continue; 214 continue;
220 DBG(" dev header type: %x\n", dev->hdr_type); 215 pr_debug(" dev header type: %x\n", dev->hdr_type);
221 } 216 }
222 217
223 /* Ally all fixups */ 218 /* Apply all fixups necessary. We don't fixup the bus "self"
224 pcibios_fixup_of_probed_bus(bus); 219 * for an existing bridge that is being rescanned
220 */
221 if (!rescan_existing)
222 pcibios_setup_bus_self(bus);
223 pcibios_setup_bus_devices(bus);
225 224
226 /* Now scan child busses */ 225 /* Now scan child busses */
227 list_for_each_entry(dev, &bus->devices, bus_list) { 226 list_for_each_entry(dev, &bus->devices, bus_list) {
@@ -233,7 +232,20 @@ void __devinit of_scan_bus(struct device_node *node,
233 } 232 }
234 } 233 }
235} 234}
236EXPORT_SYMBOL(of_scan_bus); 235
236void __devinit of_scan_bus(struct device_node *node,
237 struct pci_bus *bus)
238{
239 __of_scan_bus(node, bus, 0);
240}
241EXPORT_SYMBOL_GPL(of_scan_bus);
242
243void __devinit of_rescan_bus(struct device_node *node,
244 struct pci_bus *bus)
245{
246 __of_scan_bus(node, bus, 1);
247}
248EXPORT_SYMBOL_GPL(of_rescan_bus);
237 249
238void __devinit of_scan_pci_bridge(struct device_node *node, 250void __devinit of_scan_pci_bridge(struct device_node *node,
239 struct pci_dev *dev) 251 struct pci_dev *dev)
@@ -245,7 +257,7 @@ void __devinit of_scan_pci_bridge(struct device_node *node,
245 unsigned int flags; 257 unsigned int flags;
246 u64 size; 258 u64 size;
247 259
248 DBG("of_scan_pci_bridge(%s)\n", node->full_name); 260 pr_debug("of_scan_pci_bridge(%s)\n", node->full_name);
249 261
250 /* parse bus-range property */ 262 /* parse bus-range property */
251 busrange = of_get_property(node, "bus-range", &len); 263 busrange = of_get_property(node, "bus-range", &len);
@@ -309,12 +321,12 @@ void __devinit of_scan_pci_bridge(struct device_node *node,
309 } 321 }
310 sprintf(bus->name, "PCI Bus %04x:%02x", pci_domain_nr(bus), 322 sprintf(bus->name, "PCI Bus %04x:%02x", pci_domain_nr(bus),
311 bus->number); 323 bus->number);
312 DBG(" bus name: %s\n", bus->name); 324 pr_debug(" bus name: %s\n", bus->name);
313 325
314 mode = PCI_PROBE_NORMAL; 326 mode = PCI_PROBE_NORMAL;
315 if (ppc_md.pci_probe_mode) 327 if (ppc_md.pci_probe_mode)
316 mode = ppc_md.pci_probe_mode(bus); 328 mode = ppc_md.pci_probe_mode(bus);
317 DBG(" probe mode: %d\n", mode); 329 pr_debug(" probe mode: %d\n", mode);
318 330
319 if (mode == PCI_PROBE_DEVTREE) 331 if (mode == PCI_PROBE_DEVTREE)
320 of_scan_bus(node, bus); 332 of_scan_bus(node, bus);
@@ -327,9 +339,10 @@ void __devinit scan_phb(struct pci_controller *hose)
327{ 339{
328 struct pci_bus *bus; 340 struct pci_bus *bus;
329 struct device_node *node = hose->dn; 341 struct device_node *node = hose->dn;
330 int i, mode; 342 int mode;
331 343
332 DBG("PCI: Scanning PHB %s\n", node ? node->full_name : "<NO NAME>"); 344 pr_debug("PCI: Scanning PHB %s\n",
345 node ? node->full_name : "<NO NAME>");
333 346
334 /* Create an empty bus for the toplevel */ 347 /* Create an empty bus for the toplevel */
335 bus = pci_create_bus(hose->parent, hose->first_busno, hose->ops, node); 348 bus = pci_create_bus(hose->parent, hose->first_busno, hose->ops, node);
@@ -345,26 +358,13 @@ void __devinit scan_phb(struct pci_controller *hose)
345 pcibios_map_io_space(bus); 358 pcibios_map_io_space(bus);
346 359
347 /* Wire up PHB bus resources */ 360 /* Wire up PHB bus resources */
348 DBG("PCI: PHB IO resource = %016lx-%016lx [%lx]\n", 361 pcibios_setup_phb_resources(hose);
349 hose->io_resource.start, hose->io_resource.end,
350 hose->io_resource.flags);
351 bus->resource[0] = &hose->io_resource;
352 for (i = 0; i < 3; ++i) {
353 DBG("PCI: PHB MEM resource %d = %016lx-%016lx [%lx]\n", i,
354 hose->mem_resources[i].start,
355 hose->mem_resources[i].end,
356 hose->mem_resources[i].flags);
357 bus->resource[i+1] = &hose->mem_resources[i];
358 }
359 DBG("PCI: PHB MEM offset = %016lx\n", hose->pci_mem_offset);
360 DBG("PCI: PHB IO offset = %08lx\n",
361 (unsigned long)hose->io_base_virt - _IO_BASE);
362 362
363 /* Get probe mode and perform scan */ 363 /* Get probe mode and perform scan */
364 mode = PCI_PROBE_NORMAL; 364 mode = PCI_PROBE_NORMAL;
365 if (node && ppc_md.pci_probe_mode) 365 if (node && ppc_md.pci_probe_mode)
366 mode = ppc_md.pci_probe_mode(bus); 366 mode = ppc_md.pci_probe_mode(bus);
367 DBG(" probe mode: %d\n", mode); 367 pr_debug(" probe mode: %d\n", mode);
368 if (mode == PCI_PROBE_DEVTREE) { 368 if (mode == PCI_PROBE_DEVTREE) {
369 bus->subordinate = hose->last_busno; 369 bus->subordinate = hose->last_busno;
370 of_scan_bus(node, bus); 370 of_scan_bus(node, bus);
@@ -380,7 +380,7 @@ static int __init pcibios_init(void)
380 380
381 printk(KERN_INFO "PCI: Probing PCI hardware\n"); 381 printk(KERN_INFO "PCI: Probing PCI hardware\n");
382 382
383 /* For now, override phys_mem_access_prot. If we need it, 383 /* For now, override phys_mem_access_prot. If we need it,g
384 * later, we may move that initialization to each ppc_md 384 * later, we may move that initialization to each ppc_md
385 */ 385 */
386 ppc_md.phys_mem_access_prot = pci_phys_mem_access_prot; 386 ppc_md.phys_mem_access_prot = pci_phys_mem_access_prot;
@@ -388,6 +388,11 @@ static int __init pcibios_init(void)
388 if (pci_probe_only) 388 if (pci_probe_only)
389 ppc_pci_flags |= PPC_PCI_PROBE_ONLY; 389 ppc_pci_flags |= PPC_PCI_PROBE_ONLY;
390 390
391 /* On ppc64, we always enable PCI domains and we keep domain 0
392 * backward compatible in /proc for video cards
393 */
394 ppc_pci_flags |= PPC_PCI_ENABLE_PROC_DOMAINS | PPC_PCI_COMPAT_DOMAIN_0;
395
391 /* Scan all of the recorded PCI controllers. */ 396 /* Scan all of the recorded PCI controllers. */
392 list_for_each_entry_safe(hose, tmp, &hose_list, list_node) { 397 list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
393 scan_phb(hose); 398 scan_phb(hose);
@@ -422,8 +427,8 @@ int pcibios_unmap_io_space(struct pci_bus *bus)
422 if (bus->self) { 427 if (bus->self) {
423 struct resource *res = bus->resource[0]; 428 struct resource *res = bus->resource[0];
424 429
425 DBG("IO unmapping for PCI-PCI bridge %s\n", 430 pr_debug("IO unmapping for PCI-PCI bridge %s\n",
426 pci_name(bus->self)); 431 pci_name(bus->self));
427 432
428 __flush_hash_table_range(&init_mm, res->start + _IO_BASE, 433 __flush_hash_table_range(&init_mm, res->start + _IO_BASE,
429 res->end + _IO_BASE + 1); 434 res->end + _IO_BASE + 1);
@@ -437,8 +442,8 @@ int pcibios_unmap_io_space(struct pci_bus *bus)
437 if (hose->io_base_alloc == 0) 442 if (hose->io_base_alloc == 0)
438 return 0; 443 return 0;
439 444
440 DBG("IO unmapping for PHB %s\n", hose->dn->full_name); 445 pr_debug("IO unmapping for PHB %s\n", hose->dn->full_name);
441 DBG(" alloc=0x%p\n", hose->io_base_alloc); 446 pr_debug(" alloc=0x%p\n", hose->io_base_alloc);
442 447
443 /* This is a PHB, we fully unmap the IO area */ 448 /* This is a PHB, we fully unmap the IO area */
444 vunmap(hose->io_base_alloc); 449 vunmap(hose->io_base_alloc);
@@ -463,11 +468,11 @@ int __devinit pcibios_map_io_space(struct pci_bus *bus)
463 * thus HPTEs will be faulted in when needed 468 * thus HPTEs will be faulted in when needed
464 */ 469 */
465 if (bus->self) { 470 if (bus->self) {
466 DBG("IO mapping for PCI-PCI bridge %s\n", 471 pr_debug("IO mapping for PCI-PCI bridge %s\n",
467 pci_name(bus->self)); 472 pci_name(bus->self));
468 DBG(" virt=0x%016lx...0x%016lx\n", 473 pr_debug(" virt=0x%016lx...0x%016lx\n",
469 bus->resource[0]->start + _IO_BASE, 474 bus->resource[0]->start + _IO_BASE,
470 bus->resource[0]->end + _IO_BASE); 475 bus->resource[0]->end + _IO_BASE);
471 return 0; 476 return 0;
472 } 477 }
473 478
@@ -496,11 +501,11 @@ int __devinit pcibios_map_io_space(struct pci_bus *bus)
496 hose->io_base_virt = (void __iomem *)(area->addr + 501 hose->io_base_virt = (void __iomem *)(area->addr +
497 hose->io_base_phys - phys_page); 502 hose->io_base_phys - phys_page);
498 503
499 DBG("IO mapping for PHB %s\n", hose->dn->full_name); 504 pr_debug("IO mapping for PHB %s\n", hose->dn->full_name);
500 DBG(" phys=0x%016lx, virt=0x%p (alloc=0x%p)\n", 505 pr_debug(" phys=0x%016lx, virt=0x%p (alloc=0x%p)\n",
501 hose->io_base_phys, hose->io_base_virt, hose->io_base_alloc); 506 hose->io_base_phys, hose->io_base_virt, hose->io_base_alloc);
502 DBG(" size=0x%016lx (alloc=0x%016lx)\n", 507 pr_debug(" size=0x%016lx (alloc=0x%016lx)\n",
503 hose->pci_io_size, size_page); 508 hose->pci_io_size, size_page);
504 509
505 /* Establish the mapping */ 510 /* Establish the mapping */
506 if (__ioremap_at(phys_page, area->addr, size_page, 511 if (__ioremap_at(phys_page, area->addr, size_page,
@@ -512,24 +517,13 @@ int __devinit pcibios_map_io_space(struct pci_bus *bus)
512 hose->io_resource.start += io_virt_offset; 517 hose->io_resource.start += io_virt_offset;
513 hose->io_resource.end += io_virt_offset; 518 hose->io_resource.end += io_virt_offset;
514 519
515 DBG(" hose->io_resource=0x%016lx...0x%016lx\n", 520 pr_debug(" hose->io_resource=0x%016lx...0x%016lx\n",
516 hose->io_resource.start, hose->io_resource.end); 521 hose->io_resource.start, hose->io_resource.end);
517 522
518 return 0; 523 return 0;
519} 524}
520EXPORT_SYMBOL_GPL(pcibios_map_io_space); 525EXPORT_SYMBOL_GPL(pcibios_map_io_space);
521 526
522void __devinit pcibios_do_bus_setup(struct pci_bus *bus)
523{
524 struct pci_dev *dev;
525
526 if (ppc_md.pci_dma_bus_setup)
527 ppc_md.pci_dma_bus_setup(bus);
528
529 list_for_each_entry(dev, &bus->devices, bus_list)
530 pcibios_setup_new_device(dev);
531}
532
533unsigned long pci_address_to_pio(phys_addr_t address) 527unsigned long pci_address_to_pio(phys_addr_t address)
534{ 528{
535 struct pci_controller *hose, *tmp; 529 struct pci_controller *hose, *tmp;
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 957bded0020d..51b201ddf9a1 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -467,6 +467,8 @@ static struct regbit {
467 {MSR_VEC, "VEC"}, 467 {MSR_VEC, "VEC"},
468 {MSR_VSX, "VSX"}, 468 {MSR_VSX, "VSX"},
469 {MSR_ME, "ME"}, 469 {MSR_ME, "ME"},
470 {MSR_CE, "CE"},
471 {MSR_DE, "DE"},
470 {MSR_IR, "IR"}, 472 {MSR_IR, "IR"},
471 {MSR_DR, "DR"}, 473 {MSR_DR, "DR"},
472 {0, NULL} 474 {0, NULL}
@@ -998,7 +1000,7 @@ unsigned long get_wchan(struct task_struct *p)
998 return 0; 1000 return 0;
999} 1001}
1000 1002
1001static int kstack_depth_to_print = 64; 1003static int kstack_depth_to_print = CONFIG_PRINT_STACK_DEPTH;
1002 1004
1003void show_stack(struct task_struct *tsk, unsigned long *stack) 1005void show_stack(struct task_struct *tsk, unsigned long *stack)
1004{ 1006{
diff --git a/arch/powerpc/kernel/prom_parse.c b/arch/powerpc/kernel/prom_parse.c
index a11d68976dc8..8c1335566089 100644
--- a/arch/powerpc/kernel/prom_parse.c
+++ b/arch/powerpc/kernel/prom_parse.c
@@ -734,10 +734,7 @@ void of_irq_map_init(unsigned int flags)
734 if (flags & OF_IMAP_NO_PHANDLE) { 734 if (flags & OF_IMAP_NO_PHANDLE) {
735 struct device_node *np; 735 struct device_node *np;
736 736
737 for(np = NULL; (np = of_find_all_nodes(np)) != NULL;) { 737 for_each_node_with_property(np, "interrupt-controller") {
738 if (of_get_property(np, "interrupt-controller", NULL)
739 == NULL)
740 continue;
741 /* Skip /chosen/interrupt-controller */ 738 /* Skip /chosen/interrupt-controller */
742 if (strcmp(np->name, "chosen") == 0) 739 if (strcmp(np->name, "chosen") == 0)
743 continue; 740 continue;
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
index 1f8505c23548..fdfe14c4bdef 100644
--- a/arch/powerpc/kernel/rtas.c
+++ b/arch/powerpc/kernel/rtas.c
@@ -566,6 +566,32 @@ int rtas_get_sensor(int sensor, int index, int *state)
566} 566}
567EXPORT_SYMBOL(rtas_get_sensor); 567EXPORT_SYMBOL(rtas_get_sensor);
568 568
569bool rtas_indicator_present(int token, int *maxindex)
570{
571 int proplen, count, i;
572 const struct indicator_elem {
573 u32 token;
574 u32 maxindex;
575 } *indicators;
576
577 indicators = of_get_property(rtas.dev, "rtas-indicators", &proplen);
578 if (!indicators)
579 return false;
580
581 count = proplen / sizeof(struct indicator_elem);
582
583 for (i = 0; i < count; i++) {
584 if (indicators[i].token != token)
585 continue;
586 if (maxindex)
587 *maxindex = indicators[i].maxindex;
588 return true;
589 }
590
591 return false;
592}
593EXPORT_SYMBOL(rtas_indicator_present);
594
569int rtas_set_indicator(int indicator, int index, int new_value) 595int rtas_set_indicator(int indicator, int index, int new_value)
570{ 596{
571 int token = rtas_token("set-indicator"); 597 int token = rtas_token("set-indicator");
diff --git a/arch/powerpc/kernel/rtas_pci.c b/arch/powerpc/kernel/rtas_pci.c
index 589a2797eac2..8869001ab5d7 100644
--- a/arch/powerpc/kernel/rtas_pci.c
+++ b/arch/powerpc/kernel/rtas_pci.c
@@ -301,51 +301,3 @@ void __init find_and_init_phbs(void)
301#endif /* CONFIG_PPC32 */ 301#endif /* CONFIG_PPC32 */
302 } 302 }
303} 303}
304
305/* RPA-specific bits for removing PHBs */
306int pcibios_remove_root_bus(struct pci_controller *phb)
307{
308 struct pci_bus *b = phb->bus;
309 struct resource *res;
310 int rc, i;
311
312 res = b->resource[0];
313 if (!res->flags) {
314 printk(KERN_ERR "%s: no IO resource for PHB %s\n", __func__,
315 b->name);
316 return 1;
317 }
318
319 rc = pcibios_unmap_io_space(b);
320 if (rc) {
321 printk(KERN_ERR "%s: failed to unmap IO on bus %s\n",
322 __func__, b->name);
323 return 1;
324 }
325
326 if (release_resource(res)) {
327 printk(KERN_ERR "%s: failed to release IO on bus %s\n",
328 __func__, b->name);
329 return 1;
330 }
331
332 for (i = 1; i < 3; ++i) {
333 res = b->resource[i];
334 if (!res->flags && i == 0) {
335 printk(KERN_ERR "%s: no MEM resource for PHB %s\n",
336 __func__, b->name);
337 return 1;
338 }
339 if (res->flags && release_resource(res)) {
340 printk(KERN_ERR
341 "%s: failed to release IO %d on bus %s\n",
342 __func__, i, b->name);
343 return 1;
344 }
345 }
346
347 pcibios_free_controller(phb);
348
349 return 0;
350}
351EXPORT_SYMBOL(pcibios_remove_root_bus);
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c
index c1a27626a940..086c23c1ee5e 100644
--- a/arch/powerpc/kernel/setup_32.c
+++ b/arch/powerpc/kernel/setup_32.c
@@ -49,12 +49,12 @@ int boot_cpuid;
49EXPORT_SYMBOL_GPL(boot_cpuid); 49EXPORT_SYMBOL_GPL(boot_cpuid);
50int boot_cpuid_phys; 50int boot_cpuid_phys;
51 51
52int smp_hw_index[NR_CPUS];
53
52unsigned long ISA_DMA_THRESHOLD; 54unsigned long ISA_DMA_THRESHOLD;
53unsigned int DMA_MODE_READ; 55unsigned int DMA_MODE_READ;
54unsigned int DMA_MODE_WRITE; 56unsigned int DMA_MODE_WRITE;
55 57
56int have_of = 1;
57
58#ifdef CONFIG_VGA_CONSOLE 58#ifdef CONFIG_VGA_CONSOLE
59unsigned long vgacon_remap_base; 59unsigned long vgacon_remap_base;
60EXPORT_SYMBOL(vgacon_remap_base); 60EXPORT_SYMBOL(vgacon_remap_base);
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index 169d74cef157..ce48f5c5c542 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -70,7 +70,6 @@
70#define DBG(fmt...) 70#define DBG(fmt...)
71#endif 71#endif
72 72
73int have_of = 1;
74int boot_cpuid = 0; 73int boot_cpuid = 0;
75u64 ppc64_pft_size; 74u64 ppc64_pft_size;
76 75
@@ -606,8 +605,6 @@ void __init setup_per_cpu_areas(void)
606 605
607 for_each_possible_cpu(i) { 606 for_each_possible_cpu(i) {
608 ptr = alloc_bootmem_pages_node(NODE_DATA(cpu_to_node(i)), size); 607 ptr = alloc_bootmem_pages_node(NODE_DATA(cpu_to_node(i)), size);
609 if (!ptr)
610 panic("Cannot allocate cpu data for CPU %d\n", i);
611 608
612 paca[i].data_offset = ptr - __per_cpu_start; 609 paca[i].data_offset = ptr - __per_cpu_start;
613 memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start); 610 memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start);
diff --git a/arch/powerpc/kernel/smp-tbsync.c b/arch/powerpc/kernel/smp-tbsync.c
index bc892e69b4f7..a5e54526403d 100644
--- a/arch/powerpc/kernel/smp-tbsync.c
+++ b/arch/powerpc/kernel/smp-tbsync.c
@@ -113,7 +113,7 @@ void __devinit smp_generic_give_timebase(void)
113{ 113{
114 int i, score, score2, old, min=0, max=5000, offset=1000; 114 int i, score, score2, old, min=0, max=5000, offset=1000;
115 115
116 printk("Synchronizing timebase\n"); 116 pr_debug("Software timebase sync\n");
117 117
118 /* if this fails then this kernel won't work anyway... */ 118 /* if this fails then this kernel won't work anyway... */
119 tbsync = kzalloc( sizeof(*tbsync), GFP_KERNEL ); 119 tbsync = kzalloc( sizeof(*tbsync), GFP_KERNEL );
@@ -123,13 +123,13 @@ void __devinit smp_generic_give_timebase(void)
123 while (!tbsync->ack) 123 while (!tbsync->ack)
124 barrier(); 124 barrier();
125 125
126 printk("Got ack\n"); 126 pr_debug("Got ack\n");
127 127
128 /* binary search */ 128 /* binary search */
129 for (old = -1; old != offset ; offset = (min+max) / 2) { 129 for (old = -1; old != offset ; offset = (min+max) / 2) {
130 score = start_contest(kSetAndTest, offset, NUM_ITER); 130 score = start_contest(kSetAndTest, offset, NUM_ITER);
131 131
132 printk("score %d, offset %d\n", score, offset ); 132 pr_debug("score %d, offset %d\n", score, offset );
133 133
134 if( score > 0 ) 134 if( score > 0 )
135 max = offset; 135 max = offset;
@@ -140,8 +140,8 @@ void __devinit smp_generic_give_timebase(void)
140 score = start_contest(kSetAndTest, min, NUM_ITER); 140 score = start_contest(kSetAndTest, min, NUM_ITER);
141 score2 = start_contest(kSetAndTest, max, NUM_ITER); 141 score2 = start_contest(kSetAndTest, max, NUM_ITER);
142 142
143 printk("Min %d (score %d), Max %d (score %d)\n", 143 pr_debug("Min %d (score %d), Max %d (score %d)\n",
144 min, score, max, score2); 144 min, score, max, score2);
145 score = abs(score); 145 score = abs(score);
146 score2 = abs(score2); 146 score2 = abs(score2);
147 offset = (score < score2) ? min : max; 147 offset = (score < score2) ? min : max;
@@ -155,7 +155,7 @@ void __devinit smp_generic_give_timebase(void)
155 if (score2 <= score || score2 < 20) 155 if (score2 <= score || score2 < 20)
156 break; 156 break;
157 } 157 }
158 printk("Final offset: %d (%d/%d)\n", offset, score2, NUM_ITER ); 158 pr_debug("Final offset: %d (%d/%d)\n", offset, score2, NUM_ITER );
159 159
160 /* exiting */ 160 /* exiting */
161 tbsync->cmd = kExit; 161 tbsync->cmd = kExit;
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index ff9f7010097d..ffcb1779a220 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -57,7 +57,6 @@
57#define DBG(fmt...) 57#define DBG(fmt...)
58#endif 58#endif
59 59
60int smp_hw_index[NR_CPUS];
61struct thread_info *secondary_ti; 60struct thread_info *secondary_ti;
62 61
63cpumask_t cpu_possible_map = CPU_MASK_NONE; 62cpumask_t cpu_possible_map = CPU_MASK_NONE;
@@ -123,6 +122,65 @@ void smp_message_recv(int msg)
123 } 122 }
124} 123}
125 124
125static irqreturn_t call_function_action(int irq, void *data)
126{
127 generic_smp_call_function_interrupt();
128 return IRQ_HANDLED;
129}
130
131static irqreturn_t reschedule_action(int irq, void *data)
132{
133 /* we just need the return path side effect of checking need_resched */
134 return IRQ_HANDLED;
135}
136
137static irqreturn_t call_function_single_action(int irq, void *data)
138{
139 generic_smp_call_function_single_interrupt();
140 return IRQ_HANDLED;
141}
142
143static irqreturn_t debug_ipi_action(int irq, void *data)
144{
145 smp_message_recv(PPC_MSG_DEBUGGER_BREAK);
146 return IRQ_HANDLED;
147}
148
149static irq_handler_t smp_ipi_action[] = {
150 [PPC_MSG_CALL_FUNCTION] = call_function_action,
151 [PPC_MSG_RESCHEDULE] = reschedule_action,
152 [PPC_MSG_CALL_FUNC_SINGLE] = call_function_single_action,
153 [PPC_MSG_DEBUGGER_BREAK] = debug_ipi_action,
154};
155
156const char *smp_ipi_name[] = {
157 [PPC_MSG_CALL_FUNCTION] = "ipi call function",
158 [PPC_MSG_RESCHEDULE] = "ipi reschedule",
159 [PPC_MSG_CALL_FUNC_SINGLE] = "ipi call function single",
160 [PPC_MSG_DEBUGGER_BREAK] = "ipi debugger",
161};
162
163/* optional function to request ipi, for controllers with >= 4 ipis */
164int smp_request_message_ipi(int virq, int msg)
165{
166 int err;
167
168 if (msg < 0 || msg > PPC_MSG_DEBUGGER_BREAK) {
169 return -EINVAL;
170 }
171#if !defined(CONFIG_DEBUGGER) && !defined(CONFIG_KEXEC)
172 if (msg == PPC_MSG_DEBUGGER_BREAK) {
173 return 1;
174 }
175#endif
176 err = request_irq(virq, smp_ipi_action[msg], IRQF_DISABLED|IRQF_PERCPU,
177 smp_ipi_name[msg], 0);
178 WARN(err < 0, "unable to request_irq %d for %s (rc %d)\n",
179 virq, smp_ipi_name[msg], err);
180
181 return err;
182}
183
126void smp_send_reschedule(int cpu) 184void smp_send_reschedule(int cpu)
127{ 185{
128 if (likely(smp_ops)) 186 if (likely(smp_ops))
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index e2ee66b5831d..e1f3a5140429 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -164,8 +164,6 @@ static u64 tb_to_ns_scale __read_mostly;
164static unsigned tb_to_ns_shift __read_mostly; 164static unsigned tb_to_ns_shift __read_mostly;
165static unsigned long boot_tb __read_mostly; 165static unsigned long boot_tb __read_mostly;
166 166
167static struct gettimeofday_struct do_gtod;
168
169extern struct timezone sys_tz; 167extern struct timezone sys_tz;
170static long timezone_offset; 168static long timezone_offset;
171 169
@@ -415,31 +413,9 @@ void udelay(unsigned long usecs)
415} 413}
416EXPORT_SYMBOL(udelay); 414EXPORT_SYMBOL(udelay);
417 415
418
419/*
420 * There are two copies of tb_to_xs and stamp_xsec so that no
421 * lock is needed to access and use these values in
422 * do_gettimeofday. We alternate the copies and as long as a
423 * reasonable time elapses between changes, there will never
424 * be inconsistent values. ntpd has a minimum of one minute
425 * between updates.
426 */
427static inline void update_gtod(u64 new_tb_stamp, u64 new_stamp_xsec, 416static inline void update_gtod(u64 new_tb_stamp, u64 new_stamp_xsec,
428 u64 new_tb_to_xs) 417 u64 new_tb_to_xs)
429{ 418{
430 unsigned temp_idx;
431 struct gettimeofday_vars *temp_varp;
432
433 temp_idx = (do_gtod.var_idx == 0);
434 temp_varp = &do_gtod.vars[temp_idx];
435
436 temp_varp->tb_to_xs = new_tb_to_xs;
437 temp_varp->tb_orig_stamp = new_tb_stamp;
438 temp_varp->stamp_xsec = new_stamp_xsec;
439 smp_mb();
440 do_gtod.varp = temp_varp;
441 do_gtod.var_idx = temp_idx;
442
443 /* 419 /*
444 * tb_update_count is used to allow the userspace gettimeofday code 420 * tb_update_count is used to allow the userspace gettimeofday code
445 * to assure itself that it sees a consistent view of the tb_to_xs and 421 * to assure itself that it sees a consistent view of the tb_to_xs and
@@ -456,6 +432,7 @@ static inline void update_gtod(u64 new_tb_stamp, u64 new_stamp_xsec,
456 vdso_data->tb_to_xs = new_tb_to_xs; 432 vdso_data->tb_to_xs = new_tb_to_xs;
457 vdso_data->wtom_clock_sec = wall_to_monotonic.tv_sec; 433 vdso_data->wtom_clock_sec = wall_to_monotonic.tv_sec;
458 vdso_data->wtom_clock_nsec = wall_to_monotonic.tv_nsec; 434 vdso_data->wtom_clock_nsec = wall_to_monotonic.tv_nsec;
435 vdso_data->stamp_xtime = xtime;
459 smp_wmb(); 436 smp_wmb();
460 ++(vdso_data->tb_update_count); 437 ++(vdso_data->tb_update_count);
461} 438}
@@ -514,9 +491,7 @@ static int __init iSeries_tb_recal(void)
514 tb_ticks_per_sec = new_tb_ticks_per_sec; 491 tb_ticks_per_sec = new_tb_ticks_per_sec;
515 calc_cputime_factors(); 492 calc_cputime_factors();
516 div128_by_32( XSEC_PER_SEC, 0, tb_ticks_per_sec, &divres ); 493 div128_by_32( XSEC_PER_SEC, 0, tb_ticks_per_sec, &divres );
517 do_gtod.tb_ticks_per_sec = tb_ticks_per_sec;
518 tb_to_xs = divres.result_low; 494 tb_to_xs = divres.result_low;
519 do_gtod.varp->tb_to_xs = tb_to_xs;
520 vdso_data->tb_ticks_per_sec = tb_ticks_per_sec; 495 vdso_data->tb_ticks_per_sec = tb_ticks_per_sec;
521 vdso_data->tb_to_xs = tb_to_xs; 496 vdso_data->tb_to_xs = tb_to_xs;
522 } 497 }
@@ -988,15 +963,6 @@ void __init time_init(void)
988 sys_tz.tz_dsttime = 0; 963 sys_tz.tz_dsttime = 0;
989 } 964 }
990 965
991 do_gtod.varp = &do_gtod.vars[0];
992 do_gtod.var_idx = 0;
993 do_gtod.varp->tb_orig_stamp = tb_last_jiffy;
994 __get_cpu_var(last_jiffy) = tb_last_jiffy;
995 do_gtod.varp->stamp_xsec = (u64) xtime.tv_sec * XSEC_PER_SEC;
996 do_gtod.tb_ticks_per_sec = tb_ticks_per_sec;
997 do_gtod.varp->tb_to_xs = tb_to_xs;
998 do_gtod.tb_to_us = tb_to_us;
999
1000 vdso_data->tb_orig_stamp = tb_last_jiffy; 966 vdso_data->tb_orig_stamp = tb_last_jiffy;
1001 vdso_data->tb_update_count = 0; 967 vdso_data->tb_update_count = 0;
1002 vdso_data->tb_ticks_per_sec = tb_ticks_per_sec; 968 vdso_data->tb_ticks_per_sec = tb_ticks_per_sec;
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index f5def6cf5cd6..5457e9575685 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -1160,37 +1160,85 @@ void CacheLockingException(struct pt_regs *regs, unsigned long address,
1160#ifdef CONFIG_SPE 1160#ifdef CONFIG_SPE
1161void SPEFloatingPointException(struct pt_regs *regs) 1161void SPEFloatingPointException(struct pt_regs *regs)
1162{ 1162{
1163 extern int do_spe_mathemu(struct pt_regs *regs);
1163 unsigned long spefscr; 1164 unsigned long spefscr;
1164 int fpexc_mode; 1165 int fpexc_mode;
1165 int code = 0; 1166 int code = 0;
1167 int err;
1168
1169 preempt_disable();
1170 if (regs->msr & MSR_SPE)
1171 giveup_spe(current);
1172 preempt_enable();
1166 1173
1167 spefscr = current->thread.spefscr; 1174 spefscr = current->thread.spefscr;
1168 fpexc_mode = current->thread.fpexc_mode; 1175 fpexc_mode = current->thread.fpexc_mode;
1169 1176
1170 /* Hardware does not neccessarily set sticky
1171 * underflow/overflow/invalid flags */
1172 if ((spefscr & SPEFSCR_FOVF) && (fpexc_mode & PR_FP_EXC_OVF)) { 1177 if ((spefscr & SPEFSCR_FOVF) && (fpexc_mode & PR_FP_EXC_OVF)) {
1173 code = FPE_FLTOVF; 1178 code = FPE_FLTOVF;
1174 spefscr |= SPEFSCR_FOVFS;
1175 } 1179 }
1176 else if ((spefscr & SPEFSCR_FUNF) && (fpexc_mode & PR_FP_EXC_UND)) { 1180 else if ((spefscr & SPEFSCR_FUNF) && (fpexc_mode & PR_FP_EXC_UND)) {
1177 code = FPE_FLTUND; 1181 code = FPE_FLTUND;
1178 spefscr |= SPEFSCR_FUNFS;
1179 } 1182 }
1180 else if ((spefscr & SPEFSCR_FDBZ) && (fpexc_mode & PR_FP_EXC_DIV)) 1183 else if ((spefscr & SPEFSCR_FDBZ) && (fpexc_mode & PR_FP_EXC_DIV))
1181 code = FPE_FLTDIV; 1184 code = FPE_FLTDIV;
1182 else if ((spefscr & SPEFSCR_FINV) && (fpexc_mode & PR_FP_EXC_INV)) { 1185 else if ((spefscr & SPEFSCR_FINV) && (fpexc_mode & PR_FP_EXC_INV)) {
1183 code = FPE_FLTINV; 1186 code = FPE_FLTINV;
1184 spefscr |= SPEFSCR_FINVS;
1185 } 1187 }
1186 else if ((spefscr & (SPEFSCR_FG | SPEFSCR_FX)) && (fpexc_mode & PR_FP_EXC_RES)) 1188 else if ((spefscr & (SPEFSCR_FG | SPEFSCR_FX)) && (fpexc_mode & PR_FP_EXC_RES))
1187 code = FPE_FLTRES; 1189 code = FPE_FLTRES;
1188 1190
1189 current->thread.spefscr = spefscr; 1191 err = do_spe_mathemu(regs);
1192 if (err == 0) {
1193 regs->nip += 4; /* skip emulated instruction */
1194 emulate_single_step(regs);
1195 return;
1196 }
1197
1198 if (err == -EFAULT) {
1199 /* got an error reading the instruction */
1200 _exception(SIGSEGV, regs, SEGV_ACCERR, regs->nip);
1201 } else if (err == -EINVAL) {
1202 /* didn't recognize the instruction */
1203 printk(KERN_ERR "unrecognized spe instruction "
1204 "in %s at %lx\n", current->comm, regs->nip);
1205 } else {
1206 _exception(SIGFPE, regs, code, regs->nip);
1207 }
1190 1208
1191 _exception(SIGFPE, regs, code, regs->nip);
1192 return; 1209 return;
1193} 1210}
1211
1212void SPEFloatingPointRoundException(struct pt_regs *regs)
1213{
1214 extern int speround_handler(struct pt_regs *regs);
1215 int err;
1216
1217 preempt_disable();
1218 if (regs->msr & MSR_SPE)
1219 giveup_spe(current);
1220 preempt_enable();
1221
1222 regs->nip -= 4;
1223 err = speround_handler(regs);
1224 if (err == 0) {
1225 regs->nip += 4; /* skip emulated instruction */
1226 emulate_single_step(regs);
1227 return;
1228 }
1229
1230 if (err == -EFAULT) {
1231 /* got an error reading the instruction */
1232 _exception(SIGSEGV, regs, SEGV_ACCERR, regs->nip);
1233 } else if (err == -EINVAL) {
1234 /* didn't recognize the instruction */
1235 printk(KERN_ERR "unrecognized spe instruction "
1236 "in %s at %lx\n", current->comm, regs->nip);
1237 } else {
1238 _exception(SIGFPE, regs, 0, regs->nip);
1239 return;
1240 }
1241}
1194#endif 1242#endif
1195 1243
1196/* 1244/*
diff --git a/arch/powerpc/kernel/vdso32/gettimeofday.S b/arch/powerpc/kernel/vdso32/gettimeofday.S
index 72ca26df457e..ee038d4bf252 100644
--- a/arch/powerpc/kernel/vdso32/gettimeofday.S
+++ b/arch/powerpc/kernel/vdso32/gettimeofday.S
@@ -16,6 +16,13 @@
16#include <asm/asm-offsets.h> 16#include <asm/asm-offsets.h>
17#include <asm/unistd.h> 17#include <asm/unistd.h>
18 18
19/* Offset for the low 32-bit part of a field of long type */
20#ifdef CONFIG_PPC64
21#define LOPART 4
22#else
23#define LOPART 0
24#endif
25
19 .text 26 .text
20/* 27/*
21 * Exact prototype of gettimeofday 28 * Exact prototype of gettimeofday
@@ -90,101 +97,53 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime)
90 97
91 mflr r12 /* r12 saves lr */ 98 mflr r12 /* r12 saves lr */
92 .cfi_register lr,r12 99 .cfi_register lr,r12
93 mr r10,r3 /* r10 saves id */
94 mr r11,r4 /* r11 saves tp */ 100 mr r11,r4 /* r11 saves tp */
95 bl __get_datapage@local /* get data page */ 101 bl __get_datapage@local /* get data page */
96 mr r9,r3 /* datapage ptr in r9 */ 102 mr r9,r3 /* datapage ptr in r9 */
97 beq cr1,50f /* if monotonic -> jump there */
98
99 /*
100 * CLOCK_REALTIME
101 */
102
103 bl __do_get_xsec@local /* get xsec from tb & kernel */
104 bne- 98f /* out of line -> do syscall */
105
106 /* seconds are xsec >> 20 */
107 rlwinm r5,r4,12,20,31
108 rlwimi r5,r3,12,0,19
109 stw r5,TSPC32_TV_SEC(r11)
110 103
111 /* get remaining xsec and convert to nsec. we scale 10450: bl __do_get_tspec@local /* get sec/nsec from tb & kernel */
112 * up remaining xsec by 12 bits and get the top 32 bits 105 bne cr1,80f /* not monotonic -> all done */
113 * of the multiplication, then we multiply by 1000
114 */
115 rlwinm r5,r4,12,0,19
116 lis r6,1000000@h
117 ori r6,r6,1000000@l
118 mulhwu r5,r5,r6
119 mulli r5,r5,1000
120 stw r5,TSPC32_TV_NSEC(r11)
121 mtlr r12
122 crclr cr0*4+so
123 li r3,0
124 blr
125 106
126 /* 107 /*
127 * CLOCK_MONOTONIC 108 * CLOCK_MONOTONIC
128 */ 109 */
129 110
13050: bl __do_get_xsec@local /* get xsec from tb & kernel */
131 bne- 98f /* out of line -> do syscall */
132
133 /* seconds are xsec >> 20 */
134 rlwinm r6,r4,12,20,31
135 rlwimi r6,r3,12,0,19
136
137 /* get remaining xsec and convert to nsec. we scale
138 * up remaining xsec by 12 bits and get the top 32 bits
139 * of the multiplication, then we multiply by 1000
140 */
141 rlwinm r7,r4,12,0,19
142 lis r5,1000000@h
143 ori r5,r5,1000000@l
144 mulhwu r7,r7,r5
145 mulli r7,r7,1000
146
147 /* now we must fixup using wall to monotonic. We need to snapshot 111 /* now we must fixup using wall to monotonic. We need to snapshot
148 * that value and do the counter trick again. Fortunately, we still 112 * that value and do the counter trick again. Fortunately, we still
149 * have the counter value in r8 that was returned by __do_get_xsec. 113 * have the counter value in r8 that was returned by __do_get_xsec.
150 * At this point, r6,r7 contain our sec/nsec values, r3,r4 and r5 114 * At this point, r3,r4 contain our sec/nsec values, r5 and r6
151 * can be used 115 * can be used, r7 contains NSEC_PER_SEC.
152 */ 116 */
153 117
154 lwz r3,WTOM_CLOCK_SEC(r9) 118 lwz r5,WTOM_CLOCK_SEC(r9)
155 lwz r4,WTOM_CLOCK_NSEC(r9) 119 lwz r6,WTOM_CLOCK_NSEC(r9)
156 120
157 /* We now have our result in r3,r4. We create a fake dependency 121 /* We now have our offset in r5,r6. We create a fake dependency
158 * on that result and re-check the counter 122 * on that value and re-check the counter
159 */ 123 */
160 or r5,r4,r3 124 or r0,r6,r5
161 xor r0,r5,r5 125 xor r0,r0,r0
162 add r9,r9,r0 126 add r9,r9,r0
163#ifdef CONFIG_PPC64 127 lwz r0,(CFG_TB_UPDATE_COUNT+LOPART)(r9)
164 lwz r0,(CFG_TB_UPDATE_COUNT+4)(r9)
165#else
166 lwz r0,(CFG_TB_UPDATE_COUNT)(r9)
167#endif
168 cmpl cr0,r8,r0 /* check if updated */ 128 cmpl cr0,r8,r0 /* check if updated */
169 bne- 50b 129 bne- 50b
170 130
171 /* Calculate and store result. Note that this mimmics the C code, 131 /* Calculate and store result. Note that this mimics the C code,
172 * which may cause funny results if nsec goes negative... is that 132 * which may cause funny results if nsec goes negative... is that
173 * possible at all ? 133 * possible at all ?
174 */ 134 */
175 add r3,r3,r6 135 add r3,r3,r5
176 add r4,r4,r7 136 add r4,r4,r6
177 lis r5,NSEC_PER_SEC@h 137 cmpw cr0,r4,r7
178 ori r5,r5,NSEC_PER_SEC@l 138 cmpwi cr1,r4,0
179 cmpl cr0,r4,r5
180 cmpli cr1,r4,0
181 blt 1f 139 blt 1f
182 subf r4,r5,r4 140 subf r4,r7,r4
183 addi r3,r3,1 141 addi r3,r3,1
1841: bge cr1,1f 1421: bge cr1,80f
185 addi r3,r3,-1 143 addi r3,r3,-1
186 add r4,r4,r5 144 add r4,r4,r7
1871: stw r3,TSPC32_TV_SEC(r11) 145
14680: stw r3,TSPC32_TV_SEC(r11)
188 stw r4,TSPC32_TV_NSEC(r11) 147 stw r4,TSPC32_TV_NSEC(r11)
189 148
190 mtlr r12 149 mtlr r12
@@ -195,10 +154,6 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime)
195 /* 154 /*
196 * syscall fallback 155 * syscall fallback
197 */ 156 */
19898:
199 mtlr r12
200 mr r3,r10
201 mr r4,r11
20299: 15799:
203 li r0,__NR_clock_gettime 158 li r0,__NR_clock_gettime
204 sc 159 sc
@@ -254,11 +209,7 @@ __do_get_xsec:
254 /* Check for update count & load values. We use the low 209 /* Check for update count & load values. We use the low
255 * order 32 bits of the update count 210 * order 32 bits of the update count
256 */ 211 */
257#ifdef CONFIG_PPC64 2121: lwz r8,(CFG_TB_UPDATE_COUNT+LOPART)(r9)
2581: lwz r8,(CFG_TB_UPDATE_COUNT+4)(r9)
259#else
2601: lwz r8,(CFG_TB_UPDATE_COUNT)(r9)
261#endif
262 andi. r0,r8,1 /* pending update ? loop */ 213 andi. r0,r8,1 /* pending update ? loop */
263 bne- 1b 214 bne- 1b
264 xor r0,r8,r8 /* create dependency */ 215 xor r0,r8,r8 /* create dependency */
@@ -305,11 +256,7 @@ __do_get_xsec:
305 or r6,r4,r3 256 or r6,r4,r3
306 xor r0,r6,r6 257 xor r0,r6,r6
307 add r9,r9,r0 258 add r9,r9,r0
308#ifdef CONFIG_PPC64 259 lwz r0,(CFG_TB_UPDATE_COUNT+LOPART)(r9)
309 lwz r0,(CFG_TB_UPDATE_COUNT+4)(r9)
310#else
311 lwz r0,(CFG_TB_UPDATE_COUNT)(r9)
312#endif
313 cmpl cr0,r8,r0 /* check if updated */ 260 cmpl cr0,r8,r0 /* check if updated */
314 bne- 1b 261 bne- 1b
315 262
@@ -322,3 +269,98 @@ __do_get_xsec:
322 */ 269 */
3233: blr 2703: blr
324 .cfi_endproc 271 .cfi_endproc
272
273/*
274 * This is the core of clock_gettime(), it returns the current
275 * time in seconds and nanoseconds in r3 and r4.
276 * It expects the datapage ptr in r9 and doesn't clobber it.
277 * It clobbers r0, r5, r6, r10 and returns NSEC_PER_SEC in r7.
278 * On return, r8 contains the counter value that can be reused.
279 * This clobbers cr0 but not any other cr field.
280 */
281__do_get_tspec:
282 .cfi_startproc
283 /* Check for update count & load values. We use the low
284 * order 32 bits of the update count
285 */
2861: lwz r8,(CFG_TB_UPDATE_COUNT+LOPART)(r9)
287 andi. r0,r8,1 /* pending update ? loop */
288 bne- 1b
289 xor r0,r8,r8 /* create dependency */
290 add r9,r9,r0
291
292 /* Load orig stamp (offset to TB) */
293 lwz r5,CFG_TB_ORIG_STAMP(r9)
294 lwz r6,(CFG_TB_ORIG_STAMP+4)(r9)
295
296 /* Get a stable TB value */
2972: mftbu r3
298 mftbl r4
299 mftbu r0
300 cmpl cr0,r3,r0
301 bne- 2b
302
303 /* Subtract tb orig stamp and shift left 12 bits.
304 */
305 subfc r7,r6,r4
306 subfe r0,r5,r3
307 slwi r0,r0,12
308 rlwimi. r0,r7,12,20,31
309 slwi r7,r7,12
310
311 /* Load scale factor & do multiplication */
312 lwz r5,CFG_TB_TO_XS(r9) /* load values */
313 lwz r6,(CFG_TB_TO_XS+4)(r9)
314 mulhwu r3,r7,r6
315 mullw r10,r7,r5
316 mulhwu r4,r7,r5
317 addc r10,r3,r10
318 li r3,0
319
320 beq+ 4f /* skip high part computation if 0 */
321 mulhwu r3,r0,r5
322 mullw r7,r0,r5
323 mulhwu r5,r0,r6
324 mullw r6,r0,r6
325 adde r4,r4,r7
326 addze r3,r3
327 addc r4,r4,r5
328 addze r3,r3
329 addc r10,r10,r6
330
3314: addze r4,r4 /* add in carry */
332 lis r7,NSEC_PER_SEC@h
333 ori r7,r7,NSEC_PER_SEC@l
334 mulhwu r4,r4,r7 /* convert to nanoseconds */
335
336 /* At this point, we have seconds & nanoseconds since the xtime
337 * stamp in r3+CA and r4. Load & add the xtime stamp.
338 */
339#ifdef CONFIG_PPC64
340 lwz r5,STAMP_XTIME+TSPC64_TV_SEC+LOPART(r9)
341 lwz r6,STAMP_XTIME+TSPC64_TV_NSEC+LOPART(r9)
342#else
343 lwz r5,STAMP_XTIME+TSPC32_TV_SEC(r9)
344 lwz r6,STAMP_XTIME+TSPC32_TV_NSEC(r9)
345#endif
346 add r4,r4,r6
347 adde r3,r3,r5
348
349 /* We now have our result in r3,r4. We create a fake dependency
350 * on that result and re-check the counter
351 */
352 or r6,r4,r3
353 xor r0,r6,r6
354 add r9,r9,r0
355 lwz r0,(CFG_TB_UPDATE_COUNT+LOPART)(r9)
356 cmpl cr0,r8,r0 /* check if updated */
357 bne- 1b
358
359 /* check for nanosecond overflow and adjust if necessary */
360 cmpw r4,r7
361 bltlr /* all done if no overflow */
362 subf r4,r7,r4 /* adjust if overflow */
363 addi r3,r3,1
364
365 blr
366 .cfi_endproc
diff --git a/arch/powerpc/kernel/vdso64/gettimeofday.S b/arch/powerpc/kernel/vdso64/gettimeofday.S
index c6401f9e37f1..262cd5857a56 100644
--- a/arch/powerpc/kernel/vdso64/gettimeofday.S
+++ b/arch/powerpc/kernel/vdso64/gettimeofday.S
@@ -75,90 +75,49 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime)
75 75
76 mflr r12 /* r12 saves lr */ 76 mflr r12 /* r12 saves lr */
77 .cfi_register lr,r12 77 .cfi_register lr,r12
78 mr r10,r3 /* r10 saves id */
79 mr r11,r4 /* r11 saves tp */ 78 mr r11,r4 /* r11 saves tp */
80 bl V_LOCAL_FUNC(__get_datapage) /* get data page */ 79 bl V_LOCAL_FUNC(__get_datapage) /* get data page */
81 beq cr1,50f /* if monotonic -> jump there */ 8050: bl V_LOCAL_FUNC(__do_get_tspec) /* get time from tb & kernel */
82 81 bne cr1,80f /* if not monotonic, all done */
83 /*
84 * CLOCK_REALTIME
85 */
86
87 bl V_LOCAL_FUNC(__do_get_xsec) /* get xsec from tb & kernel */
88
89 lis r7,15 /* r7 = 1000000 = USEC_PER_SEC */
90 ori r7,r7,16960
91 rldicl r5,r4,44,20 /* r5 = sec = xsec / XSEC_PER_SEC */
92 rldicr r6,r5,20,43 /* r6 = sec * XSEC_PER_SEC */
93 std r5,TSPC64_TV_SEC(r11) /* store sec in tv */
94 subf r0,r6,r4 /* r0 = xsec = (xsec - r6) */
95 mulld r0,r0,r7 /* usec = (xsec * USEC_PER_SEC) /
96 * XSEC_PER_SEC
97 */
98 rldicl r0,r0,44,20
99 mulli r0,r0,1000 /* nsec = usec * 1000 */
100 std r0,TSPC64_TV_NSEC(r11) /* store nsec in tp */
101
102 mtlr r12
103 crclr cr0*4+so
104 li r3,0
105 blr
106 82
107 /* 83 /*
108 * CLOCK_MONOTONIC 84 * CLOCK_MONOTONIC
109 */ 85 */
110 86
11150: bl V_LOCAL_FUNC(__do_get_xsec) /* get xsec from tb & kernel */
112
113 lis r7,15 /* r7 = 1000000 = USEC_PER_SEC */
114 ori r7,r7,16960
115 rldicl r5,r4,44,20 /* r5 = sec = xsec / XSEC_PER_SEC */
116 rldicr r6,r5,20,43 /* r6 = sec * XSEC_PER_SEC */
117 subf r0,r6,r4 /* r0 = xsec = (xsec - r6) */
118 mulld r0,r0,r7 /* usec = (xsec * USEC_PER_SEC) /
119 * XSEC_PER_SEC
120 */
121 rldicl r6,r0,44,20
122 mulli r6,r6,1000 /* nsec = usec * 1000 */
123
124 /* now we must fixup using wall to monotonic. We need to snapshot 87 /* now we must fixup using wall to monotonic. We need to snapshot
125 * that value and do the counter trick again. Fortunately, we still 88 * that value and do the counter trick again. Fortunately, we still
126 * have the counter value in r8 that was returned by __do_get_xsec. 89 * have the counter value in r8 that was returned by __do_get_tspec.
127 * At this point, r5,r6 contain our sec/nsec values. 90 * At this point, r4,r5 contain our sec/nsec values.
128 * can be used
129 */ 91 */
130 92
131 lwa r4,WTOM_CLOCK_SEC(r3) 93 lwa r6,WTOM_CLOCK_SEC(r3)
132 lwa r7,WTOM_CLOCK_NSEC(r3) 94 lwa r9,WTOM_CLOCK_NSEC(r3)
133 95
134 /* We now have our result in r4,r7. We create a fake dependency 96 /* We now have our result in r6,r9. We create a fake dependency
135 * on that result and re-check the counter 97 * on that result and re-check the counter
136 */ 98 */
137 or r9,r4,r7 99 or r0,r6,r9
138 xor r0,r9,r9 100 xor r0,r0,r0
139 add r3,r3,r0 101 add r3,r3,r0
140 ld r0,CFG_TB_UPDATE_COUNT(r3) 102 ld r0,CFG_TB_UPDATE_COUNT(r3)
141 cmpld cr0,r0,r8 /* check if updated */ 103 cmpld cr0,r0,r8 /* check if updated */
142 bne- 50b 104 bne- 50b
143 105
144 /* Calculate and store result. Note that this mimmics the C code, 106 /* Add wall->monotonic offset and check for overflow or underflow.
145 * which may cause funny results if nsec goes negative... is that
146 * possible at all ?
147 */ 107 */
148 add r4,r4,r5 108 add r4,r4,r6
149 add r7,r7,r6 109 add r5,r5,r9
150 lis r9,NSEC_PER_SEC@h 110 cmpd cr0,r5,r7
151 ori r9,r9,NSEC_PER_SEC@l 111 cmpdi cr1,r5,0
152 cmpl cr0,r7,r9
153 cmpli cr1,r7,0
154 blt 1f 112 blt 1f
155 subf r7,r9,r7 113 subf r5,r7,r5
156 addi r4,r4,1 114 addi r4,r4,1
1571: bge cr1,1f 1151: bge cr1,80f
158 addi r4,r4,-1 116 addi r4,r4,-1
159 add r7,r7,r9 117 add r5,r5,r7
1601: std r4,TSPC64_TV_SEC(r11) 118
161 std r7,TSPC64_TV_NSEC(r11) 11980: std r4,TSPC64_TV_SEC(r11)
120 std r5,TSPC64_TV_NSEC(r11)
162 121
163 mtlr r12 122 mtlr r12
164 crclr cr0*4+so 123 crclr cr0*4+so
@@ -168,10 +127,6 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime)
168 /* 127 /*
169 * syscall fallback 128 * syscall fallback
170 */ 129 */
17198:
172 mtlr r12
173 mr r3,r10
174 mr r4,r11
17599: 13099:
176 li r0,__NR_clock_gettime 131 li r0,__NR_clock_gettime
177 sc 132 sc
@@ -253,3 +208,59 @@ V_FUNCTION_BEGIN(__do_get_xsec)
253 blr 208 blr
254 .cfi_endproc 209 .cfi_endproc
255V_FUNCTION_END(__do_get_xsec) 210V_FUNCTION_END(__do_get_xsec)
211
212/*
213 * This is the core of clock_gettime(), it returns the current
214 * time in seconds and nanoseconds in r4 and r5.
215 * It expects the datapage ptr in r3 and doesn't clobber it.
216 * It clobbers r0 and r6 and returns NSEC_PER_SEC in r7.
217 * On return, r8 contains the counter value that can be reused.
218 * This clobbers cr0 but not any other cr field.
219 */
220V_FUNCTION_BEGIN(__do_get_tspec)
221 .cfi_startproc
222 /* check for update count & load values */
2231: ld r8,CFG_TB_UPDATE_COUNT(r3)
224 andi. r0,r8,1 /* pending update ? loop */
225 bne- 1b
226 xor r0,r8,r8 /* create dependency */
227 add r3,r3,r0
228
229 /* Get TB & offset it. We use the MFTB macro which will generate
230 * workaround code for Cell.
231 */
232 MFTB(r7)
233 ld r9,CFG_TB_ORIG_STAMP(r3)
234 subf r7,r9,r7
235
236 /* Scale result */
237 ld r5,CFG_TB_TO_XS(r3)
238 sldi r7,r7,12 /* compute time since stamp_xtime */
239 mulhdu r6,r7,r5 /* in units of 2^-32 seconds */
240
241 /* Add stamp since epoch */
242 ld r4,STAMP_XTIME+TSPC64_TV_SEC(r3)
243 ld r5,STAMP_XTIME+TSPC64_TV_NSEC(r3)
244 or r0,r4,r5
245 or r0,r0,r6
246 xor r0,r0,r0
247 add r3,r3,r0
248 ld r0,CFG_TB_UPDATE_COUNT(r3)
249 cmpld r0,r8 /* check if updated */
250 bne- 1b /* reload if so */
251
252 /* convert to seconds & nanoseconds and add to stamp */
253 lis r7,NSEC_PER_SEC@h
254 ori r7,r7,NSEC_PER_SEC@l
255 mulhwu r0,r6,r7 /* compute nanoseconds and */
256 srdi r6,r6,32 /* seconds since stamp_xtime */
257 clrldi r0,r0,32
258 add r5,r5,r0 /* add nanoseconds together */
259 cmpd r5,r7 /* overflow? */
260 add r4,r4,r6
261 bltlr /* all done if no overflow */
262 subf r5,r7,r5 /* if overflow, adjust */
263 addi r4,r4,1
264 blr
265 .cfi_endproc
266V_FUNCTION_END(__do_get_tspec)
diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c
index a11e6bc59b30..94aa7b011b27 100644
--- a/arch/powerpc/kernel/vio.c
+++ b/arch/powerpc/kernel/vio.c
@@ -41,9 +41,9 @@
41static struct bus_type vio_bus_type; 41static struct bus_type vio_bus_type;
42 42
43static struct vio_dev vio_bus_device = { /* fake "parent" device */ 43static struct vio_dev vio_bus_device = { /* fake "parent" device */
44 .name = vio_bus_device.dev.bus_id, 44 .name = "vio",
45 .type = "", 45 .type = "",
46 .dev.bus_id = "vio", 46 .dev.init_name = "vio",
47 .dev.bus = &vio_bus_type, 47 .dev.bus = &vio_bus_type,
48}; 48};
49 49
@@ -1216,7 +1216,7 @@ struct vio_dev *vio_register_device_node(struct device_node *of_node)
1216 1216
1217 viodev->irq = irq_of_parse_and_map(of_node, 0); 1217 viodev->irq = irq_of_parse_and_map(of_node, 0);
1218 1218
1219 snprintf(viodev->dev.bus_id, BUS_ID_SIZE, "%x", *unit_address); 1219 dev_set_name(&viodev->dev, "%x", *unit_address);
1220 viodev->name = of_node->name; 1220 viodev->name = of_node->name;
1221 viodev->type = of_node->type; 1221 viodev->type = of_node->type;
1222 viodev->unit_address = *unit_address; 1222 viodev->unit_address = *unit_address;
@@ -1243,7 +1243,7 @@ struct vio_dev *vio_register_device_node(struct device_node *of_node)
1243 /* register with generic device framework */ 1243 /* register with generic device framework */
1244 if (device_register(&viodev->dev)) { 1244 if (device_register(&viodev->dev)) {
1245 printk(KERN_ERR "%s: failed to register device %s\n", 1245 printk(KERN_ERR "%s: failed to register device %s\n",
1246 __func__, viodev->dev.bus_id); 1246 __func__, dev_name(&viodev->dev));
1247 /* XXX free TCE table */ 1247 /* XXX free TCE table */
1248 kfree(viodev); 1248 kfree(viodev);
1249 return NULL; 1249 return NULL;
@@ -1400,13 +1400,13 @@ static struct vio_dev *vio_find_name(const char *name)
1400struct vio_dev *vio_find_node(struct device_node *vnode) 1400struct vio_dev *vio_find_node(struct device_node *vnode)
1401{ 1401{
1402 const uint32_t *unit_address; 1402 const uint32_t *unit_address;
1403 char kobj_name[BUS_ID_SIZE]; 1403 char kobj_name[20];
1404 1404
1405 /* construct the kobject name from the device node */ 1405 /* construct the kobject name from the device node */
1406 unit_address = of_get_property(vnode, "reg", NULL); 1406 unit_address = of_get_property(vnode, "reg", NULL);
1407 if (!unit_address) 1407 if (!unit_address)
1408 return NULL; 1408 return NULL;
1409 snprintf(kobj_name, BUS_ID_SIZE, "%x", *unit_address); 1409 snprintf(kobj_name, sizeof(kobj_name), "%x", *unit_address);
1410 1410
1411 return vio_find_name(kobj_name); 1411 return vio_find_name(kobj_name);
1412} 1412}
diff --git a/arch/powerpc/lib/copyuser_64.S b/arch/powerpc/lib/copyuser_64.S
index 25ec5378afa4..70693a5c12a1 100644
--- a/arch/powerpc/lib/copyuser_64.S
+++ b/arch/powerpc/lib/copyuser_64.S
@@ -26,11 +26,24 @@ _GLOBAL(__copy_tofrom_user)
26 andi. r6,r6,7 26 andi. r6,r6,7
27 PPC_MTOCRF 0x01,r5 27 PPC_MTOCRF 0x01,r5
28 blt cr1,.Lshort_copy 28 blt cr1,.Lshort_copy
29/* Below we want to nop out the bne if we're on a CPU that has the
30 * CPU_FTR_UNALIGNED_LD_STD bit set and the CPU_FTR_CP_USE_DCBTZ bit
31 * cleared.
32 * At the time of writing the only CPU that has this combination of bits
33 * set is Power6.
34 */
35BEGIN_FTR_SECTION
36 nop
37FTR_SECTION_ELSE
29 bne .Ldst_unaligned 38 bne .Ldst_unaligned
39ALT_FTR_SECTION_END(CPU_FTR_UNALIGNED_LD_STD | CPU_FTR_CP_USE_DCBTZ, \
40 CPU_FTR_UNALIGNED_LD_STD)
30.Ldst_aligned: 41.Ldst_aligned:
31 andi. r0,r4,7
32 addi r3,r3,-16 42 addi r3,r3,-16
43BEGIN_FTR_SECTION
44 andi. r0,r4,7
33 bne .Lsrc_unaligned 45 bne .Lsrc_unaligned
46END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_LD_STD)
34 srdi r7,r5,4 47 srdi r7,r5,4
3520: ld r9,0(r4) 4820: ld r9,0(r4)
36 addi r4,r4,-8 49 addi r4,r4,-8
@@ -138,7 +151,7 @@ _GLOBAL(__copy_tofrom_user)
138 PPC_MTOCRF 0x01,r6 /* put #bytes to 8B bdry into cr7 */ 151 PPC_MTOCRF 0x01,r6 /* put #bytes to 8B bdry into cr7 */
139 subf r5,r6,r5 152 subf r5,r6,r5
140 li r7,0 153 li r7,0
141 cmpldi r1,r5,16 154 cmpldi cr1,r5,16
142 bf cr7*4+3,1f 155 bf cr7*4+3,1f
14335: lbz r0,0(r4) 15635: lbz r0,0(r4)
14481: stb r0,0(r3) 15781: stb r0,0(r3)
diff --git a/arch/powerpc/lib/dma-noncoherent.c b/arch/powerpc/lib/dma-noncoherent.c
index 31734c0969cd..2b1ce1849344 100644
--- a/arch/powerpc/lib/dma-noncoherent.c
+++ b/arch/powerpc/lib/dma-noncoherent.c
@@ -320,7 +320,6 @@ static int __init dma_alloc_init(void)
320 ret = -ENOMEM; 320 ret = -ENOMEM;
321 break; 321 break;
322 } 322 }
323 WARN_ON(!pmd_none(*pmd));
324 323
325 pte = pte_alloc_kernel(pmd, CONSISTENT_BASE); 324 pte = pte_alloc_kernel(pmd, CONSISTENT_BASE);
326 if (!pte) { 325 if (!pte) {
diff --git a/arch/powerpc/lib/memcpy_64.S b/arch/powerpc/lib/memcpy_64.S
index 3f131129d1c1..fe2d34e5332d 100644
--- a/arch/powerpc/lib/memcpy_64.S
+++ b/arch/powerpc/lib/memcpy_64.S
@@ -18,11 +18,23 @@ _GLOBAL(memcpy)
18 andi. r6,r6,7 18 andi. r6,r6,7
19 dcbt 0,r4 19 dcbt 0,r4
20 blt cr1,.Lshort_copy 20 blt cr1,.Lshort_copy
21/* Below we want to nop out the bne if we're on a CPU that has the
22 CPU_FTR_UNALIGNED_LD_STD bit set and the CPU_FTR_CP_USE_DCBTZ bit
23 cleared.
24 At the time of writing the only CPU that has this combination of bits
25 set is Power6. */
26BEGIN_FTR_SECTION
27 nop
28FTR_SECTION_ELSE
21 bne .Ldst_unaligned 29 bne .Ldst_unaligned
30ALT_FTR_SECTION_END(CPU_FTR_UNALIGNED_LD_STD | CPU_FTR_CP_USE_DCBTZ, \
31 CPU_FTR_UNALIGNED_LD_STD)
22.Ldst_aligned: 32.Ldst_aligned:
23 andi. r0,r4,7
24 addi r3,r3,-16 33 addi r3,r3,-16
34BEGIN_FTR_SECTION
35 andi. r0,r4,7
25 bne .Lsrc_unaligned 36 bne .Lsrc_unaligned
37END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_LD_STD)
26 srdi r7,r5,4 38 srdi r7,r5,4
27 ld r9,0(r4) 39 ld r9,0(r4)
28 addi r4,r4,-8 40 addi r4,r4,-8
@@ -131,7 +143,7 @@ _GLOBAL(memcpy)
131 PPC_MTOCRF 0x01,r6 # put #bytes to 8B bdry into cr7 143 PPC_MTOCRF 0x01,r6 # put #bytes to 8B bdry into cr7
132 subf r5,r6,r5 144 subf r5,r6,r5
133 li r7,0 145 li r7,0
134 cmpldi r1,r5,16 146 cmpldi cr1,r5,16
135 bf cr7*4+3,1f 147 bf cr7*4+3,1f
136 lbz r0,0(r4) 148 lbz r0,0(r4)
137 stb r0,0(r3) 149 stb r0,0(r3)
diff --git a/arch/powerpc/math-emu/Makefile b/arch/powerpc/math-emu/Makefile
index 03aa98dd9f0a..f9e506a735ae 100644
--- a/arch/powerpc/math-emu/Makefile
+++ b/arch/powerpc/math-emu/Makefile
@@ -11,6 +11,8 @@ obj-$(CONFIG_MATH_EMULATION) += fabs.o fadd.o fadds.o fcmpo.o fcmpu.o \
11 mcrfs.o mffs.o mtfsb0.o mtfsb1.o \ 11 mcrfs.o mffs.o mtfsb0.o mtfsb1.o \
12 mtfsf.o mtfsfi.o stfiwx.o stfs.o 12 mtfsf.o mtfsfi.o stfiwx.o stfs.o
13 13
14obj-$(CONFIG_SPE) += math_efp.o
15
14CFLAGS_fabs.o = -fno-builtin-fabs 16CFLAGS_fabs.o = -fno-builtin-fabs
15CFLAGS_math.o = -fno-builtin-fabs 17CFLAGS_math.o = -fno-builtin-fabs
16 18
diff --git a/arch/powerpc/math-emu/fadd.c b/arch/powerpc/math-emu/fadd.c
index 04d3b4aa32ce..0158a16e2b82 100644
--- a/arch/powerpc/math-emu/fadd.c
+++ b/arch/powerpc/math-emu/fadd.c
@@ -13,7 +13,6 @@ fadd(void *frD, void *frA, void *frB)
13 FP_DECL_D(B); 13 FP_DECL_D(B);
14 FP_DECL_D(R); 14 FP_DECL_D(R);
15 FP_DECL_EX; 15 FP_DECL_EX;
16 int ret = 0;
17 16
18#ifdef DEBUG 17#ifdef DEBUG
19 printk("%s: %p %p %p\n", __func__, frD, frA, frB); 18 printk("%s: %p %p %p\n", __func__, frD, frA, frB);
diff --git a/arch/powerpc/math-emu/fcmpo.c b/arch/powerpc/math-emu/fcmpo.c
index b5dc4498cd71..5bce011c2aec 100644
--- a/arch/powerpc/math-emu/fcmpo.c
+++ b/arch/powerpc/math-emu/fcmpo.c
@@ -14,7 +14,6 @@ fcmpo(u32 *ccr, int crfD, void *frA, void *frB)
14 FP_DECL_EX; 14 FP_DECL_EX;
15 int code[4] = { (1 << 3), (1 << 1), (1 << 2), (1 << 0) }; 15 int code[4] = { (1 << 3), (1 << 1), (1 << 2), (1 << 0) };
16 long cmp; 16 long cmp;
17 int ret = 0;
18 17
19#ifdef DEBUG 18#ifdef DEBUG
20 printk("%s: %p (%08x) %d %p %p\n", __func__, ccr, *ccr, crfD, frA, frB); 19 printk("%s: %p (%08x) %d %p %p\n", __func__, ccr, *ccr, crfD, frA, frB);
@@ -29,7 +28,7 @@ fcmpo(u32 *ccr, int crfD, void *frA, void *frB)
29#endif 28#endif
30 29
31 if (A_c == FP_CLS_NAN || B_c == FP_CLS_NAN) 30 if (A_c == FP_CLS_NAN || B_c == FP_CLS_NAN)
32 ret |= EFLAG_VXVC; 31 FP_SET_EXCEPTION(EFLAG_VXVC);
33 32
34 FP_CMP_D(cmp, A, B, 2); 33 FP_CMP_D(cmp, A, B, 2);
35 cmp = code[(cmp + 1) & 3]; 34 cmp = code[(cmp + 1) & 3];
@@ -44,5 +43,5 @@ fcmpo(u32 *ccr, int crfD, void *frA, void *frB)
44 printk("CR: %08x\n", *ccr); 43 printk("CR: %08x\n", *ccr);
45#endif 44#endif
46 45
47 return ret; 46 return FP_CUR_EXCEPTIONS;
48} 47}
diff --git a/arch/powerpc/math-emu/fdiv.c b/arch/powerpc/math-emu/fdiv.c
index 2db15097d98e..a29239c05e3e 100644
--- a/arch/powerpc/math-emu/fdiv.c
+++ b/arch/powerpc/math-emu/fdiv.c
@@ -13,7 +13,6 @@ fdiv(void *frD, void *frA, void *frB)
13 FP_DECL_D(B); 13 FP_DECL_D(B);
14 FP_DECL_D(R); 14 FP_DECL_D(R);
15 FP_DECL_EX; 15 FP_DECL_EX;
16 int ret = 0;
17 16
18#ifdef DEBUG 17#ifdef DEBUG
19 printk("%s: %p %p %p\n", __func__, frD, frA, frB); 18 printk("%s: %p %p %p\n", __func__, frD, frA, frB);
@@ -28,22 +27,22 @@ fdiv(void *frD, void *frA, void *frB)
28#endif 27#endif
29 28
30 if (A_c == FP_CLS_ZERO && B_c == FP_CLS_ZERO) { 29 if (A_c == FP_CLS_ZERO && B_c == FP_CLS_ZERO) {
31 ret |= EFLAG_VXZDZ; 30 FP_SET_EXCEPTION(EFLAG_VXZDZ);
32#ifdef DEBUG 31#ifdef DEBUG
33 printk("%s: FPSCR_VXZDZ raised\n", __func__); 32 printk("%s: FPSCR_VXZDZ raised\n", __func__);
34#endif 33#endif
35 } 34 }
36 if (A_c == FP_CLS_INF && B_c == FP_CLS_INF) { 35 if (A_c == FP_CLS_INF && B_c == FP_CLS_INF) {
37 ret |= EFLAG_VXIDI; 36 FP_SET_EXCEPTION(EFLAG_VXIDI);
38#ifdef DEBUG 37#ifdef DEBUG
39 printk("%s: FPSCR_VXIDI raised\n", __func__); 38 printk("%s: FPSCR_VXIDI raised\n", __func__);
40#endif 39#endif
41 } 40 }
42 41
43 if (B_c == FP_CLS_ZERO && A_c != FP_CLS_ZERO) { 42 if (B_c == FP_CLS_ZERO && A_c != FP_CLS_ZERO) {
44 ret |= EFLAG_DIVZERO; 43 FP_SET_EXCEPTION(EFLAG_DIVZERO);
45 if (__FPU_TRAP_P(EFLAG_DIVZERO)) 44 if (__FPU_TRAP_P(EFLAG_DIVZERO))
46 return ret; 45 return FP_CUR_EXCEPTIONS;
47 } 46 }
48 FP_DIV_D(R, A, B); 47 FP_DIV_D(R, A, B);
49 48
diff --git a/arch/powerpc/math-emu/fdivs.c b/arch/powerpc/math-emu/fdivs.c
index 797f6a9a20b5..526bc261275f 100644
--- a/arch/powerpc/math-emu/fdivs.c
+++ b/arch/powerpc/math-emu/fdivs.c
@@ -14,7 +14,6 @@ fdivs(void *frD, void *frA, void *frB)
14 FP_DECL_D(B); 14 FP_DECL_D(B);
15 FP_DECL_D(R); 15 FP_DECL_D(R);
16 FP_DECL_EX; 16 FP_DECL_EX;
17 int ret = 0;
18 17
19#ifdef DEBUG 18#ifdef DEBUG
20 printk("%s: %p %p %p\n", __func__, frD, frA, frB); 19 printk("%s: %p %p %p\n", __func__, frD, frA, frB);
@@ -29,22 +28,22 @@ fdivs(void *frD, void *frA, void *frB)
29#endif 28#endif
30 29
31 if (A_c == FP_CLS_ZERO && B_c == FP_CLS_ZERO) { 30 if (A_c == FP_CLS_ZERO && B_c == FP_CLS_ZERO) {
32 ret |= EFLAG_VXZDZ; 31 FP_SET_EXCEPTION(EFLAG_VXZDZ);
33#ifdef DEBUG 32#ifdef DEBUG
34 printk("%s: FPSCR_VXZDZ raised\n", __func__); 33 printk("%s: FPSCR_VXZDZ raised\n", __func__);
35#endif 34#endif
36 } 35 }
37 if (A_c == FP_CLS_INF && B_c == FP_CLS_INF) { 36 if (A_c == FP_CLS_INF && B_c == FP_CLS_INF) {
38 ret |= EFLAG_VXIDI; 37 FP_SET_EXCEPTION(EFLAG_VXIDI);
39#ifdef DEBUG 38#ifdef DEBUG
40 printk("%s: FPSCR_VXIDI raised\n", __func__); 39 printk("%s: FPSCR_VXIDI raised\n", __func__);
41#endif 40#endif
42 } 41 }
43 42
44 if (B_c == FP_CLS_ZERO && A_c != FP_CLS_ZERO) { 43 if (B_c == FP_CLS_ZERO && A_c != FP_CLS_ZERO) {
45 ret |= EFLAG_DIVZERO; 44 FP_SET_EXCEPTION(EFLAG_DIVZERO);
46 if (__FPU_TRAP_P(EFLAG_DIVZERO)) 45 if (__FPU_TRAP_P(EFLAG_DIVZERO))
47 return ret; 46 return FP_CUR_EXCEPTIONS;
48 } 47 }
49 48
50 FP_DIV_D(R, A, B); 49 FP_DIV_D(R, A, B);
diff --git a/arch/powerpc/math-emu/fmadd.c b/arch/powerpc/math-emu/fmadd.c
index 925313aa6f82..8c3f20aa5a95 100644
--- a/arch/powerpc/math-emu/fmadd.c
+++ b/arch/powerpc/math-emu/fmadd.c
@@ -15,7 +15,6 @@ fmadd(void *frD, void *frA, void *frB, void *frC)
15 FP_DECL_D(C); 15 FP_DECL_D(C);
16 FP_DECL_D(T); 16 FP_DECL_D(T);
17 FP_DECL_EX; 17 FP_DECL_EX;
18 int ret = 0;
19 18
20#ifdef DEBUG 19#ifdef DEBUG
21 printk("%s: %p %p %p %p\n", __func__, frD, frA, frB, frC); 20 printk("%s: %p %p %p %p\n", __func__, frD, frA, frB, frC);
@@ -33,12 +32,12 @@ fmadd(void *frD, void *frA, void *frB, void *frC)
33 32
34 if ((A_c == FP_CLS_INF && C_c == FP_CLS_ZERO) || 33 if ((A_c == FP_CLS_INF && C_c == FP_CLS_ZERO) ||
35 (A_c == FP_CLS_ZERO && C_c == FP_CLS_INF)) 34 (A_c == FP_CLS_ZERO && C_c == FP_CLS_INF))
36 ret |= EFLAG_VXIMZ; 35 FP_SET_EXCEPTION(EFLAG_VXIMZ);
37 36
38 FP_MUL_D(T, A, C); 37 FP_MUL_D(T, A, C);
39 38
40 if (T_s != B_s && T_c == FP_CLS_INF && B_c == FP_CLS_INF) 39 if (T_s != B_s && T_c == FP_CLS_INF && B_c == FP_CLS_INF)
41 ret |= EFLAG_VXISI; 40 FP_SET_EXCEPTION(EFLAG_VXISI);
42 41
43 FP_ADD_D(R, T, B); 42 FP_ADD_D(R, T, B);
44 43
diff --git a/arch/powerpc/math-emu/fmadds.c b/arch/powerpc/math-emu/fmadds.c
index aea80ef79399..794fb31e59d1 100644
--- a/arch/powerpc/math-emu/fmadds.c
+++ b/arch/powerpc/math-emu/fmadds.c
@@ -16,7 +16,6 @@ fmadds(void *frD, void *frA, void *frB, void *frC)
16 FP_DECL_D(C); 16 FP_DECL_D(C);
17 FP_DECL_D(T); 17 FP_DECL_D(T);
18 FP_DECL_EX; 18 FP_DECL_EX;
19 int ret = 0;
20 19
21#ifdef DEBUG 20#ifdef DEBUG
22 printk("%s: %p %p %p %p\n", __func__, frD, frA, frB, frC); 21 printk("%s: %p %p %p %p\n", __func__, frD, frA, frB, frC);
@@ -34,12 +33,12 @@ fmadds(void *frD, void *frA, void *frB, void *frC)
34 33
35 if ((A_c == FP_CLS_INF && C_c == FP_CLS_ZERO) || 34 if ((A_c == FP_CLS_INF && C_c == FP_CLS_ZERO) ||
36 (A_c == FP_CLS_ZERO && C_c == FP_CLS_INF)) 35 (A_c == FP_CLS_ZERO && C_c == FP_CLS_INF))
37 ret |= EFLAG_VXIMZ; 36 FP_SET_EXCEPTION(EFLAG_VXIMZ);
38 37
39 FP_MUL_D(T, A, C); 38 FP_MUL_D(T, A, C);
40 39
41 if (T_s != B_s && T_c == FP_CLS_INF && B_c == FP_CLS_INF) 40 if (T_s != B_s && T_c == FP_CLS_INF && B_c == FP_CLS_INF)
42 ret |= EFLAG_VXISI; 41 FP_SET_EXCEPTION(EFLAG_VXISI);
43 42
44 FP_ADD_D(R, T, B); 43 FP_ADD_D(R, T, B);
45 44
diff --git a/arch/powerpc/math-emu/fmsub.c b/arch/powerpc/math-emu/fmsub.c
index a644d525fca6..626f6fed84ac 100644
--- a/arch/powerpc/math-emu/fmsub.c
+++ b/arch/powerpc/math-emu/fmsub.c
@@ -15,7 +15,6 @@ fmsub(void *frD, void *frA, void *frB, void *frC)
15 FP_DECL_D(C); 15 FP_DECL_D(C);
16 FP_DECL_D(T); 16 FP_DECL_D(T);
17 FP_DECL_EX; 17 FP_DECL_EX;
18 int ret = 0;
19 18
20#ifdef DEBUG 19#ifdef DEBUG
21 printk("%s: %p %p %p %p\n", __func__, frD, frA, frB, frC); 20 printk("%s: %p %p %p %p\n", __func__, frD, frA, frB, frC);
@@ -33,7 +32,7 @@ fmsub(void *frD, void *frA, void *frB, void *frC)
33 32
34 if ((A_c == FP_CLS_INF && C_c == FP_CLS_ZERO) || 33 if ((A_c == FP_CLS_INF && C_c == FP_CLS_ZERO) ||
35 (A_c == FP_CLS_ZERO && C_c == FP_CLS_INF)) 34 (A_c == FP_CLS_ZERO && C_c == FP_CLS_INF))
36 ret |= EFLAG_VXIMZ; 35 FP_SET_EXCEPTION(EFLAG_VXIMZ);
37 36
38 FP_MUL_D(T, A, C); 37 FP_MUL_D(T, A, C);
39 38
@@ -41,7 +40,7 @@ fmsub(void *frD, void *frA, void *frB, void *frC)
41 B_s ^= 1; 40 B_s ^= 1;
42 41
43 if (T_s != B_s && T_c == FP_CLS_INF && B_c == FP_CLS_INF) 42 if (T_s != B_s && T_c == FP_CLS_INF && B_c == FP_CLS_INF)
44 ret |= EFLAG_VXISI; 43 FP_SET_EXCEPTION(EFLAG_VXISI);
45 44
46 FP_ADD_D(R, T, B); 45 FP_ADD_D(R, T, B);
47 46
diff --git a/arch/powerpc/math-emu/fmsubs.c b/arch/powerpc/math-emu/fmsubs.c
index 2fdeeb9bb569..3425bc899760 100644
--- a/arch/powerpc/math-emu/fmsubs.c
+++ b/arch/powerpc/math-emu/fmsubs.c
@@ -16,7 +16,6 @@ fmsubs(void *frD, void *frA, void *frB, void *frC)
16 FP_DECL_D(C); 16 FP_DECL_D(C);
17 FP_DECL_D(T); 17 FP_DECL_D(T);
18 FP_DECL_EX; 18 FP_DECL_EX;
19 int ret = 0;
20 19
21#ifdef DEBUG 20#ifdef DEBUG
22 printk("%s: %p %p %p %p\n", __func__, frD, frA, frB, frC); 21 printk("%s: %p %p %p %p\n", __func__, frD, frA, frB, frC);
@@ -34,7 +33,7 @@ fmsubs(void *frD, void *frA, void *frB, void *frC)
34 33
35 if ((A_c == FP_CLS_INF && C_c == FP_CLS_ZERO) || 34 if ((A_c == FP_CLS_INF && C_c == FP_CLS_ZERO) ||
36 (A_c == FP_CLS_ZERO && C_c == FP_CLS_INF)) 35 (A_c == FP_CLS_ZERO && C_c == FP_CLS_INF))
37 ret |= EFLAG_VXIMZ; 36 FP_SET_EXCEPTION(EFLAG_VXIMZ);
38 37
39 FP_MUL_D(T, A, C); 38 FP_MUL_D(T, A, C);
40 39
@@ -42,7 +41,7 @@ fmsubs(void *frD, void *frA, void *frB, void *frC)
42 B_s ^= 1; 41 B_s ^= 1;
43 42
44 if (T_s != B_s && T_c == FP_CLS_INF && B_c == FP_CLS_INF) 43 if (T_s != B_s && T_c == FP_CLS_INF && B_c == FP_CLS_INF)
45 ret |= EFLAG_VXISI; 44 FP_SET_EXCEPTION(EFLAG_VXISI);
46 45
47 FP_ADD_D(R, T, B); 46 FP_ADD_D(R, T, B);
48 47
diff --git a/arch/powerpc/math-emu/fmul.c b/arch/powerpc/math-emu/fmul.c
index 391fd17d3440..2c1929779892 100644
--- a/arch/powerpc/math-emu/fmul.c
+++ b/arch/powerpc/math-emu/fmul.c
@@ -13,7 +13,6 @@ fmul(void *frD, void *frA, void *frB)
13 FP_DECL_D(B); 13 FP_DECL_D(B);
14 FP_DECL_D(R); 14 FP_DECL_D(R);
15 FP_DECL_EX; 15 FP_DECL_EX;
16 int ret = 0;
17 16
18#ifdef DEBUG 17#ifdef DEBUG
19 printk("%s: %p %p %p\n", __func__, frD, frA, frB); 18 printk("%s: %p %p %p\n", __func__, frD, frA, frB);
@@ -31,7 +30,7 @@ fmul(void *frD, void *frA, void *frB)
31 30
32 if ((A_c == FP_CLS_INF && B_c == FP_CLS_ZERO) || 31 if ((A_c == FP_CLS_INF && B_c == FP_CLS_ZERO) ||
33 (A_c == FP_CLS_ZERO && B_c == FP_CLS_INF)) 32 (A_c == FP_CLS_ZERO && B_c == FP_CLS_INF))
34 ret |= EFLAG_VXIMZ; 33 FP_SET_EXCEPTION(EFLAG_VXIMZ);
35 34
36 FP_MUL_D(R, A, B); 35 FP_MUL_D(R, A, B);
37 36
diff --git a/arch/powerpc/math-emu/fmuls.c b/arch/powerpc/math-emu/fmuls.c
index 2d3ec5f7da20..f5ad5c9c77d0 100644
--- a/arch/powerpc/math-emu/fmuls.c
+++ b/arch/powerpc/math-emu/fmuls.c
@@ -14,7 +14,6 @@ fmuls(void *frD, void *frA, void *frB)
14 FP_DECL_D(B); 14 FP_DECL_D(B);
15 FP_DECL_D(R); 15 FP_DECL_D(R);
16 FP_DECL_EX; 16 FP_DECL_EX;
17 int ret = 0;
18 17
19#ifdef DEBUG 18#ifdef DEBUG
20 printk("%s: %p %p %p\n", __func__, frD, frA, frB); 19 printk("%s: %p %p %p\n", __func__, frD, frA, frB);
@@ -32,7 +31,7 @@ fmuls(void *frD, void *frA, void *frB)
32 31
33 if ((A_c == FP_CLS_INF && B_c == FP_CLS_ZERO) || 32 if ((A_c == FP_CLS_INF && B_c == FP_CLS_ZERO) ||
34 (A_c == FP_CLS_ZERO && B_c == FP_CLS_INF)) 33 (A_c == FP_CLS_ZERO && B_c == FP_CLS_INF))
35 ret |= EFLAG_VXIMZ; 34 FP_SET_EXCEPTION(EFLAG_VXIMZ);
36 35
37 FP_MUL_D(R, A, B); 36 FP_MUL_D(R, A, B);
38 37
diff --git a/arch/powerpc/math-emu/fnmadd.c b/arch/powerpc/math-emu/fnmadd.c
index 2497b86494e5..e817bc5453ef 100644
--- a/arch/powerpc/math-emu/fnmadd.c
+++ b/arch/powerpc/math-emu/fnmadd.c
@@ -15,7 +15,6 @@ fnmadd(void *frD, void *frA, void *frB, void *frC)
15 FP_DECL_D(C); 15 FP_DECL_D(C);
16 FP_DECL_D(T); 16 FP_DECL_D(T);
17 FP_DECL_EX; 17 FP_DECL_EX;
18 int ret = 0;
19 18
20#ifdef DEBUG 19#ifdef DEBUG
21 printk("%s: %p %p %p %p\n", __func__, frD, frA, frB, frC); 20 printk("%s: %p %p %p %p\n", __func__, frD, frA, frB, frC);
@@ -33,12 +32,12 @@ fnmadd(void *frD, void *frA, void *frB, void *frC)
33 32
34 if ((A_c == FP_CLS_INF && C_c == FP_CLS_ZERO) || 33 if ((A_c == FP_CLS_INF && C_c == FP_CLS_ZERO) ||
35 (A_c == FP_CLS_ZERO && C_c == FP_CLS_INF)) 34 (A_c == FP_CLS_ZERO && C_c == FP_CLS_INF))
36 ret |= EFLAG_VXIMZ; 35 FP_SET_EXCEPTION(EFLAG_VXIMZ);
37 36
38 FP_MUL_D(T, A, C); 37 FP_MUL_D(T, A, C);
39 38
40 if (T_s != B_s && T_c == FP_CLS_INF && B_c == FP_CLS_INF) 39 if (T_s != B_s && T_c == FP_CLS_INF && B_c == FP_CLS_INF)
41 ret |= EFLAG_VXISI; 40 FP_SET_EXCEPTION(EFLAG_VXISI);
42 41
43 FP_ADD_D(R, T, B); 42 FP_ADD_D(R, T, B);
44 43
diff --git a/arch/powerpc/math-emu/fnmadds.c b/arch/powerpc/math-emu/fnmadds.c
index ee9d71e0b376..4db4b7d9ba8d 100644
--- a/arch/powerpc/math-emu/fnmadds.c
+++ b/arch/powerpc/math-emu/fnmadds.c
@@ -16,7 +16,6 @@ fnmadds(void *frD, void *frA, void *frB, void *frC)
16 FP_DECL_D(C); 16 FP_DECL_D(C);
17 FP_DECL_D(T); 17 FP_DECL_D(T);
18 FP_DECL_EX; 18 FP_DECL_EX;
19 int ret = 0;
20 19
21#ifdef DEBUG 20#ifdef DEBUG
22 printk("%s: %p %p %p %p\n", __func__, frD, frA, frB, frC); 21 printk("%s: %p %p %p %p\n", __func__, frD, frA, frB, frC);
@@ -34,12 +33,12 @@ fnmadds(void *frD, void *frA, void *frB, void *frC)
34 33
35 if ((A_c == FP_CLS_INF && C_c == FP_CLS_ZERO) || 34 if ((A_c == FP_CLS_INF && C_c == FP_CLS_ZERO) ||
36 (A_c == FP_CLS_ZERO && C_c == FP_CLS_INF)) 35 (A_c == FP_CLS_ZERO && C_c == FP_CLS_INF))
37 ret |= EFLAG_VXIMZ; 36 FP_SET_EXCEPTION(EFLAG_VXIMZ);
38 37
39 FP_MUL_D(T, A, C); 38 FP_MUL_D(T, A, C);
40 39
41 if (T_s != B_s && T_c == FP_CLS_INF && B_c == FP_CLS_INF) 40 if (T_s != B_s && T_c == FP_CLS_INF && B_c == FP_CLS_INF)
42 ret |= EFLAG_VXISI; 41 FP_SET_EXCEPTION(EFLAG_VXISI);
43 42
44 FP_ADD_D(R, T, B); 43 FP_ADD_D(R, T, B);
45 44
diff --git a/arch/powerpc/math-emu/fnmsub.c b/arch/powerpc/math-emu/fnmsub.c
index 3885a77acc93..f65979fa770e 100644
--- a/arch/powerpc/math-emu/fnmsub.c
+++ b/arch/powerpc/math-emu/fnmsub.c
@@ -15,7 +15,6 @@ fnmsub(void *frD, void *frA, void *frB, void *frC)
15 FP_DECL_D(C); 15 FP_DECL_D(C);
16 FP_DECL_D(T); 16 FP_DECL_D(T);
17 FP_DECL_EX; 17 FP_DECL_EX;
18 int ret = 0;
19 18
20#ifdef DEBUG 19#ifdef DEBUG
21 printk("%s: %p %p %p %p\n", __func__, frD, frA, frB, frC); 20 printk("%s: %p %p %p %p\n", __func__, frD, frA, frB, frC);
@@ -33,7 +32,7 @@ fnmsub(void *frD, void *frA, void *frB, void *frC)
33 32
34 if ((A_c == FP_CLS_INF && C_c == FP_CLS_ZERO) || 33 if ((A_c == FP_CLS_INF && C_c == FP_CLS_ZERO) ||
35 (A_c == FP_CLS_ZERO && C_c == FP_CLS_INF)) 34 (A_c == FP_CLS_ZERO && C_c == FP_CLS_INF))
36 ret |= EFLAG_VXIMZ; 35 FP_SET_EXCEPTION(EFLAG_VXIMZ);
37 36
38 FP_MUL_D(T, A, C); 37 FP_MUL_D(T, A, C);
39 38
@@ -41,7 +40,7 @@ fnmsub(void *frD, void *frA, void *frB, void *frC)
41 B_s ^= 1; 40 B_s ^= 1;
42 41
43 if (T_s != B_s && T_c == FP_CLS_INF && B_c == FP_CLS_INF) 42 if (T_s != B_s && T_c == FP_CLS_INF && B_c == FP_CLS_INF)
44 ret |= EFLAG_VXISI; 43 FP_SET_EXCEPTION(EFLAG_VXISI);
45 44
46 FP_ADD_D(R, T, B); 45 FP_ADD_D(R, T, B);
47 46
diff --git a/arch/powerpc/math-emu/fnmsubs.c b/arch/powerpc/math-emu/fnmsubs.c
index f835dfeb0fd1..9021dacc03b8 100644
--- a/arch/powerpc/math-emu/fnmsubs.c
+++ b/arch/powerpc/math-emu/fnmsubs.c
@@ -16,7 +16,6 @@ fnmsubs(void *frD, void *frA, void *frB, void *frC)
16 FP_DECL_D(C); 16 FP_DECL_D(C);
17 FP_DECL_D(T); 17 FP_DECL_D(T);
18 FP_DECL_EX; 18 FP_DECL_EX;
19 int ret = 0;
20 19
21#ifdef DEBUG 20#ifdef DEBUG
22 printk("%s: %p %p %p %p\n", __func__, frD, frA, frB, frC); 21 printk("%s: %p %p %p %p\n", __func__, frD, frA, frB, frC);
@@ -34,7 +33,7 @@ fnmsubs(void *frD, void *frA, void *frB, void *frC)
34 33
35 if ((A_c == FP_CLS_INF && C_c == FP_CLS_ZERO) || 34 if ((A_c == FP_CLS_INF && C_c == FP_CLS_ZERO) ||
36 (A_c == FP_CLS_ZERO && C_c == FP_CLS_INF)) 35 (A_c == FP_CLS_ZERO && C_c == FP_CLS_INF))
37 ret |= EFLAG_VXIMZ; 36 FP_SET_EXCEPTION(EFLAG_VXIMZ);
38 37
39 FP_MUL_D(T, A, C); 38 FP_MUL_D(T, A, C);
40 39
@@ -42,7 +41,7 @@ fnmsubs(void *frD, void *frA, void *frB, void *frC)
42 B_s ^= 1; 41 B_s ^= 1;
43 42
44 if (T_s != B_s && T_c == FP_CLS_INF && B_c == FP_CLS_INF) 43 if (T_s != B_s && T_c == FP_CLS_INF && B_c == FP_CLS_INF)
45 ret |= EFLAG_VXISI; 44 FP_SET_EXCEPTION(EFLAG_VXISI);
46 45
47 FP_ADD_D(R, T, B); 46 FP_ADD_D(R, T, B);
48 47
diff --git a/arch/powerpc/math-emu/fsqrt.c b/arch/powerpc/math-emu/fsqrt.c
index 3e90072693a0..a55fc7d49983 100644
--- a/arch/powerpc/math-emu/fsqrt.c
+++ b/arch/powerpc/math-emu/fsqrt.c
@@ -12,7 +12,6 @@ fsqrt(void *frD, void *frB)
12 FP_DECL_D(B); 12 FP_DECL_D(B);
13 FP_DECL_D(R); 13 FP_DECL_D(R);
14 FP_DECL_EX; 14 FP_DECL_EX;
15 int ret = 0;
16 15
17#ifdef DEBUG 16#ifdef DEBUG
18 printk("%s: %p %p %p %p\n", __func__, frD, frB); 17 printk("%s: %p %p %p %p\n", __func__, frD, frB);
@@ -25,9 +24,9 @@ fsqrt(void *frD, void *frB)
25#endif 24#endif
26 25
27 if (B_s && B_c != FP_CLS_ZERO) 26 if (B_s && B_c != FP_CLS_ZERO)
28 ret |= EFLAG_VXSQRT; 27 FP_SET_EXCEPTION(EFLAG_VXSQRT);
29 if (B_c == FP_CLS_NAN) 28 if (B_c == FP_CLS_NAN)
30 ret |= EFLAG_VXSNAN; 29 FP_SET_EXCEPTION(EFLAG_VXSNAN);
31 30
32 FP_SQRT_D(R, B); 31 FP_SQRT_D(R, B);
33 32
diff --git a/arch/powerpc/math-emu/fsqrts.c b/arch/powerpc/math-emu/fsqrts.c
index 2843be986e2e..31dccbfc39ff 100644
--- a/arch/powerpc/math-emu/fsqrts.c
+++ b/arch/powerpc/math-emu/fsqrts.c
@@ -13,7 +13,6 @@ fsqrts(void *frD, void *frB)
13 FP_DECL_D(B); 13 FP_DECL_D(B);
14 FP_DECL_D(R); 14 FP_DECL_D(R);
15 FP_DECL_EX; 15 FP_DECL_EX;
16 int ret = 0;
17 16
18#ifdef DEBUG 17#ifdef DEBUG
19 printk("%s: %p %p %p %p\n", __func__, frD, frB); 18 printk("%s: %p %p %p %p\n", __func__, frD, frB);
@@ -26,9 +25,9 @@ fsqrts(void *frD, void *frB)
26#endif 25#endif
27 26
28 if (B_s && B_c != FP_CLS_ZERO) 27 if (B_s && B_c != FP_CLS_ZERO)
29 ret |= EFLAG_VXSQRT; 28 FP_SET_EXCEPTION(EFLAG_VXSQRT);
30 if (B_c == FP_CLS_NAN) 29 if (B_c == FP_CLS_NAN)
31 ret |= EFLAG_VXSNAN; 30 FP_SET_EXCEPTION(EFLAG_VXSNAN);
32 31
33 FP_SQRT_D(R, B); 32 FP_SQRT_D(R, B);
34 33
diff --git a/arch/powerpc/math-emu/fsub.c b/arch/powerpc/math-emu/fsub.c
index 78b09446a0e1..02c5dff458ba 100644
--- a/arch/powerpc/math-emu/fsub.c
+++ b/arch/powerpc/math-emu/fsub.c
@@ -13,7 +13,6 @@ fsub(void *frD, void *frA, void *frB)
13 FP_DECL_D(B); 13 FP_DECL_D(B);
14 FP_DECL_D(R); 14 FP_DECL_D(R);
15 FP_DECL_EX; 15 FP_DECL_EX;
16 int ret = 0;
17 16
18#ifdef DEBUG 17#ifdef DEBUG
19 printk("%s: %p %p %p\n", __func__, frD, frA, frB); 18 printk("%s: %p %p %p\n", __func__, frD, frA, frB);
@@ -31,7 +30,7 @@ fsub(void *frD, void *frA, void *frB)
31 B_s ^= 1; 30 B_s ^= 1;
32 31
33 if (A_s != B_s && A_c == FP_CLS_INF && B_c == FP_CLS_INF) 32 if (A_s != B_s && A_c == FP_CLS_INF && B_c == FP_CLS_INF)
34 ret |= EFLAG_VXISI; 33 FP_SET_EXCEPTION(EFLAG_VXISI);
35 34
36 FP_ADD_D(R, A, B); 35 FP_ADD_D(R, A, B);
37 36
diff --git a/arch/powerpc/math-emu/fsubs.c b/arch/powerpc/math-emu/fsubs.c
index d3bf90863cf2..5d9b18c35e07 100644
--- a/arch/powerpc/math-emu/fsubs.c
+++ b/arch/powerpc/math-emu/fsubs.c
@@ -14,7 +14,6 @@ fsubs(void *frD, void *frA, void *frB)
14 FP_DECL_D(B); 14 FP_DECL_D(B);
15 FP_DECL_D(R); 15 FP_DECL_D(R);
16 FP_DECL_EX; 16 FP_DECL_EX;
17 int ret = 0;
18 17
19#ifdef DEBUG 18#ifdef DEBUG
20 printk("%s: %p %p %p\n", __func__, frD, frA, frB); 19 printk("%s: %p %p %p\n", __func__, frD, frA, frB);
@@ -32,7 +31,7 @@ fsubs(void *frD, void *frA, void *frB)
32 B_s ^= 1; 31 B_s ^= 1;
33 32
34 if (A_s != B_s && A_c == FP_CLS_INF && B_c == FP_CLS_INF) 33 if (A_s != B_s && A_c == FP_CLS_INF && B_c == FP_CLS_INF)
35 ret |= EFLAG_VXISI; 34 FP_SET_EXCEPTION(EFLAG_VXISI);
36 35
37 FP_ADD_D(R, A, B); 36 FP_ADD_D(R, A, B);
38 37
diff --git a/arch/powerpc/math-emu/math_efp.c b/arch/powerpc/math-emu/math_efp.c
new file mode 100644
index 000000000000..41f4ef30e480
--- /dev/null
+++ b/arch/powerpc/math-emu/math_efp.c
@@ -0,0 +1,720 @@
1/*
2 * arch/powerpc/math-emu/math_efp.c
3 *
4 * Copyright (C) 2006-2008 Freescale Semiconductor, Inc. All rights reserved.
5 *
6 * Author: Ebony Zhu, <ebony.zhu@freescale.com>
7 * Yu Liu, <yu.liu@freescale.com>
8 *
9 * Derived from arch/alpha/math-emu/math.c
10 * arch/powerpc/math-emu/math.c
11 *
12 * Description:
13 * This file is the exception handler to make E500 SPE instructions
14 * fully comply with IEEE-754 floating point standard.
15 *
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License
18 * as published by the Free Software Foundation; either version
19 * 2 of the License, or (at your option) any later version.
20 */
21
22#include <linux/types.h>
23
24#include <asm/uaccess.h>
25#include <asm/reg.h>
26
27#define FP_EX_BOOKE_E500_SPE
28#include <asm/sfp-machine.h>
29
30#include <math-emu/soft-fp.h>
31#include <math-emu/single.h>
32#include <math-emu/double.h>
33
34#define EFAPU 0x4
35
36#define VCT 0x4
37#define SPFP 0x6
38#define DPFP 0x7
39
40#define EFSADD 0x2c0
41#define EFSSUB 0x2c1
42#define EFSABS 0x2c4
43#define EFSNABS 0x2c5
44#define EFSNEG 0x2c6
45#define EFSMUL 0x2c8
46#define EFSDIV 0x2c9
47#define EFSCMPGT 0x2cc
48#define EFSCMPLT 0x2cd
49#define EFSCMPEQ 0x2ce
50#define EFSCFD 0x2cf
51#define EFSCFSI 0x2d1
52#define EFSCTUI 0x2d4
53#define EFSCTSI 0x2d5
54#define EFSCTUF 0x2d6
55#define EFSCTSF 0x2d7
56#define EFSCTUIZ 0x2d8
57#define EFSCTSIZ 0x2da
58
59#define EVFSADD 0x280
60#define EVFSSUB 0x281
61#define EVFSABS 0x284
62#define EVFSNABS 0x285
63#define EVFSNEG 0x286
64#define EVFSMUL 0x288
65#define EVFSDIV 0x289
66#define EVFSCMPGT 0x28c
67#define EVFSCMPLT 0x28d
68#define EVFSCMPEQ 0x28e
69#define EVFSCTUI 0x294
70#define EVFSCTSI 0x295
71#define EVFSCTUF 0x296
72#define EVFSCTSF 0x297
73#define EVFSCTUIZ 0x298
74#define EVFSCTSIZ 0x29a
75
76#define EFDADD 0x2e0
77#define EFDSUB 0x2e1
78#define EFDABS 0x2e4
79#define EFDNABS 0x2e5
80#define EFDNEG 0x2e6
81#define EFDMUL 0x2e8
82#define EFDDIV 0x2e9
83#define EFDCTUIDZ 0x2ea
84#define EFDCTSIDZ 0x2eb
85#define EFDCMPGT 0x2ec
86#define EFDCMPLT 0x2ed
87#define EFDCMPEQ 0x2ee
88#define EFDCFS 0x2ef
89#define EFDCTUI 0x2f4
90#define EFDCTSI 0x2f5
91#define EFDCTUF 0x2f6
92#define EFDCTSF 0x2f7
93#define EFDCTUIZ 0x2f8
94#define EFDCTSIZ 0x2fa
95
96#define AB 2
97#define XA 3
98#define XB 4
99#define XCR 5
100#define NOTYPE 0
101
102#define SIGN_BIT_S (1UL << 31)
103#define SIGN_BIT_D (1ULL << 63)
104#define FP_EX_MASK (FP_EX_INEXACT | FP_EX_INVALID | FP_EX_DIVZERO | \
105 FP_EX_UNDERFLOW | FP_EX_OVERFLOW)
106
107union dw_union {
108 u64 dp[1];
109 u32 wp[2];
110};
111
112static unsigned long insn_type(unsigned long speinsn)
113{
114 unsigned long ret = NOTYPE;
115
116 switch (speinsn & 0x7ff) {
117 case EFSABS: ret = XA; break;
118 case EFSADD: ret = AB; break;
119 case EFSCFD: ret = XB; break;
120 case EFSCMPEQ: ret = XCR; break;
121 case EFSCMPGT: ret = XCR; break;
122 case EFSCMPLT: ret = XCR; break;
123 case EFSCTSF: ret = XB; break;
124 case EFSCTSI: ret = XB; break;
125 case EFSCTSIZ: ret = XB; break;
126 case EFSCTUF: ret = XB; break;
127 case EFSCTUI: ret = XB; break;
128 case EFSCTUIZ: ret = XB; break;
129 case EFSDIV: ret = AB; break;
130 case EFSMUL: ret = AB; break;
131 case EFSNABS: ret = XA; break;
132 case EFSNEG: ret = XA; break;
133 case EFSSUB: ret = AB; break;
134 case EFSCFSI: ret = XB; break;
135
136 case EVFSABS: ret = XA; break;
137 case EVFSADD: ret = AB; break;
138 case EVFSCMPEQ: ret = XCR; break;
139 case EVFSCMPGT: ret = XCR; break;
140 case EVFSCMPLT: ret = XCR; break;
141 case EVFSCTSF: ret = XB; break;
142 case EVFSCTSI: ret = XB; break;
143 case EVFSCTSIZ: ret = XB; break;
144 case EVFSCTUF: ret = XB; break;
145 case EVFSCTUI: ret = XB; break;
146 case EVFSCTUIZ: ret = XB; break;
147 case EVFSDIV: ret = AB; break;
148 case EVFSMUL: ret = AB; break;
149 case EVFSNABS: ret = XA; break;
150 case EVFSNEG: ret = XA; break;
151 case EVFSSUB: ret = AB; break;
152
153 case EFDABS: ret = XA; break;
154 case EFDADD: ret = AB; break;
155 case EFDCFS: ret = XB; break;
156 case EFDCMPEQ: ret = XCR; break;
157 case EFDCMPGT: ret = XCR; break;
158 case EFDCMPLT: ret = XCR; break;
159 case EFDCTSF: ret = XB; break;
160 case EFDCTSI: ret = XB; break;
161 case EFDCTSIDZ: ret = XB; break;
162 case EFDCTSIZ: ret = XB; break;
163 case EFDCTUF: ret = XB; break;
164 case EFDCTUI: ret = XB; break;
165 case EFDCTUIDZ: ret = XB; break;
166 case EFDCTUIZ: ret = XB; break;
167 case EFDDIV: ret = AB; break;
168 case EFDMUL: ret = AB; break;
169 case EFDNABS: ret = XA; break;
170 case EFDNEG: ret = XA; break;
171 case EFDSUB: ret = AB; break;
172
173 default:
174 printk(KERN_ERR "\nOoops! SPE instruction no type found.");
175 printk(KERN_ERR "\ninst code: %08lx\n", speinsn);
176 }
177
178 return ret;
179}
180
181int do_spe_mathemu(struct pt_regs *regs)
182{
183 FP_DECL_EX;
184 int IR, cmp;
185
186 unsigned long type, func, fc, fa, fb, src, speinsn;
187 union dw_union vc, va, vb;
188
189 if (get_user(speinsn, (unsigned int __user *) regs->nip))
190 return -EFAULT;
191 if ((speinsn >> 26) != EFAPU)
192 return -EINVAL; /* not an spe instruction */
193
194 type = insn_type(speinsn);
195 if (type == NOTYPE)
196 return -ENOSYS;
197
198 func = speinsn & 0x7ff;
199 fc = (speinsn >> 21) & 0x1f;
200 fa = (speinsn >> 16) & 0x1f;
201 fb = (speinsn >> 11) & 0x1f;
202 src = (speinsn >> 5) & 0x7;
203
204 vc.wp[0] = current->thread.evr[fc];
205 vc.wp[1] = regs->gpr[fc];
206 va.wp[0] = current->thread.evr[fa];
207 va.wp[1] = regs->gpr[fa];
208 vb.wp[0] = current->thread.evr[fb];
209 vb.wp[1] = regs->gpr[fb];
210
211 __FPU_FPSCR = mfspr(SPRN_SPEFSCR);
212
213#ifdef DEBUG
214 printk("speinsn:%08lx spefscr:%08lx\n", speinsn, __FPU_FPSCR);
215 printk("vc: %08x %08x\n", vc.wp[0], vc.wp[1]);
216 printk("va: %08x %08x\n", va.wp[0], va.wp[1]);
217 printk("vb: %08x %08x\n", vb.wp[0], vb.wp[1]);
218#endif
219
220 switch (src) {
221 case SPFP: {
222 FP_DECL_S(SA); FP_DECL_S(SB); FP_DECL_S(SR);
223
224 switch (type) {
225 case AB:
226 case XCR:
227 FP_UNPACK_SP(SA, va.wp + 1);
228 case XB:
229 FP_UNPACK_SP(SB, vb.wp + 1);
230 break;
231 case XA:
232 FP_UNPACK_SP(SA, va.wp + 1);
233 break;
234 }
235
236#ifdef DEBUG
237 printk("SA: %ld %08lx %ld (%ld)\n", SA_s, SA_f, SA_e, SA_c);
238 printk("SB: %ld %08lx %ld (%ld)\n", SB_s, SB_f, SB_e, SB_c);
239#endif
240
241 switch (func) {
242 case EFSABS:
243 vc.wp[1] = va.wp[1] & ~SIGN_BIT_S;
244 goto update_regs;
245
246 case EFSNABS:
247 vc.wp[1] = va.wp[1] | SIGN_BIT_S;
248 goto update_regs;
249
250 case EFSNEG:
251 vc.wp[1] = va.wp[1] ^ SIGN_BIT_S;
252 goto update_regs;
253
254 case EFSADD:
255 FP_ADD_S(SR, SA, SB);
256 goto pack_s;
257
258 case EFSSUB:
259 FP_SUB_S(SR, SA, SB);
260 goto pack_s;
261
262 case EFSMUL:
263 FP_MUL_S(SR, SA, SB);
264 goto pack_s;
265
266 case EFSDIV:
267 FP_DIV_S(SR, SA, SB);
268 goto pack_s;
269
270 case EFSCMPEQ:
271 cmp = 0;
272 goto cmp_s;
273
274 case EFSCMPGT:
275 cmp = 1;
276 goto cmp_s;
277
278 case EFSCMPLT:
279 cmp = -1;
280 goto cmp_s;
281
282 case EFSCTSF:
283 case EFSCTUF:
284 if (!((vb.wp[1] >> 23) == 0xff && ((vb.wp[1] & 0x7fffff) > 0))) {
285 /* NaN */
286 if (((vb.wp[1] >> 23) & 0xff) == 0) {
287 /* denorm */
288 vc.wp[1] = 0x0;
289 } else if ((vb.wp[1] >> 31) == 0) {
290 /* positive normal */
291 vc.wp[1] = (func == EFSCTSF) ?
292 0x7fffffff : 0xffffffff;
293 } else { /* negative normal */
294 vc.wp[1] = (func == EFSCTSF) ?
295 0x80000000 : 0x0;
296 }
297 } else { /* rB is NaN */
298 vc.wp[1] = 0x0;
299 }
300 goto update_regs;
301
302 case EFSCFD: {
303 FP_DECL_D(DB);
304 FP_CLEAR_EXCEPTIONS;
305 FP_UNPACK_DP(DB, vb.dp);
306#ifdef DEBUG
307 printk("DB: %ld %08lx %08lx %ld (%ld)\n",
308 DB_s, DB_f1, DB_f0, DB_e, DB_c);
309#endif
310 FP_CONV(S, D, 1, 2, SR, DB);
311 goto pack_s;
312 }
313
314 case EFSCTSI:
315 case EFSCTSIZ:
316 case EFSCTUI:
317 case EFSCTUIZ:
318 if (func & 0x4) {
319 _FP_ROUND(1, SB);
320 } else {
321 _FP_ROUND_ZERO(1, SB);
322 }
323 FP_TO_INT_S(vc.wp[1], SB, 32, ((func & 0x3) != 0));
324 goto update_regs;
325
326 default:
327 goto illegal;
328 }
329 break;
330
331pack_s:
332#ifdef DEBUG
333 printk("SR: %ld %08lx %ld (%ld)\n", SR_s, SR_f, SR_e, SR_c);
334#endif
335 FP_PACK_SP(vc.wp + 1, SR);
336 goto update_regs;
337
338cmp_s:
339 FP_CMP_S(IR, SA, SB, 3);
340 if (IR == 3 && (FP_ISSIGNAN_S(SA) || FP_ISSIGNAN_S(SB)))
341 FP_SET_EXCEPTION(FP_EX_INVALID);
342 if (IR == cmp) {
343 IR = 0x4;
344 } else {
345 IR = 0;
346 }
347 goto update_ccr;
348 }
349
350 case DPFP: {
351 FP_DECL_D(DA); FP_DECL_D(DB); FP_DECL_D(DR);
352
353 switch (type) {
354 case AB:
355 case XCR:
356 FP_UNPACK_DP(DA, va.dp);
357 case XB:
358 FP_UNPACK_DP(DB, vb.dp);
359 break;
360 case XA:
361 FP_UNPACK_DP(DA, va.dp);
362 break;
363 }
364
365#ifdef DEBUG
366 printk("DA: %ld %08lx %08lx %ld (%ld)\n",
367 DA_s, DA_f1, DA_f0, DA_e, DA_c);
368 printk("DB: %ld %08lx %08lx %ld (%ld)\n",
369 DB_s, DB_f1, DB_f0, DB_e, DB_c);
370#endif
371
372 switch (func) {
373 case EFDABS:
374 vc.dp[0] = va.dp[0] & ~SIGN_BIT_D;
375 goto update_regs;
376
377 case EFDNABS:
378 vc.dp[0] = va.dp[0] | SIGN_BIT_D;
379 goto update_regs;
380
381 case EFDNEG:
382 vc.dp[0] = va.dp[0] ^ SIGN_BIT_D;
383 goto update_regs;
384
385 case EFDADD:
386 FP_ADD_D(DR, DA, DB);
387 goto pack_d;
388
389 case EFDSUB:
390 FP_SUB_D(DR, DA, DB);
391 goto pack_d;
392
393 case EFDMUL:
394 FP_MUL_D(DR, DA, DB);
395 goto pack_d;
396
397 case EFDDIV:
398 FP_DIV_D(DR, DA, DB);
399 goto pack_d;
400
401 case EFDCMPEQ:
402 cmp = 0;
403 goto cmp_d;
404
405 case EFDCMPGT:
406 cmp = 1;
407 goto cmp_d;
408
409 case EFDCMPLT:
410 cmp = -1;
411 goto cmp_d;
412
413 case EFDCTSF:
414 case EFDCTUF:
415 if (!((vb.wp[0] >> 20) == 0x7ff &&
416 ((vb.wp[0] & 0xfffff) > 0 || (vb.wp[1] > 0)))) {
417 /* not a NaN */
418 if (((vb.wp[0] >> 20) & 0x7ff) == 0) {
419 /* denorm */
420 vc.wp[1] = 0x0;
421 } else if ((vb.wp[0] >> 31) == 0) {
422 /* positive normal */
423 vc.wp[1] = (func == EFDCTSF) ?
424 0x7fffffff : 0xffffffff;
425 } else { /* negative normal */
426 vc.wp[1] = (func == EFDCTSF) ?
427 0x80000000 : 0x0;
428 }
429 } else { /* NaN */
430 vc.wp[1] = 0x0;
431 }
432 goto update_regs;
433
434 case EFDCFS: {
435 FP_DECL_S(SB);
436 FP_CLEAR_EXCEPTIONS;
437 FP_UNPACK_SP(SB, vb.wp + 1);
438#ifdef DEBUG
439 printk("SB: %ld %08lx %ld (%ld)\n",
440 SB_s, SB_f, SB_e, SB_c);
441#endif
442 FP_CONV(D, S, 2, 1, DR, SB);
443 goto pack_d;
444 }
445
446 case EFDCTUIDZ:
447 case EFDCTSIDZ:
448 _FP_ROUND_ZERO(2, DB);
449 FP_TO_INT_D(vc.dp[0], DB, 64, ((func & 0x1) == 0));
450 goto update_regs;
451
452 case EFDCTUI:
453 case EFDCTSI:
454 case EFDCTUIZ:
455 case EFDCTSIZ:
456 if (func & 0x4) {
457 _FP_ROUND(2, DB);
458 } else {
459 _FP_ROUND_ZERO(2, DB);
460 }
461 FP_TO_INT_D(vc.wp[1], DB, 32, ((func & 0x3) != 0));
462 goto update_regs;
463
464 default:
465 goto illegal;
466 }
467 break;
468
469pack_d:
470#ifdef DEBUG
471 printk("DR: %ld %08lx %08lx %ld (%ld)\n",
472 DR_s, DR_f1, DR_f0, DR_e, DR_c);
473#endif
474 FP_PACK_DP(vc.dp, DR);
475 goto update_regs;
476
477cmp_d:
478 FP_CMP_D(IR, DA, DB, 3);
479 if (IR == 3 && (FP_ISSIGNAN_D(DA) || FP_ISSIGNAN_D(DB)))
480 FP_SET_EXCEPTION(FP_EX_INVALID);
481 if (IR == cmp) {
482 IR = 0x4;
483 } else {
484 IR = 0;
485 }
486 goto update_ccr;
487
488 }
489
490 case VCT: {
491 FP_DECL_S(SA0); FP_DECL_S(SB0); FP_DECL_S(SR0);
492 FP_DECL_S(SA1); FP_DECL_S(SB1); FP_DECL_S(SR1);
493 int IR0, IR1;
494
495 switch (type) {
496 case AB:
497 case XCR:
498 FP_UNPACK_SP(SA0, va.wp);
499 FP_UNPACK_SP(SA1, va.wp + 1);
500 case XB:
501 FP_UNPACK_SP(SB0, vb.wp);
502 FP_UNPACK_SP(SB1, vb.wp + 1);
503 break;
504 case XA:
505 FP_UNPACK_SP(SA0, va.wp);
506 FP_UNPACK_SP(SA1, va.wp + 1);
507 break;
508 }
509
510#ifdef DEBUG
511 printk("SA0: %ld %08lx %ld (%ld)\n", SA0_s, SA0_f, SA0_e, SA0_c);
512 printk("SA1: %ld %08lx %ld (%ld)\n", SA1_s, SA1_f, SA1_e, SA1_c);
513 printk("SB0: %ld %08lx %ld (%ld)\n", SB0_s, SB0_f, SB0_e, SB0_c);
514 printk("SB1: %ld %08lx %ld (%ld)\n", SB1_s, SB1_f, SB1_e, SB1_c);
515#endif
516
517 switch (func) {
518 case EVFSABS:
519 vc.wp[0] = va.wp[0] & ~SIGN_BIT_S;
520 vc.wp[1] = va.wp[1] & ~SIGN_BIT_S;
521 goto update_regs;
522
523 case EVFSNABS:
524 vc.wp[0] = va.wp[0] | SIGN_BIT_S;
525 vc.wp[1] = va.wp[1] | SIGN_BIT_S;
526 goto update_regs;
527
528 case EVFSNEG:
529 vc.wp[0] = va.wp[0] ^ SIGN_BIT_S;
530 vc.wp[1] = va.wp[1] ^ SIGN_BIT_S;
531 goto update_regs;
532
533 case EVFSADD:
534 FP_ADD_S(SR0, SA0, SB0);
535 FP_ADD_S(SR1, SA1, SB1);
536 goto pack_vs;
537
538 case EVFSSUB:
539 FP_SUB_S(SR0, SA0, SB0);
540 FP_SUB_S(SR1, SA1, SB1);
541 goto pack_vs;
542
543 case EVFSMUL:
544 FP_MUL_S(SR0, SA0, SB0);
545 FP_MUL_S(SR1, SA1, SB1);
546 goto pack_vs;
547
548 case EVFSDIV:
549 FP_DIV_S(SR0, SA0, SB0);
550 FP_DIV_S(SR1, SA1, SB1);
551 goto pack_vs;
552
553 case EVFSCMPEQ:
554 cmp = 0;
555 goto cmp_vs;
556
557 case EVFSCMPGT:
558 cmp = 1;
559 goto cmp_vs;
560
561 case EVFSCMPLT:
562 cmp = -1;
563 goto cmp_vs;
564
565 case EVFSCTSF:
566 __asm__ __volatile__ ("mtspr 512, %4\n"
567 "efsctsf %0, %2\n"
568 "efsctsf %1, %3\n"
569 : "=r" (vc.wp[0]), "=r" (vc.wp[1])
570 : "r" (vb.wp[0]), "r" (vb.wp[1]), "r" (0));
571 goto update_regs;
572
573 case EVFSCTUF:
574 __asm__ __volatile__ ("mtspr 512, %4\n"
575 "efsctuf %0, %2\n"
576 "efsctuf %1, %3\n"
577 : "=r" (vc.wp[0]), "=r" (vc.wp[1])
578 : "r" (vb.wp[0]), "r" (vb.wp[1]), "r" (0));
579 goto update_regs;
580
581 case EVFSCTUI:
582 case EVFSCTSI:
583 case EVFSCTUIZ:
584 case EVFSCTSIZ:
585 if (func & 0x4) {
586 _FP_ROUND(1, SB0);
587 _FP_ROUND(1, SB1);
588 } else {
589 _FP_ROUND_ZERO(1, SB0);
590 _FP_ROUND_ZERO(1, SB1);
591 }
592 FP_TO_INT_S(vc.wp[0], SB0, 32, ((func & 0x3) != 0));
593 FP_TO_INT_S(vc.wp[1], SB1, 32, ((func & 0x3) != 0));
594 goto update_regs;
595
596 default:
597 goto illegal;
598 }
599 break;
600
601pack_vs:
602#ifdef DEBUG
603 printk("SR0: %ld %08lx %ld (%ld)\n", SR0_s, SR0_f, SR0_e, SR0_c);
604 printk("SR1: %ld %08lx %ld (%ld)\n", SR1_s, SR1_f, SR1_e, SR1_c);
605#endif
606 FP_PACK_SP(vc.wp, SR0);
607 FP_PACK_SP(vc.wp + 1, SR1);
608 goto update_regs;
609
610cmp_vs:
611 {
612 int ch, cl;
613
614 FP_CMP_S(IR0, SA0, SB0, 3);
615 FP_CMP_S(IR1, SA1, SB1, 3);
616 if (IR0 == 3 && (FP_ISSIGNAN_S(SA0) || FP_ISSIGNAN_S(SB0)))
617 FP_SET_EXCEPTION(FP_EX_INVALID);
618 if (IR1 == 3 && (FP_ISSIGNAN_S(SA1) || FP_ISSIGNAN_S(SB1)))
619 FP_SET_EXCEPTION(FP_EX_INVALID);
620 ch = (IR0 == cmp) ? 1 : 0;
621 cl = (IR1 == cmp) ? 1 : 0;
622 IR = (ch << 3) | (cl << 2) | ((ch | cl) << 1) |
623 ((ch & cl) << 0);
624 goto update_ccr;
625 }
626 }
627 default:
628 return -EINVAL;
629 }
630
631update_ccr:
632 regs->ccr &= ~(15 << ((7 - ((speinsn >> 23) & 0x7)) << 2));
633 regs->ccr |= (IR << ((7 - ((speinsn >> 23) & 0x7)) << 2));
634
635update_regs:
636 __FPU_FPSCR &= ~FP_EX_MASK;
637 __FPU_FPSCR |= (FP_CUR_EXCEPTIONS & FP_EX_MASK);
638 mtspr(SPRN_SPEFSCR, __FPU_FPSCR);
639
640 current->thread.evr[fc] = vc.wp[0];
641 regs->gpr[fc] = vc.wp[1];
642
643#ifdef DEBUG
644 printk("ccr = %08lx\n", regs->ccr);
645 printk("cur exceptions = %08x spefscr = %08lx\n",
646 FP_CUR_EXCEPTIONS, __FPU_FPSCR);
647 printk("vc: %08x %08x\n", vc.wp[0], vc.wp[1]);
648 printk("va: %08x %08x\n", va.wp[0], va.wp[1]);
649 printk("vb: %08x %08x\n", vb.wp[0], vb.wp[1]);
650#endif
651
652 return 0;
653
654illegal:
655 printk(KERN_ERR "\nOoops! IEEE-754 compliance handler encountered un-supported instruction.\ninst code: %08lx\n", speinsn);
656 return -ENOSYS;
657}
658
659int speround_handler(struct pt_regs *regs)
660{
661 union dw_union fgpr;
662 int s_lo, s_hi;
663 unsigned long speinsn, type, fc;
664
665 if (get_user(speinsn, (unsigned int __user *) regs->nip))
666 return -EFAULT;
667 if ((speinsn >> 26) != 4)
668 return -EINVAL; /* not an spe instruction */
669
670 type = insn_type(speinsn & 0x7ff);
671 if (type == XCR) return -ENOSYS;
672
673 fc = (speinsn >> 21) & 0x1f;
674 s_lo = regs->gpr[fc] & SIGN_BIT_S;
675 s_hi = current->thread.evr[fc] & SIGN_BIT_S;
676 fgpr.wp[0] = current->thread.evr[fc];
677 fgpr.wp[1] = regs->gpr[fc];
678
679 __FPU_FPSCR = mfspr(SPRN_SPEFSCR);
680
681 switch ((speinsn >> 5) & 0x7) {
682 /* Since SPE instructions on E500 core can handle round to nearest
683 * and round toward zero with IEEE-754 complied, we just need
684 * to handle round toward +Inf and round toward -Inf by software.
685 */
686 case SPFP:
687 if ((FP_ROUNDMODE) == FP_RND_PINF) {
688 if (!s_lo) fgpr.wp[1]++; /* Z > 0, choose Z1 */
689 } else { /* round to -Inf */
690 if (s_lo) fgpr.wp[1]++; /* Z < 0, choose Z2 */
691 }
692 break;
693
694 case DPFP:
695 if (FP_ROUNDMODE == FP_RND_PINF) {
696 if (!s_hi) fgpr.dp[0]++; /* Z > 0, choose Z1 */
697 } else { /* round to -Inf */
698 if (s_hi) fgpr.dp[0]++; /* Z < 0, choose Z2 */
699 }
700 break;
701
702 case VCT:
703 if (FP_ROUNDMODE == FP_RND_PINF) {
704 if (!s_lo) fgpr.wp[1]++; /* Z_low > 0, choose Z1 */
705 if (!s_hi) fgpr.wp[0]++; /* Z_high word > 0, choose Z1 */
706 } else { /* round to -Inf */
707 if (s_lo) fgpr.wp[1]++; /* Z_low < 0, choose Z2 */
708 if (s_hi) fgpr.wp[0]++; /* Z_high < 0, choose Z2 */
709 }
710 break;
711
712 default:
713 return -EINVAL;
714 }
715
716 current->thread.evr[fc] = fgpr.wp[0];
717 regs->gpr[fc] = fgpr.wp[1];
718
719 return 0;
720}
diff --git a/arch/powerpc/mm/Makefile b/arch/powerpc/mm/Makefile
index e7392b45a5ef..148de35c9eef 100644
--- a/arch/powerpc/mm/Makefile
+++ b/arch/powerpc/mm/Makefile
@@ -6,7 +6,7 @@ ifeq ($(CONFIG_PPC64),y)
6EXTRA_CFLAGS += -mno-minimal-toc 6EXTRA_CFLAGS += -mno-minimal-toc
7endif 7endif
8 8
9obj-y := fault.o mem.o \ 9obj-y := fault.o mem.o pgtable.o \
10 init_$(CONFIG_WORD_SIZE).o \ 10 init_$(CONFIG_WORD_SIZE).o \
11 pgtable_$(CONFIG_WORD_SIZE).o \ 11 pgtable_$(CONFIG_WORD_SIZE).o \
12 mmu_context_$(CONFIG_WORD_SIZE).o 12 mmu_context_$(CONFIG_WORD_SIZE).o
@@ -16,7 +16,7 @@ obj-$(CONFIG_PPC64) += hash_utils_64.o \
16 gup.o mmap.o $(hash-y) 16 gup.o mmap.o $(hash-y)
17obj-$(CONFIG_PPC_STD_MMU_32) += ppc_mmu_32.o 17obj-$(CONFIG_PPC_STD_MMU_32) += ppc_mmu_32.o
18obj-$(CONFIG_PPC_STD_MMU) += hash_low_$(CONFIG_WORD_SIZE).o \ 18obj-$(CONFIG_PPC_STD_MMU) += hash_low_$(CONFIG_WORD_SIZE).o \
19 tlb_$(CONFIG_WORD_SIZE).o 19 tlb_hash$(CONFIG_WORD_SIZE).o
20obj-$(CONFIG_40x) += 40x_mmu.o 20obj-$(CONFIG_40x) += 40x_mmu.o
21obj-$(CONFIG_44x) += 44x_mmu.o 21obj-$(CONFIG_44x) += 44x_mmu.o
22obj-$(CONFIG_FSL_BOOKE) += fsl_booke_mmu.o 22obj-$(CONFIG_FSL_BOOKE) += fsl_booke_mmu.o
diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c
index 565b7a237c84..7df0409107ad 100644
--- a/arch/powerpc/mm/fault.c
+++ b/arch/powerpc/mm/fault.c
@@ -30,6 +30,7 @@
30#include <linux/kprobes.h> 30#include <linux/kprobes.h>
31#include <linux/kdebug.h> 31#include <linux/kdebug.h>
32 32
33#include <asm/firmware.h>
33#include <asm/page.h> 34#include <asm/page.h>
34#include <asm/pgtable.h> 35#include <asm/pgtable.h>
35#include <asm/mmu.h> 36#include <asm/mmu.h>
@@ -318,9 +319,16 @@ good_area:
318 goto do_sigbus; 319 goto do_sigbus;
319 BUG(); 320 BUG();
320 } 321 }
321 if (ret & VM_FAULT_MAJOR) 322 if (ret & VM_FAULT_MAJOR) {
322 current->maj_flt++; 323 current->maj_flt++;
323 else 324#ifdef CONFIG_PPC_SMLPAR
325 if (firmware_has_feature(FW_FEATURE_CMO)) {
326 preempt_disable();
327 get_lppaca()->page_ins += (1 << PAGE_FACTOR);
328 preempt_enable();
329 }
330#endif
331 } else
324 current->min_flt++; 332 current->min_flt++;
325 up_read(&mm->mmap_sem); 333 up_read(&mm->mmap_sem);
326 return 0; 334 return 0;
diff --git a/arch/powerpc/mm/hash_low_32.S b/arch/powerpc/mm/hash_low_32.S
index 7bffb70b9fe2..c5536b8b37a9 100644
--- a/arch/powerpc/mm/hash_low_32.S
+++ b/arch/powerpc/mm/hash_low_32.S
@@ -36,36 +36,6 @@ mmu_hash_lock:
36#endif /* CONFIG_SMP */ 36#endif /* CONFIG_SMP */
37 37
38/* 38/*
39 * Sync CPUs with hash_page taking & releasing the hash
40 * table lock
41 */
42#ifdef CONFIG_SMP
43 .text
44_GLOBAL(hash_page_sync)
45 mfmsr r10
46 rlwinm r0,r10,0,17,15 /* clear bit 16 (MSR_EE) */
47 mtmsr r0
48 lis r8,mmu_hash_lock@h
49 ori r8,r8,mmu_hash_lock@l
50 lis r0,0x0fff
51 b 10f
5211: lwz r6,0(r8)
53 cmpwi 0,r6,0
54 bne 11b
5510: lwarx r6,0,r8
56 cmpwi 0,r6,0
57 bne- 11b
58 stwcx. r0,0,r8
59 bne- 10b
60 isync
61 eieio
62 li r0,0
63 stw r0,0(r8)
64 mtmsr r10
65 blr
66#endif /* CONFIG_SMP */
67
68/*
69 * Load a PTE into the hash table, if possible. 39 * Load a PTE into the hash table, if possible.
70 * The address is in r4, and r3 contains an access flag: 40 * The address is in r4, and r3 contains an access flag:
71 * _PAGE_RW (0x400) if a write. 41 * _PAGE_RW (0x400) if a write.
diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c
index f0c3b88d50fa..201c7a5486cb 100644
--- a/arch/powerpc/mm/hugetlbpage.c
+++ b/arch/powerpc/mm/hugetlbpage.c
@@ -53,8 +53,7 @@ unsigned int mmu_huge_psizes[MMU_PAGE_COUNT] = { }; /* initialize all to 0 */
53 53
54/* Subtract one from array size because we don't need a cache for 4K since 54/* Subtract one from array size because we don't need a cache for 4K since
55 * is not a huge page size */ 55 * is not a huge page size */
56#define huge_pgtable_cache(psize) (pgtable_cache[HUGEPTE_CACHE_NUM \ 56#define HUGE_PGTABLE_INDEX(psize) (HUGEPTE_CACHE_NUM + psize - 1)
57 + psize-1])
58#define HUGEPTE_CACHE_NAME(psize) (huge_pgtable_cache_name[psize]) 57#define HUGEPTE_CACHE_NAME(psize) (huge_pgtable_cache_name[psize])
59 58
60static const char *huge_pgtable_cache_name[MMU_PAGE_COUNT] = { 59static const char *huge_pgtable_cache_name[MMU_PAGE_COUNT] = {
@@ -113,7 +112,7 @@ static inline pte_t *hugepte_offset(hugepd_t *hpdp, unsigned long addr,
113static int __hugepte_alloc(struct mm_struct *mm, hugepd_t *hpdp, 112static int __hugepte_alloc(struct mm_struct *mm, hugepd_t *hpdp,
114 unsigned long address, unsigned int psize) 113 unsigned long address, unsigned int psize)
115{ 114{
116 pte_t *new = kmem_cache_zalloc(huge_pgtable_cache(psize), 115 pte_t *new = kmem_cache_zalloc(pgtable_cache[HUGE_PGTABLE_INDEX(psize)],
117 GFP_KERNEL|__GFP_REPEAT); 116 GFP_KERNEL|__GFP_REPEAT);
118 117
119 if (! new) 118 if (! new)
@@ -121,7 +120,7 @@ static int __hugepte_alloc(struct mm_struct *mm, hugepd_t *hpdp,
121 120
122 spin_lock(&mm->page_table_lock); 121 spin_lock(&mm->page_table_lock);
123 if (!hugepd_none(*hpdp)) 122 if (!hugepd_none(*hpdp))
124 kmem_cache_free(huge_pgtable_cache(psize), new); 123 kmem_cache_free(pgtable_cache[HUGE_PGTABLE_INDEX(psize)], new);
125 else 124 else
126 hpdp->pd = (unsigned long)new | HUGEPD_OK; 125 hpdp->pd = (unsigned long)new | HUGEPD_OK;
127 spin_unlock(&mm->page_table_lock); 126 spin_unlock(&mm->page_table_lock);
@@ -763,13 +762,14 @@ static int __init hugetlbpage_init(void)
763 762
764 for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) { 763 for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) {
765 if (mmu_huge_psizes[psize]) { 764 if (mmu_huge_psizes[psize]) {
766 huge_pgtable_cache(psize) = kmem_cache_create( 765 pgtable_cache[HUGE_PGTABLE_INDEX(psize)] =
767 HUGEPTE_CACHE_NAME(psize), 766 kmem_cache_create(
768 HUGEPTE_TABLE_SIZE(psize), 767 HUGEPTE_CACHE_NAME(psize),
769 HUGEPTE_TABLE_SIZE(psize), 768 HUGEPTE_TABLE_SIZE(psize),
770 0, 769 HUGEPTE_TABLE_SIZE(psize),
771 NULL); 770 0,
772 if (!huge_pgtable_cache(psize)) 771 NULL);
772 if (!pgtable_cache[HUGE_PGTABLE_INDEX(psize)])
773 panic("hugetlbpage_init(): could not create %s"\ 773 panic("hugetlbpage_init(): could not create %s"\
774 "\n", HUGEPTE_CACHE_NAME(psize)); 774 "\n", HUGEPTE_CACHE_NAME(psize));
775 } 775 }
diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h
index fab3cfad4099..b4344fd30f2a 100644
--- a/arch/powerpc/mm/mmu_decl.h
+++ b/arch/powerpc/mm/mmu_decl.h
@@ -58,17 +58,14 @@ extern phys_addr_t lowmem_end_addr;
58 * architectures. -- Dan 58 * architectures. -- Dan
59 */ 59 */
60#if defined(CONFIG_8xx) 60#if defined(CONFIG_8xx)
61#define flush_HPTE(X, va, pg) _tlbie(va, 0 /* 8xx doesn't care about PID */)
62#define MMU_init_hw() do { } while(0) 61#define MMU_init_hw() do { } while(0)
63#define mmu_mapin_ram() (0UL) 62#define mmu_mapin_ram() (0UL)
64 63
65#elif defined(CONFIG_4xx) 64#elif defined(CONFIG_4xx)
66#define flush_HPTE(pid, va, pg) _tlbie(va, pid)
67extern void MMU_init_hw(void); 65extern void MMU_init_hw(void);
68extern unsigned long mmu_mapin_ram(void); 66extern unsigned long mmu_mapin_ram(void);
69 67
70#elif defined(CONFIG_FSL_BOOKE) 68#elif defined(CONFIG_FSL_BOOKE)
71#define flush_HPTE(pid, va, pg) _tlbie(va, pid)
72extern void MMU_init_hw(void); 69extern void MMU_init_hw(void);
73extern unsigned long mmu_mapin_ram(void); 70extern unsigned long mmu_mapin_ram(void);
74extern void adjust_total_lowmem(void); 71extern void adjust_total_lowmem(void);
@@ -77,18 +74,4 @@ extern void adjust_total_lowmem(void);
77/* anything 32-bit except 4xx or 8xx */ 74/* anything 32-bit except 4xx or 8xx */
78extern void MMU_init_hw(void); 75extern void MMU_init_hw(void);
79extern unsigned long mmu_mapin_ram(void); 76extern unsigned long mmu_mapin_ram(void);
80
81/* Be careful....this needs to be updated if we ever encounter 603 SMPs,
82 * which includes all new 82xx processors. We need tlbie/tlbsync here
83 * in that case (I think). -- Dan.
84 */
85static inline void flush_HPTE(unsigned context, unsigned long va,
86 unsigned long pdval)
87{
88 if ((Hash != 0) &&
89 cpu_has_feature(CPU_FTR_HPTE_TABLE))
90 flush_hash_pages(0, va, pdval, 1);
91 else
92 _tlbie(va);
93}
94#endif 77#endif
diff --git a/arch/powerpc/mm/pgtable.c b/arch/powerpc/mm/pgtable.c
new file mode 100644
index 000000000000..6d94116fdea1
--- /dev/null
+++ b/arch/powerpc/mm/pgtable.c
@@ -0,0 +1,117 @@
1/*
2 * This file contains common routines for dealing with free of page tables
3 *
4 * Derived from arch/powerpc/mm/tlb_64.c:
5 * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
6 *
7 * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
8 * and Cort Dougan (PReP) (cort@cs.nmt.edu)
9 * Copyright (C) 1996 Paul Mackerras
10 *
11 * Derived from "arch/i386/mm/init.c"
12 * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
13 *
14 * Dave Engebretsen <engebret@us.ibm.com>
15 * Rework for PPC64 port.
16 *
17 * This program is free software; you can redistribute it and/or
18 * modify it under the terms of the GNU General Public License
19 * as published by the Free Software Foundation; either version
20 * 2 of the License, or (at your option) any later version.
21 */
22
23#include <linux/kernel.h>
24#include <linux/mm.h>
25#include <linux/init.h>
26#include <linux/percpu.h>
27#include <linux/hardirq.h>
28#include <asm/pgalloc.h>
29#include <asm/tlbflush.h>
30#include <asm/tlb.h>
31
32static DEFINE_PER_CPU(struct pte_freelist_batch *, pte_freelist_cur);
33static unsigned long pte_freelist_forced_free;
34
35struct pte_freelist_batch
36{
37 struct rcu_head rcu;
38 unsigned int index;
39 pgtable_free_t tables[0];
40};
41
42#define PTE_FREELIST_SIZE \
43 ((PAGE_SIZE - sizeof(struct pte_freelist_batch)) \
44 / sizeof(pgtable_free_t))
45
46static void pte_free_smp_sync(void *arg)
47{
48 /* Do nothing, just ensure we sync with all CPUs */
49}
50
51/* This is only called when we are critically out of memory
52 * (and fail to get a page in pte_free_tlb).
53 */
54static void pgtable_free_now(pgtable_free_t pgf)
55{
56 pte_freelist_forced_free++;
57
58 smp_call_function(pte_free_smp_sync, NULL, 1);
59
60 pgtable_free(pgf);
61}
62
63static void pte_free_rcu_callback(struct rcu_head *head)
64{
65 struct pte_freelist_batch *batch =
66 container_of(head, struct pte_freelist_batch, rcu);
67 unsigned int i;
68
69 for (i = 0; i < batch->index; i++)
70 pgtable_free(batch->tables[i]);
71
72 free_page((unsigned long)batch);
73}
74
75static void pte_free_submit(struct pte_freelist_batch *batch)
76{
77 INIT_RCU_HEAD(&batch->rcu);
78 call_rcu(&batch->rcu, pte_free_rcu_callback);
79}
80
81void pgtable_free_tlb(struct mmu_gather *tlb, pgtable_free_t pgf)
82{
83 /* This is safe since tlb_gather_mmu has disabled preemption */
84 cpumask_t local_cpumask = cpumask_of_cpu(smp_processor_id());
85 struct pte_freelist_batch **batchp = &__get_cpu_var(pte_freelist_cur);
86
87 if (atomic_read(&tlb->mm->mm_users) < 2 ||
88 cpus_equal(tlb->mm->cpu_vm_mask, local_cpumask)) {
89 pgtable_free(pgf);
90 return;
91 }
92
93 if (*batchp == NULL) {
94 *batchp = (struct pte_freelist_batch *)__get_free_page(GFP_ATOMIC);
95 if (*batchp == NULL) {
96 pgtable_free_now(pgf);
97 return;
98 }
99 (*batchp)->index = 0;
100 }
101 (*batchp)->tables[(*batchp)->index++] = pgf;
102 if ((*batchp)->index == PTE_FREELIST_SIZE) {
103 pte_free_submit(*batchp);
104 *batchp = NULL;
105 }
106}
107
108void pte_free_finish(void)
109{
110 /* This is safe since tlb_gather_mmu has disabled preemption */
111 struct pte_freelist_batch **batchp = &__get_cpu_var(pte_freelist_cur);
112
113 if (*batchp == NULL)
114 return;
115 pte_free_submit(*batchp);
116 *batchp = NULL;
117}
diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
index c31d6d26f0b5..341472440137 100644
--- a/arch/powerpc/mm/pgtable_32.c
+++ b/arch/powerpc/mm/pgtable_32.c
@@ -48,10 +48,6 @@ EXPORT_SYMBOL(ioremap_bot); /* aka VMALLOC_END */
48 48
49extern char etext[], _stext[]; 49extern char etext[], _stext[];
50 50
51#ifdef CONFIG_SMP
52extern void hash_page_sync(void);
53#endif
54
55#ifdef HAVE_BATS 51#ifdef HAVE_BATS
56extern phys_addr_t v_mapped_by_bats(unsigned long va); 52extern phys_addr_t v_mapped_by_bats(unsigned long va);
57extern unsigned long p_mapped_by_bats(phys_addr_t pa); 53extern unsigned long p_mapped_by_bats(phys_addr_t pa);
@@ -125,23 +121,6 @@ pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long address)
125 return ptepage; 121 return ptepage;
126} 122}
127 123
128void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
129{
130#ifdef CONFIG_SMP
131 hash_page_sync();
132#endif
133 free_page((unsigned long)pte);
134}
135
136void pte_free(struct mm_struct *mm, pgtable_t ptepage)
137{
138#ifdef CONFIG_SMP
139 hash_page_sync();
140#endif
141 pgtable_page_dtor(ptepage);
142 __free_page(ptepage);
143}
144
145void __iomem * 124void __iomem *
146ioremap(phys_addr_t addr, unsigned long size) 125ioremap(phys_addr_t addr, unsigned long size)
147{ 126{
@@ -363,7 +342,11 @@ static int __change_page_attr(struct page *page, pgprot_t prot)
363 return -EINVAL; 342 return -EINVAL;
364 set_pte_at(&init_mm, address, kpte, mk_pte(page, prot)); 343 set_pte_at(&init_mm, address, kpte, mk_pte(page, prot));
365 wmb(); 344 wmb();
366 flush_HPTE(0, address, pmd_val(*kpmd)); 345#ifdef CONFIG_PPC_STD_MMU
346 flush_hash_pages(0, address, pmd_val(*kpmd), 1);
347#else
348 flush_tlb_page(NULL, address);
349#endif
367 pte_unmap(kpte); 350 pte_unmap(kpte);
368 351
369 return 0; 352 return 0;
diff --git a/arch/powerpc/mm/tlb_32.c b/arch/powerpc/mm/tlb_hash32.c
index f9a47fee3927..f9a47fee3927 100644
--- a/arch/powerpc/mm/tlb_32.c
+++ b/arch/powerpc/mm/tlb_hash32.c
diff --git a/arch/powerpc/mm/tlb_64.c b/arch/powerpc/mm/tlb_hash64.c
index be7dd422c0fa..c931bc7d1079 100644
--- a/arch/powerpc/mm/tlb_64.c
+++ b/arch/powerpc/mm/tlb_hash64.c
@@ -37,81 +37,6 @@ DEFINE_PER_CPU(struct ppc64_tlb_batch, ppc64_tlb_batch);
37 * arch/powerpc/include/asm/tlb.h file -- tgall 37 * arch/powerpc/include/asm/tlb.h file -- tgall
38 */ 38 */
39DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); 39DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
40static DEFINE_PER_CPU(struct pte_freelist_batch *, pte_freelist_cur);
41static unsigned long pte_freelist_forced_free;
42
43struct pte_freelist_batch
44{
45 struct rcu_head rcu;
46 unsigned int index;
47 pgtable_free_t tables[0];
48};
49
50#define PTE_FREELIST_SIZE \
51 ((PAGE_SIZE - sizeof(struct pte_freelist_batch)) \
52 / sizeof(pgtable_free_t))
53
54static void pte_free_smp_sync(void *arg)
55{
56 /* Do nothing, just ensure we sync with all CPUs */
57}
58
59/* This is only called when we are critically out of memory
60 * (and fail to get a page in pte_free_tlb).
61 */
62static void pgtable_free_now(pgtable_free_t pgf)
63{
64 pte_freelist_forced_free++;
65
66 smp_call_function(pte_free_smp_sync, NULL, 1);
67
68 pgtable_free(pgf);
69}
70
71static void pte_free_rcu_callback(struct rcu_head *head)
72{
73 struct pte_freelist_batch *batch =
74 container_of(head, struct pte_freelist_batch, rcu);
75 unsigned int i;
76
77 for (i = 0; i < batch->index; i++)
78 pgtable_free(batch->tables[i]);
79
80 free_page((unsigned long)batch);
81}
82
83static void pte_free_submit(struct pte_freelist_batch *batch)
84{
85 INIT_RCU_HEAD(&batch->rcu);
86 call_rcu(&batch->rcu, pte_free_rcu_callback);
87}
88
89void pgtable_free_tlb(struct mmu_gather *tlb, pgtable_free_t pgf)
90{
91 /* This is safe since tlb_gather_mmu has disabled preemption */
92 cpumask_t local_cpumask = cpumask_of_cpu(smp_processor_id());
93 struct pte_freelist_batch **batchp = &__get_cpu_var(pte_freelist_cur);
94
95 if (atomic_read(&tlb->mm->mm_users) < 2 ||
96 cpus_equal(tlb->mm->cpu_vm_mask, local_cpumask)) {
97 pgtable_free(pgf);
98 return;
99 }
100
101 if (*batchp == NULL) {
102 *batchp = (struct pte_freelist_batch *)__get_free_page(GFP_ATOMIC);
103 if (*batchp == NULL) {
104 pgtable_free_now(pgf);
105 return;
106 }
107 (*batchp)->index = 0;
108 }
109 (*batchp)->tables[(*batchp)->index++] = pgf;
110 if ((*batchp)->index == PTE_FREELIST_SIZE) {
111 pte_free_submit(*batchp);
112 *batchp = NULL;
113 }
114}
115 40
116/* 41/*
117 * A linux PTE was changed and the corresponding hash table entry 42 * A linux PTE was changed and the corresponding hash table entry
@@ -229,17 +154,6 @@ void __flush_tlb_pending(struct ppc64_tlb_batch *batch)
229 batch->index = 0; 154 batch->index = 0;
230} 155}
231 156
232void pte_free_finish(void)
233{
234 /* This is safe since tlb_gather_mmu has disabled preemption */
235 struct pte_freelist_batch **batchp = &__get_cpu_var(pte_freelist_cur);
236
237 if (*batchp == NULL)
238 return;
239 pte_free_submit(*batchp);
240 *batchp = NULL;
241}
242
243/** 157/**
244 * __flush_hash_table_range - Flush all HPTEs for a given address range 158 * __flush_hash_table_range - Flush all HPTEs for a given address range
245 * from the hash table (and the TLB). But keeps 159 * from the hash table (and the TLB). But keeps
diff --git a/arch/powerpc/platforms/40x/ep405.c b/arch/powerpc/platforms/40x/ep405.c
index ae2e7f67c18e..4058fd1e7fc7 100644
--- a/arch/powerpc/platforms/40x/ep405.c
+++ b/arch/powerpc/platforms/40x/ep405.c
@@ -100,7 +100,7 @@ static void __init ep405_setup_arch(void)
100 /* Find & init the BCSR CPLD */ 100 /* Find & init the BCSR CPLD */
101 ep405_init_bcsr(); 101 ep405_init_bcsr();
102 102
103 ppc_pci_flags = PPC_PCI_REASSIGN_ALL_RSRC; 103 ppc_pci_set_flags(PPC_PCI_REASSIGN_ALL_RSRC);
104} 104}
105 105
106static int __init ep405_probe(void) 106static int __init ep405_probe(void)
diff --git a/arch/powerpc/platforms/40x/kilauea.c b/arch/powerpc/platforms/40x/kilauea.c
index 1dd24ffc0dc1..fd7d934dac8b 100644
--- a/arch/powerpc/platforms/40x/kilauea.c
+++ b/arch/powerpc/platforms/40x/kilauea.c
@@ -44,7 +44,7 @@ static int __init kilauea_probe(void)
44 if (!of_flat_dt_is_compatible(root, "amcc,kilauea")) 44 if (!of_flat_dt_is_compatible(root, "amcc,kilauea"))
45 return 0; 45 return 0;
46 46
47 ppc_pci_flags = PPC_PCI_REASSIGN_ALL_RSRC; 47 ppc_pci_set_flags(PPC_PCI_REASSIGN_ALL_RSRC);
48 48
49 return 1; 49 return 1;
50} 50}
diff --git a/arch/powerpc/platforms/40x/ppc40x_simple.c b/arch/powerpc/platforms/40x/ppc40x_simple.c
index 4498a86b46c3..f40ac9b8f99f 100644
--- a/arch/powerpc/platforms/40x/ppc40x_simple.c
+++ b/arch/powerpc/platforms/40x/ppc40x_simple.c
@@ -61,7 +61,7 @@ static int __init ppc40x_probe(void)
61 61
62 for (i = 0; i < ARRAY_SIZE(board); i++) { 62 for (i = 0; i < ARRAY_SIZE(board); i++) {
63 if (of_flat_dt_is_compatible(root, board[i])) { 63 if (of_flat_dt_is_compatible(root, board[i])) {
64 ppc_pci_flags = PPC_PCI_REASSIGN_ALL_RSRC; 64 ppc_pci_set_flags(PPC_PCI_REASSIGN_ALL_RSRC);
65 return 1; 65 return 1;
66 } 66 }
67 } 67 }
diff --git a/arch/powerpc/platforms/44x/ebony.c b/arch/powerpc/platforms/44x/ebony.c
index a0e8fe4662f6..88b9117fa691 100644
--- a/arch/powerpc/platforms/44x/ebony.c
+++ b/arch/powerpc/platforms/44x/ebony.c
@@ -54,7 +54,7 @@ static int __init ebony_probe(void)
54 if (!of_flat_dt_is_compatible(root, "ibm,ebony")) 54 if (!of_flat_dt_is_compatible(root, "ibm,ebony"))
55 return 0; 55 return 0;
56 56
57 ppc_pci_flags = PPC_PCI_REASSIGN_ALL_RSRC; 57 ppc_pci_set_flags(PPC_PCI_REASSIGN_ALL_RSRC);
58 58
59 return 1; 59 return 1;
60} 60}
diff --git a/arch/powerpc/platforms/44x/ppc44x_simple.c b/arch/powerpc/platforms/44x/ppc44x_simple.c
index 29671262801f..76fdc51dac8b 100644
--- a/arch/powerpc/platforms/44x/ppc44x_simple.c
+++ b/arch/powerpc/platforms/44x/ppc44x_simple.c
@@ -69,7 +69,7 @@ static int __init ppc44x_probe(void)
69 69
70 for (i = 0; i < ARRAY_SIZE(board); i++) { 70 for (i = 0; i < ARRAY_SIZE(board); i++) {
71 if (of_flat_dt_is_compatible(root, board[i])) { 71 if (of_flat_dt_is_compatible(root, board[i])) {
72 ppc_pci_flags = PPC_PCI_REASSIGN_ALL_RSRC; 72 ppc_pci_set_flags(PPC_PCI_REASSIGN_ALL_RSRC);
73 return 1; 73 return 1;
74 } 74 }
75 } 75 }
diff --git a/arch/powerpc/platforms/44x/sam440ep.c b/arch/powerpc/platforms/44x/sam440ep.c
index 47f10e647735..a78e8eb6da41 100644
--- a/arch/powerpc/platforms/44x/sam440ep.c
+++ b/arch/powerpc/platforms/44x/sam440ep.c
@@ -51,7 +51,7 @@ static int __init sam440ep_probe(void)
51 if (!of_flat_dt_is_compatible(root, "acube,sam440ep")) 51 if (!of_flat_dt_is_compatible(root, "acube,sam440ep"))
52 return 0; 52 return 0;
53 53
54 ppc_pci_flags = PPC_PCI_REASSIGN_ALL_RSRC; 54 ppc_pci_set_flags(PPC_PCI_REASSIGN_ALL_RSRC);
55 55
56 return 1; 56 return 1;
57} 57}
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pci.c b/arch/powerpc/platforms/52xx/mpc52xx_pci.c
index b49a18527661..c3f2c21024e3 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_pci.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_pci.c
@@ -375,7 +375,7 @@ mpc52xx_add_bridge(struct device_node *node)
375 375
376 pr_debug("Adding MPC52xx PCI host bridge %s\n", node->full_name); 376 pr_debug("Adding MPC52xx PCI host bridge %s\n", node->full_name);
377 377
378 ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS; 378 ppc_pci_add_flags(PPC_PCI_REASSIGN_ALL_BUS);
379 379
380 if (of_address_to_resource(node, 0, &rsrc) != 0) { 380 if (of_address_to_resource(node, 0, &rsrc) != 0) {
381 printk(KERN_ERR "Can't get %s resources\n", node->full_name); 381 printk(KERN_ERR "Can't get %s resources\n", node->full_name);
diff --git a/arch/powerpc/platforms/82xx/pq2.c b/arch/powerpc/platforms/82xx/pq2.c
index 1b75902fad64..9761a59f175f 100644
--- a/arch/powerpc/platforms/82xx/pq2.c
+++ b/arch/powerpc/platforms/82xx/pq2.c
@@ -53,7 +53,7 @@ static void __init pq2_pci_add_bridge(struct device_node *np)
53 if (of_address_to_resource(np, 0, &r) || r.end - r.start < 0x10b) 53 if (of_address_to_resource(np, 0, &r) || r.end - r.start < 0x10b)
54 goto err; 54 goto err;
55 55
56 ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS; 56 ppc_pci_add_flags(PPC_PCI_REASSIGN_ALL_BUS);
57 57
58 hose = pcibios_alloc_controller(np); 58 hose = pcibios_alloc_controller(np);
59 if (!hose) 59 if (!hose)
diff --git a/arch/powerpc/platforms/85xx/Makefile b/arch/powerpc/platforms/85xx/Makefile
index cb3054e1001d..f0798c09980f 100644
--- a/arch/powerpc/platforms/85xx/Makefile
+++ b/arch/powerpc/platforms/85xx/Makefile
@@ -1,6 +1,8 @@
1# 1#
2# Makefile for the PowerPC 85xx linux kernel. 2# Makefile for the PowerPC 85xx linux kernel.
3# 3#
4obj-$(CONFIG_SMP) += smp.o
5
4obj-$(CONFIG_MPC8540_ADS) += mpc85xx_ads.o 6obj-$(CONFIG_MPC8540_ADS) += mpc85xx_ads.o
5obj-$(CONFIG_MPC8560_ADS) += mpc85xx_ads.o 7obj-$(CONFIG_MPC8560_ADS) += mpc85xx_ads.o
6obj-$(CONFIG_MPC85xx_CDS) += mpc85xx_cds.o 8obj-$(CONFIG_MPC85xx_CDS) += mpc85xx_cds.o
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ds.c b/arch/powerpc/platforms/85xx/mpc85xx_ds.c
index 613bf8c2e30d..a8301c8ad537 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_ds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_ds.c
@@ -63,6 +63,7 @@ void __init mpc85xx_ds_pic_init(void)
63 struct device_node *cascade_node = NULL; 63 struct device_node *cascade_node = NULL;
64 int cascade_irq; 64 int cascade_irq;
65#endif 65#endif
66 unsigned long root = of_get_flat_dt_root();
66 67
67 np = of_find_node_by_type(NULL, "open-pic"); 68 np = of_find_node_by_type(NULL, "open-pic");
68 if (np == NULL) { 69 if (np == NULL) {
@@ -76,11 +77,19 @@ void __init mpc85xx_ds_pic_init(void)
76 return; 77 return;
77 } 78 }
78 79
79 mpic = mpic_alloc(np, r.start, 80 if (of_flat_dt_is_compatible(root, "fsl,MPC8572DS-CAMP")) {
81 mpic = mpic_alloc(np, r.start,
82 MPIC_PRIMARY |
83 MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS,
84 0, 256, " OpenPIC ");
85 } else {
86 mpic = mpic_alloc(np, r.start,
80 MPIC_PRIMARY | MPIC_WANTS_RESET | 87 MPIC_PRIMARY | MPIC_WANTS_RESET |
81 MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS | 88 MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS |
82 MPIC_SINGLE_DEST_CPU, 89 MPIC_SINGLE_DEST_CPU,
83 0, 256, " OpenPIC "); 90 0, 256, " OpenPIC ");
91 }
92
84 BUG_ON(mpic == NULL); 93 BUG_ON(mpic == NULL);
85 of_node_put(np); 94 of_node_put(np);
86 95
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
index 2494c5155919..658a36fab3ab 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_mds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
@@ -231,7 +231,7 @@ static void __init mpc85xx_mds_setup_arch(void)
231 231
232static int __init board_fixups(void) 232static int __init board_fixups(void)
233{ 233{
234 char phy_id[BUS_ID_SIZE]; 234 char phy_id[20];
235 char *compstrs[2] = {"fsl,gianfar-mdio", "fsl,ucc-mdio"}; 235 char *compstrs[2] = {"fsl,gianfar-mdio", "fsl,ucc-mdio"};
236 struct device_node *mdio; 236 struct device_node *mdio;
237 struct resource res; 237 struct resource res;
@@ -241,13 +241,15 @@ static int __init board_fixups(void)
241 mdio = of_find_compatible_node(NULL, NULL, compstrs[i]); 241 mdio = of_find_compatible_node(NULL, NULL, compstrs[i]);
242 242
243 of_address_to_resource(mdio, 0, &res); 243 of_address_to_resource(mdio, 0, &res);
244 snprintf(phy_id, BUS_ID_SIZE, "%x:%02x", res.start, 1); 244 snprintf(phy_id, sizeof(phy_id), "%llx:%02x",
245 (unsigned long long)res.start, 1);
245 246
246 phy_register_fixup_for_id(phy_id, mpc8568_fixup_125_clock); 247 phy_register_fixup_for_id(phy_id, mpc8568_fixup_125_clock);
247 phy_register_fixup_for_id(phy_id, mpc8568_mds_phy_fixups); 248 phy_register_fixup_for_id(phy_id, mpc8568_mds_phy_fixups);
248 249
249 /* Register a workaround for errata */ 250 /* Register a workaround for errata */
250 snprintf(phy_id, BUS_ID_SIZE, "%x:%02x", res.start, 7); 251 snprintf(phy_id, sizeof(phy_id), "%llx:%02x",
252 (unsigned long long)res.start, 7);
251 phy_register_fixup_for_id(phy_id, mpc8568_mds_phy_fixups); 253 phy_register_fixup_for_id(phy_id, mpc8568_mds_phy_fixups);
252 254
253 of_node_put(mdio); 255 of_node_put(mdio);
diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c
new file mode 100644
index 000000000000..d652c713f496
--- /dev/null
+++ b/arch/powerpc/platforms/85xx/smp.c
@@ -0,0 +1,104 @@
1/*
2 * Author: Andy Fleming <afleming@freescale.com>
3 * Kumar Gala <galak@kernel.crashing.org>
4 *
5 * Copyright 2006-2008 Freescale Semiconductor Inc.
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13#include <linux/stddef.h>
14#include <linux/kernel.h>
15#include <linux/init.h>
16#include <linux/delay.h>
17#include <linux/of.h>
18
19#include <asm/machdep.h>
20#include <asm/pgtable.h>
21#include <asm/page.h>
22#include <asm/mpic.h>
23#include <asm/cacheflush.h>
24
25#include <sysdev/fsl_soc.h>
26
27extern volatile unsigned long __secondary_hold_acknowledge;
28extern void __early_start(void);
29
30#define BOOT_ENTRY_ADDR_UPPER 0
31#define BOOT_ENTRY_ADDR_LOWER 1
32#define BOOT_ENTRY_R3_UPPER 2
33#define BOOT_ENTRY_R3_LOWER 3
34#define BOOT_ENTRY_RESV 4
35#define BOOT_ENTRY_PIR 5
36#define BOOT_ENTRY_R6_UPPER 6
37#define BOOT_ENTRY_R6_LOWER 7
38#define NUM_BOOT_ENTRY 8
39#define SIZE_BOOT_ENTRY (NUM_BOOT_ENTRY * sizeof(u32))
40
41static void __init
42smp_85xx_kick_cpu(int nr)
43{
44 unsigned long flags;
45 const u64 *cpu_rel_addr;
46 __iomem u32 *bptr_vaddr;
47 struct device_node *np;
48 int n = 0;
49
50 WARN_ON (nr < 0 || nr >= NR_CPUS);
51
52 pr_debug("smp_85xx_kick_cpu: kick CPU #%d\n", nr);
53
54 local_irq_save(flags);
55
56 np = of_get_cpu_node(nr, NULL);
57 cpu_rel_addr = of_get_property(np, "cpu-release-addr", NULL);
58
59 if (cpu_rel_addr == NULL) {
60 printk(KERN_ERR "No cpu-release-addr for cpu %d\n", nr);
61 return;
62 }
63
64 /* Map the spin table */
65 bptr_vaddr = ioremap(*cpu_rel_addr, SIZE_BOOT_ENTRY);
66
67 out_be32(bptr_vaddr + BOOT_ENTRY_PIR, nr);
68 out_be32(bptr_vaddr + BOOT_ENTRY_ADDR_LOWER, __pa(__early_start));
69
70 /* Wait a bit for the CPU to ack. */
71 while ((__secondary_hold_acknowledge != nr) && (++n < 1000))
72 mdelay(1);
73
74 iounmap(bptr_vaddr);
75
76 local_irq_restore(flags);
77
78 pr_debug("waited %d msecs for CPU #%d.\n", n, nr);
79}
80
81static void __init
82smp_85xx_setup_cpu(int cpu_nr)
83{
84 mpic_setup_this_cpu();
85
86 /* Clear any pending timer interrupts */
87 mtspr(SPRN_TSR, TSR_ENW | TSR_WIS | TSR_DIS | TSR_FIS);
88
89 /* Enable decrementer interrupt */
90 mtspr(SPRN_TCR, TCR_DIE);
91}
92
93struct smp_ops_t smp_85xx_ops = {
94 .message_pass = smp_mpic_message_pass,
95 .probe = smp_mpic_probe,
96 .kick_cpu = smp_85xx_kick_cpu,
97 .setup_cpu = smp_85xx_setup_cpu,
98};
99
100void __init
101mpc85xx_smp_init(void)
102{
103 smp_ops = &smp_85xx_ops;
104}
diff --git a/arch/powerpc/platforms/86xx/Kconfig b/arch/powerpc/platforms/86xx/Kconfig
index 77dd797a2580..8e5693935975 100644
--- a/arch/powerpc/platforms/86xx/Kconfig
+++ b/arch/powerpc/platforms/86xx/Kconfig
@@ -34,6 +34,8 @@ config MPC8610_HPCD
34config GEF_SBC610 34config GEF_SBC610
35 bool "GE Fanuc SBC610" 35 bool "GE Fanuc SBC610"
36 select DEFAULT_UIMAGE 36 select DEFAULT_UIMAGE
37 select GENERIC_GPIO
38 select ARCH_REQUIRE_GPIOLIB
37 select HAS_RAPIDIO 39 select HAS_RAPIDIO
38 help 40 help
39 This option enables support for GE Fanuc's SBC610. 41 This option enables support for GE Fanuc's SBC610.
diff --git a/arch/powerpc/platforms/86xx/Makefile b/arch/powerpc/platforms/86xx/Makefile
index 4a56ff619afd..31e540c2ebbc 100644
--- a/arch/powerpc/platforms/86xx/Makefile
+++ b/arch/powerpc/platforms/86xx/Makefile
@@ -7,4 +7,5 @@ obj-$(CONFIG_SMP) += mpc86xx_smp.o
7obj-$(CONFIG_MPC8641_HPCN) += mpc86xx_hpcn.o 7obj-$(CONFIG_MPC8641_HPCN) += mpc86xx_hpcn.o
8obj-$(CONFIG_SBC8641D) += sbc8641d.o 8obj-$(CONFIG_SBC8641D) += sbc8641d.o
9obj-$(CONFIG_MPC8610_HPCD) += mpc8610_hpcd.o 9obj-$(CONFIG_MPC8610_HPCD) += mpc8610_hpcd.o
10obj-$(CONFIG_GEF_SBC610) += gef_sbc610.o gef_pic.o 10gef-gpio-$(CONFIG_GPIOLIB) += gef_gpio.o
11obj-$(CONFIG_GEF_SBC610) += gef_sbc610.o gef_pic.o $(gef-gpio-y)
diff --git a/arch/powerpc/platforms/86xx/gef_gpio.c b/arch/powerpc/platforms/86xx/gef_gpio.c
new file mode 100644
index 000000000000..85b2800f4cb7
--- /dev/null
+++ b/arch/powerpc/platforms/86xx/gef_gpio.c
@@ -0,0 +1,143 @@
1/*
2 * Driver for GE Fanuc's FPGA based GPIO pins
3 *
4 * Author: Martyn Welch <martyn.welch@gefanuc.com>
5 *
6 * 2008 (c) GE Fanuc Intelligent Platforms Embedded Systems, Inc.
7 *
8 * This file is licensed under the terms of the GNU General Public License
9 * version 2. This program is licensed "as is" without any warranty of any
10 * kind, whether express or implied.
11 */
12
13/* TODO
14 *
15 * Configuration of output modes (totem-pole/open-drain)
16 * Interrupt configuration - interrupts are always generated the FPGA relies on
17 * the I/O interrupt controllers mask to stop them propergating
18 */
19
20#include <linux/kernel.h>
21#include <linux/compiler.h>
22#include <linux/init.h>
23#include <linux/io.h>
24#include <linux/of.h>
25#include <linux/of_device.h>
26#include <linux/of_platform.h>
27#include <linux/of_gpio.h>
28#include <linux/gpio.h>
29
30#define GEF_GPIO_DIRECT 0x00
31#define GEF_GPIO_IN 0x04
32#define GEF_GPIO_OUT 0x08
33#define GEF_GPIO_TRIG 0x0C
34#define GEF_GPIO_POLAR_A 0x10
35#define GEF_GPIO_POLAR_B 0x14
36#define GEF_GPIO_INT_STAT 0x18
37#define GEF_GPIO_OVERRUN 0x1C
38#define GEF_GPIO_MODE 0x20
39
40#define NUM_GPIO 19
41
42static void _gef_gpio_set(void __iomem *reg, unsigned int offset, int value)
43{
44 unsigned int data;
45
46 data = ioread32be(reg);
47 /* value: 0=low; 1=high */
48 if (value & 0x1)
49 data = data | (0x1 << offset);
50 else
51 data = data & ~(0x1 << offset);
52
53 iowrite32be(data, reg);
54}
55
56
57static int gef_gpio_dir_in(struct gpio_chip *chip, unsigned offset)
58{
59 unsigned int data;
60 struct of_mm_gpio_chip *mmchip = to_of_mm_gpio_chip(chip);
61
62 data = ioread32be(mmchip->regs + GEF_GPIO_DIRECT);
63 data = data | (0x1 << offset);
64 iowrite32be(data, mmchip->regs + GEF_GPIO_DIRECT);
65
66 return 0;
67}
68
69static int gef_gpio_dir_out(struct gpio_chip *chip, unsigned offset, int value)
70{
71 unsigned int data;
72 struct of_mm_gpio_chip *mmchip = to_of_mm_gpio_chip(chip);
73
74 /* Set direction before switching to input */
75 _gef_gpio_set(mmchip->regs + GEF_GPIO_OUT, offset, value);
76
77 data = ioread32be(mmchip->regs + GEF_GPIO_DIRECT);
78 data = data & ~(0x1 << offset);
79 iowrite32be(data, mmchip->regs + GEF_GPIO_DIRECT);
80
81 return 0;
82}
83
84static int gef_gpio_get(struct gpio_chip *chip, unsigned offset)
85{
86 unsigned int data;
87 int state = 0;
88 struct of_mm_gpio_chip *mmchip = to_of_mm_gpio_chip(chip);
89
90 data = ioread32be(mmchip->regs + GEF_GPIO_IN);
91 state = (int)((data >> offset) & 0x1);
92
93 return state;
94}
95
96static void gef_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
97{
98 struct of_mm_gpio_chip *mmchip = to_of_mm_gpio_chip(chip);
99
100 _gef_gpio_set(mmchip->regs + GEF_GPIO_OUT, offset, value);
101}
102
103static int __init gef_gpio_init(void)
104{
105 struct device_node *np;
106
107 for_each_compatible_node(np, NULL, "gef,sbc610-gpio") {
108 int retval;
109 struct of_mm_gpio_chip *gef_gpio_chip;
110
111 pr_debug("%s: Initialising GEF GPIO\n", np->full_name);
112
113 /* Allocate chip structure */
114 gef_gpio_chip = kzalloc(sizeof(*gef_gpio_chip), GFP_KERNEL);
115 if (!gef_gpio_chip) {
116 pr_err("%s: Unable to allocate structure\n",
117 np->full_name);
118 continue;
119 }
120
121 /* Setup pointers to chip functions */
122 gef_gpio_chip->of_gc.gpio_cells = 2;
123 gef_gpio_chip->of_gc.gc.ngpio = NUM_GPIO;
124 gef_gpio_chip->of_gc.gc.direction_input = gef_gpio_dir_in;
125 gef_gpio_chip->of_gc.gc.direction_output = gef_gpio_dir_out;
126 gef_gpio_chip->of_gc.gc.get = gef_gpio_get;
127 gef_gpio_chip->of_gc.gc.set = gef_gpio_set;
128
129 /* This function adds a memory mapped GPIO chip */
130 retval = of_mm_gpiochip_add(np, gef_gpio_chip);
131 if (retval) {
132 kfree(gef_gpio_chip);
133 pr_err("%s: Unable to add GPIO\n", np->full_name);
134 }
135 }
136
137 return 0;
138};
139arch_initcall(gef_gpio_init);
140
141MODULE_DESCRIPTION("GE Fanuc I/O FPGA GPIO driver");
142MODULE_AUTHOR("Martyn Welch <martyn.welch@gefanuc.com");
143MODULE_LICENSE("GPL");
diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c
index 3168272ab0d7..86db4dd170a0 100644
--- a/arch/powerpc/platforms/cell/iommu.c
+++ b/arch/powerpc/platforms/cell/iommu.c
@@ -1053,10 +1053,7 @@ static int __init cell_iommu_fixed_mapping_init(void)
1053 } 1053 }
1054 1054
1055 /* We must have dma-ranges properties for fixed mapping to work */ 1055 /* We must have dma-ranges properties for fixed mapping to work */
1056 for (np = NULL; (np = of_find_all_nodes(np));) { 1056 np = of_find_node_with_property(NULL, "dma-ranges");
1057 if (of_find_property(np, "dma-ranges", NULL))
1058 break;
1059 }
1060 of_node_put(np); 1057 of_node_put(np);
1061 1058
1062 if (!np) { 1059 if (!np) {
diff --git a/arch/powerpc/platforms/chrp/pci.c b/arch/powerpc/platforms/chrp/pci.c
index d3cde6b9d2df..f6b0c519d5a2 100644
--- a/arch/powerpc/platforms/chrp/pci.c
+++ b/arch/powerpc/platforms/chrp/pci.c
@@ -141,6 +141,7 @@ hydra_init(void)
141 of_node_put(np); 141 of_node_put(np);
142 return 0; 142 return 0;
143 } 143 }
144 of_node_put(np);
144 Hydra = ioremap(r.start, r.end-r.start); 145 Hydra = ioremap(r.start, r.end-r.start);
145 printk("Hydra Mac I/O at %llx\n", (unsigned long long)r.start); 146 printk("Hydra Mac I/O at %llx\n", (unsigned long long)r.start);
146 printk("Hydra Feature_Control was %x", 147 printk("Hydra Feature_Control was %x",
@@ -198,7 +199,7 @@ static void __init setup_peg2(struct pci_controller *hose, struct device_node *d
198 printk ("RTAS supporting Pegasos OF not found, please upgrade" 199 printk ("RTAS supporting Pegasos OF not found, please upgrade"
199 " your firmware\n"); 200 " your firmware\n");
200 } 201 }
201 ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS; 202 ppc_pci_add_flags(PPC_PCI_REASSIGN_ALL_BUS);
202 /* keep the reference to the root node */ 203 /* keep the reference to the root node */
203} 204}
204 205
diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c
index bcf50d7056e9..54b7b76ed4f0 100644
--- a/arch/powerpc/platforms/powermac/pci.c
+++ b/arch/powerpc/platforms/powermac/pci.c
@@ -729,7 +729,7 @@ static void __init setup_bandit(struct pci_controller *hose,
729static int __init setup_uninorth(struct pci_controller *hose, 729static int __init setup_uninorth(struct pci_controller *hose,
730 struct resource *addr) 730 struct resource *addr)
731{ 731{
732 ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS; 732 ppc_pci_add_flags(PPC_PCI_REASSIGN_ALL_BUS);
733 has_uninorth = 1; 733 has_uninorth = 1;
734 hose->ops = &macrisc_pci_ops; 734 hose->ops = &macrisc_pci_ops;
735 hose->cfg_addr = ioremap(addr->start + 0x800000, 0x1000); 735 hose->cfg_addr = ioremap(addr->start + 0x800000, 0x1000);
@@ -996,7 +996,7 @@ void __init pmac_pci_init(void)
996 struct device_node *np, *root; 996 struct device_node *np, *root;
997 struct device_node *ht = NULL; 997 struct device_node *ht = NULL;
998 998
999 ppc_pci_flags = PPC_PCI_CAN_SKIP_ISA_ALIGN; 999 ppc_pci_set_flags(PPC_PCI_CAN_SKIP_ISA_ALIGN);
1000 1000
1001 root = of_find_node_by_path("/"); 1001 root = of_find_node_by_path("/");
1002 if (root == NULL) { 1002 if (root == NULL) {
@@ -1055,7 +1055,7 @@ void __init pmac_pci_init(void)
1055 * some offset between bus number and domains for now when we 1055 * some offset between bus number and domains for now when we
1056 * assign all busses should help for now 1056 * assign all busses should help for now
1057 */ 1057 */
1058 if (ppc_pci_flags & PPC_PCI_REASSIGN_ALL_BUS) 1058 if (ppc_pci_has_flag(PPC_PCI_REASSIGN_ALL_BUS))
1059 pcibios_assign_bus_offset = 0x10; 1059 pcibios_assign_bus_offset = 0x10;
1060#endif 1060#endif
1061} 1061}
diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c
index 82c14d203d8b..12937725f869 100644
--- a/arch/powerpc/platforms/powermac/setup.c
+++ b/arch/powerpc/platforms/powermac/setup.c
@@ -310,9 +310,7 @@ static void __init pmac_setup_arch(void)
310 } 310 }
311 311
312 /* See if newworld or oldworld */ 312 /* See if newworld or oldworld */
313 for (ic = NULL; (ic = of_find_all_nodes(ic)) != NULL; ) 313 ic = of_find_node_with_property(NULL, "interrupt-controller");
314 if (of_get_property(ic, "interrupt-controller", NULL))
315 break;
316 if (ic) { 314 if (ic) {
317 pmac_newworld = 1; 315 pmac_newworld = 1;
318 of_node_put(ic); 316 of_node_put(ic);
diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c
index 40f72c2a4699..6b0711c15eca 100644
--- a/arch/powerpc/platforms/powermac/smp.c
+++ b/arch/powerpc/platforms/powermac/smp.c
@@ -739,7 +739,7 @@ static void __init smp_core99_setup(int ncpus)
739 739
740 /* XXX should get this from reg properties */ 740 /* XXX should get this from reg properties */
741 for (i = 1; i < ncpus; ++i) 741 for (i = 1; i < ncpus; ++i)
742 smp_hw_index[i] = i; 742 set_hard_smp_processor_id(i, i);
743 } 743 }
744#endif 744#endif
745 745
diff --git a/arch/powerpc/platforms/ps3/device-init.c b/arch/powerpc/platforms/ps3/device-init.c
index ffdd8e963fbd..dbc124e05646 100644
--- a/arch/powerpc/platforms/ps3/device-init.c
+++ b/arch/powerpc/platforms/ps3/device-init.c
@@ -314,11 +314,17 @@ static int __init ps3_setup_vuart_device(enum ps3_match_id match_id,
314 314
315 result = ps3_system_bus_device_register(&p->dev); 315 result = ps3_system_bus_device_register(&p->dev);
316 316
317 if (result) 317 if (result) {
318 pr_debug("%s:%d ps3_system_bus_device_register failed\n", 318 pr_debug("%s:%d ps3_system_bus_device_register failed\n",
319 __func__, __LINE__); 319 __func__, __LINE__);
320 320 goto fail_device_register;
321 }
321 pr_debug(" <- %s:%d\n", __func__, __LINE__); 322 pr_debug(" <- %s:%d\n", __func__, __LINE__);
323 return 0;
324
325fail_device_register:
326 kfree(p);
327 pr_debug(" <- %s:%d fail\n", __func__, __LINE__);
322 return result; 328 return result;
323} 329}
324 330
@@ -463,11 +469,17 @@ static int __init ps3_register_sound_devices(void)
463 469
464 result = ps3_system_bus_device_register(&p->dev); 470 result = ps3_system_bus_device_register(&p->dev);
465 471
466 if (result) 472 if (result) {
467 pr_debug("%s:%d ps3_system_bus_device_register failed\n", 473 pr_debug("%s:%d ps3_system_bus_device_register failed\n",
468 __func__, __LINE__); 474 __func__, __LINE__);
469 475 goto fail_device_register;
476 }
470 pr_debug(" <- %s:%d\n", __func__, __LINE__); 477 pr_debug(" <- %s:%d\n", __func__, __LINE__);
478 return 0;
479
480fail_device_register:
481 kfree(p);
482 pr_debug(" <- %s:%d failed\n", __func__, __LINE__);
471 return result; 483 return result;
472} 484}
473 485
@@ -485,17 +497,24 @@ static int __init ps3_register_graphics_devices(void)
485 if (!p) 497 if (!p)
486 return -ENOMEM; 498 return -ENOMEM;
487 499
488 p->dev.match_id = PS3_MATCH_ID_GRAPHICS; 500 p->dev.match_id = PS3_MATCH_ID_GPU;
489 p->dev.match_sub_id = PS3_MATCH_SUB_ID_FB; 501 p->dev.match_sub_id = PS3_MATCH_SUB_ID_GPU_FB;
490 p->dev.dev_type = PS3_DEVICE_TYPE_IOC0; 502 p->dev.dev_type = PS3_DEVICE_TYPE_IOC0;
491 503
492 result = ps3_system_bus_device_register(&p->dev); 504 result = ps3_system_bus_device_register(&p->dev);
493 505
494 if (result) 506 if (result) {
495 pr_debug("%s:%d ps3_system_bus_device_register failed\n", 507 pr_debug("%s:%d ps3_system_bus_device_register failed\n",
496 __func__, __LINE__); 508 __func__, __LINE__);
509 goto fail_device_register;
510 }
497 511
498 pr_debug(" <- %s:%d\n", __func__, __LINE__); 512 pr_debug(" <- %s:%d\n", __func__, __LINE__);
513 return 0;
514
515fail_device_register:
516 kfree(p);
517 pr_debug(" <- %s:%d failed\n", __func__, __LINE__);
499 return result; 518 return result;
500} 519}
501 520
diff --git a/arch/powerpc/platforms/ps3/mm.c b/arch/powerpc/platforms/ps3/mm.c
index 3a58ffabccd9..a4d49dd9e8a9 100644
--- a/arch/powerpc/platforms/ps3/mm.c
+++ b/arch/powerpc/platforms/ps3/mm.c
@@ -649,7 +649,7 @@ static int dma_sb_region_create(struct ps3_dma_region *r)
649{ 649{
650 int result; 650 int result;
651 651
652 pr_info(" -> %s:%d:\n", __func__, __LINE__); 652 DBG(" -> %s:%d:\n", __func__, __LINE__);
653 653
654 BUG_ON(!r); 654 BUG_ON(!r);
655 655
diff --git a/arch/powerpc/platforms/ps3/setup.c b/arch/powerpc/platforms/ps3/setup.c
index 77bc330263c4..bfc33fb2c7c4 100644
--- a/arch/powerpc/platforms/ps3/setup.c
+++ b/arch/powerpc/platforms/ps3/setup.c
@@ -42,6 +42,10 @@
42#define DBG pr_debug 42#define DBG pr_debug
43#endif 43#endif
44 44
45/* mutex synchronizing GPU accesses and video mode changes */
46DEFINE_MUTEX(ps3_gpu_mutex);
47EXPORT_SYMBOL_GPL(ps3_gpu_mutex);
48
45#if !defined(CONFIG_SMP) 49#if !defined(CONFIG_SMP)
46static void smp_send_stop(void) {} 50static void smp_send_stop(void) {}
47#endif 51#endif
diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c
index 661e9f77ebf6..ee0d22911621 100644
--- a/arch/powerpc/platforms/ps3/system-bus.c
+++ b/arch/powerpc/platforms/ps3/system-bus.c
@@ -31,7 +31,7 @@
31#include "platform.h" 31#include "platform.h"
32 32
33static struct device ps3_system_bus = { 33static struct device ps3_system_bus = {
34 .bus_id = "ps3_system", 34 .init_name = "ps3_system",
35}; 35};
36 36
37/* FIXME: need device usage counters! */ 37/* FIXME: need device usage counters! */
@@ -175,7 +175,7 @@ int ps3_open_hv_device(struct ps3_system_bus_device *dev)
175 return ps3_open_hv_device_sb(dev); 175 return ps3_open_hv_device_sb(dev);
176 176
177 case PS3_MATCH_ID_SOUND: 177 case PS3_MATCH_ID_SOUND:
178 case PS3_MATCH_ID_GRAPHICS: 178 case PS3_MATCH_ID_GPU:
179 return ps3_open_hv_device_gpu(dev); 179 return ps3_open_hv_device_gpu(dev);
180 180
181 case PS3_MATCH_ID_AV_SETTINGS: 181 case PS3_MATCH_ID_AV_SETTINGS:
@@ -213,7 +213,7 @@ int ps3_close_hv_device(struct ps3_system_bus_device *dev)
213 return ps3_close_hv_device_sb(dev); 213 return ps3_close_hv_device_sb(dev);
214 214
215 case PS3_MATCH_ID_SOUND: 215 case PS3_MATCH_ID_SOUND:
216 case PS3_MATCH_ID_GRAPHICS: 216 case PS3_MATCH_ID_GPU:
217 return ps3_close_hv_device_gpu(dev); 217 return ps3_close_hv_device_gpu(dev);
218 218
219 case PS3_MATCH_ID_AV_SETTINGS: 219 case PS3_MATCH_ID_AV_SETTINGS:
@@ -356,12 +356,12 @@ static int ps3_system_bus_match(struct device *_dev,
356 if (result) 356 if (result)
357 pr_info("%s:%d: dev=%u.%u(%s), drv=%u.%u(%s): match\n", 357 pr_info("%s:%d: dev=%u.%u(%s), drv=%u.%u(%s): match\n",
358 __func__, __LINE__, 358 __func__, __LINE__,
359 dev->match_id, dev->match_sub_id, dev->core.bus_id, 359 dev->match_id, dev->match_sub_id, dev_name(&dev->core),
360 drv->match_id, drv->match_sub_id, drv->core.name); 360 drv->match_id, drv->match_sub_id, drv->core.name);
361 else 361 else
362 pr_debug("%s:%d: dev=%u.%u(%s), drv=%u.%u(%s): miss\n", 362 pr_debug("%s:%d: dev=%u.%u(%s), drv=%u.%u(%s): miss\n",
363 __func__, __LINE__, 363 __func__, __LINE__,
364 dev->match_id, dev->match_sub_id, dev->core.bus_id, 364 dev->match_id, dev->match_sub_id, dev_name(&dev->core),
365 drv->match_id, drv->match_sub_id, drv->core.name); 365 drv->match_id, drv->match_sub_id, drv->core.name);
366 366
367 return result; 367 return result;
@@ -383,9 +383,9 @@ static int ps3_system_bus_probe(struct device *_dev)
383 result = drv->probe(dev); 383 result = drv->probe(dev);
384 else 384 else
385 pr_debug("%s:%d: %s no probe method\n", __func__, __LINE__, 385 pr_debug("%s:%d: %s no probe method\n", __func__, __LINE__,
386 dev->core.bus_id); 386 dev_name(&dev->core));
387 387
388 pr_debug(" <- %s:%d: %s\n", __func__, __LINE__, dev->core.bus_id); 388 pr_debug(" <- %s:%d: %s\n", __func__, __LINE__, dev_name(&dev->core));
389 return result; 389 return result;
390} 390}
391 391
@@ -407,7 +407,7 @@ static int ps3_system_bus_remove(struct device *_dev)
407 dev_dbg(&dev->core, "%s:%d %s: no remove method\n", 407 dev_dbg(&dev->core, "%s:%d %s: no remove method\n",
408 __func__, __LINE__, drv->core.name); 408 __func__, __LINE__, drv->core.name);
409 409
410 pr_debug(" <- %s:%d: %s\n", __func__, __LINE__, dev->core.bus_id); 410 pr_debug(" <- %s:%d: %s\n", __func__, __LINE__, dev_name(&dev->core));
411 return result; 411 return result;
412} 412}
413 413
@@ -432,7 +432,7 @@ static void ps3_system_bus_shutdown(struct device *_dev)
432 BUG_ON(!drv); 432 BUG_ON(!drv);
433 433
434 dev_dbg(&dev->core, "%s:%d: %s -> %s\n", __func__, __LINE__, 434 dev_dbg(&dev->core, "%s:%d: %s -> %s\n", __func__, __LINE__,
435 dev->core.bus_id, drv->core.name); 435 dev_name(&dev->core), drv->core.name);
436 436
437 if (drv->shutdown) 437 if (drv->shutdown)
438 drv->shutdown(dev); 438 drv->shutdown(dev);
@@ -453,7 +453,8 @@ static int ps3_system_bus_uevent(struct device *_dev, struct kobj_uevent_env *en
453{ 453{
454 struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev); 454 struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
455 455
456 if (add_uevent_var(env, "MODALIAS=ps3:%d", dev->match_id)) 456 if (add_uevent_var(env, "MODALIAS=ps3:%d:%d", dev->match_id,
457 dev->match_sub_id))
457 return -ENOMEM; 458 return -ENOMEM;
458 return 0; 459 return 0;
459} 460}
@@ -462,7 +463,8 @@ static ssize_t modalias_show(struct device *_dev, struct device_attribute *a,
462 char *buf) 463 char *buf)
463{ 464{
464 struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev); 465 struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
465 int len = snprintf(buf, PAGE_SIZE, "ps3:%d\n", dev->match_id); 466 int len = snprintf(buf, PAGE_SIZE, "ps3:%d:%d\n", dev->match_id,
467 dev->match_sub_id);
466 468
467 return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len; 469 return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len;
468} 470}
@@ -742,22 +744,18 @@ int ps3_system_bus_device_register(struct ps3_system_bus_device *dev)
742 switch (dev->dev_type) { 744 switch (dev->dev_type) {
743 case PS3_DEVICE_TYPE_IOC0: 745 case PS3_DEVICE_TYPE_IOC0:
744 dev->core.archdata.dma_ops = &ps3_ioc0_dma_ops; 746 dev->core.archdata.dma_ops = &ps3_ioc0_dma_ops;
745 snprintf(dev->core.bus_id, sizeof(dev->core.bus_id), 747 dev_set_name(&dev->core, "ioc0_%02x", ++dev_ioc0_count);
746 "ioc0_%02x", ++dev_ioc0_count);
747 break; 748 break;
748 case PS3_DEVICE_TYPE_SB: 749 case PS3_DEVICE_TYPE_SB:
749 dev->core.archdata.dma_ops = &ps3_sb_dma_ops; 750 dev->core.archdata.dma_ops = &ps3_sb_dma_ops;
750 snprintf(dev->core.bus_id, sizeof(dev->core.bus_id), 751 dev_set_name(&dev->core, "sb_%02x", ++dev_sb_count);
751 "sb_%02x", ++dev_sb_count);
752 752
753 break; 753 break;
754 case PS3_DEVICE_TYPE_VUART: 754 case PS3_DEVICE_TYPE_VUART:
755 snprintf(dev->core.bus_id, sizeof(dev->core.bus_id), 755 dev_set_name(&dev->core, "vuart_%02x", ++dev_vuart_count);
756 "vuart_%02x", ++dev_vuart_count);
757 break; 756 break;
758 case PS3_DEVICE_TYPE_LPM: 757 case PS3_DEVICE_TYPE_LPM:
759 snprintf(dev->core.bus_id, sizeof(dev->core.bus_id), 758 dev_set_name(&dev->core, "lpm_%02x", ++dev_lpm_count);
760 "lpm_%02x", ++dev_lpm_count);
761 break; 759 break;
762 default: 760 default:
763 BUG(); 761 BUG();
@@ -766,7 +764,7 @@ int ps3_system_bus_device_register(struct ps3_system_bus_device *dev)
766 dev->core.archdata.of_node = NULL; 764 dev->core.archdata.of_node = NULL;
767 set_dev_node(&dev->core, 0); 765 set_dev_node(&dev->core, 0);
768 766
769 pr_debug("%s:%d add %s\n", __func__, __LINE__, dev->core.bus_id); 767 pr_debug("%s:%d add %s\n", __func__, __LINE__, dev_name(&dev->core));
770 768
771 result = device_register(&dev->core); 769 result = device_register(&dev->core);
772 return result; 770 return result;
diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c
index 54816d75b578..989d6462c154 100644
--- a/arch/powerpc/platforms/pseries/eeh.c
+++ b/arch/powerpc/platforms/pseries/eeh.c
@@ -21,6 +21,8 @@
21 * Please address comments and feedback to Linas Vepstas <linas@austin.ibm.com> 21 * Please address comments and feedback to Linas Vepstas <linas@austin.ibm.com>
22 */ 22 */
23 23
24#undef DEBUG
25
24#include <linux/delay.h> 26#include <linux/delay.h>
25#include <linux/init.h> 27#include <linux/init.h>
26#include <linux/list.h> 28#include <linux/list.h>
@@ -488,10 +490,8 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
488 if (!(pdn->eeh_mode & EEH_MODE_SUPPORTED) || 490 if (!(pdn->eeh_mode & EEH_MODE_SUPPORTED) ||
489 pdn->eeh_mode & EEH_MODE_NOCHECK) { 491 pdn->eeh_mode & EEH_MODE_NOCHECK) {
490 ignored_check++; 492 ignored_check++;
491#ifdef DEBUG 493 pr_debug("EEH: Ignored check (%x) for %s %s\n",
492 printk ("EEH:ignored check (%x) for %s %s\n", 494 pdn->eeh_mode, pci_name (dev), dn->full_name);
493 pdn->eeh_mode, pci_name (dev), dn->full_name);
494#endif
495 return 0; 495 return 0;
496 } 496 }
497 497
@@ -1014,10 +1014,9 @@ static void *early_enable_eeh(struct device_node *dn, void *data)
1014 eeh_subsystem_enabled = 1; 1014 eeh_subsystem_enabled = 1;
1015 pdn->eeh_mode |= EEH_MODE_SUPPORTED; 1015 pdn->eeh_mode |= EEH_MODE_SUPPORTED;
1016 1016
1017#ifdef DEBUG 1017 pr_debug("EEH: %s: eeh enabled, config=%x pe_config=%x\n",
1018 printk(KERN_DEBUG "EEH: %s: eeh enabled, config=%x pe_config=%x\n", 1018 dn->full_name, pdn->eeh_config_addr,
1019 dn->full_name, pdn->eeh_config_addr, pdn->eeh_pe_config_addr); 1019 pdn->eeh_pe_config_addr);
1020#endif
1021 } else { 1020 } else {
1022 1021
1023 /* This device doesn't support EEH, but it may have an 1022 /* This device doesn't support EEH, but it may have an
@@ -1161,13 +1160,17 @@ static void eeh_add_device_late(struct pci_dev *dev)
1161 if (!dev || !eeh_subsystem_enabled) 1160 if (!dev || !eeh_subsystem_enabled)
1162 return; 1161 return;
1163 1162
1164#ifdef DEBUG 1163 pr_debug("EEH: Adding device %s\n", pci_name(dev));
1165 printk(KERN_DEBUG "EEH: adding device %s\n", pci_name(dev));
1166#endif
1167 1164
1168 pci_dev_get (dev);
1169 dn = pci_device_to_OF_node(dev); 1165 dn = pci_device_to_OF_node(dev);
1170 pdn = PCI_DN(dn); 1166 pdn = PCI_DN(dn);
1167 if (pdn->pcidev == dev) {
1168 pr_debug("EEH: Already referenced !\n");
1169 return;
1170 }
1171 WARN_ON(pdn->pcidev);
1172
1173 pci_dev_get (dev);
1171 pdn->pcidev = dev; 1174 pdn->pcidev = dev;
1172 1175
1173 pci_addr_cache_insert_device(dev); 1176 pci_addr_cache_insert_device(dev);
@@ -1206,17 +1209,18 @@ static void eeh_remove_device(struct pci_dev *dev)
1206 return; 1209 return;
1207 1210
1208 /* Unregister the device with the EEH/PCI address search system */ 1211 /* Unregister the device with the EEH/PCI address search system */
1209#ifdef DEBUG 1212 pr_debug("EEH: Removing device %s\n", pci_name(dev));
1210 printk(KERN_DEBUG "EEH: remove device %s\n", pci_name(dev));
1211#endif
1212 pci_addr_cache_remove_device(dev);
1213 eeh_sysfs_remove_device(dev);
1214 1213
1215 dn = pci_device_to_OF_node(dev); 1214 dn = pci_device_to_OF_node(dev);
1216 if (PCI_DN(dn)->pcidev) { 1215 if (PCI_DN(dn)->pcidev == NULL) {
1217 PCI_DN(dn)->pcidev = NULL; 1216 pr_debug("EEH: Not referenced !\n");
1218 pci_dev_put (dev); 1217 return;
1219 } 1218 }
1219 PCI_DN(dn)->pcidev = NULL;
1220 pci_dev_put (dev);
1221
1222 pci_addr_cache_remove_device(dev);
1223 eeh_sysfs_remove_device(dev);
1220} 1224}
1221 1225
1222void eeh_remove_bus_device(struct pci_dev *dev) 1226void eeh_remove_bus_device(struct pci_dev *dev)
diff --git a/arch/powerpc/platforms/pseries/pci_dlpar.c b/arch/powerpc/platforms/pseries/pci_dlpar.c
index 7190493e9bdc..5e1ed3d60ee5 100644
--- a/arch/powerpc/platforms/pseries/pci_dlpar.c
+++ b/arch/powerpc/platforms/pseries/pci_dlpar.c
@@ -25,6 +25,8 @@
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 */ 26 */
27 27
28#undef DEBUG
29
28#include <linux/pci.h> 30#include <linux/pci.h>
29#include <asm/pci-bridge.h> 31#include <asm/pci-bridge.h>
30#include <asm/ppc-pci.h> 32#include <asm/ppc-pci.h>
@@ -69,74 +71,25 @@ EXPORT_SYMBOL_GPL(pcibios_find_pci_bus);
69 * Remove all of the PCI devices under this bus both from the 71 * Remove all of the PCI devices under this bus both from the
70 * linux pci device tree, and from the powerpc EEH address cache. 72 * linux pci device tree, and from the powerpc EEH address cache.
71 */ 73 */
72void 74void pcibios_remove_pci_devices(struct pci_bus *bus)
73pcibios_remove_pci_devices(struct pci_bus *bus)
74{ 75{
75 struct pci_dev *dev, *tmp; 76 struct pci_dev *dev, *tmp;
77 struct pci_bus *child_bus;
78
79 /* First go down child busses */
80 list_for_each_entry(child_bus, &bus->children, node)
81 pcibios_remove_pci_devices(child_bus);
76 82
83 pr_debug("PCI: Removing devices on bus %04x:%02x\n",
84 pci_domain_nr(bus), bus->number);
77 list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) { 85 list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) {
86 pr_debug(" * Removing %s...\n", pci_name(dev));
78 eeh_remove_bus_device(dev); 87 eeh_remove_bus_device(dev);
79 pci_remove_bus_device(dev); 88 pci_remove_bus_device(dev);
80 } 89 }
81} 90}
82EXPORT_SYMBOL_GPL(pcibios_remove_pci_devices); 91EXPORT_SYMBOL_GPL(pcibios_remove_pci_devices);
83 92
84/* Must be called before pci_bus_add_devices */
85void
86pcibios_fixup_new_pci_devices(struct pci_bus *bus)
87{
88 struct pci_dev *dev;
89
90 list_for_each_entry(dev, &bus->devices, bus_list) {
91 /* Skip already-added devices */
92 if (!dev->is_added) {
93 int i;
94
95 /* Fill device archdata and setup iommu table */
96 pcibios_setup_new_device(dev);
97
98 pci_read_irq_line(dev);
99 for (i = 0; i < PCI_NUM_RESOURCES; i++) {
100 struct resource *r = &dev->resource[i];
101
102 if (r->parent || !r->start || !r->flags)
103 continue;
104 pci_claim_resource(dev, i);
105 }
106 }
107 }
108}
109EXPORT_SYMBOL_GPL(pcibios_fixup_new_pci_devices);
110
111static int
112pcibios_pci_config_bridge(struct pci_dev *dev)
113{
114 u8 sec_busno;
115 struct pci_bus *child_bus;
116
117 /* Get busno of downstream bus */
118 pci_read_config_byte(dev, PCI_SECONDARY_BUS, &sec_busno);
119
120 /* Add to children of PCI bridge dev->bus */
121 child_bus = pci_add_new_bus(dev->bus, dev, sec_busno);
122 if (!child_bus) {
123 printk (KERN_ERR "%s: could not add second bus\n", __func__);
124 return -EIO;
125 }
126 sprintf(child_bus->name, "PCI Bus #%02x", child_bus->number);
127
128 pci_scan_child_bus(child_bus);
129
130 /* Fixup new pci devices */
131 pcibios_fixup_new_pci_devices(child_bus);
132
133 /* Make the discovered devices available */
134 pci_bus_add_devices(child_bus);
135
136 eeh_add_device_tree_late(child_bus);
137 return 0;
138}
139
140/** 93/**
141 * pcibios_add_pci_devices - adds new pci devices to bus 94 * pcibios_add_pci_devices - adds new pci devices to bus
142 * 95 *
@@ -147,10 +100,9 @@ pcibios_pci_config_bridge(struct pci_dev *dev)
147 * is how this routine differs from other, similar pcibios 100 * is how this routine differs from other, similar pcibios
148 * routines.) 101 * routines.)
149 */ 102 */
150void 103void pcibios_add_pci_devices(struct pci_bus * bus)
151pcibios_add_pci_devices(struct pci_bus * bus)
152{ 104{
153 int slotno, num, mode; 105 int slotno, num, mode, pass, max;
154 struct pci_dev *dev; 106 struct pci_dev *dev;
155 struct device_node *dn = pci_bus_to_OF_node(bus); 107 struct device_node *dn = pci_bus_to_OF_node(bus);
156 108
@@ -162,26 +114,23 @@ pcibios_add_pci_devices(struct pci_bus * bus)
162 114
163 if (mode == PCI_PROBE_DEVTREE) { 115 if (mode == PCI_PROBE_DEVTREE) {
164 /* use ofdt-based probe */ 116 /* use ofdt-based probe */
165 of_scan_bus(dn, bus); 117 of_rescan_bus(dn, bus);
166 if (!list_empty(&bus->devices)) {
167 pcibios_fixup_new_pci_devices(bus);
168 pci_bus_add_devices(bus);
169 eeh_add_device_tree_late(bus);
170 }
171 } else if (mode == PCI_PROBE_NORMAL) { 118 } else if (mode == PCI_PROBE_NORMAL) {
172 /* use legacy probe */ 119 /* use legacy probe */
173 slotno = PCI_SLOT(PCI_DN(dn->child)->devfn); 120 slotno = PCI_SLOT(PCI_DN(dn->child)->devfn);
174 num = pci_scan_slot(bus, PCI_DEVFN(slotno, 0)); 121 num = pci_scan_slot(bus, PCI_DEVFN(slotno, 0));
175 if (num) { 122 if (!num)
176 pcibios_fixup_new_pci_devices(bus); 123 return;
177 pci_bus_add_devices(bus); 124 pcibios_setup_bus_devices(bus);
178 eeh_add_device_tree_late(bus); 125 max = bus->secondary;
126 for (pass=0; pass < 2; pass++)
127 list_for_each_entry(dev, &bus->devices, bus_list) {
128 if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
129 dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)
130 max = pci_scan_bridge(bus, dev, max, pass);
179 } 131 }
180
181 list_for_each_entry(dev, &bus->devices, bus_list)
182 if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)
183 pcibios_pci_config_bridge(dev);
184 } 132 }
133 pcibios_finish_adding_to_bus(bus);
185} 134}
186EXPORT_SYMBOL_GPL(pcibios_add_pci_devices); 135EXPORT_SYMBOL_GPL(pcibios_add_pci_devices);
187 136
@@ -190,6 +139,8 @@ struct pci_controller * __devinit init_phb_dynamic(struct device_node *dn)
190 struct pci_controller *phb; 139 struct pci_controller *phb;
191 int primary; 140 int primary;
192 141
142 pr_debug("PCI: Initializing new hotplug PHB %s\n", dn->full_name);
143
193 primary = list_empty(&hose_list); 144 primary = list_empty(&hose_list);
194 phb = pcibios_alloc_controller(dn); 145 phb = pcibios_alloc_controller(dn);
195 if (!phb) 146 if (!phb)
@@ -203,11 +154,59 @@ struct pci_controller * __devinit init_phb_dynamic(struct device_node *dn)
203 eeh_add_device_tree_early(dn); 154 eeh_add_device_tree_early(dn);
204 155
205 scan_phb(phb); 156 scan_phb(phb);
206 pcibios_allocate_bus_resources(phb->bus); 157 pcibios_finish_adding_to_bus(phb->bus);
207 pcibios_fixup_new_pci_devices(phb->bus);
208 pci_bus_add_devices(phb->bus);
209 eeh_add_device_tree_late(phb->bus);
210 158
211 return phb; 159 return phb;
212} 160}
213EXPORT_SYMBOL_GPL(init_phb_dynamic); 161EXPORT_SYMBOL_GPL(init_phb_dynamic);
162
163/* RPA-specific bits for removing PHBs */
164int remove_phb_dynamic(struct pci_controller *phb)
165{
166 struct pci_bus *b = phb->bus;
167 struct resource *res;
168 int rc, i;
169
170 pr_debug("PCI: Removing PHB %04x:%02x... \n",
171 pci_domain_nr(b), b->number);
172
173 /* We cannot to remove a root bus that has children */
174 if (!(list_empty(&b->children) && list_empty(&b->devices)))
175 return -EBUSY;
176
177 /* We -know- there aren't any child devices anymore at this stage
178 * and thus, we can safely unmap the IO space as it's not in use
179 */
180 res = &phb->io_resource;
181 if (res->flags & IORESOURCE_IO) {
182 rc = pcibios_unmap_io_space(b);
183 if (rc) {
184 printk(KERN_ERR "%s: failed to unmap IO on bus %s\n",
185 __func__, b->name);
186 return 1;
187 }
188 }
189
190 /* Unregister the bridge device from sysfs and remove the PCI bus */
191 device_unregister(b->bridge);
192 phb->bus = NULL;
193 pci_remove_bus(b);
194
195 /* Now release the IO resource */
196 if (res->flags & IORESOURCE_IO)
197 release_resource(res);
198
199 /* Release memory resources */
200 for (i = 0; i < 3; ++i) {
201 res = &phb->mem_resources[i];
202 if (!(res->flags & IORESOURCE_MEM))
203 continue;
204 release_resource(res);
205 }
206
207 /* Free pci_controller data structure */
208 pcibios_free_controller(phb);
209
210 return 0;
211}
212EXPORT_SYMBOL_GPL(remove_phb_dynamic);
diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c
index e1904774a70f..f7a69021b7bf 100644
--- a/arch/powerpc/platforms/pseries/xics.c
+++ b/arch/powerpc/platforms/pseries/xics.c
@@ -579,7 +579,7 @@ static void xics_update_irq_servers(void)
579 int i, j; 579 int i, j;
580 struct device_node *np; 580 struct device_node *np;
581 u32 ilen; 581 u32 ilen;
582 const u32 *ireg, *isize; 582 const u32 *ireg;
583 u32 hcpuid; 583 u32 hcpuid;
584 584
585 /* Find the server numbers for the boot cpu. */ 585 /* Find the server numbers for the boot cpu. */
@@ -607,11 +607,6 @@ static void xics_update_irq_servers(void)
607 } 607 }
608 } 608 }
609 609
610 /* get the bit size of server numbers */
611 isize = of_get_property(np, "ibm,interrupt-server#-size", NULL);
612 if (isize)
613 interrupt_server_size = *isize;
614
615 of_node_put(np); 610 of_node_put(np);
616} 611}
617 612
@@ -682,6 +677,7 @@ void __init xics_init_IRQ(void)
682 struct device_node *np; 677 struct device_node *np;
683 u32 indx = 0; 678 u32 indx = 0;
684 int found = 0; 679 int found = 0;
680 const u32 *isize;
685 681
686 ppc64_boot_msg(0x20, "XICS Init"); 682 ppc64_boot_msg(0x20, "XICS Init");
687 683
@@ -701,6 +697,26 @@ void __init xics_init_IRQ(void)
701 if (found == 0) 697 if (found == 0)
702 return; 698 return;
703 699
700 /* get the bit size of server numbers */
701 found = 0;
702
703 for_each_compatible_node(np, NULL, "ibm,ppc-xics") {
704 isize = of_get_property(np, "ibm,interrupt-server#-size", NULL);
705
706 if (!isize)
707 continue;
708
709 if (!found) {
710 interrupt_server_size = *isize;
711 found = 1;
712 } else if (*isize != interrupt_server_size) {
713 printk(KERN_WARNING "XICS: "
714 "mismatched ibm,interrupt-server#-size\n");
715 interrupt_server_size = max(*isize,
716 interrupt_server_size);
717 }
718 }
719
704 xics_update_irq_servers(); 720 xics_update_irq_servers();
705 xics_init_host(); 721 xics_init_host();
706 722
@@ -728,9 +744,18 @@ static void xics_set_cpu_priority(unsigned char cppr)
728/* Have the calling processor join or leave the specified global queue */ 744/* Have the calling processor join or leave the specified global queue */
729static void xics_set_cpu_giq(unsigned int gserver, unsigned int join) 745static void xics_set_cpu_giq(unsigned int gserver, unsigned int join)
730{ 746{
731 int status = rtas_set_indicator_fast(GLOBAL_INTERRUPT_QUEUE, 747 int index;
732 (1UL << interrupt_server_size) - 1 - gserver, join); 748 int status;
733 WARN_ON(status < 0); 749
750 if (!rtas_indicator_present(GLOBAL_INTERRUPT_QUEUE, NULL))
751 return;
752
753 index = (1UL << interrupt_server_size) - 1 - gserver;
754
755 status = rtas_set_indicator_fast(GLOBAL_INTERRUPT_QUEUE, index, join);
756
757 WARN(status < 0, "set-indicator(%d, %d, %u) returned %d\n",
758 GLOBAL_INTERRUPT_QUEUE, index, join, status);
734} 759}
735 760
736void xics_setup_cpu(void) 761void xics_setup_cpu(void)
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index 5b264eb4b1f7..d5f9ae0f1b75 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -187,7 +187,7 @@ int __init fsl_add_bridge(struct device_node *dev, int is_primary)
187 printk(KERN_WARNING "Can't get bus-range for %s, assume" 187 printk(KERN_WARNING "Can't get bus-range for %s, assume"
188 " bus 0\n", dev->full_name); 188 " bus 0\n", dev->full_name);
189 189
190 ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS; 190 ppc_pci_add_flags(PPC_PCI_REASSIGN_ALL_BUS);
191 hose = pcibios_alloc_controller(dev); 191 hose = pcibios_alloc_controller(dev);
192 if (!hose) 192 if (!hose)
193 return -ENOMEM; 193 return -ENOMEM;
@@ -300,7 +300,7 @@ int __init mpc83xx_add_bridge(struct device_node *dev)
300 " bus 0\n", dev->full_name); 300 " bus 0\n", dev->full_name);
301 } 301 }
302 302
303 ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS; 303 ppc_pci_add_flags(PPC_PCI_REASSIGN_ALL_BUS);
304 hose = pcibios_alloc_controller(dev); 304 hose = pcibios_alloc_controller(dev);
305 if (!hose) 305 if (!hose)
306 return -ENOMEM; 306 return -ENOMEM;
diff --git a/arch/powerpc/sysdev/grackle.c b/arch/powerpc/sysdev/grackle.c
index d502927644c6..5da37c2f22ee 100644
--- a/arch/powerpc/sysdev/grackle.c
+++ b/arch/powerpc/sysdev/grackle.c
@@ -57,7 +57,7 @@ void __init setup_grackle(struct pci_controller *hose)
57{ 57{
58 setup_indirect_pci(hose, 0xfec00000, 0xfee00000, 0); 58 setup_indirect_pci(hose, 0xfec00000, 0xfee00000, 0);
59 if (machine_is_compatible("PowerMac1,1")) 59 if (machine_is_compatible("PowerMac1,1"))
60 ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS; 60 ppc_pci_add_flags(PPC_PCI_REASSIGN_ALL_BUS);
61 if (machine_is_compatible("AAPL,PowerBook1998")) 61 if (machine_is_compatible("AAPL,PowerBook1998"))
62 grackle_set_loop_snoop(hose, 1); 62 grackle_set_loop_snoop(hose, 1);
63#if 0 /* Disabled for now, HW problems ??? */ 63#if 0 /* Disabled for now, HW problems ??? */
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index 1890fb085cde..c82babb70074 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -661,17 +661,6 @@ static inline void mpic_eoi(struct mpic *mpic)
661 (void)mpic_cpu_read(MPIC_INFO(CPU_WHOAMI)); 661 (void)mpic_cpu_read(MPIC_INFO(CPU_WHOAMI));
662} 662}
663 663
664#ifdef CONFIG_SMP
665static irqreturn_t mpic_ipi_action(int irq, void *data)
666{
667 long ipi = (long)data;
668
669 smp_message_recv(ipi);
670
671 return IRQ_HANDLED;
672}
673#endif /* CONFIG_SMP */
674
675/* 664/*
676 * Linux descriptor level callbacks 665 * Linux descriptor level callbacks
677 */ 666 */
@@ -1548,13 +1537,7 @@ unsigned int mpic_get_mcirq(void)
1548void mpic_request_ipis(void) 1537void mpic_request_ipis(void)
1549{ 1538{
1550 struct mpic *mpic = mpic_primary; 1539 struct mpic *mpic = mpic_primary;
1551 long i, err; 1540 int i;
1552 static char *ipi_names[] = {
1553 "IPI0 (call function)",
1554 "IPI1 (reschedule)",
1555 "IPI2 (call function single)",
1556 "IPI3 (debugger break)",
1557 };
1558 BUG_ON(mpic == NULL); 1541 BUG_ON(mpic == NULL);
1559 1542
1560 printk(KERN_INFO "mpic: requesting IPIs ... \n"); 1543 printk(KERN_INFO "mpic: requesting IPIs ... \n");
@@ -1563,17 +1546,10 @@ void mpic_request_ipis(void)
1563 unsigned int vipi = irq_create_mapping(mpic->irqhost, 1546 unsigned int vipi = irq_create_mapping(mpic->irqhost,
1564 mpic->ipi_vecs[0] + i); 1547 mpic->ipi_vecs[0] + i);
1565 if (vipi == NO_IRQ) { 1548 if (vipi == NO_IRQ) {
1566 printk(KERN_ERR "Failed to map IPI %ld\n", i); 1549 printk(KERN_ERR "Failed to map %s\n", smp_ipi_name[i]);
1567 break; 1550 continue;
1568 }
1569 err = request_irq(vipi, mpic_ipi_action,
1570 IRQF_DISABLED|IRQF_PERCPU,
1571 ipi_names[i], (void *)i);
1572 if (err) {
1573 printk(KERN_ERR "Request of irq %d for IPI %ld failed\n",
1574 vipi, i);
1575 break;
1576 } 1551 }
1552 smp_request_message_ipi(vipi, i);
1577 } 1553 }
1578} 1554}
1579 1555
diff --git a/arch/powerpc/sysdev/ppc4xx_pci.c b/arch/powerpc/sysdev/ppc4xx_pci.c
index d3e4d61030b5..77fae5f64f2e 100644
--- a/arch/powerpc/sysdev/ppc4xx_pci.c
+++ b/arch/powerpc/sysdev/ppc4xx_pci.c
@@ -194,11 +194,41 @@ static int __init ppc4xx_parse_dma_ranges(struct pci_controller *hose,
194 * 4xx PCI 2.x part 194 * 4xx PCI 2.x part
195 */ 195 */
196 196
197static int __init ppc4xx_setup_one_pci_PMM(struct pci_controller *hose,
198 void __iomem *reg,
199 u64 plb_addr,
200 u64 pci_addr,
201 u64 size,
202 unsigned int flags,
203 int index)
204{
205 u32 ma, pcila, pciha;
206
207 if ((plb_addr + size) > 0xffffffffull || !is_power_of_2(size) ||
208 size < 0x1000 || (plb_addr & (size - 1)) != 0) {
209 printk(KERN_WARNING "%s: Resource out of range\n",
210 hose->dn->full_name);
211 return -1;
212 }
213 ma = (0xffffffffu << ilog2(size)) | 1;
214 if (flags & IORESOURCE_PREFETCH)
215 ma |= 2;
216
217 pciha = RES_TO_U32_HIGH(pci_addr);
218 pcila = RES_TO_U32_LOW(pci_addr);
219
220 writel(plb_addr, reg + PCIL0_PMM0LA + (0x10 * index));
221 writel(pcila, reg + PCIL0_PMM0PCILA + (0x10 * index));
222 writel(pciha, reg + PCIL0_PMM0PCIHA + (0x10 * index));
223 writel(ma, reg + PCIL0_PMM0MA + (0x10 * index));
224
225 return 0;
226}
227
197static void __init ppc4xx_configure_pci_PMMs(struct pci_controller *hose, 228static void __init ppc4xx_configure_pci_PMMs(struct pci_controller *hose,
198 void __iomem *reg) 229 void __iomem *reg)
199{ 230{
200 u32 la, ma, pcila, pciha; 231 int i, j, found_isa_hole = 0;
201 int i, j;
202 232
203 /* Setup outbound memory windows */ 233 /* Setup outbound memory windows */
204 for (i = j = 0; i < 3; i++) { 234 for (i = j = 0; i < 3; i++) {
@@ -213,28 +243,29 @@ static void __init ppc4xx_configure_pci_PMMs(struct pci_controller *hose,
213 break; 243 break;
214 } 244 }
215 245
216 /* Calculate register values */ 246 /* Configure the resource */
217 la = res->start; 247 if (ppc4xx_setup_one_pci_PMM(hose, reg,
218 pciha = RES_TO_U32_HIGH(res->start - hose->pci_mem_offset); 248 res->start,
219 pcila = RES_TO_U32_LOW(res->start - hose->pci_mem_offset); 249 res->start - hose->pci_mem_offset,
220 250 res->end + 1 - res->start,
221 ma = res->end + 1 - res->start; 251 res->flags,
222 if (!is_power_of_2(ma) || ma < 0x1000 || ma > 0xffffffffu) { 252 j) == 0) {
223 printk(KERN_WARNING "%s: Resource out of range\n", 253 j++;
224 hose->dn->full_name); 254
225 continue; 255 /* If the resource PCI address is 0 then we have our
256 * ISA memory hole
257 */
258 if (res->start == hose->pci_mem_offset)
259 found_isa_hole = 1;
226 } 260 }
227 ma = (0xffffffffu << ilog2(ma)) | 0x1;
228 if (res->flags & IORESOURCE_PREFETCH)
229 ma |= 0x2;
230
231 /* Program register values */
232 writel(la, reg + PCIL0_PMM0LA + (0x10 * j));
233 writel(pcila, reg + PCIL0_PMM0PCILA + (0x10 * j));
234 writel(pciha, reg + PCIL0_PMM0PCIHA + (0x10 * j));
235 writel(ma, reg + PCIL0_PMM0MA + (0x10 * j));
236 j++;
237 } 261 }
262
263 /* Handle ISA memory hole if not already covered */
264 if (j <= 2 && !found_isa_hole && hose->isa_mem_size)
265 if (ppc4xx_setup_one_pci_PMM(hose, reg, hose->isa_mem_phys, 0,
266 hose->isa_mem_size, 0, j) == 0)
267 printk(KERN_INFO "%s: Legacy ISA memory support enabled\n",
268 hose->dn->full_name);
238} 269}
239 270
240static void __init ppc4xx_configure_pci_PTMs(struct pci_controller *hose, 271static void __init ppc4xx_configure_pci_PTMs(struct pci_controller *hose,
@@ -352,11 +383,52 @@ static void __init ppc4xx_probe_pci_bridge(struct device_node *np)
352 * 4xx PCI-X part 383 * 4xx PCI-X part
353 */ 384 */
354 385
386static int __init ppc4xx_setup_one_pcix_POM(struct pci_controller *hose,
387 void __iomem *reg,
388 u64 plb_addr,
389 u64 pci_addr,
390 u64 size,
391 unsigned int flags,
392 int index)
393{
394 u32 lah, lal, pciah, pcial, sa;
395
396 if (!is_power_of_2(size) || size < 0x1000 ||
397 (plb_addr & (size - 1)) != 0) {
398 printk(KERN_WARNING "%s: Resource out of range\n",
399 hose->dn->full_name);
400 return -1;
401 }
402
403 /* Calculate register values */
404 lah = RES_TO_U32_HIGH(plb_addr);
405 lal = RES_TO_U32_LOW(plb_addr);
406 pciah = RES_TO_U32_HIGH(pci_addr);
407 pcial = RES_TO_U32_LOW(pci_addr);
408 sa = (0xffffffffu << ilog2(size)) | 0x1;
409
410 /* Program register values */
411 if (index == 0) {
412 writel(lah, reg + PCIX0_POM0LAH);
413 writel(lal, reg + PCIX0_POM0LAL);
414 writel(pciah, reg + PCIX0_POM0PCIAH);
415 writel(pcial, reg + PCIX0_POM0PCIAL);
416 writel(sa, reg + PCIX0_POM0SA);
417 } else {
418 writel(lah, reg + PCIX0_POM1LAH);
419 writel(lal, reg + PCIX0_POM1LAL);
420 writel(pciah, reg + PCIX0_POM1PCIAH);
421 writel(pcial, reg + PCIX0_POM1PCIAL);
422 writel(sa, reg + PCIX0_POM1SA);
423 }
424
425 return 0;
426}
427
355static void __init ppc4xx_configure_pcix_POMs(struct pci_controller *hose, 428static void __init ppc4xx_configure_pcix_POMs(struct pci_controller *hose,
356 void __iomem *reg) 429 void __iomem *reg)
357{ 430{
358 u32 lah, lal, pciah, pcial, sa; 431 int i, j, found_isa_hole = 0;
359 int i, j;
360 432
361 /* Setup outbound memory windows */ 433 /* Setup outbound memory windows */
362 for (i = j = 0; i < 3; i++) { 434 for (i = j = 0; i < 3; i++) {
@@ -371,36 +443,29 @@ static void __init ppc4xx_configure_pcix_POMs(struct pci_controller *hose,
371 break; 443 break;
372 } 444 }
373 445
374 /* Calculate register values */ 446 /* Configure the resource */
375 lah = RES_TO_U32_HIGH(res->start); 447 if (ppc4xx_setup_one_pcix_POM(hose, reg,
376 lal = RES_TO_U32_LOW(res->start); 448 res->start,
377 pciah = RES_TO_U32_HIGH(res->start - hose->pci_mem_offset); 449 res->start - hose->pci_mem_offset,
378 pcial = RES_TO_U32_LOW(res->start - hose->pci_mem_offset); 450 res->end + 1 - res->start,
379 sa = res->end + 1 - res->start; 451 res->flags,
380 if (!is_power_of_2(sa) || sa < 0x100000 || 452 j) == 0) {
381 sa > 0xffffffffu) { 453 j++;
382 printk(KERN_WARNING "%s: Resource out of range\n", 454
383 hose->dn->full_name); 455 /* If the resource PCI address is 0 then we have our
384 continue; 456 * ISA memory hole
457 */
458 if (res->start == hose->pci_mem_offset)
459 found_isa_hole = 1;
385 } 460 }
386 sa = (0xffffffffu << ilog2(sa)) | 0x1;
387
388 /* Program register values */
389 if (j == 0) {
390 writel(lah, reg + PCIX0_POM0LAH);
391 writel(lal, reg + PCIX0_POM0LAL);
392 writel(pciah, reg + PCIX0_POM0PCIAH);
393 writel(pcial, reg + PCIX0_POM0PCIAL);
394 writel(sa, reg + PCIX0_POM0SA);
395 } else {
396 writel(lah, reg + PCIX0_POM1LAH);
397 writel(lal, reg + PCIX0_POM1LAL);
398 writel(pciah, reg + PCIX0_POM1PCIAH);
399 writel(pcial, reg + PCIX0_POM1PCIAL);
400 writel(sa, reg + PCIX0_POM1SA);
401 }
402 j++;
403 } 461 }
462
463 /* Handle ISA memory hole if not already covered */
464 if (j <= 1 && !found_isa_hole && hose->isa_mem_size)
465 if (ppc4xx_setup_one_pcix_POM(hose, reg, hose->isa_mem_phys, 0,
466 hose->isa_mem_size, 0, j) == 0)
467 printk(KERN_INFO "%s: Legacy ISA memory support enabled\n",
468 hose->dn->full_name);
404} 469}
405 470
406static void __init ppc4xx_configure_pcix_PIMs(struct pci_controller *hose, 471static void __init ppc4xx_configure_pcix_PIMs(struct pci_controller *hose,
@@ -1317,12 +1382,72 @@ static struct pci_ops ppc4xx_pciex_pci_ops =
1317 .write = ppc4xx_pciex_write_config, 1382 .write = ppc4xx_pciex_write_config,
1318}; 1383};
1319 1384
1385static int __init ppc4xx_setup_one_pciex_POM(struct ppc4xx_pciex_port *port,
1386 struct pci_controller *hose,
1387 void __iomem *mbase,
1388 u64 plb_addr,
1389 u64 pci_addr,
1390 u64 size,
1391 unsigned int flags,
1392 int index)
1393{
1394 u32 lah, lal, pciah, pcial, sa;
1395
1396 if (!is_power_of_2(size) ||
1397 (index < 2 && size < 0x100000) ||
1398 (index == 2 && size < 0x100) ||
1399 (plb_addr & (size - 1)) != 0) {
1400 printk(KERN_WARNING "%s: Resource out of range\n",
1401 hose->dn->full_name);
1402 return -1;
1403 }
1404
1405 /* Calculate register values */
1406 lah = RES_TO_U32_HIGH(plb_addr);
1407 lal = RES_TO_U32_LOW(plb_addr);
1408 pciah = RES_TO_U32_HIGH(pci_addr);
1409 pcial = RES_TO_U32_LOW(pci_addr);
1410 sa = (0xffffffffu << ilog2(size)) | 0x1;
1411
1412 /* Program register values */
1413 switch (index) {
1414 case 0:
1415 out_le32(mbase + PECFG_POM0LAH, pciah);
1416 out_le32(mbase + PECFG_POM0LAL, pcial);
1417 dcr_write(port->dcrs, DCRO_PEGPL_OMR1BAH, lah);
1418 dcr_write(port->dcrs, DCRO_PEGPL_OMR1BAL, lal);
1419 dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKH, 0x7fffffff);
1420 /* Note that 3 here means enabled | single region */
1421 dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKL, sa | 3);
1422 break;
1423 case 1:
1424 out_le32(mbase + PECFG_POM1LAH, pciah);
1425 out_le32(mbase + PECFG_POM1LAL, pcial);
1426 dcr_write(port->dcrs, DCRO_PEGPL_OMR2BAH, lah);
1427 dcr_write(port->dcrs, DCRO_PEGPL_OMR2BAL, lal);
1428 dcr_write(port->dcrs, DCRO_PEGPL_OMR2MSKH, 0x7fffffff);
1429 /* Note that 3 here means enabled | single region */
1430 dcr_write(port->dcrs, DCRO_PEGPL_OMR2MSKL, sa | 3);
1431 break;
1432 case 2:
1433 out_le32(mbase + PECFG_POM2LAH, pciah);
1434 out_le32(mbase + PECFG_POM2LAL, pcial);
1435 dcr_write(port->dcrs, DCRO_PEGPL_OMR3BAH, lah);
1436 dcr_write(port->dcrs, DCRO_PEGPL_OMR3BAL, lal);
1437 dcr_write(port->dcrs, DCRO_PEGPL_OMR3MSKH, 0x7fffffff);
1438 /* Note that 3 here means enabled | IO space !!! */
1439 dcr_write(port->dcrs, DCRO_PEGPL_OMR3MSKL, sa | 3);
1440 break;
1441 }
1442
1443 return 0;
1444}
1445
1320static void __init ppc4xx_configure_pciex_POMs(struct ppc4xx_pciex_port *port, 1446static void __init ppc4xx_configure_pciex_POMs(struct ppc4xx_pciex_port *port,
1321 struct pci_controller *hose, 1447 struct pci_controller *hose,
1322 void __iomem *mbase) 1448 void __iomem *mbase)
1323{ 1449{
1324 u32 lah, lal, pciah, pcial, sa; 1450 int i, j, found_isa_hole = 0;
1325 int i, j;
1326 1451
1327 /* Setup outbound memory windows */ 1452 /* Setup outbound memory windows */
1328 for (i = j = 0; i < 3; i++) { 1453 for (i = j = 0; i < 3; i++) {
@@ -1337,53 +1462,38 @@ static void __init ppc4xx_configure_pciex_POMs(struct ppc4xx_pciex_port *port,
1337 break; 1462 break;
1338 } 1463 }
1339 1464
1340 /* Calculate register values */ 1465 /* Configure the resource */
1341 lah = RES_TO_U32_HIGH(res->start); 1466 if (ppc4xx_setup_one_pciex_POM(port, hose, mbase,
1342 lal = RES_TO_U32_LOW(res->start); 1467 res->start,
1343 pciah = RES_TO_U32_HIGH(res->start - hose->pci_mem_offset); 1468 res->start - hose->pci_mem_offset,
1344 pcial = RES_TO_U32_LOW(res->start - hose->pci_mem_offset); 1469 res->end + 1 - res->start,
1345 sa = res->end + 1 - res->start; 1470 res->flags,
1346 if (!is_power_of_2(sa) || sa < 0x100000 || 1471 j) == 0) {
1347 sa > 0xffffffffu) { 1472 j++;
1348 printk(KERN_WARNING "%s: Resource out of range\n", 1473
1349 port->node->full_name); 1474 /* If the resource PCI address is 0 then we have our
1350 continue; 1475 * ISA memory hole
1351 } 1476 */
1352 sa = (0xffffffffu << ilog2(sa)) | 0x1; 1477 if (res->start == hose->pci_mem_offset)
1353 1478 found_isa_hole = 1;
1354 /* Program register values */
1355 switch (j) {
1356 case 0:
1357 out_le32(mbase + PECFG_POM0LAH, pciah);
1358 out_le32(mbase + PECFG_POM0LAL, pcial);
1359 dcr_write(port->dcrs, DCRO_PEGPL_OMR1BAH, lah);
1360 dcr_write(port->dcrs, DCRO_PEGPL_OMR1BAL, lal);
1361 dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKH, 0x7fffffff);
1362 dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKL, sa | 3);
1363 break;
1364 case 1:
1365 out_le32(mbase + PECFG_POM1LAH, pciah);
1366 out_le32(mbase + PECFG_POM1LAL, pcial);
1367 dcr_write(port->dcrs, DCRO_PEGPL_OMR2BAH, lah);
1368 dcr_write(port->dcrs, DCRO_PEGPL_OMR2BAL, lal);
1369 dcr_write(port->dcrs, DCRO_PEGPL_OMR2MSKH, 0x7fffffff);
1370 dcr_write(port->dcrs, DCRO_PEGPL_OMR2MSKL, sa | 3);
1371 break;
1372 } 1479 }
1373 j++;
1374 } 1480 }
1375 1481
1376 /* Configure IO, always 64K starting at 0 */ 1482 /* Handle ISA memory hole if not already covered */
1377 if (hose->io_resource.flags & IORESOURCE_IO) { 1483 if (j <= 1 && !found_isa_hole && hose->isa_mem_size)
1378 lah = RES_TO_U32_HIGH(hose->io_base_phys); 1484 if (ppc4xx_setup_one_pciex_POM(port, hose, mbase,
1379 lal = RES_TO_U32_LOW(hose->io_base_phys); 1485 hose->isa_mem_phys, 0,
1380 out_le32(mbase + PECFG_POM2LAH, 0); 1486 hose->isa_mem_size, 0, j) == 0)
1381 out_le32(mbase + PECFG_POM2LAL, 0); 1487 printk(KERN_INFO "%s: Legacy ISA memory support enabled\n",
1382 dcr_write(port->dcrs, DCRO_PEGPL_OMR3BAH, lah); 1488 hose->dn->full_name);
1383 dcr_write(port->dcrs, DCRO_PEGPL_OMR3BAL, lal); 1489
1384 dcr_write(port->dcrs, DCRO_PEGPL_OMR3MSKH, 0x7fffffff); 1490 /* Configure IO, always 64K starting at 0. We hard wire it to 64K !
1385 dcr_write(port->dcrs, DCRO_PEGPL_OMR3MSKL, 0xffff0000 | 3); 1491 * Note also that it -has- to be region index 2 on this HW
1386 } 1492 */
1493 if (hose->io_resource.flags & IORESOURCE_IO)
1494 ppc4xx_setup_one_pciex_POM(port, hose, mbase,
1495 hose->io_base_phys, 0,
1496 0x10000, IORESOURCE_IO, 2);
1387} 1497}
1388 1498
1389static void __init ppc4xx_configure_pciex_PIMs(struct ppc4xx_pciex_port *port, 1499static void __init ppc4xx_configure_pciex_PIMs(struct ppc4xx_pciex_port *port,
diff --git a/arch/powerpc/sysdev/qe_lib/qe.c b/arch/powerpc/sysdev/qe_lib/qe.c
index b3b73ae57d6d..01bce3784b0a 100644
--- a/arch/powerpc/sysdev/qe_lib/qe.c
+++ b/arch/powerpc/sysdev/qe_lib/qe.c
@@ -19,6 +19,7 @@
19#include <linux/kernel.h> 19#include <linux/kernel.h>
20#include <linux/param.h> 20#include <linux/param.h>
21#include <linux/string.h> 21#include <linux/string.h>
22#include <linux/spinlock.h>
22#include <linux/mm.h> 23#include <linux/mm.h>
23#include <linux/interrupt.h> 24#include <linux/interrupt.h>
24#include <linux/bootmem.h> 25#include <linux/bootmem.h>
@@ -38,6 +39,8 @@ static void qe_snums_init(void);
38static int qe_sdma_init(void); 39static int qe_sdma_init(void);
39 40
40static DEFINE_SPINLOCK(qe_lock); 41static DEFINE_SPINLOCK(qe_lock);
42DEFINE_SPINLOCK(cmxgcr_lock);
43EXPORT_SYMBOL(cmxgcr_lock);
41 44
42/* QE snum state */ 45/* QE snum state */
43enum qe_snum_state { 46enum qe_snum_state {
diff --git a/arch/powerpc/sysdev/qe_lib/ucc.c b/arch/powerpc/sysdev/qe_lib/ucc.c
index 1d78071aad7d..ebb442ea1917 100644
--- a/arch/powerpc/sysdev/qe_lib/ucc.c
+++ b/arch/powerpc/sysdev/qe_lib/ucc.c
@@ -18,6 +18,7 @@
18#include <linux/errno.h> 18#include <linux/errno.h>
19#include <linux/slab.h> 19#include <linux/slab.h>
20#include <linux/stddef.h> 20#include <linux/stddef.h>
21#include <linux/spinlock.h>
21#include <linux/module.h> 22#include <linux/module.h>
22 23
23#include <asm/irq.h> 24#include <asm/irq.h>
@@ -26,9 +27,6 @@
26#include <asm/qe.h> 27#include <asm/qe.h>
27#include <asm/ucc.h> 28#include <asm/ucc.h>
28 29
29DEFINE_SPINLOCK(cmxgcr_lock);
30EXPORT_SYMBOL(cmxgcr_lock);
31
32int ucc_set_qe_mux_mii_mng(unsigned int ucc_num) 30int ucc_set_qe_mux_mii_mng(unsigned int ucc_num)
33{ 31{
34 unsigned long flags; 32 unsigned long flags;
diff --git a/arch/sparc/include/asm/device.h b/arch/sparc/include/asm/device.h
index 19790eb99cc6..3702e087df2c 100644
--- a/arch/sparc/include/asm/device.h
+++ b/arch/sparc/include/asm/device.h
@@ -20,4 +20,16 @@ struct dev_archdata {
20 int numa_node; 20 int numa_node;
21}; 21};
22 22
23static inline void dev_archdata_set_node(struct dev_archdata *ad,
24 struct device_node *np)
25{
26 ad->prom_node = np;
27}
28
29static inline struct device_node *
30dev_archdata_get_node(const struct dev_archdata *ad)
31{
32 return ad->prom_node;
33}
34
23#endif /* _ASM_SPARC_DEVICE_H */ 35#endif /* _ASM_SPARC_DEVICE_H */