aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2008-02-07 12:02:26 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2008-02-07 12:02:26 -0500
commit37969581301e50872a1ae84dc73962b5f7ee6b76 (patch)
tree35bbd6a07f903f248f4bd209b8d194a922415fe0 /arch/powerpc
parent80ff8a805113850a3ffafcc8e6eaa1fdd51b02f3 (diff)
parent24f1a849614ba1805e26a05da7cc8c6bd67490ea (diff)
Merge branch 'for-2.6.25' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc
* 'for-2.6.25' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc: (69 commits) [POWERPC] Add SPE registers to core dumps [POWERPC] Use regset code for compat PTRACE_*REGS* calls [POWERPC] Use generic compat_sys_ptrace [POWERPC] Use generic compat_ptrace_request [POWERPC] Use generic ptrace peekdata/pokedata [POWERPC] Use regset code for PTRACE_*REGS* requests [POWERPC] Switch to generic compat_binfmt_elf code [POWERPC] Switch to using user_regset-based core dumps [POWERPC] Add user_regset compat support [POWERPC] Add user_regset_view definitions [POWERPC] Use user_regset accessors for GPRs [POWERPC] ptrace accessors for special regs MSR and TRAP [POWERPC] Use user_regset accessors for SPE regs [POWERPC] Use user_regset accessors for altivec regs [POWERPC] Use user_regset accessors for FP regs [POWERPC] mpc52xx: fix compile error introduce when rebasing patch [POWERPC] 4xx: PCIe indirect DCR spinlock fix. [POWERPC] Add missing native dcr dcr_ind_lock spinlock [POWERPC] 4xx: Fix offset value on Warp board [POWERPC] 4xx: Add 440EPx Sequoia ehci dts entry ...
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/Kconfig22
-rw-r--r--arch/powerpc/Makefile9
-rw-r--r--arch/powerpc/boot/Makefile126
-rw-r--r--arch/powerpc/boot/cuboot-mpc7448hpc2.c (renamed from arch/powerpc/boot/cuboot-hpc2.c)0
-rw-r--r--arch/powerpc/boot/dts/adder875-redboot.dts1
-rw-r--r--arch/powerpc/boot/dts/adder875-uboot.dts1
-rw-r--r--arch/powerpc/boot/dts/mpc5121ads.dts122
-rw-r--r--arch/powerpc/boot/dts/mpc8313erdb.dts4
-rw-r--r--arch/powerpc/boot/dts/mpc8315erdb.dts2
-rw-r--r--arch/powerpc/boot/dts/mpc834x_mds.dts2
-rw-r--r--arch/powerpc/boot/dts/mpc8572ds.dts12
-rw-r--r--arch/powerpc/boot/dts/mpc885ads.dts1
-rw-r--r--arch/powerpc/boot/dts/sequoia.dts8
-rw-r--r--arch/powerpc/boot/dts/storcenter.dts12
-rwxr-xr-xarch/powerpc/boot/wrapper23
-rw-r--r--arch/powerpc/configs/mpc83xx_defconfig10
-rw-r--r--arch/powerpc/kernel/Makefile4
-rw-r--r--arch/powerpc/kernel/asm-offsets.c3
-rw-r--r--arch/powerpc/kernel/binfmt_elf32.c69
-rw-r--r--arch/powerpc/kernel/cputable.c10
-rw-r--r--arch/powerpc/kernel/legacy_serial.c3
-rw-r--r--arch/powerpc/kernel/pmc.c2
-rw-r--r--arch/powerpc/kernel/ptrace.c727
-rw-r--r--arch/powerpc/kernel/ptrace32.c161
-rw-r--r--arch/powerpc/kernel/traps.c2
-rw-r--r--arch/powerpc/kernel/vio.c2
-rw-r--r--arch/powerpc/mm/mem.c7
-rw-r--r--arch/powerpc/mm/numa.c66
-rw-r--r--arch/powerpc/oprofile/Makefile2
-rw-r--r--arch/powerpc/oprofile/common.c6
-rw-r--r--arch/powerpc/oprofile/op_model_fsl_emb.c (renamed from arch/powerpc/oprofile/op_model_fsl_booke.c)28
-rw-r--r--arch/powerpc/platforms/40x/Kconfig1
-rw-r--r--arch/powerpc/platforms/40x/virtex.c2
-rw-r--r--arch/powerpc/platforms/40x/walnut.c1
-rw-r--r--arch/powerpc/platforms/44x/warp.c2
-rw-r--r--arch/powerpc/platforms/512x/Kconfig20
-rw-r--r--arch/powerpc/platforms/512x/Makefile4
-rw-r--r--arch/powerpc/platforms/512x/mpc5121_ads.c104
-rw-r--r--arch/powerpc/platforms/82xx/mpc8272_ads.c3
-rw-r--r--arch/powerpc/platforms/82xx/pq2fads.c3
-rw-r--r--arch/powerpc/platforms/83xx/mpc832x_rdb.c2
-rw-r--r--arch/powerpc/platforms/83xx/mpc83xx.h2
-rw-r--r--arch/powerpc/platforms/83xx/usb.c17
-rw-r--r--arch/powerpc/platforms/8xx/adder875.c6
-rw-r--r--arch/powerpc/platforms/8xx/ep88xc.c1
-rw-r--r--arch/powerpc/platforms/Kconfig2
-rw-r--r--arch/powerpc/platforms/Kconfig.cputype10
-rw-r--r--arch/powerpc/platforms/Makefile1
-rw-r--r--arch/powerpc/platforms/cell/Kconfig7
-rw-r--r--arch/powerpc/platforms/cell/axon_msi.c99
-rw-r--r--arch/powerpc/platforms/cell/setup.c2
-rw-r--r--arch/powerpc/platforms/cell/spufs/Makefile2
-rw-r--r--arch/powerpc/platforms/cell/spufs/file.c6
-rw-r--r--arch/powerpc/platforms/cell/spufs/inode.c29
-rw-r--r--arch/powerpc/platforms/cell/spufs/run.c7
-rw-r--r--arch/powerpc/platforms/cell/spufs/sched.c28
-rw-r--r--arch/powerpc/platforms/cell/spufs/spufs.h5
-rw-r--r--arch/powerpc/platforms/cell/spufs/sputrace.c250
-rw-r--r--arch/powerpc/platforms/embedded6xx/storcenter.c25
-rw-r--r--arch/powerpc/platforms/pseries/hotplug-cpu.c2
-rw-r--r--arch/powerpc/platforms/pseries/kexec.c2
-rw-r--r--arch/powerpc/platforms/pseries/reconfig.c1
-rw-r--r--arch/powerpc/platforms/pseries/xics.c118
-rw-r--r--arch/powerpc/platforms/pseries/xics.h3
-rw-r--r--arch/powerpc/sysdev/dcr.c5
-rw-r--r--arch/powerpc/sysdev/fsl_soc.c2
-rw-r--r--arch/powerpc/sysdev/mpc8xx_pic.c10
-rw-r--r--arch/powerpc/sysdev/qe_lib/qe.c10
68 files changed, 1516 insertions, 725 deletions
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index cf030b004415..8dcac0b22d68 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -97,6 +97,7 @@ config EARLY_PRINTK
97config COMPAT 97config COMPAT
98 bool 98 bool
99 default y if PPC64 99 default y if PPC64
100 select COMPAT_BINFMT_ELF
100 101
101config SYSVIPC_COMPAT 102config SYSVIPC_COMPAT
102 bool 103 bool
@@ -438,25 +439,6 @@ config WANT_DEVICE_TREE
438 bool 439 bool
439 default n 440 default n
440 441
441config DEVICE_TREE
442 string "Static device tree source file"
443 depends on WANT_DEVICE_TREE
444 help
445 This specifies the device tree source (.dts) file to be
446 compiled and included when building the bootwrapper. If a
447 relative filename is given, then it will be relative to
448 arch/powerpc/boot/dts. If you are not using the bootwrapper,
449 or do not need to build a dts into the bootwrapper, this
450 field is ignored.
451
452 For example, this is required when building a cuImage target
453 for an older U-Boot, which cannot pass a device tree itself.
454 Such a kernel will not work with a newer U-Boot that tries to
455 pass a device tree (unless you tell it not to). If your U-Boot
456 does not mention a device tree in "help bootm", then use the
457 cuImage target and specify a device tree here. Otherwise, use
458 the uImage target and leave this field blank.
459
460endmenu 442endmenu
461 443
462config ISA_DMA_API 444config ISA_DMA_API
@@ -512,7 +494,7 @@ config PCI
512 bool "PCI support" if 40x || CPM2 || PPC_83xx || PPC_85xx || PPC_86xx \ 494 bool "PCI support" if 40x || CPM2 || PPC_83xx || PPC_85xx || PPC_86xx \
513 || PPC_MPC52xx || (EMBEDDED && (PPC_PSERIES || PPC_ISERIES)) \ 495 || PPC_MPC52xx || (EMBEDDED && (PPC_PSERIES || PPC_ISERIES)) \
514 || PPC_PS3 || 44x 496 || PPC_PS3 || 44x
515 default y if !40x && !CPM2 && !8xx && !PPC_83xx \ 497 default y if !40x && !CPM2 && !8xx && !PPC_MPC512x && !PPC_83xx \
516 && !PPC_85xx && !PPC_86xx 498 && !PPC_85xx && !PPC_86xx
517 default PCI_PERMEDIA if !4xx && !CPM2 && !8xx 499 default PCI_PERMEDIA if !4xx && !CPM2 && !8xx
518 default PCI_QSPAN if !4xx && !CPM2 && 8xx 500 default PCI_QSPAN if !4xx && !CPM2 && 8xx
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
index f70df9b64f8f..6845482f0093 100644
--- a/arch/powerpc/Makefile
+++ b/arch/powerpc/Makefile
@@ -151,14 +151,11 @@ core-$(CONFIG_XMON) += arch/powerpc/xmon/
151drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/ 151drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/
152 152
153# Default to zImage, override when needed 153# Default to zImage, override when needed
154defaultimage-y := zImage 154all: zImage
155defaultimage-$(CONFIG_DEFAULT_UIMAGE) := uImage
156KBUILD_IMAGE := $(defaultimage-y)
157all: $(KBUILD_IMAGE)
158 155
159CPPFLAGS_vmlinux.lds := -Upowerpc 156CPPFLAGS_vmlinux.lds := -Upowerpc
160 157
161BOOT_TARGETS = zImage zImage.initrd uImage 158BOOT_TARGETS = zImage zImage.initrd uImage treeImage.% cuImage.%
162 159
163PHONY += $(BOOT_TARGETS) 160PHONY += $(BOOT_TARGETS)
164 161
@@ -180,7 +177,7 @@ define archhelp
180endef 177endef
181 178
182install: vdso_install 179install: vdso_install
183 $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) install 180 $(Q)$(MAKE) $(build)=$(boot) install
184 181
185vdso_install: 182vdso_install:
186ifeq ($(CONFIG_PPC64),y) 183ifeq ($(CONFIG_PPC64),y)
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
index 122a27078998..49797a45416c 100644
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -60,8 +60,9 @@ src-wlib := string.S crt0.S stdio.c main.c \
60src-plat := of.c cuboot-52xx.c cuboot-824x.c cuboot-83xx.c cuboot-85xx.c holly.c \ 60src-plat := of.c cuboot-52xx.c cuboot-824x.c cuboot-83xx.c cuboot-85xx.c holly.c \
61 cuboot-ebony.c treeboot-ebony.c prpmc2800.c \ 61 cuboot-ebony.c treeboot-ebony.c prpmc2800.c \
62 ps3-head.S ps3-hvcall.S ps3.c treeboot-bamboo.c cuboot-8xx.c \ 62 ps3-head.S ps3-hvcall.S ps3.c treeboot-bamboo.c cuboot-8xx.c \
63 cuboot-pq2.c cuboot-sequoia.c treeboot-walnut.c cuboot-bamboo.c \ 63 cuboot-pq2.c cuboot-sequoia.c treeboot-walnut.c \
64 fixed-head.S ep88xc.c cuboot-hpc2.c ep405.c cuboot-taishan.c \ 64 cuboot-bamboo.c cuboot-mpc7448hpc2.c cuboot-taishan.c \
65 fixed-head.S ep88xc.c ep405.c \
65 cuboot-katmai.c cuboot-rainier.c redboot-8xx.c ep8248e.c \ 66 cuboot-katmai.c cuboot-rainier.c redboot-8xx.c ep8248e.c \
66 cuboot-warp.c cuboot-85xx-cpm2.c 67 cuboot-warp.c cuboot-85xx-cpm2.c
67src-boot := $(src-wlib) $(src-plat) empty.c 68src-boot := $(src-wlib) $(src-plat) empty.c
@@ -123,6 +124,8 @@ targets += $(patsubst $(obj)/%,%,$(obj-boot) wrapper.a)
123extra-y := $(obj)/wrapper.a $(obj-plat) $(obj)/empty.o \ 124extra-y := $(obj)/wrapper.a $(obj-plat) $(obj)/empty.o \
124 $(obj)/zImage.lds $(obj)/zImage.coff.lds $(obj)/zImage.ps3.lds 125 $(obj)/zImage.lds $(obj)/zImage.coff.lds $(obj)/zImage.ps3.lds
125 126
127dtstree := $(srctree)/$(src)/dts
128
126wrapper :=$(srctree)/$(src)/wrapper 129wrapper :=$(srctree)/$(src)/wrapper
127wrapperbits := $(extra-y) $(addprefix $(obj)/,addnote hack-coff mktree dtc) \ 130wrapperbits := $(extra-y) $(addprefix $(obj)/,addnote hack-coff mktree dtc) \
128 $(wrapper) FORCE 131 $(wrapper) FORCE
@@ -181,7 +184,7 @@ quiet_cmd_wrap = WRAP $@
181image-$(CONFIG_PPC_PSERIES) += zImage.pseries 184image-$(CONFIG_PPC_PSERIES) += zImage.pseries
182image-$(CONFIG_PPC_MAPLE) += zImage.pseries 185image-$(CONFIG_PPC_MAPLE) += zImage.pseries
183image-$(CONFIG_PPC_IBM_CELL_BLADE) += zImage.pseries 186image-$(CONFIG_PPC_IBM_CELL_BLADE) += zImage.pseries
184image-$(CONFIG_PPC_PS3) += zImage.ps3 187image-$(CONFIG_PPC_PS3) += zImage-dtb.ps3
185image-$(CONFIG_PPC_CELLEB) += zImage.pseries 188image-$(CONFIG_PPC_CELLEB) += zImage.pseries
186image-$(CONFIG_PPC_CHRP) += zImage.chrp 189image-$(CONFIG_PPC_CHRP) += zImage.chrp
187image-$(CONFIG_PPC_EFIKA) += zImage.chrp 190image-$(CONFIG_PPC_EFIKA) += zImage.chrp
@@ -191,33 +194,69 @@ image-$(CONFIG_PPC_PRPMC2800) += zImage.prpmc2800
191image-$(CONFIG_PPC_ISERIES) += zImage.iseries 194image-$(CONFIG_PPC_ISERIES) += zImage.iseries
192image-$(CONFIG_DEFAULT_UIMAGE) += uImage 195image-$(CONFIG_DEFAULT_UIMAGE) += uImage
193 196
194ifneq ($(CONFIG_DEVICE_TREE),"") 197#
195image-$(CONFIG_PPC_8xx) += cuImage.8xx 198# Targets which embed a device tree blob
196image-$(CONFIG_PPC_EP88XC) += zImage.ep88xc 199#
197image-$(CONFIG_EP405) += zImage.ep405 200# Theses are default targets to build images which embed device tree blobs.
198image-$(CONFIG_8260) += cuImage.pq2 201# They are only required on boards which do not have FDT support in firmware.
199image-$(CONFIG_EP8248E) += zImage.ep8248e 202# Boards with newish u-boot firmare can use the uImage target above
200image-$(CONFIG_PPC_MPC52xx) += cuImage.52xx 203#
201image-$(CONFIG_STORCENTER) += cuImage.824x 204
202image-$(CONFIG_PPC_83xx) += cuImage.83xx 205# Board ports in arch/powerpc/platform/40x/Kconfig
203image-$(CONFIG_PPC_85xx) += cuImage.85xx 206image-$(CONFIG_EP405) += zImage-dtb.ep405
204ifeq ($(CONFIG_CPM2),y) 207image-$(CONFIG_WALNUT) += treeImage.walnut
205image-$(CONFIG_PPC_85xx) += cuImage.85xx-cpm2 208
206endif 209# Board ports in arch/powerpc/platform/44x/Kconfig
207image-$(CONFIG_MPC7448HPC2) += cuImage.hpc2
208image-$(CONFIG_EBONY) += treeImage.ebony cuImage.ebony 210image-$(CONFIG_EBONY) += treeImage.ebony cuImage.ebony
209image-$(CONFIG_BAMBOO) += treeImage.bamboo cuImage.bamboo 211image-$(CONFIG_BAMBOO) += treeImage.bamboo cuImage.bamboo
210image-$(CONFIG_SEQUOIA) += cuImage.sequoia 212image-$(CONFIG_SEQUOIA) += cuImage.sequoia
211image-$(CONFIG_RAINIER) += cuImage.rainier 213image-$(CONFIG_RAINIER) += cuImage.rainier
212image-$(CONFIG_WALNUT) += treeImage.walnut
213image-$(CONFIG_TAISHAN) += cuImage.taishan 214image-$(CONFIG_TAISHAN) += cuImage.taishan
214image-$(CONFIG_KATMAI) += cuImage.katmai 215image-$(CONFIG_KATMAI) += cuImage.katmai
215image-$(CONFIG_WARP) += cuImage.warp 216image-$(CONFIG_WARP) += cuImage.warp
216endif
217 217
218ifneq ($(CONFIG_REDBOOT),"") 218# Board ports in arch/powerpc/platform/8xx/Kconfig
219image-$(CONFIG_PPC_8xx) += zImage.redboot-8xx 219image-$(CONFIG_PPC_MPC86XADS) += cuImage.mpc866ads
220endif 220image-$(CONFIG_PPC_MPC885ADS) += cuImage.mpc885ads
221image-$(CONFIG_PPC_EP88XC) += zImage-dtb.ep88xc
222image-$(CONFIG_PPC_ADDER875) += cuImage.adder875-uboot \
223 zImage-dtb.adder875-redboot
224
225# Board ports in arch/powerpc/platform/52xx/Kconfig
226image-$(CONFIG_PPC_LITE5200) += cuImage.lite5200 cuImage.lite5200b
227
228# Board ports in arch/powerpc/platform/82xx/Kconfig
229image-$(CONFIG_MPC8272_ADS) += cuImage.mpc8272ads
230image-$(CONFIG_PQ2FADS) += cuImage.pq2fads
231image-$(CONFIG_EP8248E) += zImage-dtb.ep8248e
232
233# Board ports in arch/powerpc/platform/83xx/Kconfig
234image-$(CONFIG_MPC832x_MDS) += cuImage.mpc832x_mds
235image-$(CONFIG_MPC832x_RDB) += cuImage.mpc832x_rdb
236image-$(CONFIG_MPC834x_ITX) += cuImage.mpc8349emitx \
237 cuImage.mpc8349emitxgp
238image-$(CONFIG_MPC834x_MDS) += cuImage.mpc834x_mds
239image-$(CONFIG_MPC836x_MDS) += cuImage.mpc836x_mds
240
241# Board ports in arch/powerpc/platform/85xx/Kconfig
242image-$(CONFIG_MPC8540_ADS) += cuImage.mpc8540ads
243image-$(CONFIG_MPC8560_ADS) += cuImage.mpc8560ads
244image-$(CONFIG_MPC85xx_CDS) += cuImage.mpc8541cds \
245 cuImage.mpc8548cds \
246 cuImage.mpc8555cds
247image-$(CONFIG_MPC85xx_MDS) += cuImage.mpc8568mds
248image-$(CONFIG_MPC85xx_DS) += cuImage.mpc8544ds \
249 cuImage.mpc8572ds
250image-$(CONFIG_TQM8540) += cuImage.tqm8540
251image-$(CONFIG_TQM8541) += cuImage.tqm8541
252image-$(CONFIG_TQM8555) += cuImage.tqm8555
253image-$(CONFIG_TQM8560) += cuImage.tqm8560
254image-$(CONFIG_SBC8548) += cuImage.tqm8548
255image-$(CONFIG_SBC8560) += cuImage.tqm8560
256
257# Board ports in arch/powerpc/platform/embedded6xx/Kconfig
258image-$(CONFIG_STORCENTER) += cuImage.storcenter
259image-$(CONFIG_MPC7448HPC2) += cuImage.mpc7448hpc2
221 260
222# For 32-bit powermacs, build the COFF and miboot images 261# For 32-bit powermacs, build the COFF and miboot images
223# as well as the ELF images. 262# as well as the ELF images.
@@ -233,24 +272,20 @@ targets += $(image-y) $(initrd-y)
233 272
234$(addprefix $(obj)/, $(initrd-y)): $(obj)/ramdisk.image.gz 273$(addprefix $(obj)/, $(initrd-y)): $(obj)/ramdisk.image.gz
235 274
236# If CONFIG_WANT_DEVICE_TREE is set and CONFIG_DEVICE_TREE isn't an
237# empty string, define 'dts' to be path to the dts
238# CONFIG_DEVICE_TREE will have "" around it, make sure to strip them
239ifeq ($(CONFIG_WANT_DEVICE_TREE),y)
240ifneq ($(CONFIG_DEVICE_TREE),"")
241dts = $(if $(shell echo $(CONFIG_DEVICE_TREE) | grep '^/'),\
242 ,$(srctree)/$(src)/dts/)$(CONFIG_DEVICE_TREE:"%"=%)
243endif
244endif
245
246# Don't put the ramdisk on the pattern rule; when its missing make will try 275# Don't put the ramdisk on the pattern rule; when its missing make will try
247# the pattern rule with less dependencies that also matches (even with the 276# the pattern rule with less dependencies that also matches (even with the
248# hard dependency listed). 277# hard dependency listed).
249$(obj)/zImage.initrd.%: vmlinux $(wrapperbits) $(dts) 278$(obj)/zImage.initrd.%: vmlinux $(wrapperbits)
250 $(call if_changed,wrap,$*,$(dts),,$(obj)/ramdisk.image.gz) 279 $(call if_changed,wrap,$*,,,$(obj)/ramdisk.image.gz)
251 280
252$(obj)/zImage.%: vmlinux $(wrapperbits) $(dts) 281$(obj)/zImage.%: vmlinux $(wrapperbits)
253 $(call if_changed,wrap,$*,$(dts)) 282 $(call if_changed,wrap,$*)
283
284$(obj)/zImage-dtb.initrd.%: vmlinux $(wrapperbits) $(dtstree)/%.dts
285 $(call if_changed,wrap,$*,$(dtstree)/$*.dts,,$(obj)/ramdisk.image.gz)
286
287$(obj)/zImage-dtb.%: vmlinux $(wrapperbits) $(dtstree)/%.dts
288 $(call if_changed,wrap,$*,$(dtstree)/$*.dts)
254 289
255# This cannot be in the root of $(src) as the zImage rule always adds a $(obj) 290# This cannot be in the root of $(src) as the zImage rule always adds a $(obj)
256# prefix 291# prefix
@@ -260,24 +295,17 @@ $(obj)/vmlinux.strip: vmlinux
260$(obj)/zImage.iseries: vmlinux 295$(obj)/zImage.iseries: vmlinux
261 $(STRIP) -s -R .comment $< -o $@ 296 $(STRIP) -s -R .comment $< -o $@
262 297
263$(obj)/zImage.ps3: vmlinux $(wrapper) $(wrapperbits) $(srctree)/$(src)/dts/ps3.dts
264 $(STRIP) -s -R .comment $< -o vmlinux.strip
265 $(call cmd,wrap,ps3,$(srctree)/$(src)/dts/ps3.dts,,)
266
267$(obj)/zImage.initrd.ps3: vmlinux $(wrapper) $(wrapperbits) $(srctree)/$(src)/dts/ps3.dts $(obj)/ramdisk.image.gz
268 $(call cmd,wrap,ps3,$(srctree)/$(src)/dts/ps3.dts,,$(obj)/ramdisk.image.gz)
269
270$(obj)/uImage: vmlinux $(wrapperbits) 298$(obj)/uImage: vmlinux $(wrapperbits)
271 $(call if_changed,wrap,uboot) 299 $(call if_changed,wrap,uboot)
272 300
273$(obj)/cuImage.%: vmlinux $(dts) $(wrapperbits) 301$(obj)/cuImage.%: vmlinux $(dtstree)/%.dts $(wrapperbits)
274 $(call if_changed,wrap,cuboot-$*,$(dts)) 302 $(call if_changed,wrap,cuboot-$*,$(dtstree)/$*.dts)
275 303
276$(obj)/treeImage.initrd.%: vmlinux $(dts) $(wrapperbits) 304$(obj)/treeImage.initrd.%: vmlinux $(dtstree)/%.dts $(wrapperbits)
277 $(call if_changed,wrap,treeboot-$*,$(dts),,$(obj)/ramdisk.image.gz) 305 $(call if_changed,wrap,treeboot-$*,$(dtstree)/$*.dts,,$(obj)/ramdisk.image.gz)
278 306
279$(obj)/treeImage.%: vmlinux $(dts) $(wrapperbits) 307$(obj)/treeImage.%: vmlinux $(dtstree)/%.dts $(wrapperbits)
280 $(call if_changed,wrap,treeboot-$*,$(dts)) 308 $(call if_changed,wrap,treeboot-$*,$(dtstree)/$*.dts)
281 309
282# If there isn't a platform selected then just strip the vmlinux. 310# If there isn't a platform selected then just strip the vmlinux.
283ifeq (,$(image-y)) 311ifeq (,$(image-y))
diff --git a/arch/powerpc/boot/cuboot-hpc2.c b/arch/powerpc/boot/cuboot-mpc7448hpc2.c
index 1b8953259d75..1b8953259d75 100644
--- a/arch/powerpc/boot/cuboot-hpc2.c
+++ b/arch/powerpc/boot/cuboot-mpc7448hpc2.c
diff --git a/arch/powerpc/boot/dts/adder875-redboot.dts b/arch/powerpc/boot/dts/adder875-redboot.dts
index 930bfb3894eb..28e9cd3d7a21 100644
--- a/arch/powerpc/boot/dts/adder875-redboot.dts
+++ b/arch/powerpc/boot/dts/adder875-redboot.dts
@@ -151,6 +151,7 @@
151 compatible = "fsl,mpc875-brg", 151 compatible = "fsl,mpc875-brg",
152 "fsl,cpm1-brg", 152 "fsl,cpm1-brg",
153 "fsl,cpm-brg"; 153 "fsl,cpm-brg";
154 clock-frequency = <50000000>;
154 reg = <0x9f0 0x10>; 155 reg = <0x9f0 0x10>;
155 }; 156 };
156 157
diff --git a/arch/powerpc/boot/dts/adder875-uboot.dts b/arch/powerpc/boot/dts/adder875-uboot.dts
index 0197242dacfb..54fb60ec03e5 100644
--- a/arch/powerpc/boot/dts/adder875-uboot.dts
+++ b/arch/powerpc/boot/dts/adder875-uboot.dts
@@ -150,6 +150,7 @@
150 compatible = "fsl,mpc875-brg", 150 compatible = "fsl,mpc875-brg",
151 "fsl,cpm1-brg", 151 "fsl,cpm1-brg",
152 "fsl,cpm-brg"; 152 "fsl,cpm-brg";
153 clock-frequency = <50000000>;
153 reg = <0x9f0 0x10>; 154 reg = <0x9f0 0x10>;
154 }; 155 };
155 156
diff --git a/arch/powerpc/boot/dts/mpc5121ads.dts b/arch/powerpc/boot/dts/mpc5121ads.dts
new file mode 100644
index 000000000000..94ad7b2b241e
--- /dev/null
+++ b/arch/powerpc/boot/dts/mpc5121ads.dts
@@ -0,0 +1,122 @@
1/*
2 * MPC5121E MDS Device Tree Source
3 *
4 * Copyright 2007 Freescale Semiconductor Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 */
11
12/dts-v1/;
13
14/ {
15 model = "mpc5121ads";
16 compatible = "fsl,mpc5121ads";
17 #address-cells = <1>;
18 #size-cells = <1>;
19
20 cpus {
21 #address-cells = <1>;
22 #size-cells = <0>;
23
24 PowerPC,5121@0 {
25 device_type = "cpu";
26 reg = <0>;
27 d-cache-line-size = <0x20>; // 32 bytes
28 i-cache-line-size = <0x20>; // 32 bytes
29 d-cache-size = <0x8000>; // L1, 32K
30 i-cache-size = <0x8000>; // L1, 32K
31 timebase-frequency = <49500000>;// 49.5 MHz (csb/4)
32 bus-frequency = <198000000>; // 198 MHz csb bus
33 clock-frequency = <396000000>; // 396 MHz ppc core
34 };
35 };
36
37 memory {
38 device_type = "memory";
39 reg = <0x00000000 0x10000000>; // 256MB at 0
40 };
41
42 localbus@80000020 {
43 compatible = "fsl,mpc5121ads-localbus";
44 #address-cells = <2>;
45 #size-cells = <1>;
46 reg = <0x80000020 0x40>;
47
48 ranges = <0x0 0x0 0xfc000000 0x04000000
49 0x2 0x0 0x82000000 0x00008000>;
50
51 flash@0,0 {
52 compatible = "cfi-flash";
53 reg = <0 0x0 0x4000000>;
54 bank-width = <4>;
55 device-width = <1>;
56 };
57
58 board-control@2,0 {
59 compatible = "fsl,mpc5121ads-cpld";
60 reg = <0x2 0x0 0x8000>;
61 };
62 };
63
64 soc@80000000 {
65 compatible = "fsl,mpc5121-immr";
66 #address-cells = <1>;
67 #size-cells = <1>;
68 #interrupt-cells = <2>;
69 ranges = <0x0 0x80000000 0x400000>;
70 reg = <0x80000000 0x400000>;
71 bus-frequency = <66000000>; // 66 MHz ips bus
72
73
74 // IPIC
75 // interrupts cell = <intr #, sense>
76 // sense values match linux IORESOURCE_IRQ_* defines:
77 // sense == 8: Level, low assertion
78 // sense == 2: Edge, high-to-low change
79 //
80 ipic: interrupt-controller@c00 {
81 compatible = "fsl,mpc5121-ipic", "fsl,ipic";
82 interrupt-controller;
83 #address-cells = <0>;
84 #interrupt-cells = <2>;
85 reg = <0xc00 0x100>;
86 };
87
88 // 512x PSCs are not 52xx PSCs compatible
89 // PSC3 serial port A aka ttyPSC0
90 serial@11300 {
91 device_type = "serial";
92 compatible = "fsl,mpc5121-psc-uart";
93 // Logical port assignment needed until driver
94 // learns to use aliases
95 port-number = <0>;
96 cell-index = <3>;
97 reg = <0x11300 0x100>;
98 interrupts = <0x28 0x8>; // actually the fifo irq
99 interrupt-parent = < &ipic >;
100 };
101
102 // PSC4 serial port B aka ttyPSC1
103 serial@11400 {
104 device_type = "serial";
105 compatible = "fsl,mpc5121-psc-uart";
106 // Logical port assignment needed until driver
107 // learns to use aliases
108 port-number = <1>;
109 cell-index = <4>;
110 reg = <0x11400 0x100>;
111 interrupts = <0x28 0x8>; // actually the fifo irq
112 interrupt-parent = < &ipic >;
113 };
114
115 pscsfifo@11f00 {
116 compatible = "fsl,mpc5121-psc-fifo";
117 reg = <0x11f00 0x100>;
118 interrupts = <0x28 0x8>;
119 interrupt-parent = < &ipic >;
120 };
121 };
122};
diff --git a/arch/powerpc/boot/dts/mpc8313erdb.dts b/arch/powerpc/boot/dts/mpc8313erdb.dts
index 2d6653fe72ff..e1f0dca8ac39 100644
--- a/arch/powerpc/boot/dts/mpc8313erdb.dts
+++ b/arch/powerpc/boot/dts/mpc8313erdb.dts
@@ -118,6 +118,10 @@
118 interrupts = <14 0x8>; 118 interrupts = <14 0x8>;
119 interrupt-parent = <&ipic>; 119 interrupt-parent = <&ipic>;
120 dfsrr; 120 dfsrr;
121 rtc@68 {
122 compatible = "dallas,ds1339";
123 reg = <0x68>;
124 };
121 }; 125 };
122 126
123 i2c@3100 { 127 i2c@3100 {
diff --git a/arch/powerpc/boot/dts/mpc8315erdb.dts b/arch/powerpc/boot/dts/mpc8315erdb.dts
index b582032ba3d6..d7a1ececa30f 100644
--- a/arch/powerpc/boot/dts/mpc8315erdb.dts
+++ b/arch/powerpc/boot/dts/mpc8315erdb.dts
@@ -96,7 +96,7 @@
96 #address-cells = <1>; 96 #address-cells = <1>;
97 #size-cells = <1>; 97 #size-cells = <1>;
98 device_type = "soc"; 98 device_type = "soc";
99 compatible = "simple-bus"; 99 compatible = "fsl,mpc8315-immr", "simple-bus";
100 ranges = <0 0xe0000000 0x00100000>; 100 ranges = <0 0xe0000000 0x00100000>;
101 reg = <0xe0000000 0x00000200>; 101 reg = <0xe0000000 0x00000200>;
102 bus-frequency = <0>; 102 bus-frequency = <0>;
diff --git a/arch/powerpc/boot/dts/mpc834x_mds.dts b/arch/powerpc/boot/dts/mpc834x_mds.dts
index 7480edae85ed..0199c5c548d8 100644
--- a/arch/powerpc/boot/dts/mpc834x_mds.dts
+++ b/arch/powerpc/boot/dts/mpc834x_mds.dts
@@ -332,7 +332,7 @@
332 0xc000 0x0 0x0 0x3 &ipic 23 0x8 332 0xc000 0x0 0x0 0x3 &ipic 23 0x8
333 0xc000 0x0 0x0 0x4 &ipic 20 0x8>; 333 0xc000 0x0 0x0 0x4 &ipic 20 0x8>;
334 interrupt-parent = <&ipic>; 334 interrupt-parent = <&ipic>;
335 interrupts = <66 0x8>; 335 interrupts = <67 0x8>;
336 bus-range = <0 0>; 336 bus-range = <0 0>;
337 ranges = <0x02000000 0x0 0xb0000000 0xb0000000 0x0 0x10000000 337 ranges = <0x02000000 0x0 0xb0000000 0xb0000000 0x0 0x10000000
338 0x42000000 0x0 0xa0000000 0xa0000000 0x0 0x10000000 338 0x42000000 0x0 0xa0000000 0xa0000000 0x0 0x10000000
diff --git a/arch/powerpc/boot/dts/mpc8572ds.dts b/arch/powerpc/boot/dts/mpc8572ds.dts
index 813c259abbe5..db37214aee37 100644
--- a/arch/powerpc/boot/dts/mpc8572ds.dts
+++ b/arch/powerpc/boot/dts/mpc8572ds.dts
@@ -42,6 +42,18 @@
42 bus-frequency = <0>; 42 bus-frequency = <0>;
43 clock-frequency = <0>; 43 clock-frequency = <0>;
44 }; 44 };
45
46 PowerPC,8572@1 {
47 device_type = "cpu";
48 reg = <1>;
49 d-cache-line-size = <20>; // 32 bytes
50 i-cache-line-size = <20>; // 32 bytes
51 d-cache-size = <8000>; // L1, 32K
52 i-cache-size = <8000>; // L1, 32K
53 timebase-frequency = <0>;
54 bus-frequency = <0>;
55 clock-frequency = <0>;
56 };
45 }; 57 };
46 58
47 memory { 59 memory {
diff --git a/arch/powerpc/boot/dts/mpc885ads.dts b/arch/powerpc/boot/dts/mpc885ads.dts
index 8848e637293e..d84a012c2aaf 100644
--- a/arch/powerpc/boot/dts/mpc885ads.dts
+++ b/arch/powerpc/boot/dts/mpc885ads.dts
@@ -166,6 +166,7 @@
166 compatible = "fsl,mpc885-brg", 166 compatible = "fsl,mpc885-brg",
167 "fsl,cpm1-brg", 167 "fsl,cpm1-brg",
168 "fsl,cpm-brg"; 168 "fsl,cpm-brg";
169 clock-frequency = <0>;
169 reg = <9f0 10>; 170 reg = <9f0 10>;
170 }; 171 };
171 172
diff --git a/arch/powerpc/boot/dts/sequoia.dts b/arch/powerpc/boot/dts/sequoia.dts
index d9046c1adcbe..5c13d46f441d 100644
--- a/arch/powerpc/boot/dts/sequoia.dts
+++ b/arch/powerpc/boot/dts/sequoia.dts
@@ -138,6 +138,14 @@
138 interrupts = <15 8>; 138 interrupts = <15 8>;
139 }; 139 };
140 140
141 USB0: ehci@e0000300 {
142 compatible = "ibm,usb-ehci-440epx", "usb-ehci";
143 interrupt-parent = <&UIC0>;
144 interrupts = <1a 4>;
145 reg = <0 e0000300 90 0 e0000390 70>;
146 big-endian;
147 };
148
141 POB0: opb { 149 POB0: opb {
142 compatible = "ibm,opb-440epx", "ibm,opb"; 150 compatible = "ibm,opb-440epx", "ibm,opb";
143 #address-cells = <1>; 151 #address-cells = <1>;
diff --git a/arch/powerpc/boot/dts/storcenter.dts b/arch/powerpc/boot/dts/storcenter.dts
index 2204874ac5f3..5893816c0bce 100644
--- a/arch/powerpc/boot/dts/storcenter.dts
+++ b/arch/powerpc/boot/dts/storcenter.dts
@@ -15,7 +15,7 @@
15 15
16/ { 16/ {
17 model = "StorCenter"; 17 model = "StorCenter";
18 compatible = "storcenter"; 18 compatible = "iomega,storcenter";
19 #address-cells = <1>; 19 #address-cells = <1>;
20 #size-cells = <1>; 20 #size-cells = <1>;
21 21
@@ -62,12 +62,12 @@
62 #size-cells = <0>; 62 #size-cells = <0>;
63 compatible = "fsl-i2c"; 63 compatible = "fsl-i2c";
64 reg = <0x3000 0x100>; 64 reg = <0x3000 0x100>;
65 interrupts = <5 2>; 65 interrupts = <17 2>;
66 interrupt-parent = <&mpic>; 66 interrupt-parent = <&mpic>;
67 67
68 rtc@68 { 68 rtc@68 {
69 compatible = "dallas,ds1337"; 69 compatible = "dallas,ds1337";
70 reg = <68>; 70 reg = <0x68>;
71 }; 71 };
72 }; 72 };
73 73
@@ -78,7 +78,7 @@
78 reg = <0x4500 0x20>; 78 reg = <0x4500 0x20>;
79 clock-frequency = <97553800>; /* Hz */ 79 clock-frequency = <97553800>; /* Hz */
80 current-speed = <115200>; 80 current-speed = <115200>;
81 interrupts = <9 2>; 81 interrupts = <25 2>;
82 interrupt-parent = <&mpic>; 82 interrupt-parent = <&mpic>;
83 }; 83 };
84 84
@@ -89,7 +89,7 @@
89 reg = <0x4600 0x20>; 89 reg = <0x4600 0x20>;
90 clock-frequency = <97553800>; /* Hz */ 90 clock-frequency = <97553800>; /* Hz */
91 current-speed = <9600>; 91 current-speed = <9600>;
92 interrupts = <10 2>; 92 interrupts = <26 2>;
93 interrupt-parent = <&mpic>; 93 interrupt-parent = <&mpic>;
94 }; 94 };
95 95
@@ -136,6 +136,6 @@
136 }; 136 };
137 137
138 chosen { 138 chosen {
139 linux,stdout-path = "/soc/serial@4500"; 139 linux,stdout-path = &serial0;
140 }; 140 };
141}; 141};
diff --git a/arch/powerpc/boot/wrapper b/arch/powerpc/boot/wrapper
index 763a0c46f441..c3178155311b 100755
--- a/arch/powerpc/boot/wrapper
+++ b/arch/powerpc/boot/wrapper
@@ -158,6 +158,29 @@ miboot|uboot)
158cuboot*) 158cuboot*)
159 binary=y 159 binary=y
160 gzip= 160 gzip=
161 case "$platform" in
162 *-mpc885ads|*-adder875*|*-ep88xc)
163 platformo=$object/cuboot-8xx.o
164 ;;
165 *5200*|*-motionpro)
166 platformo=$object/cuboot-52xx.o
167 ;;
168 *-pq2fads|*-ep8248e|*-mpc8272*|*-storcenter)
169 platformo=$object/cuboot-pq2.o
170 ;;
171 *-mpc824*)
172 platformo=$object/cuboot-824x.o
173 ;;
174 *-mpc83*)
175 platformo=$object/cuboot-83xx.o
176 ;;
177 *-tqm8541|*-mpc8560*|*-tqm8560|*-tqm8555*)
178 platformo=$object/cuboot-85xx-cpm2.o
179 ;;
180 *-mpc85*)
181 platformo=$object/cuboot-85xx.o
182 ;;
183 esac
161 ;; 184 ;;
162ps3) 185ps3)
163 platformo="$object/ps3-head.o $object/ps3-hvcall.o $object/ps3.o" 186 platformo="$object/ps3-head.o $object/ps3-hvcall.o $object/ps3.o"
diff --git a/arch/powerpc/configs/mpc83xx_defconfig b/arch/powerpc/configs/mpc83xx_defconfig
index 31bdbf3f7566..a9807f083bc4 100644
--- a/arch/powerpc/configs/mpc83xx_defconfig
+++ b/arch/powerpc/configs/mpc83xx_defconfig
@@ -186,7 +186,7 @@ CONFIG_PREEMPT_NONE=y
186# CONFIG_PREEMPT is not set 186# CONFIG_PREEMPT is not set
187CONFIG_BINFMT_ELF=y 187CONFIG_BINFMT_ELF=y
188# CONFIG_BINFMT_MISC is not set 188# CONFIG_BINFMT_MISC is not set
189# CONFIG_MATH_EMULATION is not set 189CONFIG_MATH_EMULATION=y
190CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y 190CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
191CONFIG_ARCH_FLATMEM_ENABLE=y 191CONFIG_ARCH_FLATMEM_ENABLE=y
192CONFIG_ARCH_POPULATES_NODE_MAP=y 192CONFIG_ARCH_POPULATES_NODE_MAP=y
@@ -416,14 +416,14 @@ CONFIG_PHYLIB=y
416# MII PHY device drivers 416# MII PHY device drivers
417# 417#
418CONFIG_MARVELL_PHY=y 418CONFIG_MARVELL_PHY=y
419# CONFIG_DAVICOM_PHY is not set 419CONFIG_DAVICOM_PHY=y
420# CONFIG_QSEMI_PHY is not set 420# CONFIG_QSEMI_PHY is not set
421# CONFIG_LXT_PHY is not set 421# CONFIG_LXT_PHY is not set
422# CONFIG_CICADA_PHY is not set 422# CONFIG_CICADA_PHY is not set
423# CONFIG_VITESSE_PHY is not set 423CONFIG_VITESSE_PHY=y
424# CONFIG_SMSC_PHY is not set 424# CONFIG_SMSC_PHY is not set
425# CONFIG_BROADCOM_PHY is not set 425# CONFIG_BROADCOM_PHY is not set
426# CONFIG_ICPLUS_PHY is not set 426CONFIG_ICPLUS_PHY=y
427# CONFIG_FIXED_PHY is not set 427# CONFIG_FIXED_PHY is not set
428# CONFIG_MDIO_BITBANG is not set 428# CONFIG_MDIO_BITBANG is not set
429CONFIG_NET_ETHERNET=y 429CONFIG_NET_ETHERNET=y
@@ -436,7 +436,7 @@ CONFIG_MII=y
436CONFIG_NETDEV_1000=y 436CONFIG_NETDEV_1000=y
437CONFIG_GIANFAR=y 437CONFIG_GIANFAR=y
438# CONFIG_GFAR_NAPI is not set 438# CONFIG_GFAR_NAPI is not set
439# CONFIG_UCC_GETH is not set 439CONFIG_UCC_GETH=y
440CONFIG_NETDEV_10000=y 440CONFIG_NETDEV_10000=y
441 441
442# 442#
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 58dbfeff9b4d..0662ae46f724 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -2,6 +2,8 @@
2# Makefile for the linux kernel. 2# Makefile for the linux kernel.
3# 3#
4 4
5CFLAGS_ptrace.o += -DUTS_MACHINE='"$(UTS_MACHINE)"'
6
5ifeq ($(CONFIG_PPC64),y) 7ifeq ($(CONFIG_PPC64),y)
6CFLAGS_prom_init.o += -mno-minimal-toc 8CFLAGS_prom_init.o += -mno-minimal-toc
7endif 9endif
@@ -15,7 +17,7 @@ obj-y := semaphore.o cputable.o ptrace.o syscalls.o \
15 init_task.o process.o systbl.o idle.o \ 17 init_task.o process.o systbl.o idle.o \
16 signal.o 18 signal.o
17obj-y += vdso32/ 19obj-y += vdso32/
18obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \ 20obj-$(CONFIG_PPC64) += setup_64.o sys_ppc32.o \
19 signal_64.o ptrace32.o \ 21 signal_64.o ptrace32.o \
20 paca.o cpu_setup_ppc970.o \ 22 paca.o cpu_setup_ppc970.o \
21 cpu_setup_pa6t.o \ 23 cpu_setup_pa6t.o \
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index ed083feaf6f9..e6e49289f788 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -22,6 +22,7 @@
22#include <linux/mman.h> 22#include <linux/mman.h>
23#include <linux/mm.h> 23#include <linux/mm.h>
24#include <linux/suspend.h> 24#include <linux/suspend.h>
25#include <linux/hrtimer.h>
25#ifdef CONFIG_PPC64 26#ifdef CONFIG_PPC64
26#include <linux/time.h> 27#include <linux/time.h>
27#include <linux/hardirq.h> 28#include <linux/hardirq.h>
@@ -312,7 +313,7 @@ int main(void)
312 DEFINE(CLOCK_REALTIME, CLOCK_REALTIME); 313 DEFINE(CLOCK_REALTIME, CLOCK_REALTIME);
313 DEFINE(CLOCK_MONOTONIC, CLOCK_MONOTONIC); 314 DEFINE(CLOCK_MONOTONIC, CLOCK_MONOTONIC);
314 DEFINE(NSEC_PER_SEC, NSEC_PER_SEC); 315 DEFINE(NSEC_PER_SEC, NSEC_PER_SEC);
315 DEFINE(CLOCK_REALTIME_RES, TICK_NSEC); 316 DEFINE(CLOCK_REALTIME_RES, (KTIME_MONOTONIC_RES).tv64);
316 317
317#ifdef CONFIG_BUG 318#ifdef CONFIG_BUG
318 DEFINE(BUG_ENTRY_SIZE, sizeof(struct bug_entry)); 319 DEFINE(BUG_ENTRY_SIZE, sizeof(struct bug_entry));
diff --git a/arch/powerpc/kernel/binfmt_elf32.c b/arch/powerpc/kernel/binfmt_elf32.c
deleted file mode 100644
index 1d45d7782d4e..000000000000
--- a/arch/powerpc/kernel/binfmt_elf32.c
+++ /dev/null
@@ -1,69 +0,0 @@
1/*
2 * binfmt_elf32.c: Support 32-bit PPC ELF binaries on Power3 and followons.
3 * based on the SPARC64 version.
4 * Copyright (C) 1995, 1996, 1997, 1998 David S. Miller (davem@redhat.com)
5 * Copyright (C) 1995, 1996, 1997, 1998 Jakub Jelinek (jj@ultra.linux.cz)
6 *
7 * Copyright (C) 2000,2001 Ken Aaker (kdaaker@rchland.vnet.ibm.com), IBM Corp
8 * Copyright (C) 2001 Anton Blanchard (anton@au.ibm.com), IBM
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version
13 * 2 of the License, or (at your option) any later version.
14 */
15
16#include <asm/processor.h>
17#include <linux/module.h>
18#include <linux/compat.h>
19#include <linux/elfcore-compat.h>
20
21#undef ELF_ARCH
22#undef ELF_CLASS
23#define ELF_CLASS ELFCLASS32
24#define ELF_ARCH EM_PPC
25
26#undef elfhdr
27#undef elf_phdr
28#undef elf_note
29#undef elf_addr_t
30#define elfhdr elf32_hdr
31#define elf_phdr elf32_phdr
32#define elf_note elf32_note
33#define elf_addr_t Elf32_Off
34
35#define elf_prstatus compat_elf_prstatus
36#define elf_prpsinfo compat_elf_prpsinfo
37
38#define elf_core_copy_regs compat_elf_core_copy_regs
39static inline void compat_elf_core_copy_regs(compat_elf_gregset_t *elf_regs,
40 struct pt_regs *regs)
41{
42 PPC_ELF_CORE_COPY_REGS((*elf_regs), regs);
43}
44
45#define elf_core_copy_task_regs compat_elf_core_copy_task_regs
46static int compat_elf_core_copy_task_regs(struct task_struct *tsk,
47 compat_elf_gregset_t *elf_regs)
48{
49 struct pt_regs *regs = tsk->thread.regs;
50 if (regs)
51 compat_elf_core_copy_regs(elf_regs, regs);
52 return 1;
53}
54
55#include <linux/time.h>
56
57#undef cputime_to_timeval
58#define cputime_to_timeval cputime_to_compat_timeval
59static __inline__ void
60cputime_to_compat_timeval(const cputime_t cputime, struct compat_timeval *value)
61{
62 unsigned long jiffies = cputime_to_jiffies(cputime);
63 value->tv_usec = (jiffies % HZ) * (1000000L / HZ);
64 value->tv_sec = jiffies / HZ;
65}
66
67#define init_elf_binfmt init_elf32_binfmt
68
69#include "../../../fs/binfmt_elf.c"
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index a4c2771b5e62..2a8f5cc5184f 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -959,6 +959,9 @@ static struct cpu_spec __initdata cpu_specs[] = {
959 .icache_bsize = 32, 959 .icache_bsize = 32,
960 .dcache_bsize = 32, 960 .dcache_bsize = 32,
961 .cpu_setup = __setup_cpu_603, 961 .cpu_setup = __setup_cpu_603,
962 .num_pmcs = 4,
963 .oprofile_cpu_type = "ppc/e300",
964 .oprofile_type = PPC_OPROFILE_FSL_EMB,
962 .platform = "ppc603", 965 .platform = "ppc603",
963 }, 966 },
964 { /* e300c4 (e300c1, plus one IU) */ 967 { /* e300c4 (e300c1, plus one IU) */
@@ -971,6 +974,9 @@ static struct cpu_spec __initdata cpu_specs[] = {
971 .dcache_bsize = 32, 974 .dcache_bsize = 32,
972 .cpu_setup = __setup_cpu_603, 975 .cpu_setup = __setup_cpu_603,
973 .machine_check = machine_check_generic, 976 .machine_check = machine_check_generic,
977 .num_pmcs = 4,
978 .oprofile_cpu_type = "ppc/e300",
979 .oprofile_type = PPC_OPROFILE_FSL_EMB,
974 .platform = "ppc603", 980 .platform = "ppc603",
975 }, 981 },
976 { /* default match, we assume split I/D cache & TB (non-601)... */ 982 { /* default match, we assume split I/D cache & TB (non-601)... */
@@ -1435,7 +1441,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
1435 .dcache_bsize = 32, 1441 .dcache_bsize = 32,
1436 .num_pmcs = 4, 1442 .num_pmcs = 4,
1437 .oprofile_cpu_type = "ppc/e500", 1443 .oprofile_cpu_type = "ppc/e500",
1438 .oprofile_type = PPC_OPROFILE_BOOKE, 1444 .oprofile_type = PPC_OPROFILE_FSL_EMB,
1439 .machine_check = machine_check_e500, 1445 .machine_check = machine_check_e500,
1440 .platform = "ppc8540", 1446 .platform = "ppc8540",
1441 }, 1447 },
@@ -1453,7 +1459,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
1453 .dcache_bsize = 32, 1459 .dcache_bsize = 32,
1454 .num_pmcs = 4, 1460 .num_pmcs = 4,
1455 .oprofile_cpu_type = "ppc/e500", 1461 .oprofile_cpu_type = "ppc/e500",
1456 .oprofile_type = PPC_OPROFILE_BOOKE, 1462 .oprofile_type = PPC_OPROFILE_FSL_EMB,
1457 .machine_check = machine_check_e500, 1463 .machine_check = machine_check_e500,
1458 .platform = "ppc8548", 1464 .platform = "ppc8548",
1459 }, 1465 },
diff --git a/arch/powerpc/kernel/legacy_serial.c b/arch/powerpc/kernel/legacy_serial.c
index 76b862bd1fe9..61dd17449ddc 100644
--- a/arch/powerpc/kernel/legacy_serial.c
+++ b/arch/powerpc/kernel/legacy_serial.c
@@ -36,7 +36,8 @@ static struct legacy_serial_info {
36static struct __initdata of_device_id parents[] = { 36static struct __initdata of_device_id parents[] = {
37 {.type = "soc",}, 37 {.type = "soc",},
38 {.type = "tsi-bridge",}, 38 {.type = "tsi-bridge",},
39 {.type = "opb", .compatible = "ibm,opb",}, 39 {.type = "opb", },
40 {.compatible = "ibm,opb",},
40 {.compatible = "simple-bus",}, 41 {.compatible = "simple-bus",},
41 {.compatible = "wrs,epld-localbus",}, 42 {.compatible = "wrs,epld-localbus",},
42}; 43};
diff --git a/arch/powerpc/kernel/pmc.c b/arch/powerpc/kernel/pmc.c
index ea04e0ab3f2f..0516e2d3e02e 100644
--- a/arch/powerpc/kernel/pmc.c
+++ b/arch/powerpc/kernel/pmc.c
@@ -26,7 +26,7 @@
26 26
27static void dummy_perf(struct pt_regs *regs) 27static void dummy_perf(struct pt_regs *regs)
28{ 28{
29#if defined(CONFIG_FSL_BOOKE) && !defined(CONFIG_E200) 29#if defined(CONFIG_FSL_EMB_PERFMON)
30 mtpmr(PMRN_PMGC0, mfpmr(PMRN_PMGC0) & ~PMGC0_PMIE); 30 mtpmr(PMRN_PMGC0, mfpmr(PMRN_PMGC0) & ~PMGC0_PMIE);
31#elif defined(CONFIG_PPC64) || defined(CONFIG_6xx) 31#elif defined(CONFIG_PPC64) || defined(CONFIG_6xx)
32 if (cur_cpu_spec->pmc_type == PPC_PMC_IBM) 32 if (cur_cpu_spec->pmc_type == PPC_PMC_IBM)
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index 8b056d2295cc..7673e9865733 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -21,6 +21,8 @@
21#include <linux/smp.h> 21#include <linux/smp.h>
22#include <linux/errno.h> 22#include <linux/errno.h>
23#include <linux/ptrace.h> 23#include <linux/ptrace.h>
24#include <linux/regset.h>
25#include <linux/elf.h>
24#include <linux/user.h> 26#include <linux/user.h>
25#include <linux/security.h> 27#include <linux/security.h>
26#include <linux/signal.h> 28#include <linux/signal.h>
@@ -58,20 +60,38 @@
58#define PT_MAX_PUT_REG PT_CCR 60#define PT_MAX_PUT_REG PT_CCR
59#endif 61#endif
60 62
63static unsigned long get_user_msr(struct task_struct *task)
64{
65 return task->thread.regs->msr | task->thread.fpexc_mode;
66}
67
68static int set_user_msr(struct task_struct *task, unsigned long msr)
69{
70 task->thread.regs->msr &= ~MSR_DEBUGCHANGE;
71 task->thread.regs->msr |= msr & MSR_DEBUGCHANGE;
72 return 0;
73}
74
75/*
76 * We prevent mucking around with the reserved area of trap
77 * which are used internally by the kernel.
78 */
79static int set_user_trap(struct task_struct *task, unsigned long trap)
80{
81 task->thread.regs->trap = trap & 0xfff0;
82 return 0;
83}
84
61/* 85/*
62 * Get contents of register REGNO in task TASK. 86 * Get contents of register REGNO in task TASK.
63 */ 87 */
64unsigned long ptrace_get_reg(struct task_struct *task, int regno) 88unsigned long ptrace_get_reg(struct task_struct *task, int regno)
65{ 89{
66 unsigned long tmp = 0;
67
68 if (task->thread.regs == NULL) 90 if (task->thread.regs == NULL)
69 return -EIO; 91 return -EIO;
70 92
71 if (regno == PT_MSR) { 93 if (regno == PT_MSR)
72 tmp = ((unsigned long *)task->thread.regs)[PT_MSR]; 94 return get_user_msr(task);
73 return tmp | task->thread.fpexc_mode;
74 }
75 95
76 if (regno < (sizeof(struct pt_regs) / sizeof(unsigned long))) 96 if (regno < (sizeof(struct pt_regs) / sizeof(unsigned long)))
77 return ((unsigned long *)task->thread.regs)[regno]; 97 return ((unsigned long *)task->thread.regs)[regno];
@@ -87,40 +107,134 @@ int ptrace_put_reg(struct task_struct *task, int regno, unsigned long data)
87 if (task->thread.regs == NULL) 107 if (task->thread.regs == NULL)
88 return -EIO; 108 return -EIO;
89 109
90 if (regno <= PT_MAX_PUT_REG || regno == PT_TRAP) { 110 if (regno == PT_MSR)
91 if (regno == PT_MSR) 111 return set_user_msr(task, data);
92 data = (data & MSR_DEBUGCHANGE) 112 if (regno == PT_TRAP)
93 | (task->thread.regs->msr & ~MSR_DEBUGCHANGE); 113 return set_user_trap(task, data);
94 /* We prevent mucking around with the reserved area of trap 114
95 * which are used internally by the kernel 115 if (regno <= PT_MAX_PUT_REG) {
96 */
97 if (regno == PT_TRAP)
98 data &= 0xfff0;
99 ((unsigned long *)task->thread.regs)[regno] = data; 116 ((unsigned long *)task->thread.regs)[regno] = data;
100 return 0; 117 return 0;
101 } 118 }
102 return -EIO; 119 return -EIO;
103} 120}
104 121
122static int gpr_get(struct task_struct *target, const struct user_regset *regset,
123 unsigned int pos, unsigned int count,
124 void *kbuf, void __user *ubuf)
125{
126 int ret;
127
128 if (target->thread.regs == NULL)
129 return -EIO;
130
131 CHECK_FULL_REGS(target->thread.regs);
132
133 ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
134 target->thread.regs,
135 0, offsetof(struct pt_regs, msr));
136 if (!ret) {
137 unsigned long msr = get_user_msr(target);
138 ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &msr,
139 offsetof(struct pt_regs, msr),
140 offsetof(struct pt_regs, msr) +
141 sizeof(msr));
142 }
143
144 BUILD_BUG_ON(offsetof(struct pt_regs, orig_gpr3) !=
145 offsetof(struct pt_regs, msr) + sizeof(long));
146
147 if (!ret)
148 ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
149 &target->thread.regs->orig_gpr3,
150 offsetof(struct pt_regs, orig_gpr3),
151 sizeof(struct pt_regs));
152 if (!ret)
153 ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
154 sizeof(struct pt_regs), -1);
155
156 return ret;
157}
158
159static int gpr_set(struct task_struct *target, const struct user_regset *regset,
160 unsigned int pos, unsigned int count,
161 const void *kbuf, const void __user *ubuf)
162{
163 unsigned long reg;
164 int ret;
165
166 if (target->thread.regs == NULL)
167 return -EIO;
168
169 CHECK_FULL_REGS(target->thread.regs);
170
171 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
172 target->thread.regs,
173 0, PT_MSR * sizeof(reg));
105 174
106static int get_fpregs(void __user *data, struct task_struct *task, 175 if (!ret && count > 0) {
107 int has_fpscr) 176 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &reg,
177 PT_MSR * sizeof(reg),
178 (PT_MSR + 1) * sizeof(reg));
179 if (!ret)
180 ret = set_user_msr(target, reg);
181 }
182
183 BUILD_BUG_ON(offsetof(struct pt_regs, orig_gpr3) !=
184 offsetof(struct pt_regs, msr) + sizeof(long));
185
186 if (!ret)
187 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
188 &target->thread.regs->orig_gpr3,
189 PT_ORIG_R3 * sizeof(reg),
190 (PT_MAX_PUT_REG + 1) * sizeof(reg));
191
192 if (PT_MAX_PUT_REG + 1 < PT_TRAP && !ret)
193 ret = user_regset_copyin_ignore(
194 &pos, &count, &kbuf, &ubuf,
195 (PT_MAX_PUT_REG + 1) * sizeof(reg),
196 PT_TRAP * sizeof(reg));
197
198 if (!ret && count > 0) {
199 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &reg,
200 PT_TRAP * sizeof(reg),
201 (PT_TRAP + 1) * sizeof(reg));
202 if (!ret)
203 ret = set_user_trap(target, reg);
204 }
205
206 if (!ret)
207 ret = user_regset_copyin_ignore(
208 &pos, &count, &kbuf, &ubuf,
209 (PT_TRAP + 1) * sizeof(reg), -1);
210
211 return ret;
212}
213
214static int fpr_get(struct task_struct *target, const struct user_regset *regset,
215 unsigned int pos, unsigned int count,
216 void *kbuf, void __user *ubuf)
108{ 217{
109 unsigned int count = has_fpscr ? 33 : 32; 218 flush_fp_to_thread(target);
110 219
111 if (copy_to_user(data, task->thread.fpr, count * sizeof(double))) 220 BUILD_BUG_ON(offsetof(struct thread_struct, fpscr) !=
112 return -EFAULT; 221 offsetof(struct thread_struct, fpr[32]));
113 return 0; 222
223 return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
224 &target->thread.fpr, 0, -1);
114} 225}
115 226
116static int set_fpregs(void __user *data, struct task_struct *task, 227static int fpr_set(struct task_struct *target, const struct user_regset *regset,
117 int has_fpscr) 228 unsigned int pos, unsigned int count,
229 const void *kbuf, const void __user *ubuf)
118{ 230{
119 unsigned int count = has_fpscr ? 33 : 32; 231 flush_fp_to_thread(target);
120 232
121 if (copy_from_user(task->thread.fpr, data, count * sizeof(double))) 233 BUILD_BUG_ON(offsetof(struct thread_struct, fpscr) !=
122 return -EFAULT; 234 offsetof(struct thread_struct, fpr[32]));
123 return 0; 235
236 return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
237 &target->thread.fpr, 0, -1);
124} 238}
125 239
126 240
@@ -138,56 +252,74 @@ static int set_fpregs(void __user *data, struct task_struct *task,
138 * (combined (32- and 64-bit) gdb. 252 * (combined (32- and 64-bit) gdb.
139 */ 253 */
140 254
141/* 255static int vr_active(struct task_struct *target,
142 * Get contents of AltiVec register state in task TASK 256 const struct user_regset *regset)
143 */
144static int get_vrregs(unsigned long __user *data, struct task_struct *task)
145{ 257{
146 unsigned long regsize; 258 flush_altivec_to_thread(target);
259 return target->thread.used_vr ? regset->n : 0;
260}
147 261
148 /* copy AltiVec registers VR[0] .. VR[31] */ 262static int vr_get(struct task_struct *target, const struct user_regset *regset,
149 regsize = 32 * sizeof(vector128); 263 unsigned int pos, unsigned int count,
150 if (copy_to_user(data, task->thread.vr, regsize)) 264 void *kbuf, void __user *ubuf)
151 return -EFAULT; 265{
152 data += (regsize / sizeof(unsigned long)); 266 int ret;
153 267
154 /* copy VSCR */ 268 flush_altivec_to_thread(target);
155 regsize = 1 * sizeof(vector128);
156 if (copy_to_user(data, &task->thread.vscr, regsize))
157 return -EFAULT;
158 data += (regsize / sizeof(unsigned long));
159 269
160 /* copy VRSAVE */ 270 BUILD_BUG_ON(offsetof(struct thread_struct, vscr) !=
161 if (put_user(task->thread.vrsave, (u32 __user *)data)) 271 offsetof(struct thread_struct, vr[32]));
162 return -EFAULT;
163 272
164 return 0; 273 ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
274 &target->thread.vr, 0,
275 33 * sizeof(vector128));
276 if (!ret) {
277 /*
278 * Copy out only the low-order word of vrsave.
279 */
280 union {
281 elf_vrreg_t reg;
282 u32 word;
283 } vrsave;
284 memset(&vrsave, 0, sizeof(vrsave));
285 vrsave.word = target->thread.vrsave;
286 ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &vrsave,
287 33 * sizeof(vector128), -1);
288 }
289
290 return ret;
165} 291}
166 292
167/* 293static int vr_set(struct task_struct *target, const struct user_regset *regset,
168 * Write contents of AltiVec register state into task TASK. 294 unsigned int pos, unsigned int count,
169 */ 295 const void *kbuf, const void __user *ubuf)
170static int set_vrregs(struct task_struct *task, unsigned long __user *data)
171{ 296{
172 unsigned long regsize; 297 int ret;
173 298
174 /* copy AltiVec registers VR[0] .. VR[31] */ 299 flush_altivec_to_thread(target);
175 regsize = 32 * sizeof(vector128);
176 if (copy_from_user(task->thread.vr, data, regsize))
177 return -EFAULT;
178 data += (regsize / sizeof(unsigned long));
179 300
180 /* copy VSCR */ 301 BUILD_BUG_ON(offsetof(struct thread_struct, vscr) !=
181 regsize = 1 * sizeof(vector128); 302 offsetof(struct thread_struct, vr[32]));
182 if (copy_from_user(&task->thread.vscr, data, regsize))
183 return -EFAULT;
184 data += (regsize / sizeof(unsigned long));
185 303
186 /* copy VRSAVE */ 304 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
187 if (get_user(task->thread.vrsave, (u32 __user *)data)) 305 &target->thread.vr, 0, 33 * sizeof(vector128));
188 return -EFAULT; 306 if (!ret && count > 0) {
307 /*
308 * We use only the first word of vrsave.
309 */
310 union {
311 elf_vrreg_t reg;
312 u32 word;
313 } vrsave;
314 memset(&vrsave, 0, sizeof(vrsave));
315 vrsave.word = target->thread.vrsave;
316 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &vrsave,
317 33 * sizeof(vector128), -1);
318 if (!ret)
319 target->thread.vrsave = vrsave.word;
320 }
189 321
190 return 0; 322 return ret;
191} 323}
192#endif /* CONFIG_ALTIVEC */ 324#endif /* CONFIG_ALTIVEC */
193 325
@@ -203,57 +335,273 @@ static int set_vrregs(struct task_struct *task, unsigned long __user *data)
203 * } 335 * }
204 */ 336 */
205 337
206/* 338static int evr_active(struct task_struct *target,
207 * Get contents of SPE register state in task TASK. 339 const struct user_regset *regset)
208 */
209static int get_evrregs(unsigned long *data, struct task_struct *task)
210{ 340{
211 int i; 341 flush_spe_to_thread(target);
342 return target->thread.used_spe ? regset->n : 0;
343}
212 344
213 if (!access_ok(VERIFY_WRITE, data, 35 * sizeof(unsigned long))) 345static int evr_get(struct task_struct *target, const struct user_regset *regset,
214 return -EFAULT; 346 unsigned int pos, unsigned int count,
347 void *kbuf, void __user *ubuf)
348{
349 int ret;
215 350
216 /* copy SPEFSCR */ 351 flush_spe_to_thread(target);
217 if (__put_user(task->thread.spefscr, &data[34]))
218 return -EFAULT;
219 352
220 /* copy SPE registers EVR[0] .. EVR[31] */ 353 ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
221 for (i = 0; i < 32; i++, data++) 354 &target->thread.evr,
222 if (__put_user(task->thread.evr[i], data)) 355 0, sizeof(target->thread.evr));
223 return -EFAULT;
224 356
225 /* copy ACC */ 357 BUILD_BUG_ON(offsetof(struct thread_struct, acc) + sizeof(u64) !=
226 if (__put_user64(task->thread.acc, (unsigned long long *)data)) 358 offsetof(struct thread_struct, spefscr));
227 return -EFAULT;
228 359
229 return 0; 360 if (!ret)
361 ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
362 &target->thread.acc,
363 sizeof(target->thread.evr), -1);
364
365 return ret;
366}
367
368static int evr_set(struct task_struct *target, const struct user_regset *regset,
369 unsigned int pos, unsigned int count,
370 const void *kbuf, const void __user *ubuf)
371{
372 int ret;
373
374 flush_spe_to_thread(target);
375
376 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
377 &target->thread.evr,
378 0, sizeof(target->thread.evr));
379
380 BUILD_BUG_ON(offsetof(struct thread_struct, acc) + sizeof(u64) !=
381 offsetof(struct thread_struct, spefscr));
382
383 if (!ret)
384 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
385 &target->thread.acc,
386 sizeof(target->thread.evr), -1);
387
388 return ret;
230} 389}
390#endif /* CONFIG_SPE */
391
231 392
232/* 393/*
233 * Write contents of SPE register state into task TASK. 394 * These are our native regset flavors.
234 */ 395 */
235static int set_evrregs(struct task_struct *task, unsigned long *data) 396enum powerpc_regset {
397 REGSET_GPR,
398 REGSET_FPR,
399#ifdef CONFIG_ALTIVEC
400 REGSET_VMX,
401#endif
402#ifdef CONFIG_SPE
403 REGSET_SPE,
404#endif
405};
406
407static const struct user_regset native_regsets[] = {
408 [REGSET_GPR] = {
409 .core_note_type = NT_PRSTATUS, .n = ELF_NGREG,
410 .size = sizeof(long), .align = sizeof(long),
411 .get = gpr_get, .set = gpr_set
412 },
413 [REGSET_FPR] = {
414 .core_note_type = NT_PRFPREG, .n = ELF_NFPREG,
415 .size = sizeof(double), .align = sizeof(double),
416 .get = fpr_get, .set = fpr_set
417 },
418#ifdef CONFIG_ALTIVEC
419 [REGSET_VMX] = {
420 .core_note_type = NT_PPC_VMX, .n = 34,
421 .size = sizeof(vector128), .align = sizeof(vector128),
422 .active = vr_active, .get = vr_get, .set = vr_set
423 },
424#endif
425#ifdef CONFIG_SPE
426 [REGSET_SPE] = {
427 .n = 35,
428 .size = sizeof(u32), .align = sizeof(u32),
429 .active = evr_active, .get = evr_get, .set = evr_set
430 },
431#endif
432};
433
434static const struct user_regset_view user_ppc_native_view = {
435 .name = UTS_MACHINE, .e_machine = ELF_ARCH, .ei_osabi = ELF_OSABI,
436 .regsets = native_regsets, .n = ARRAY_SIZE(native_regsets)
437};
438
439#ifdef CONFIG_PPC64
440#include <linux/compat.h>
441
442static int gpr32_get(struct task_struct *target,
443 const struct user_regset *regset,
444 unsigned int pos, unsigned int count,
445 void *kbuf, void __user *ubuf)
236{ 446{
237 int i; 447 const unsigned long *regs = &target->thread.regs->gpr[0];
448 compat_ulong_t *k = kbuf;
449 compat_ulong_t __user *u = ubuf;
450 compat_ulong_t reg;
451
452 if (target->thread.regs == NULL)
453 return -EIO;
454
455 CHECK_FULL_REGS(target->thread.regs);
238 456
239 if (!access_ok(VERIFY_READ, data, 35 * sizeof(unsigned long))) 457 pos /= sizeof(reg);
240 return -EFAULT; 458 count /= sizeof(reg);
241 459
242 /* copy SPEFSCR */ 460 if (kbuf)
243 if (__get_user(task->thread.spefscr, &data[34])) 461 for (; count > 0 && pos < PT_MSR; --count)
244 return -EFAULT; 462 *k++ = regs[pos++];
463 else
464 for (; count > 0 && pos < PT_MSR; --count)
465 if (__put_user((compat_ulong_t) regs[pos++], u++))
466 return -EFAULT;
245 467
246 /* copy SPE registers EVR[0] .. EVR[31] */ 468 if (count > 0 && pos == PT_MSR) {
247 for (i = 0; i < 32; i++, data++) 469 reg = get_user_msr(target);
248 if (__get_user(task->thread.evr[i], data)) 470 if (kbuf)
471 *k++ = reg;
472 else if (__put_user(reg, u++))
249 return -EFAULT; 473 return -EFAULT;
250 /* copy ACC */ 474 ++pos;
251 if (__get_user64(task->thread.acc, (unsigned long long*)data)) 475 --count;
252 return -EFAULT; 476 }
253 477
254 return 0; 478 if (kbuf)
479 for (; count > 0 && pos < PT_REGS_COUNT; --count)
480 *k++ = regs[pos++];
481 else
482 for (; count > 0 && pos < PT_REGS_COUNT; --count)
483 if (__put_user((compat_ulong_t) regs[pos++], u++))
484 return -EFAULT;
485
486 kbuf = k;
487 ubuf = u;
488 pos *= sizeof(reg);
489 count *= sizeof(reg);
490 return user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
491 PT_REGS_COUNT * sizeof(reg), -1);
492}
493
494static int gpr32_set(struct task_struct *target,
495 const struct user_regset *regset,
496 unsigned int pos, unsigned int count,
497 const void *kbuf, const void __user *ubuf)
498{
499 unsigned long *regs = &target->thread.regs->gpr[0];
500 const compat_ulong_t *k = kbuf;
501 const compat_ulong_t __user *u = ubuf;
502 compat_ulong_t reg;
503
504 if (target->thread.regs == NULL)
505 return -EIO;
506
507 CHECK_FULL_REGS(target->thread.regs);
508
509 pos /= sizeof(reg);
510 count /= sizeof(reg);
511
512 if (kbuf)
513 for (; count > 0 && pos < PT_MSR; --count)
514 regs[pos++] = *k++;
515 else
516 for (; count > 0 && pos < PT_MSR; --count) {
517 if (__get_user(reg, u++))
518 return -EFAULT;
519 regs[pos++] = reg;
520 }
521
522
523 if (count > 0 && pos == PT_MSR) {
524 if (kbuf)
525 reg = *k++;
526 else if (__get_user(reg, u++))
527 return -EFAULT;
528 set_user_msr(target, reg);
529 ++pos;
530 --count;
531 }
532
533 if (kbuf)
534 for (; count > 0 && pos <= PT_MAX_PUT_REG; --count)
535 regs[pos++] = *k++;
536 else
537 for (; count > 0 && pos <= PT_MAX_PUT_REG; --count) {
538 if (__get_user(reg, u++))
539 return -EFAULT;
540 regs[pos++] = reg;
541 }
542
543 if (count > 0 && pos == PT_TRAP) {
544 if (kbuf)
545 reg = *k++;
546 else if (__get_user(reg, u++))
547 return -EFAULT;
548 set_user_trap(target, reg);
549 ++pos;
550 --count;
551 }
552
553 kbuf = k;
554 ubuf = u;
555 pos *= sizeof(reg);
556 count *= sizeof(reg);
557 return user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
558 (PT_TRAP + 1) * sizeof(reg), -1);
559}
560
561/*
562 * These are the regset flavors matching the CONFIG_PPC32 native set.
563 */
564static const struct user_regset compat_regsets[] = {
565 [REGSET_GPR] = {
566 .core_note_type = NT_PRSTATUS, .n = ELF_NGREG,
567 .size = sizeof(compat_long_t), .align = sizeof(compat_long_t),
568 .get = gpr32_get, .set = gpr32_set
569 },
570 [REGSET_FPR] = {
571 .core_note_type = NT_PRFPREG, .n = ELF_NFPREG,
572 .size = sizeof(double), .align = sizeof(double),
573 .get = fpr_get, .set = fpr_set
574 },
575#ifdef CONFIG_ALTIVEC
576 [REGSET_VMX] = {
577 .core_note_type = NT_PPC_VMX, .n = 34,
578 .size = sizeof(vector128), .align = sizeof(vector128),
579 .active = vr_active, .get = vr_get, .set = vr_set
580 },
581#endif
582#ifdef CONFIG_SPE
583 [REGSET_SPE] = {
584 .core_note_type = NT_PPC_SPE, .n = 35,
585 .size = sizeof(u32), .align = sizeof(u32),
586 .active = evr_active, .get = evr_get, .set = evr_set
587 },
588#endif
589};
590
591static const struct user_regset_view user_ppc_compat_view = {
592 .name = "ppc", .e_machine = EM_PPC, .ei_osabi = ELF_OSABI,
593 .regsets = compat_regsets, .n = ARRAY_SIZE(compat_regsets)
594};
595#endif /* CONFIG_PPC64 */
596
597const struct user_regset_view *task_user_regset_view(struct task_struct *task)
598{
599#ifdef CONFIG_PPC64
600 if (test_tsk_thread_flag(task, TIF_32BIT))
601 return &user_ppc_compat_view;
602#endif
603 return &user_ppc_native_view;
255} 604}
256#endif /* CONFIG_SPE */
257 605
258 606
259void user_enable_single_step(struct task_struct *task) 607void user_enable_single_step(struct task_struct *task)
@@ -323,55 +671,29 @@ void ptrace_disable(struct task_struct *child)
323static long arch_ptrace_old(struct task_struct *child, long request, long addr, 671static long arch_ptrace_old(struct task_struct *child, long request, long addr,
324 long data) 672 long data)
325{ 673{
326 int ret = -EPERM; 674 switch (request) {
327 675 case PPC_PTRACE_GETREGS: /* Get GPRs 0 - 31. */
328 switch(request) { 676 return copy_regset_to_user(child, &user_ppc_native_view,
329 case PPC_PTRACE_GETREGS: { /* Get GPRs 0 - 31. */ 677 REGSET_GPR, 0, 32 * sizeof(long),
330 int i; 678 (void __user *) data);
331 unsigned long *reg = &((unsigned long *)child->thread.regs)[0]; 679
332 unsigned long __user *tmp = (unsigned long __user *)addr; 680 case PPC_PTRACE_SETREGS: /* Set GPRs 0 - 31. */
333 681 return copy_regset_from_user(child, &user_ppc_native_view,
334 CHECK_FULL_REGS(child->thread.regs); 682 REGSET_GPR, 0, 32 * sizeof(long),
335 for (i = 0; i < 32; i++) { 683 (const void __user *) data);
336 ret = put_user(*reg, tmp); 684
337 if (ret) 685 case PPC_PTRACE_GETFPREGS: /* Get FPRs 0 - 31. */
338 break; 686 return copy_regset_to_user(child, &user_ppc_native_view,
339 reg++; 687 REGSET_FPR, 0, 32 * sizeof(double),
340 tmp++; 688 (void __user *) data);
341 } 689
342 break; 690 case PPC_PTRACE_SETFPREGS: /* Set FPRs 0 - 31. */
343 } 691 return copy_regset_from_user(child, &user_ppc_native_view,
344 692 REGSET_FPR, 0, 32 * sizeof(double),
345 case PPC_PTRACE_SETREGS: { /* Set GPRs 0 - 31. */ 693 (const void __user *) data);
346 int i;
347 unsigned long *reg = &((unsigned long *)child->thread.regs)[0];
348 unsigned long __user *tmp = (unsigned long __user *)addr;
349
350 CHECK_FULL_REGS(child->thread.regs);
351 for (i = 0; i < 32; i++) {
352 ret = get_user(*reg, tmp);
353 if (ret)
354 break;
355 reg++;
356 tmp++;
357 }
358 break;
359 }
360
361 case PPC_PTRACE_GETFPREGS: { /* Get FPRs 0 - 31. */
362 flush_fp_to_thread(child);
363 ret = get_fpregs((void __user *)addr, child, 0);
364 break;
365 }
366
367 case PPC_PTRACE_SETFPREGS: { /* Get FPRs 0 - 31. */
368 flush_fp_to_thread(child);
369 ret = set_fpregs((void __user *)addr, child, 0);
370 break;
371 } 694 }
372 695
373 } 696 return -EPERM;
374 return ret;
375} 697}
376 698
377long arch_ptrace(struct task_struct *child, long request, long addr, long data) 699long arch_ptrace(struct task_struct *child, long request, long addr, long data)
@@ -379,12 +701,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
379 int ret = -EPERM; 701 int ret = -EPERM;
380 702
381 switch (request) { 703 switch (request) {
382 /* when I and D space are separate, these will need to be fixed. */
383 case PTRACE_PEEKTEXT: /* read word at location addr. */
384 case PTRACE_PEEKDATA:
385 ret = generic_ptrace_peekdata(child, addr, data);
386 break;
387
388 /* read the word at location addr in the USER area. */ 704 /* read the word at location addr in the USER area. */
389 case PTRACE_PEEKUSR: { 705 case PTRACE_PEEKUSR: {
390 unsigned long index, tmp; 706 unsigned long index, tmp;
@@ -412,12 +728,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
412 break; 728 break;
413 } 729 }
414 730
415 /* If I and D space are separate, this will have to be fixed. */
416 case PTRACE_POKETEXT: /* write the word at location addr. */
417 case PTRACE_POKEDATA:
418 ret = generic_ptrace_pokedata(child, addr, data);
419 break;
420
421 /* write the word at location addr in the USER area */ 731 /* write the word at location addr in the USER area */
422 case PTRACE_POKEUSR: { 732 case PTRACE_POKEUSR: {
423 unsigned long index; 733 unsigned long index;
@@ -462,85 +772,60 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
462#ifdef CONFIG_PPC64 772#ifdef CONFIG_PPC64
463 case PTRACE_GETREGS64: 773 case PTRACE_GETREGS64:
464#endif 774#endif
465 case PTRACE_GETREGS: { /* Get all pt_regs from the child. */ 775 case PTRACE_GETREGS: /* Get all pt_regs from the child. */
466 int ui; 776 return copy_regset_to_user(child, &user_ppc_native_view,
467 if (!access_ok(VERIFY_WRITE, (void __user *)data, 777 REGSET_GPR,
468 sizeof(struct pt_regs))) { 778 0, sizeof(struct pt_regs),
469 ret = -EIO; 779 (void __user *) data);
470 break;
471 }
472 CHECK_FULL_REGS(child->thread.regs);
473 ret = 0;
474 for (ui = 0; ui < PT_REGS_COUNT; ui ++) {
475 ret |= __put_user(ptrace_get_reg(child, ui),
476 (unsigned long __user *) data);
477 data += sizeof(long);
478 }
479 break;
480 }
481 780
482#ifdef CONFIG_PPC64 781#ifdef CONFIG_PPC64
483 case PTRACE_SETREGS64: 782 case PTRACE_SETREGS64:
484#endif 783#endif
485 case PTRACE_SETREGS: { /* Set all gp regs in the child. */ 784 case PTRACE_SETREGS: /* Set all gp regs in the child. */
486 unsigned long tmp; 785 return copy_regset_from_user(child, &user_ppc_native_view,
487 int ui; 786 REGSET_GPR,
488 if (!access_ok(VERIFY_READ, (void __user *)data, 787 0, sizeof(struct pt_regs),
489 sizeof(struct pt_regs))) { 788 (const void __user *) data);
490 ret = -EIO; 789
491 break; 790 case PTRACE_GETFPREGS: /* Get the child FPU state (FPR0...31 + FPSCR) */
492 } 791 return copy_regset_to_user(child, &user_ppc_native_view,
493 CHECK_FULL_REGS(child->thread.regs); 792 REGSET_FPR,
494 ret = 0; 793 0, sizeof(elf_fpregset_t),
495 for (ui = 0; ui < PT_REGS_COUNT; ui ++) { 794 (void __user *) data);
496 ret = __get_user(tmp, (unsigned long __user *) data); 795
497 if (ret) 796 case PTRACE_SETFPREGS: /* Set the child FPU state (FPR0...31 + FPSCR) */
498 break; 797 return copy_regset_from_user(child, &user_ppc_native_view,
499 ptrace_put_reg(child, ui, tmp); 798 REGSET_FPR,
500 data += sizeof(long); 799 0, sizeof(elf_fpregset_t),
501 } 800 (const void __user *) data);
502 break;
503 }
504
505 case PTRACE_GETFPREGS: { /* Get the child FPU state (FPR0...31 + FPSCR) */
506 flush_fp_to_thread(child);
507 ret = get_fpregs((void __user *)data, child, 1);
508 break;
509 }
510
511 case PTRACE_SETFPREGS: { /* Set the child FPU state (FPR0...31 + FPSCR) */
512 flush_fp_to_thread(child);
513 ret = set_fpregs((void __user *)data, child, 1);
514 break;
515 }
516 801
517#ifdef CONFIG_ALTIVEC 802#ifdef CONFIG_ALTIVEC
518 case PTRACE_GETVRREGS: 803 case PTRACE_GETVRREGS:
519 /* Get the child altivec register state. */ 804 return copy_regset_to_user(child, &user_ppc_native_view,
520 flush_altivec_to_thread(child); 805 REGSET_VMX,
521 ret = get_vrregs((unsigned long __user *)data, child); 806 0, (33 * sizeof(vector128) +
522 break; 807 sizeof(u32)),
808 (void __user *) data);
523 809
524 case PTRACE_SETVRREGS: 810 case PTRACE_SETVRREGS:
525 /* Set the child altivec register state. */ 811 return copy_regset_from_user(child, &user_ppc_native_view,
526 flush_altivec_to_thread(child); 812 REGSET_VMX,
527 ret = set_vrregs(child, (unsigned long __user *)data); 813 0, (33 * sizeof(vector128) +
528 break; 814 sizeof(u32)),
815 (const void __user *) data);
529#endif 816#endif
530#ifdef CONFIG_SPE 817#ifdef CONFIG_SPE
531 case PTRACE_GETEVRREGS: 818 case PTRACE_GETEVRREGS:
532 /* Get the child spe register state. */ 819 /* Get the child spe register state. */
533 flush_spe_to_thread(child); 820 return copy_regset_to_user(child, &user_ppc_native_view,
534 ret = get_evrregs((unsigned long __user *)data, child); 821 REGSET_SPE, 0, 35 * sizeof(u32),
535 break; 822 (void __user *) data);
536 823
537 case PTRACE_SETEVRREGS: 824 case PTRACE_SETEVRREGS:
538 /* Set the child spe register state. */ 825 /* Set the child spe register state. */
539 /* this is to clear the MSR_SPE bit to force a reload 826 return copy_regset_from_user(child, &user_ppc_native_view,
540 * of register state from memory */ 827 REGSET_SPE, 0, 35 * sizeof(u32),
541 flush_spe_to_thread(child); 828 (const void __user *) data);
542 ret = set_evrregs(child, (unsigned long __user *)data);
543 break;
544#endif 829#endif
545 830
546 /* Old reverse args ptrace callss */ 831 /* Old reverse args ptrace callss */
diff --git a/arch/powerpc/kernel/ptrace32.c b/arch/powerpc/kernel/ptrace32.c
index fea6206ff90f..4c1de6af4c09 100644
--- a/arch/powerpc/kernel/ptrace32.c
+++ b/arch/powerpc/kernel/ptrace32.c
@@ -24,9 +24,11 @@
24#include <linux/smp_lock.h> 24#include <linux/smp_lock.h>
25#include <linux/errno.h> 25#include <linux/errno.h>
26#include <linux/ptrace.h> 26#include <linux/ptrace.h>
27#include <linux/regset.h>
27#include <linux/user.h> 28#include <linux/user.h>
28#include <linux/security.h> 29#include <linux/security.h>
29#include <linux/signal.h> 30#include <linux/signal.h>
31#include <linux/compat.h>
30 32
31#include <asm/uaccess.h> 33#include <asm/uaccess.h>
32#include <asm/page.h> 34#include <asm/page.h>
@@ -45,87 +47,31 @@
45static long compat_ptrace_old(struct task_struct *child, long request, 47static long compat_ptrace_old(struct task_struct *child, long request,
46 long addr, long data) 48 long addr, long data)
47{ 49{
48 int ret = -EPERM; 50 switch (request) {
49 51 case PPC_PTRACE_GETREGS: /* Get GPRs 0 - 31. */
50 switch(request) { 52 return copy_regset_to_user(child,
51 case PPC_PTRACE_GETREGS: { /* Get GPRs 0 - 31. */ 53 task_user_regset_view(current), 0,
52 int i; 54 0, 32 * sizeof(compat_long_t),
53 unsigned long *reg = &((unsigned long *)child->thread.regs)[0]; 55 compat_ptr(data));
54 unsigned int __user *tmp = (unsigned int __user *)addr; 56
55 57 case PPC_PTRACE_SETREGS: /* Set GPRs 0 - 31. */
56 CHECK_FULL_REGS(child->thread.regs); 58 return copy_regset_from_user(child,
57 for (i = 0; i < 32; i++) { 59 task_user_regset_view(current), 0,
58 ret = put_user(*reg, tmp); 60 0, 32 * sizeof(compat_long_t),
59 if (ret) 61 compat_ptr(data));
60 break;
61 reg++;
62 tmp++;
63 }
64 break;
65 }
66
67 case PPC_PTRACE_SETREGS: { /* Set GPRs 0 - 31. */
68 int i;
69 unsigned long *reg = &((unsigned long *)child->thread.regs)[0];
70 unsigned int __user *tmp = (unsigned int __user *)addr;
71
72 CHECK_FULL_REGS(child->thread.regs);
73 for (i = 0; i < 32; i++) {
74 ret = get_user(*reg, tmp);
75 if (ret)
76 break;
77 reg++;
78 tmp++;
79 }
80 break;
81 } 62 }
82 63
83 } 64 return -EPERM;
84 return ret;
85} 65}
86 66
87long compat_sys_ptrace(int request, int pid, unsigned long addr, 67long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
88 unsigned long data) 68 compat_ulong_t caddr, compat_ulong_t cdata)
89{ 69{
90 struct task_struct *child; 70 unsigned long addr = caddr;
71 unsigned long data = cdata;
91 int ret; 72 int ret;
92 73
93 lock_kernel();
94 if (request == PTRACE_TRACEME) {
95 ret = ptrace_traceme();
96 goto out;
97 }
98
99 child = ptrace_get_task_struct(pid);
100 if (IS_ERR(child)) {
101 ret = PTR_ERR(child);
102 goto out;
103 }
104
105 if (request == PTRACE_ATTACH) {
106 ret = ptrace_attach(child);
107 goto out_tsk;
108 }
109
110 ret = ptrace_check_attach(child, request == PTRACE_KILL);
111 if (ret < 0)
112 goto out_tsk;
113
114 switch (request) { 74 switch (request) {
115 /* when I and D space are separate, these will need to be fixed. */
116 case PTRACE_PEEKTEXT: /* read word at location addr. */
117 case PTRACE_PEEKDATA: {
118 unsigned int tmp;
119 int copied;
120
121 copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
122 ret = -EIO;
123 if (copied != sizeof(tmp))
124 break;
125 ret = put_user(tmp, (u32 __user *)data);
126 break;
127 }
128
129 /* 75 /*
130 * Read 4 bytes of the other process' storage 76 * Read 4 bytes of the other process' storage
131 * data is a pointer specifying where the user wants the 77 * data is a pointer specifying where the user wants the
@@ -225,19 +171,6 @@ long compat_sys_ptrace(int request, int pid, unsigned long addr,
225 break; 171 break;
226 } 172 }
227 173
228 /* If I and D space are separate, this will have to be fixed. */
229 case PTRACE_POKETEXT: /* write the word at location addr. */
230 case PTRACE_POKEDATA: {
231 unsigned int tmp;
232 tmp = data;
233 ret = 0;
234 if (access_process_vm(child, addr, &tmp, sizeof(tmp), 1)
235 == sizeof(tmp))
236 break;
237 ret = -EIO;
238 break;
239 }
240
241 /* 174 /*
242 * Write 4 bytes into the other process' storage 175 * Write 4 bytes into the other process' storage
243 * data is the 4 bytes that the user wants written 176 * data is the 4 bytes that the user wants written
@@ -337,46 +270,17 @@ long compat_sys_ptrace(int request, int pid, unsigned long addr,
337 break; 270 break;
338 } 271 }
339 272
340 case PTRACE_GETEVENTMSG: 273 case PTRACE_GETREGS: /* Get all pt_regs from the child. */
341 ret = put_user(child->ptrace_message, (unsigned int __user *) data); 274 return copy_regset_to_user(
342 break; 275 child, task_user_regset_view(current), 0,
276 0, PT_REGS_COUNT * sizeof(compat_long_t),
277 compat_ptr(data));
343 278
344 case PTRACE_GETREGS: { /* Get all pt_regs from the child. */ 279 case PTRACE_SETREGS: /* Set all gp regs in the child. */
345 int ui; 280 return copy_regset_from_user(
346 if (!access_ok(VERIFY_WRITE, (void __user *)data, 281 child, task_user_regset_view(current), 0,
347 PT_REGS_COUNT * sizeof(int))) { 282 0, PT_REGS_COUNT * sizeof(compat_long_t),
348 ret = -EIO; 283 compat_ptr(data));
349 break;
350 }
351 CHECK_FULL_REGS(child->thread.regs);
352 ret = 0;
353 for (ui = 0; ui < PT_REGS_COUNT; ui ++) {
354 ret |= __put_user(ptrace_get_reg(child, ui),
355 (unsigned int __user *) data);
356 data += sizeof(int);
357 }
358 break;
359 }
360
361 case PTRACE_SETREGS: { /* Set all gp regs in the child. */
362 unsigned long tmp;
363 int ui;
364 if (!access_ok(VERIFY_READ, (void __user *)data,
365 PT_REGS_COUNT * sizeof(int))) {
366 ret = -EIO;
367 break;
368 }
369 CHECK_FULL_REGS(child->thread.regs);
370 ret = 0;
371 for (ui = 0; ui < PT_REGS_COUNT; ui ++) {
372 ret = __get_user(tmp, (unsigned int __user *) data);
373 if (ret)
374 break;
375 ptrace_put_reg(child, ui, tmp);
376 data += sizeof(int);
377 }
378 break;
379 }
380 284
381 case PTRACE_GETFPREGS: 285 case PTRACE_GETFPREGS:
382 case PTRACE_SETFPREGS: 286 case PTRACE_SETFPREGS:
@@ -402,12 +306,9 @@ long compat_sys_ptrace(int request, int pid, unsigned long addr,
402 break; 306 break;
403 307
404 default: 308 default:
405 ret = ptrace_request(child, request, addr, data); 309 ret = compat_ptrace_request(child, request, addr, data);
406 break; 310 break;
407 } 311 }
408out_tsk: 312
409 put_task_struct(child);
410out:
411 unlock_kernel();
412 return ret; 313 return ret;
413} 314}
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 848a20475db8..4b5b7ff4f78b 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -54,7 +54,7 @@
54#endif 54#endif
55#include <asm/kexec.h> 55#include <asm/kexec.h>
56 56
57#ifdef CONFIG_DEBUGGER 57#if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC)
58int (*__debugger)(struct pt_regs *regs); 58int (*__debugger)(struct pt_regs *regs);
59int (*__debugger_ipi)(struct pt_regs *regs); 59int (*__debugger_ipi)(struct pt_regs *regs);
60int (*__debugger_bpt)(struct pt_regs *regs); 60int (*__debugger_bpt)(struct pt_regs *regs);
diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c
index f0bad7070fb5..f98867252ee2 100644
--- a/arch/powerpc/kernel/vio.c
+++ b/arch/powerpc/kernel/vio.c
@@ -176,7 +176,7 @@ static void __devinit vio_dev_release(struct device *dev)
176 * Returns a pointer to the created vio_dev or NULL if node has 176 * Returns a pointer to the created vio_dev or NULL if node has
177 * NULL device_type or compatible fields. 177 * NULL device_type or compatible fields.
178 */ 178 */
179struct vio_dev * __devinit vio_register_device_node(struct device_node *of_node) 179struct vio_dev *vio_register_device_node(struct device_node *of_node)
180{ 180{
181 struct vio_dev *viodev; 181 struct vio_dev *viodev;
182 const unsigned int *unit_address; 182 const unsigned int *unit_address;
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index ff5debf5eedd..93a5c53e3423 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -485,7 +485,12 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address,
485 */ 485 */
486 _tlbie(address, 0 /* 8xx doesn't care about PID */); 486 _tlbie(address, 0 /* 8xx doesn't care about PID */);
487#endif 487#endif
488 if (!PageReserved(page) 488 /* The _PAGE_USER test should really be _PAGE_EXEC, but
489 * older glibc versions execute some code from no-exec
490 * pages, which for now we are supporting. If exec-only
491 * pages are ever implemented, this will have to change.
492 */
493 if (!PageReserved(page) && (pte_val(pte) & _PAGE_USER)
489 && !test_bit(PG_arch_1, &page->flags)) { 494 && !test_bit(PG_arch_1, &page->flags)) {
490 if (vma->vm_mm == current->active_mm) { 495 if (vma->vm_mm == current->active_mm) {
491 __flush_dcache_icache((void *) address); 496 __flush_dcache_icache((void *) address);
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index bc60322d2436..a300d254aac6 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -24,6 +24,8 @@
24 24
25static int numa_enabled = 1; 25static int numa_enabled = 1;
26 26
27static char *cmdline __initdata;
28
27static int numa_debug; 29static int numa_debug;
28#define dbg(args...) if (numa_debug) { printk(KERN_INFO args); } 30#define dbg(args...) if (numa_debug) { printk(KERN_INFO args); }
29 31
@@ -39,6 +41,53 @@ static bootmem_data_t __initdata plat_node_bdata[MAX_NUMNODES];
39static int min_common_depth; 41static int min_common_depth;
40static int n_mem_addr_cells, n_mem_size_cells; 42static int n_mem_addr_cells, n_mem_size_cells;
41 43
44static int __cpuinit fake_numa_create_new_node(unsigned long end_pfn,
45 unsigned int *nid)
46{
47 unsigned long long mem;
48 char *p = cmdline;
49 static unsigned int fake_nid;
50 static unsigned long long curr_boundary;
51
52 /*
53 * Modify node id, iff we started creating NUMA nodes
54 * We want to continue from where we left of the last time
55 */
56 if (fake_nid)
57 *nid = fake_nid;
58 /*
59 * In case there are no more arguments to parse, the
60 * node_id should be the same as the last fake node id
61 * (we've handled this above).
62 */
63 if (!p)
64 return 0;
65
66 mem = memparse(p, &p);
67 if (!mem)
68 return 0;
69
70 if (mem < curr_boundary)
71 return 0;
72
73 curr_boundary = mem;
74
75 if ((end_pfn << PAGE_SHIFT) > mem) {
76 /*
77 * Skip commas and spaces
78 */
79 while (*p == ',' || *p == ' ' || *p == '\t')
80 p++;
81
82 cmdline = p;
83 fake_nid++;
84 *nid = fake_nid;
85 dbg("created new fake_node with id %d\n", fake_nid);
86 return 1;
87 }
88 return 0;
89}
90
42static void __cpuinit map_cpu_to_node(int cpu, int node) 91static void __cpuinit map_cpu_to_node(int cpu, int node)
43{ 92{
44 numa_cpu_lookup_table[cpu] = node; 93 numa_cpu_lookup_table[cpu] = node;
@@ -344,6 +393,9 @@ static void __init parse_drconf_memory(struct device_node *memory)
344 if (nid == 0xffff || nid >= MAX_NUMNODES) 393 if (nid == 0xffff || nid >= MAX_NUMNODES)
345 nid = default_nid; 394 nid = default_nid;
346 } 395 }
396
397 fake_numa_create_new_node(((start + lmb_size) >> PAGE_SHIFT),
398 &nid);
347 node_set_online(nid); 399 node_set_online(nid);
348 400
349 size = numa_enforce_memory_limit(start, lmb_size); 401 size = numa_enforce_memory_limit(start, lmb_size);
@@ -429,6 +481,8 @@ new_range:
429 nid = of_node_to_nid_single(memory); 481 nid = of_node_to_nid_single(memory);
430 if (nid < 0) 482 if (nid < 0)
431 nid = default_nid; 483 nid = default_nid;
484
485 fake_numa_create_new_node(((start + size) >> PAGE_SHIFT), &nid);
432 node_set_online(nid); 486 node_set_online(nid);
433 487
434 if (!(size = numa_enforce_memory_limit(start, size))) { 488 if (!(size = numa_enforce_memory_limit(start, size))) {
@@ -461,7 +515,7 @@ static void __init setup_nonnuma(void)
461 unsigned long top_of_ram = lmb_end_of_DRAM(); 515 unsigned long top_of_ram = lmb_end_of_DRAM();
462 unsigned long total_ram = lmb_phys_mem_size(); 516 unsigned long total_ram = lmb_phys_mem_size();
463 unsigned long start_pfn, end_pfn; 517 unsigned long start_pfn, end_pfn;
464 unsigned int i; 518 unsigned int i, nid = 0;
465 519
466 printk(KERN_DEBUG "Top of RAM: 0x%lx, Total RAM: 0x%lx\n", 520 printk(KERN_DEBUG "Top of RAM: 0x%lx, Total RAM: 0x%lx\n",
467 top_of_ram, total_ram); 521 top_of_ram, total_ram);
@@ -471,9 +525,11 @@ static void __init setup_nonnuma(void)
471 for (i = 0; i < lmb.memory.cnt; ++i) { 525 for (i = 0; i < lmb.memory.cnt; ++i) {
472 start_pfn = lmb.memory.region[i].base >> PAGE_SHIFT; 526 start_pfn = lmb.memory.region[i].base >> PAGE_SHIFT;
473 end_pfn = start_pfn + lmb_size_pages(&lmb.memory, i); 527 end_pfn = start_pfn + lmb_size_pages(&lmb.memory, i);
474 add_active_range(0, start_pfn, end_pfn); 528
529 fake_numa_create_new_node(end_pfn, &nid);
530 add_active_range(nid, start_pfn, end_pfn);
531 node_set_online(nid);
475 } 532 }
476 node_set_online(0);
477} 533}
478 534
479void __init dump_numa_cpu_topology(void) 535void __init dump_numa_cpu_topology(void)
@@ -702,6 +758,10 @@ static int __init early_numa(char *p)
702 if (strstr(p, "debug")) 758 if (strstr(p, "debug"))
703 numa_debug = 1; 759 numa_debug = 1;
704 760
761 p = strstr(p, "fake=");
762 if (p)
763 cmdline = p + strlen("fake=");
764
705 return 0; 765 return 0;
706} 766}
707early_param("numa", early_numa); 767early_param("numa", early_numa);
diff --git a/arch/powerpc/oprofile/Makefile b/arch/powerpc/oprofile/Makefile
index c5f64c3bd668..2ef6b0dddd8c 100644
--- a/arch/powerpc/oprofile/Makefile
+++ b/arch/powerpc/oprofile/Makefile
@@ -15,5 +15,5 @@ oprofile-$(CONFIG_OPROFILE_CELL) += op_model_cell.o \
15 cell/spu_profiler.o cell/vma_map.o \ 15 cell/spu_profiler.o cell/vma_map.o \
16 cell/spu_task_sync.o 16 cell/spu_task_sync.o
17oprofile-$(CONFIG_PPC64) += op_model_rs64.o op_model_power4.o op_model_pa6t.o 17oprofile-$(CONFIG_PPC64) += op_model_rs64.o op_model_power4.o op_model_pa6t.o
18oprofile-$(CONFIG_FSL_BOOKE) += op_model_fsl_booke.o 18oprofile-$(CONFIG_FSL_EMB_PERFMON) += op_model_fsl_emb.o
19oprofile-$(CONFIG_6xx) += op_model_7450.o 19oprofile-$(CONFIG_6xx) += op_model_7450.o
diff --git a/arch/powerpc/oprofile/common.c b/arch/powerpc/oprofile/common.c
index a28cce1d6c24..4908dc98f9ca 100644
--- a/arch/powerpc/oprofile/common.c
+++ b/arch/powerpc/oprofile/common.c
@@ -202,9 +202,9 @@ int __init oprofile_arch_init(struct oprofile_operations *ops)
202 model = &op_model_7450; 202 model = &op_model_7450;
203 break; 203 break;
204#endif 204#endif
205#ifdef CONFIG_FSL_BOOKE 205#if defined(CONFIG_FSL_EMB_PERFMON)
206 case PPC_OPROFILE_BOOKE: 206 case PPC_OPROFILE_FSL_EMB:
207 model = &op_model_fsl_booke; 207 model = &op_model_fsl_emb;
208 break; 208 break;
209#endif 209#endif
210 default: 210 default:
diff --git a/arch/powerpc/oprofile/op_model_fsl_booke.c b/arch/powerpc/oprofile/op_model_fsl_emb.c
index 183a28bb1812..91596f6ba1f4 100644
--- a/arch/powerpc/oprofile/op_model_fsl_booke.c
+++ b/arch/powerpc/oprofile/op_model_fsl_emb.c
@@ -1,7 +1,5 @@
1/* 1/*
2 * arch/powerpc/oprofile/op_model_fsl_booke.c 2 * Freescale Embedded oprofile support, based on ppc64 oprofile support
3 *
4 * Freescale Book-E oprofile support, based on ppc64 oprofile support
5 * Copyright (C) 2004 Anton Blanchard <anton@au.ibm.com>, IBM 3 * Copyright (C) 2004 Anton Blanchard <anton@au.ibm.com>, IBM
6 * 4 *
7 * Copyright (c) 2004 Freescale Semiconductor, Inc 5 * Copyright (c) 2004 Freescale Semiconductor, Inc
@@ -22,7 +20,7 @@
22#include <asm/system.h> 20#include <asm/system.h>
23#include <asm/processor.h> 21#include <asm/processor.h>
24#include <asm/cputable.h> 22#include <asm/cputable.h>
25#include <asm/reg_booke.h> 23#include <asm/reg_fsl_emb.h>
26#include <asm/page.h> 24#include <asm/page.h>
27#include <asm/pmc.h> 25#include <asm/pmc.h>
28#include <asm/oprofile_impl.h> 26#include <asm/oprofile_impl.h>
@@ -244,7 +242,7 @@ static void dump_pmcs(void)
244 mfpmr(PMRN_PMLCA3), mfpmr(PMRN_PMLCB3)); 242 mfpmr(PMRN_PMLCA3), mfpmr(PMRN_PMLCB3));
245} 243}
246 244
247static int fsl_booke_cpu_setup(struct op_counter_config *ctr) 245static int fsl_emb_cpu_setup(struct op_counter_config *ctr)
248{ 246{
249 int i; 247 int i;
250 248
@@ -262,7 +260,7 @@ static int fsl_booke_cpu_setup(struct op_counter_config *ctr)
262 return 0; 260 return 0;
263} 261}
264 262
265static int fsl_booke_reg_setup(struct op_counter_config *ctr, 263static int fsl_emb_reg_setup(struct op_counter_config *ctr,
266 struct op_system_config *sys, 264 struct op_system_config *sys,
267 int num_ctrs) 265 int num_ctrs)
268{ 266{
@@ -281,7 +279,7 @@ static int fsl_booke_reg_setup(struct op_counter_config *ctr,
281 return 0; 279 return 0;
282} 280}
283 281
284static int fsl_booke_start(struct op_counter_config *ctr) 282static int fsl_emb_start(struct op_counter_config *ctr)
285{ 283{
286 int i; 284 int i;
287 285
@@ -315,7 +313,7 @@ static int fsl_booke_start(struct op_counter_config *ctr)
315 return 0; 313 return 0;
316} 314}
317 315
318static void fsl_booke_stop(void) 316static void fsl_emb_stop(void)
319{ 317{
320 /* freeze counters */ 318 /* freeze counters */
321 pmc_stop_ctrs(); 319 pmc_stop_ctrs();
@@ -329,7 +327,7 @@ static void fsl_booke_stop(void)
329} 327}
330 328
331 329
332static void fsl_booke_handle_interrupt(struct pt_regs *regs, 330static void fsl_emb_handle_interrupt(struct pt_regs *regs,
333 struct op_counter_config *ctr) 331 struct op_counter_config *ctr)
334{ 332{
335 unsigned long pc; 333 unsigned long pc;
@@ -362,10 +360,10 @@ static void fsl_booke_handle_interrupt(struct pt_regs *regs,
362 pmc_start_ctrs(1); 360 pmc_start_ctrs(1);
363} 361}
364 362
365struct op_powerpc_model op_model_fsl_booke = { 363struct op_powerpc_model op_model_fsl_emb = {
366 .reg_setup = fsl_booke_reg_setup, 364 .reg_setup = fsl_emb_reg_setup,
367 .cpu_setup = fsl_booke_cpu_setup, 365 .cpu_setup = fsl_emb_cpu_setup,
368 .start = fsl_booke_start, 366 .start = fsl_emb_start,
369 .stop = fsl_booke_stop, 367 .stop = fsl_emb_stop,
370 .handle_interrupt = fsl_booke_handle_interrupt, 368 .handle_interrupt = fsl_emb_handle_interrupt,
371}; 369};
diff --git a/arch/powerpc/platforms/40x/Kconfig b/arch/powerpc/platforms/40x/Kconfig
index 74f31177e47a..a9260e21451e 100644
--- a/arch/powerpc/platforms/40x/Kconfig
+++ b/arch/powerpc/platforms/40x/Kconfig
@@ -72,6 +72,7 @@ config WALNUT
72 default y 72 default y
73 select 405GP 73 select 405GP
74 select PCI 74 select PCI
75 select OF_RTC
75 help 76 help
76 This option enables support for the IBM PPC405GP evaluation board. 77 This option enables support for the IBM PPC405GP evaluation board.
77 78
diff --git a/arch/powerpc/platforms/40x/virtex.c b/arch/powerpc/platforms/40x/virtex.c
index 88b66444dfb2..0422590040db 100644
--- a/arch/powerpc/platforms/40x/virtex.c
+++ b/arch/powerpc/platforms/40x/virtex.c
@@ -37,7 +37,7 @@ static int __init virtex_probe(void)
37{ 37{
38 unsigned long root = of_get_flat_dt_root(); 38 unsigned long root = of_get_flat_dt_root();
39 39
40 if (!of_flat_dt_is_compatible(root, "xilinx,virtex")) 40 if (!of_flat_dt_is_compatible(root, "xlnx,virtex"))
41 return 0; 41 return 0;
42 42
43 return 1; 43 return 1;
diff --git a/arch/powerpc/platforms/40x/walnut.c b/arch/powerpc/platforms/40x/walnut.c
index 5d9edd917f92..b8b257efeb77 100644
--- a/arch/powerpc/platforms/40x/walnut.c
+++ b/arch/powerpc/platforms/40x/walnut.c
@@ -18,6 +18,7 @@
18 18
19#include <linux/init.h> 19#include <linux/init.h>
20#include <linux/of_platform.h> 20#include <linux/of_platform.h>
21#include <linux/rtc.h>
21 22
22#include <asm/machdep.h> 23#include <asm/machdep.h>
23#include <asm/prom.h> 24#include <asm/prom.h>
diff --git a/arch/powerpc/platforms/44x/warp.c b/arch/powerpc/platforms/44x/warp.c
index 8f01563dbd2a..da5b7b7599db 100644
--- a/arch/powerpc/platforms/44x/warp.c
+++ b/arch/powerpc/platforms/44x/warp.c
@@ -137,7 +137,7 @@ static int __init pika_dtm_start(void)
137 } 137 }
138 of_node_put(np); 138 of_node_put(np);
139 139
140 fpga = ioremap(res.start + 0x20, 4); 140 fpga = ioremap(res.start, 0x24);
141 if (fpga == NULL) 141 if (fpga == NULL)
142 return -ENOENT; 142 return -ENOENT;
143 143
diff --git a/arch/powerpc/platforms/512x/Kconfig b/arch/powerpc/platforms/512x/Kconfig
new file mode 100644
index 000000000000..c6fa49e23dc0
--- /dev/null
+++ b/arch/powerpc/platforms/512x/Kconfig
@@ -0,0 +1,20 @@
1config PPC_MPC512x
2 bool
3 select FSL_SOC
4 select IPIC
5 default n
6
7config PPC_MPC5121
8 bool
9 select PPC_MPC512x
10 default n
11
12config MPC5121_ADS
13 bool "Freescale MPC5121E ADS"
14 depends on PPC_MULTIPLATFORM && PPC32
15 select DEFAULT_UIMAGE
16 select WANT_DEVICE_TREE
17 select PPC_MPC5121
18 help
19 This option enables support for the MPC5121E ADS board.
20 default n
diff --git a/arch/powerpc/platforms/512x/Makefile b/arch/powerpc/platforms/512x/Makefile
new file mode 100644
index 000000000000..232c89f2039a
--- /dev/null
+++ b/arch/powerpc/platforms/512x/Makefile
@@ -0,0 +1,4 @@
1#
2# Makefile for the Freescale PowerPC 512x linux kernel.
3#
4obj-$(CONFIG_MPC5121_ADS) += mpc5121_ads.o
diff --git a/arch/powerpc/platforms/512x/mpc5121_ads.c b/arch/powerpc/platforms/512x/mpc5121_ads.c
new file mode 100644
index 000000000000..50bd3a319022
--- /dev/null
+++ b/arch/powerpc/platforms/512x/mpc5121_ads.c
@@ -0,0 +1,104 @@
1/*
2 * Copyright (C) 2007 Freescale Semiconductor, Inc. All rights reserved.
3 *
4 * Author: John Rigby, <jrigby@freescale.com>, Thur Mar 29 2007
5 *
6 * Description:
7 * MPC5121 ADS board setup
8 *
9 * This is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 */
15
16#include <linux/kernel.h>
17#include <linux/io.h>
18#include <linux/irq.h>
19#include <linux/of_platform.h>
20
21#include <asm/machdep.h>
22#include <asm/ipic.h>
23#include <asm/prom.h>
24#include <asm/time.h>
25
26/**
27 * mpc512x_find_ips_freq - Find the IPS bus frequency for a device
28 * @node: device node
29 *
30 * Returns IPS bus frequency, or 0 if the bus frequency cannot be found.
31 */
32unsigned long
33mpc512x_find_ips_freq(struct device_node *node)
34{
35 struct device_node *np;
36 const unsigned int *p_ips_freq = NULL;
37
38 of_node_get(node);
39 while (node) {
40 p_ips_freq = of_get_property(node, "bus-frequency", NULL);
41 if (p_ips_freq)
42 break;
43
44 np = of_get_parent(node);
45 of_node_put(node);
46 node = np;
47 }
48 if (node)
49 of_node_put(node);
50
51 return p_ips_freq ? *p_ips_freq : 0;
52}
53EXPORT_SYMBOL(mpc512x_find_ips_freq);
54
55static struct of_device_id __initdata of_bus_ids[] = {
56 { .name = "soc", },
57 { .name = "localbus", },
58 {},
59};
60
61static void __init mpc5121_ads_declare_of_platform_devices(void)
62{
63 /* Find every child of the SOC node and add it to of_platform */
64 if (of_platform_bus_probe(NULL, of_bus_ids, NULL))
65 printk(KERN_ERR __FILE__ ": "
66 "Error while probing of_platform bus\n");
67}
68
69static void __init mpc5121_ads_init_IRQ(void)
70{
71 struct device_node *np;
72
73 np = of_find_compatible_node(NULL, NULL, "fsl,ipic");
74 if (!np)
75 return;
76
77 ipic_init(np, 0);
78 of_node_put(np);
79
80 /*
81 * Initialize the default interrupt mapping priorities,
82 * in case the boot rom changed something on us.
83 */
84 ipic_set_default_priority();
85}
86
87/*
88 * Called very early, MMU is off, device-tree isn't unflattened
89 */
90static int __init mpc5121_ads_probe(void)
91{
92 unsigned long root = of_get_flat_dt_root();
93
94 return of_flat_dt_is_compatible(root, "fsl,mpc5121ads");
95}
96
97define_machine(mpc5121_ads) {
98 .name = "MPC5121 ADS",
99 .probe = mpc5121_ads_probe,
100 .init = mpc5121_ads_declare_of_platform_devices,
101 .init_IRQ = mpc5121_ads_init_IRQ,
102 .get_irq = ipic_get_irq,
103 .calibrate_decr = generic_calibrate_decr,
104};
diff --git a/arch/powerpc/platforms/82xx/mpc8272_ads.c b/arch/powerpc/platforms/82xx/mpc8272_ads.c
index 3fce6b375dbc..7d3018751988 100644
--- a/arch/powerpc/platforms/82xx/mpc8272_ads.c
+++ b/arch/powerpc/platforms/82xx/mpc8272_ads.c
@@ -134,13 +134,12 @@ static void __init mpc8272_ads_setup_arch(void)
134 } 134 }
135 135
136 bcsr = of_iomap(np, 0); 136 bcsr = of_iomap(np, 0);
137 of_node_put(np);
137 if (!bcsr) { 138 if (!bcsr) {
138 printk(KERN_ERR "Cannot map BCSR registers\n"); 139 printk(KERN_ERR "Cannot map BCSR registers\n");
139 return; 140 return;
140 } 141 }
141 142
142 of_node_put(np);
143
144 clrbits32(&bcsr[1], BCSR1_RS232_EN1 | BCSR1_RS232_EN2 | BCSR1_FETHIEN); 143 clrbits32(&bcsr[1], BCSR1_RS232_EN1 | BCSR1_RS232_EN2 | BCSR1_FETHIEN);
145 setbits32(&bcsr[1], BCSR1_FETH_RST); 144 setbits32(&bcsr[1], BCSR1_FETH_RST);
146 145
diff --git a/arch/powerpc/platforms/82xx/pq2fads.c b/arch/powerpc/platforms/82xx/pq2fads.c
index 68196e349994..e1dceeec4994 100644
--- a/arch/powerpc/platforms/82xx/pq2fads.c
+++ b/arch/powerpc/platforms/82xx/pq2fads.c
@@ -130,13 +130,12 @@ static void __init pq2fads_setup_arch(void)
130 } 130 }
131 131
132 bcsr = of_iomap(np, 0); 132 bcsr = of_iomap(np, 0);
133 of_node_put(np);
133 if (!bcsr) { 134 if (!bcsr) {
134 printk(KERN_ERR "Cannot map BCSR registers\n"); 135 printk(KERN_ERR "Cannot map BCSR registers\n");
135 return; 136 return;
136 } 137 }
137 138
138 of_node_put(np);
139
140 /* Enable the serial and ethernet ports */ 139 /* Enable the serial and ethernet ports */
141 140
142 clrbits32(&bcsr[1], BCSR1_RS232_EN1 | BCSR1_RS232_EN2 | BCSR1_FETHIEN); 141 clrbits32(&bcsr[1], BCSR1_RS232_EN1 | BCSR1_RS232_EN2 | BCSR1_FETHIEN);
diff --git a/arch/powerpc/platforms/83xx/mpc832x_rdb.c b/arch/powerpc/platforms/83xx/mpc832x_rdb.c
index 9f0fd88b2b1f..e7f706b624fe 100644
--- a/arch/powerpc/platforms/83xx/mpc832x_rdb.c
+++ b/arch/powerpc/platforms/83xx/mpc832x_rdb.c
@@ -101,7 +101,7 @@ static void __init mpc832x_rdb_setup_arch(void)
101#ifdef CONFIG_QUICC_ENGINE 101#ifdef CONFIG_QUICC_ENGINE
102 qe_reset(); 102 qe_reset();
103 103
104 if ((np = of_find_node_by_name(np, "par_io")) != NULL) { 104 if ((np = of_find_node_by_name(NULL, "par_io")) != NULL) {
105 par_io_init(np); 105 par_io_init(np);
106 of_node_put(np); 106 of_node_put(np);
107 107
diff --git a/arch/powerpc/platforms/83xx/mpc83xx.h b/arch/powerpc/platforms/83xx/mpc83xx.h
index 88bb748aff0d..68065e62fc3d 100644
--- a/arch/powerpc/platforms/83xx/mpc83xx.h
+++ b/arch/powerpc/platforms/83xx/mpc83xx.h
@@ -14,6 +14,8 @@
14#define MPC83XX_SCCR_USB_DRCM_11 0x00300000 14#define MPC83XX_SCCR_USB_DRCM_11 0x00300000
15#define MPC83XX_SCCR_USB_DRCM_01 0x00100000 15#define MPC83XX_SCCR_USB_DRCM_01 0x00100000
16#define MPC83XX_SCCR_USB_DRCM_10 0x00200000 16#define MPC83XX_SCCR_USB_DRCM_10 0x00200000
17#define MPC8315_SCCR_USB_MASK 0x00c00000
18#define MPC8315_SCCR_USB_DRCM_11 0x00c00000
17#define MPC837X_SCCR_USB_DRCM_11 0x00c00000 19#define MPC837X_SCCR_USB_DRCM_11 0x00c00000
18 20
19/* system i/o configuration register low */ 21/* system i/o configuration register low */
diff --git a/arch/powerpc/platforms/83xx/usb.c b/arch/powerpc/platforms/83xx/usb.c
index 681230a30acd..471fdd8f4108 100644
--- a/arch/powerpc/platforms/83xx/usb.c
+++ b/arch/powerpc/platforms/83xx/usb.c
@@ -104,6 +104,7 @@ int mpc831x_usb_cfg(void)
104 u32 temp; 104 u32 temp;
105 void __iomem *immap, *usb_regs; 105 void __iomem *immap, *usb_regs;
106 struct device_node *np = NULL; 106 struct device_node *np = NULL;
107 struct device_node *immr_node = NULL;
107 const void *prop; 108 const void *prop;
108 struct resource res; 109 struct resource res;
109 int ret = 0; 110 int ret = 0;
@@ -124,10 +125,15 @@ int mpc831x_usb_cfg(void)
124 } 125 }
125 126
126 /* Configure clock */ 127 /* Configure clock */
127 temp = in_be32(immap + MPC83XX_SCCR_OFFS); 128 immr_node = of_get_parent(np);
128 temp &= ~MPC83XX_SCCR_USB_MASK; 129 if (immr_node && of_device_is_compatible(immr_node, "fsl,mpc8315-immr"))
129 temp |= MPC83XX_SCCR_USB_DRCM_11; /* 1:3 */ 130 clrsetbits_be32(immap + MPC83XX_SCCR_OFFS,
130 out_be32(immap + MPC83XX_SCCR_OFFS, temp); 131 MPC8315_SCCR_USB_MASK,
132 MPC8315_SCCR_USB_DRCM_11);
133 else
134 clrsetbits_be32(immap + MPC83XX_SCCR_OFFS,
135 MPC83XX_SCCR_USB_MASK,
136 MPC83XX_SCCR_USB_DRCM_11);
131 137
132 /* Configure pin mux for ULPI. There is no pin mux for UTMI */ 138 /* Configure pin mux for ULPI. There is no pin mux for UTMI */
133 if (prop && !strcmp(prop, "ulpi")) { 139 if (prop && !strcmp(prop, "ulpi")) {
@@ -144,6 +150,9 @@ int mpc831x_usb_cfg(void)
144 150
145 iounmap(immap); 151 iounmap(immap);
146 152
153 if (immr_node)
154 of_node_put(immr_node);
155
147 /* Map USB SOC space */ 156 /* Map USB SOC space */
148 ret = of_address_to_resource(np, 0, &res); 157 ret = of_address_to_resource(np, 0, &res);
149 if (ret) { 158 if (ret) {
diff --git a/arch/powerpc/platforms/8xx/adder875.c b/arch/powerpc/platforms/8xx/adder875.c
index c6bc0783c3b0..82363e98f50e 100644
--- a/arch/powerpc/platforms/8xx/adder875.c
+++ b/arch/powerpc/platforms/8xx/adder875.c
@@ -15,12 +15,12 @@
15 15
16#include <asm/time.h> 16#include <asm/time.h>
17#include <asm/machdep.h> 17#include <asm/machdep.h>
18#include <asm/commproc.h> 18#include <asm/cpm1.h>
19#include <asm/fs_pd.h> 19#include <asm/fs_pd.h>
20#include <asm/udbg.h> 20#include <asm/udbg.h>
21#include <asm/prom.h> 21#include <asm/prom.h>
22 22
23#include <sysdev/commproc.h> 23#include "mpc8xx.h"
24 24
25struct cpm_pin { 25struct cpm_pin {
26 int port, pin, flags; 26 int port, pin, flags;
@@ -108,7 +108,7 @@ define_machine(adder875) {
108 .name = "Adder MPC875", 108 .name = "Adder MPC875",
109 .probe = adder875_probe, 109 .probe = adder875_probe,
110 .setup_arch = adder875_setup, 110 .setup_arch = adder875_setup,
111 .init_IRQ = m8xx_pic_init, 111 .init_IRQ = mpc8xx_pics_init,
112 .get_irq = mpc8xx_get_irq, 112 .get_irq = mpc8xx_get_irq,
113 .restart = mpc8xx_restart, 113 .restart = mpc8xx_restart,
114 .calibrate_decr = generic_calibrate_decr, 114 .calibrate_decr = generic_calibrate_decr,
diff --git a/arch/powerpc/platforms/8xx/ep88xc.c b/arch/powerpc/platforms/8xx/ep88xc.c
index a8dffa005775..7d9ac6040d63 100644
--- a/arch/powerpc/platforms/8xx/ep88xc.c
+++ b/arch/powerpc/platforms/8xx/ep88xc.c
@@ -15,7 +15,6 @@
15#include <asm/machdep.h> 15#include <asm/machdep.h>
16#include <asm/io.h> 16#include <asm/io.h>
17#include <asm/udbg.h> 17#include <asm/udbg.h>
18#include <asm/commproc.h>
19#include <asm/cpm1.h> 18#include <asm/cpm1.h>
20 19
21#include "mpc8xx.h" 20#include "mpc8xx.h"
diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig
index fdce10c4f074..fcedbec07f94 100644
--- a/arch/powerpc/platforms/Kconfig
+++ b/arch/powerpc/platforms/Kconfig
@@ -24,6 +24,7 @@ config PPC_83xx
24 select MPC83xx 24 select MPC83xx
25 select IPIC 25 select IPIC
26 select WANT_DEVICE_TREE 26 select WANT_DEVICE_TREE
27 select FSL_EMB_PERFMON
27 28
28config PPC_86xx 29config PPC_86xx
29 bool "Freescale 86xx" 30 bool "Freescale 86xx"
@@ -41,6 +42,7 @@ config CLASSIC32
41source "arch/powerpc/platforms/pseries/Kconfig" 42source "arch/powerpc/platforms/pseries/Kconfig"
42source "arch/powerpc/platforms/iseries/Kconfig" 43source "arch/powerpc/platforms/iseries/Kconfig"
43source "arch/powerpc/platforms/chrp/Kconfig" 44source "arch/powerpc/platforms/chrp/Kconfig"
45source "arch/powerpc/platforms/512x/Kconfig"
44source "arch/powerpc/platforms/52xx/Kconfig" 46source "arch/powerpc/platforms/52xx/Kconfig"
45source "arch/powerpc/platforms/powermac/Kconfig" 47source "arch/powerpc/platforms/powermac/Kconfig"
46source "arch/powerpc/platforms/prep/Kconfig" 48source "arch/powerpc/platforms/prep/Kconfig"
diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype
index 7fc41104d53e..69941ba70975 100644
--- a/arch/powerpc/platforms/Kconfig.cputype
+++ b/arch/powerpc/platforms/Kconfig.cputype
@@ -14,7 +14,7 @@ choice
14 There are five families of 32 bit PowerPC chips supported. 14 There are five families of 32 bit PowerPC chips supported.
15 The most common ones are the desktop and server CPUs (601, 603, 15 The most common ones are the desktop and server CPUs (601, 603,
16 604, 740, 750, 74xx) CPUs from Freescale and IBM, with their 16 604, 740, 750, 74xx) CPUs from Freescale and IBM, with their
17 embedded 52xx/82xx/83xx/86xx counterparts. 17 embedded 512x/52xx/82xx/83xx/86xx counterparts.
18 The other embeeded parts, namely 4xx, 8xx, e200 (55xx) and e500 18 The other embeeded parts, namely 4xx, 8xx, e200 (55xx) and e500
19 (85xx) each form a family of their own that is not compatible 19 (85xx) each form a family of their own that is not compatible
20 with the others. 20 with the others.
@@ -22,7 +22,7 @@ choice
22 If unsure, select 52xx/6xx/7xx/74xx/82xx/83xx/86xx. 22 If unsure, select 52xx/6xx/7xx/74xx/82xx/83xx/86xx.
23 23
24config 6xx 24config 6xx
25 bool "52xx/6xx/7xx/74xx/82xx/83xx/86xx" 25 bool "512x/52xx/6xx/7xx/74xx/82xx/83xx/86xx"
26 select PPC_FPU 26 select PPC_FPU
27 27
28config PPC_85xx 28config PPC_85xx
@@ -94,6 +94,7 @@ config 8xx
94 bool 94 bool
95 95
96config E500 96config E500
97 select FSL_EMB_PERFMON
97 bool 98 bool
98 99
99config PPC_FPU 100config PPC_FPU
@@ -115,6 +116,9 @@ config FSL_BOOKE
115 depends on E200 || E500 116 depends on E200 || E500
116 default y 117 default y
117 118
119config FSL_EMB_PERFMON
120 bool
121
118config PTE_64BIT 122config PTE_64BIT
119 bool 123 bool
120 depends on 44x || E500 124 depends on 44x || E500
@@ -221,7 +225,7 @@ config NR_CPUS
221 225
222config NOT_COHERENT_CACHE 226config NOT_COHERENT_CACHE
223 bool 227 bool
224 depends on 4xx || 8xx || E200 228 depends on 4xx || 8xx || E200 || PPC_MPC512x
225 default y 229 default y
226 230
227config CHECK_CACHE_COHERENCY 231config CHECK_CACHE_COHERENCY
diff --git a/arch/powerpc/platforms/Makefile b/arch/powerpc/platforms/Makefile
index 6d9079da5f5a..a984894466d9 100644
--- a/arch/powerpc/platforms/Makefile
+++ b/arch/powerpc/platforms/Makefile
@@ -11,6 +11,7 @@ endif
11obj-$(CONFIG_PPC_CHRP) += chrp/ 11obj-$(CONFIG_PPC_CHRP) += chrp/
12obj-$(CONFIG_40x) += 40x/ 12obj-$(CONFIG_40x) += 40x/
13obj-$(CONFIG_44x) += 44x/ 13obj-$(CONFIG_44x) += 44x/
14obj-$(CONFIG_PPC_MPC512x) += 512x/
14obj-$(CONFIG_PPC_MPC52xx) += 52xx/ 15obj-$(CONFIG_PPC_MPC52xx) += 52xx/
15obj-$(CONFIG_PPC_8xx) += 8xx/ 16obj-$(CONFIG_PPC_8xx) += 8xx/
16obj-$(CONFIG_PPC_82xx) += 82xx/ 17obj-$(CONFIG_PPC_82xx) += 82xx/
diff --git a/arch/powerpc/platforms/cell/Kconfig b/arch/powerpc/platforms/cell/Kconfig
index 3a963b4a9be0..2f169991896d 100644
--- a/arch/powerpc/platforms/cell/Kconfig
+++ b/arch/powerpc/platforms/cell/Kconfig
@@ -54,6 +54,13 @@ config SPU_FS_64K_LS
54 uses 4K pages. This can improve performances of applications 54 uses 4K pages. This can improve performances of applications
55 using multiple SPEs by lowering the TLB pressure on them. 55 using multiple SPEs by lowering the TLB pressure on them.
56 56
57config SPU_TRACE
58 tristate "SPU event tracing support"
59 depends on SPU_FS && MARKERS
60 help
61 This option allows reading a trace of spu-related events through
62 the sputrace file in procfs.
63
57config SPU_BASE 64config SPU_BASE
58 bool 65 bool
59 default n 66 default n
diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c
index 095988f13bf4..d95e71dee91f 100644
--- a/arch/powerpc/platforms/cell/axon_msi.c
+++ b/arch/powerpc/platforms/cell/axon_msi.c
@@ -13,7 +13,7 @@
13#include <linux/kernel.h> 13#include <linux/kernel.h>
14#include <linux/pci.h> 14#include <linux/pci.h>
15#include <linux/msi.h> 15#include <linux/msi.h>
16#include <linux/reboot.h> 16#include <linux/of_platform.h>
17 17
18#include <asm/dcr.h> 18#include <asm/dcr.h>
19#include <asm/machdep.h> 19#include <asm/machdep.h>
@@ -65,14 +65,12 @@
65 65
66struct axon_msic { 66struct axon_msic {
67 struct irq_host *irq_host; 67 struct irq_host *irq_host;
68 __le32 *fifo; 68 __le32 *fifo_virt;
69 dma_addr_t fifo_phys;
69 dcr_host_t dcr_host; 70 dcr_host_t dcr_host;
70 struct list_head list;
71 u32 read_offset; 71 u32 read_offset;
72}; 72};
73 73
74static LIST_HEAD(axon_msic_list);
75
76static void msic_dcr_write(struct axon_msic *msic, unsigned int dcr_n, u32 val) 74static void msic_dcr_write(struct axon_msic *msic, unsigned int dcr_n, u32 val)
77{ 75{
78 pr_debug("axon_msi: dcr_write(0x%x, 0x%x)\n", val, dcr_n); 76 pr_debug("axon_msi: dcr_write(0x%x, 0x%x)\n", val, dcr_n);
@@ -94,7 +92,7 @@ static void axon_msi_cascade(unsigned int irq, struct irq_desc *desc)
94 92
95 while (msic->read_offset != write_offset) { 93 while (msic->read_offset != write_offset) {
96 idx = msic->read_offset / sizeof(__le32); 94 idx = msic->read_offset / sizeof(__le32);
97 msi = le32_to_cpu(msic->fifo[idx]); 95 msi = le32_to_cpu(msic->fifo_virt[idx]);
98 msi &= 0xFFFF; 96 msi &= 0xFFFF;
99 97
100 pr_debug("axon_msi: woff %x roff %x msi %x\n", 98 pr_debug("axon_msi: woff %x roff %x msi %x\n",
@@ -139,6 +137,7 @@ static struct axon_msic *find_msi_translator(struct pci_dev *dev)
139 137
140 tmp = dn; 138 tmp = dn;
141 dn = of_find_node_by_phandle(*ph); 139 dn = of_find_node_by_phandle(*ph);
140 of_node_put(tmp);
142 if (!dn) { 141 if (!dn) {
143 dev_dbg(&dev->dev, 142 dev_dbg(&dev->dev,
144 "axon_msi: msi-translator doesn't point to a node\n"); 143 "axon_msi: msi-translator doesn't point to a node\n");
@@ -156,7 +155,6 @@ static struct axon_msic *find_msi_translator(struct pci_dev *dev)
156 155
157out_error: 156out_error:
158 of_node_put(dn); 157 of_node_put(dn);
159 of_node_put(tmp);
160 158
161 return msic; 159 return msic;
162} 160}
@@ -292,30 +290,24 @@ static struct irq_host_ops msic_host_ops = {
292 .map = msic_host_map, 290 .map = msic_host_map,
293}; 291};
294 292
295static int axon_msi_notify_reboot(struct notifier_block *nb, 293static int axon_msi_shutdown(struct of_device *device)
296 unsigned long code, void *data)
297{ 294{
298 struct axon_msic *msic; 295 struct axon_msic *msic = device->dev.platform_data;
299 u32 tmp; 296 u32 tmp;
300 297
301 list_for_each_entry(msic, &axon_msic_list, list) { 298 pr_debug("axon_msi: disabling %s\n",
302 pr_debug("axon_msi: disabling %s\n", 299 msic->irq_host->of_node->full_name);
303 msic->irq_host->of_node->full_name); 300 tmp = dcr_read(msic->dcr_host, MSIC_CTRL_REG);
304 tmp = dcr_read(msic->dcr_host, MSIC_CTRL_REG); 301 tmp &= ~MSIC_CTRL_ENABLE & ~MSIC_CTRL_IRQ_ENABLE;
305 tmp &= ~MSIC_CTRL_ENABLE & ~MSIC_CTRL_IRQ_ENABLE; 302 msic_dcr_write(msic, MSIC_CTRL_REG, tmp);
306 msic_dcr_write(msic, MSIC_CTRL_REG, tmp);
307 }
308 303
309 return 0; 304 return 0;
310} 305}
311 306
312static struct notifier_block axon_msi_reboot_notifier = { 307static int axon_msi_probe(struct of_device *device,
313 .notifier_call = axon_msi_notify_reboot 308 const struct of_device_id *device_id)
314};
315
316static int axon_msi_setup_one(struct device_node *dn)
317{ 309{
318 struct page *page; 310 struct device_node *dn = device->node;
319 struct axon_msic *msic; 311 struct axon_msic *msic;
320 unsigned int virq; 312 unsigned int virq;
321 int dcr_base, dcr_len; 313 int dcr_base, dcr_len;
@@ -346,16 +338,14 @@ static int axon_msi_setup_one(struct device_node *dn)
346 goto out_free_msic; 338 goto out_free_msic;
347 } 339 }
348 340
349 page = alloc_pages_node(of_node_to_nid(dn), GFP_KERNEL, 341 msic->fifo_virt = dma_alloc_coherent(&device->dev, MSIC_FIFO_SIZE_BYTES,
350 get_order(MSIC_FIFO_SIZE_BYTES)); 342 &msic->fifo_phys, GFP_KERNEL);
351 if (!page) { 343 if (!msic->fifo_virt) {
352 printk(KERN_ERR "axon_msi: couldn't allocate fifo for %s\n", 344 printk(KERN_ERR "axon_msi: couldn't allocate fifo for %s\n",
353 dn->full_name); 345 dn->full_name);
354 goto out_free_msic; 346 goto out_free_msic;
355 } 347 }
356 348
357 msic->fifo = page_address(page);
358
359 msic->irq_host = irq_alloc_host(of_node_get(dn), IRQ_HOST_MAP_NOMAP, 349 msic->irq_host = irq_alloc_host(of_node_get(dn), IRQ_HOST_MAP_NOMAP,
360 NR_IRQS, &msic_host_ops, 0); 350 NR_IRQS, &msic_host_ops, 0);
361 if (!msic->irq_host) { 351 if (!msic->irq_host) {
@@ -378,14 +368,18 @@ static int axon_msi_setup_one(struct device_node *dn)
378 pr_debug("axon_msi: irq 0x%x setup for axon_msi\n", virq); 368 pr_debug("axon_msi: irq 0x%x setup for axon_msi\n", virq);
379 369
380 /* Enable the MSIC hardware */ 370 /* Enable the MSIC hardware */
381 msic_dcr_write(msic, MSIC_BASE_ADDR_HI_REG, (u64)msic->fifo >> 32); 371 msic_dcr_write(msic, MSIC_BASE_ADDR_HI_REG, msic->fifo_phys >> 32);
382 msic_dcr_write(msic, MSIC_BASE_ADDR_LO_REG, 372 msic_dcr_write(msic, MSIC_BASE_ADDR_LO_REG,
383 (u64)msic->fifo & 0xFFFFFFFF); 373 msic->fifo_phys & 0xFFFFFFFF);
384 msic_dcr_write(msic, MSIC_CTRL_REG, 374 msic_dcr_write(msic, MSIC_CTRL_REG,
385 MSIC_CTRL_IRQ_ENABLE | MSIC_CTRL_ENABLE | 375 MSIC_CTRL_IRQ_ENABLE | MSIC_CTRL_ENABLE |
386 MSIC_CTRL_FIFO_SIZE); 376 MSIC_CTRL_FIFO_SIZE);
387 377
388 list_add(&msic->list, &axon_msic_list); 378 device->dev.platform_data = msic;
379
380 ppc_md.setup_msi_irqs = axon_msi_setup_msi_irqs;
381 ppc_md.teardown_msi_irqs = axon_msi_teardown_msi_irqs;
382 ppc_md.msi_check_device = axon_msi_check_device;
389 383
390 printk(KERN_DEBUG "axon_msi: setup MSIC on %s\n", dn->full_name); 384 printk(KERN_DEBUG "axon_msi: setup MSIC on %s\n", dn->full_name);
391 385
@@ -394,7 +388,8 @@ static int axon_msi_setup_one(struct device_node *dn)
394out_free_host: 388out_free_host:
395 kfree(msic->irq_host); 389 kfree(msic->irq_host);
396out_free_fifo: 390out_free_fifo:
397 __free_pages(virt_to_page(msic->fifo), get_order(MSIC_FIFO_SIZE_BYTES)); 391 dma_free_coherent(&device->dev, MSIC_FIFO_SIZE_BYTES, msic->fifo_virt,
392 msic->fifo_phys);
398out_free_msic: 393out_free_msic:
399 kfree(msic); 394 kfree(msic);
400out: 395out:
@@ -402,28 +397,24 @@ out:
402 return -1; 397 return -1;
403} 398}
404 399
405static int axon_msi_init(void) 400static const struct of_device_id axon_msi_device_id[] = {
406{ 401 {
407 struct device_node *dn; 402 .compatible = "ibm,axon-msic"
408 int found = 0; 403 },
409 404 {}
410 pr_debug("axon_msi: initialising ...\n"); 405};
411
412 for_each_compatible_node(dn, NULL, "ibm,axon-msic") {
413 if (axon_msi_setup_one(dn) == 0)
414 found++;
415 }
416
417 if (found) {
418 ppc_md.setup_msi_irqs = axon_msi_setup_msi_irqs;
419 ppc_md.teardown_msi_irqs = axon_msi_teardown_msi_irqs;
420 ppc_md.msi_check_device = axon_msi_check_device;
421
422 register_reboot_notifier(&axon_msi_reboot_notifier);
423 406
424 pr_debug("axon_msi: registered callbacks!\n"); 407static struct of_platform_driver axon_msi_driver = {
425 } 408 .match_table = axon_msi_device_id,
409 .probe = axon_msi_probe,
410 .shutdown = axon_msi_shutdown,
411 .driver = {
412 .name = "axon-msi"
413 },
414};
426 415
427 return 0; 416static int __init axon_msi_init(void)
417{
418 return of_register_platform_driver(&axon_msi_driver);
428} 419}
429arch_initcall(axon_msi_init); 420subsys_initcall(axon_msi_init);
diff --git a/arch/powerpc/platforms/cell/setup.c b/arch/powerpc/platforms/cell/setup.c
index e6534b519c9a..a7f609b3b876 100644
--- a/arch/powerpc/platforms/cell/setup.c
+++ b/arch/powerpc/platforms/cell/setup.c
@@ -98,7 +98,7 @@ static int __init cell_publish_devices(void)
98 } 98 }
99 return 0; 99 return 0;
100} 100}
101machine_device_initcall(cell, cell_publish_devices); 101machine_subsys_initcall(cell, cell_publish_devices);
102 102
103static void cell_mpic_cascade(unsigned int irq, struct irq_desc *desc) 103static void cell_mpic_cascade(unsigned int irq, struct irq_desc *desc)
104{ 104{
diff --git a/arch/powerpc/platforms/cell/spufs/Makefile b/arch/powerpc/platforms/cell/spufs/Makefile
index d3a349fb42e5..99610a6361f2 100644
--- a/arch/powerpc/platforms/cell/spufs/Makefile
+++ b/arch/powerpc/platforms/cell/spufs/Makefile
@@ -4,6 +4,8 @@ spufs-y += inode.o file.o context.o syscalls.o coredump.o
4spufs-y += sched.o backing_ops.o hw_ops.o run.o gang.o 4spufs-y += sched.o backing_ops.o hw_ops.o run.o gang.o
5spufs-y += switch.o fault.o lscsa_alloc.o 5spufs-y += switch.o fault.o lscsa_alloc.o
6 6
7obj-$(CONFIG_SPU_TRACE) += sputrace.o
8
7# Rules to build switch.o with the help of SPU tool chain 9# Rules to build switch.o with the help of SPU tool chain
8SPU_CROSS := spu- 10SPU_CROSS := spu-
9SPU_CC := $(SPU_CROSS)gcc 11SPU_CC := $(SPU_CROSS)gcc
diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c
index 3fcd06418b01..1018acd1746b 100644
--- a/arch/powerpc/platforms/cell/spufs/file.c
+++ b/arch/powerpc/platforms/cell/spufs/file.c
@@ -29,6 +29,7 @@
29#include <linux/poll.h> 29#include <linux/poll.h>
30#include <linux/ptrace.h> 30#include <linux/ptrace.h>
31#include <linux/seq_file.h> 31#include <linux/seq_file.h>
32#include <linux/marker.h>
32 33
33#include <asm/io.h> 34#include <asm/io.h>
34#include <asm/semaphore.h> 35#include <asm/semaphore.h>
@@ -358,6 +359,8 @@ static unsigned long spufs_ps_nopfn(struct vm_area_struct *vma,
358 struct spu_context *ctx = vma->vm_file->private_data; 359 struct spu_context *ctx = vma->vm_file->private_data;
359 unsigned long area, offset = address - vma->vm_start; 360 unsigned long area, offset = address - vma->vm_start;
360 361
362 spu_context_nospu_trace(spufs_ps_nopfn__enter, ctx);
363
361 offset += vma->vm_pgoff << PAGE_SHIFT; 364 offset += vma->vm_pgoff << PAGE_SHIFT;
362 if (offset >= ps_size) 365 if (offset >= ps_size)
363 return NOPFN_SIGBUS; 366 return NOPFN_SIGBUS;
@@ -375,11 +378,14 @@ static unsigned long spufs_ps_nopfn(struct vm_area_struct *vma,
375 378
376 if (ctx->state == SPU_STATE_SAVED) { 379 if (ctx->state == SPU_STATE_SAVED) {
377 up_read(&current->mm->mmap_sem); 380 up_read(&current->mm->mmap_sem);
381 spu_context_nospu_trace(spufs_ps_nopfn__sleep, ctx);
378 spufs_wait(ctx->run_wq, ctx->state == SPU_STATE_RUNNABLE); 382 spufs_wait(ctx->run_wq, ctx->state == SPU_STATE_RUNNABLE);
383 spu_context_trace(spufs_ps_nopfn__wake, ctx, ctx->spu);
379 down_read(&current->mm->mmap_sem); 384 down_read(&current->mm->mmap_sem);
380 } else { 385 } else {
381 area = ctx->spu->problem_phys + ps_offs; 386 area = ctx->spu->problem_phys + ps_offs;
382 vm_insert_pfn(vma, address, (area + offset) >> PAGE_SHIFT); 387 vm_insert_pfn(vma, address, (area + offset) >> PAGE_SHIFT);
388 spu_context_trace(spufs_ps_nopfn__insert, ctx, ctx->spu);
383 } 389 }
384 390
385 spu_release(ctx); 391 spu_release(ctx);
diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c
index c0e968a4c211..90784c029f25 100644
--- a/arch/powerpc/platforms/cell/spufs/inode.c
+++ b/arch/powerpc/platforms/cell/spufs/inode.c
@@ -322,7 +322,7 @@ static struct spu_context *
322spufs_assert_affinity(unsigned int flags, struct spu_gang *gang, 322spufs_assert_affinity(unsigned int flags, struct spu_gang *gang,
323 struct file *filp) 323 struct file *filp)
324{ 324{
325 struct spu_context *tmp, *neighbor; 325 struct spu_context *tmp, *neighbor, *err;
326 int count, node; 326 int count, node;
327 int aff_supp; 327 int aff_supp;
328 328
@@ -354,11 +354,15 @@ spufs_assert_affinity(unsigned int flags, struct spu_gang *gang,
354 if (!list_empty(&neighbor->aff_list) && !(neighbor->aff_head) && 354 if (!list_empty(&neighbor->aff_list) && !(neighbor->aff_head) &&
355 !list_is_last(&neighbor->aff_list, &gang->aff_list_head) && 355 !list_is_last(&neighbor->aff_list, &gang->aff_list_head) &&
356 !list_entry(neighbor->aff_list.next, struct spu_context, 356 !list_entry(neighbor->aff_list.next, struct spu_context,
357 aff_list)->aff_head) 357 aff_list)->aff_head) {
358 return ERR_PTR(-EEXIST); 358 err = ERR_PTR(-EEXIST);
359 goto out_put_neighbor;
360 }
359 361
360 if (gang != neighbor->gang) 362 if (gang != neighbor->gang) {
361 return ERR_PTR(-EINVAL); 363 err = ERR_PTR(-EINVAL);
364 goto out_put_neighbor;
365 }
362 366
363 count = 1; 367 count = 1;
364 list_for_each_entry(tmp, &gang->aff_list_head, aff_list) 368 list_for_each_entry(tmp, &gang->aff_list_head, aff_list)
@@ -372,11 +376,17 @@ spufs_assert_affinity(unsigned int flags, struct spu_gang *gang,
372 break; 376 break;
373 } 377 }
374 378
375 if (node == MAX_NUMNODES) 379 if (node == MAX_NUMNODES) {
376 return ERR_PTR(-EEXIST); 380 err = ERR_PTR(-EEXIST);
381 goto out_put_neighbor;
382 }
377 } 383 }
378 384
379 return neighbor; 385 return neighbor;
386
387out_put_neighbor:
388 put_spu_context(neighbor);
389 return err;
380} 390}
381 391
382static void 392static void
@@ -454,9 +464,12 @@ spufs_create_context(struct inode *inode, struct dentry *dentry,
454 if (ret) 464 if (ret)
455 goto out_aff_unlock; 465 goto out_aff_unlock;
456 466
457 if (affinity) 467 if (affinity) {
458 spufs_set_affinity(flags, SPUFS_I(dentry->d_inode)->i_ctx, 468 spufs_set_affinity(flags, SPUFS_I(dentry->d_inode)->i_ctx,
459 neighbor); 469 neighbor);
470 if (neighbor)
471 put_spu_context(neighbor);
472 }
460 473
461 /* 474 /*
462 * get references for dget and mntget, will be released 475 * get references for dget and mntget, will be released
diff --git a/arch/powerpc/platforms/cell/spufs/run.c b/arch/powerpc/platforms/cell/spufs/run.c
index c01a09da1e56..b4814c740d8a 100644
--- a/arch/powerpc/platforms/cell/spufs/run.c
+++ b/arch/powerpc/platforms/cell/spufs/run.c
@@ -410,8 +410,11 @@ long spufs_run_spu(struct spu_context *ctx, u32 *npc, u32 *event)
410 * since we have TIF_SINGLESTEP set, thus the kernel will do 410 * since we have TIF_SINGLESTEP set, thus the kernel will do
411 * it upon return from the syscall anyawy 411 * it upon return from the syscall anyawy
412 */ 412 */
413 if ((status & SPU_STATUS_STOPPED_BY_STOP) 413 if (unlikely(status & SPU_STATUS_SINGLE_STEP))
414 && (status >> SPU_STOP_STATUS_SHIFT) == 0x3fff) { 414 ret = -ERESTARTSYS;
415
416 else if (unlikely((status & SPU_STATUS_STOPPED_BY_STOP)
417 && (status >> SPU_STOP_STATUS_SHIFT) == 0x3fff)) {
415 force_sig(SIGTRAP, current); 418 force_sig(SIGTRAP, current);
416 ret = -ERESTARTSYS; 419 ret = -ERESTARTSYS;
417 } 420 }
diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c
index 00d914232af1..5915343e2599 100644
--- a/arch/powerpc/platforms/cell/spufs/sched.c
+++ b/arch/powerpc/platforms/cell/spufs/sched.c
@@ -39,6 +39,7 @@
39#include <linux/pid_namespace.h> 39#include <linux/pid_namespace.h>
40#include <linux/proc_fs.h> 40#include <linux/proc_fs.h>
41#include <linux/seq_file.h> 41#include <linux/seq_file.h>
42#include <linux/marker.h>
42 43
43#include <asm/io.h> 44#include <asm/io.h>
44#include <asm/mmu_context.h> 45#include <asm/mmu_context.h>
@@ -216,8 +217,8 @@ void do_notify_spus_active(void)
216 */ 217 */
217static void spu_bind_context(struct spu *spu, struct spu_context *ctx) 218static void spu_bind_context(struct spu *spu, struct spu_context *ctx)
218{ 219{
219 pr_debug("%s: pid=%d SPU=%d NODE=%d\n", __FUNCTION__, current->pid, 220 spu_context_trace(spu_bind_context__enter, ctx, spu);
220 spu->number, spu->node); 221
221 spuctx_switch_state(ctx, SPU_UTIL_SYSTEM); 222 spuctx_switch_state(ctx, SPU_UTIL_SYSTEM);
222 223
223 if (ctx->flags & SPU_CREATE_NOSCHED) 224 if (ctx->flags & SPU_CREATE_NOSCHED)
@@ -399,8 +400,8 @@ static int has_affinity(struct spu_context *ctx)
399 */ 400 */
400static void spu_unbind_context(struct spu *spu, struct spu_context *ctx) 401static void spu_unbind_context(struct spu *spu, struct spu_context *ctx)
401{ 402{
402 pr_debug("%s: unbind pid=%d SPU=%d NODE=%d\n", __FUNCTION__, 403 spu_context_trace(spu_unbind_context__enter, ctx, spu);
403 spu->pid, spu->number, spu->node); 404
404 spuctx_switch_state(ctx, SPU_UTIL_SYSTEM); 405 spuctx_switch_state(ctx, SPU_UTIL_SYSTEM);
405 406
406 if (spu->ctx->flags & SPU_CREATE_NOSCHED) 407 if (spu->ctx->flags & SPU_CREATE_NOSCHED)
@@ -528,6 +529,8 @@ static struct spu *spu_get_idle(struct spu_context *ctx)
528 struct spu *spu, *aff_ref_spu; 529 struct spu *spu, *aff_ref_spu;
529 int node, n; 530 int node, n;
530 531
532 spu_context_nospu_trace(spu_get_idle__enter, ctx);
533
531 if (ctx->gang) { 534 if (ctx->gang) {
532 mutex_lock(&ctx->gang->aff_mutex); 535 mutex_lock(&ctx->gang->aff_mutex);
533 if (has_affinity(ctx)) { 536 if (has_affinity(ctx)) {
@@ -546,8 +549,7 @@ static struct spu *spu_get_idle(struct spu_context *ctx)
546 if (atomic_dec_and_test(&ctx->gang->aff_sched_count)) 549 if (atomic_dec_and_test(&ctx->gang->aff_sched_count))
547 ctx->gang->aff_ref_spu = NULL; 550 ctx->gang->aff_ref_spu = NULL;
548 mutex_unlock(&ctx->gang->aff_mutex); 551 mutex_unlock(&ctx->gang->aff_mutex);
549 552 goto not_found;
550 return NULL;
551 } 553 }
552 mutex_unlock(&ctx->gang->aff_mutex); 554 mutex_unlock(&ctx->gang->aff_mutex);
553 } 555 }
@@ -565,12 +567,14 @@ static struct spu *spu_get_idle(struct spu_context *ctx)
565 mutex_unlock(&cbe_spu_info[node].list_mutex); 567 mutex_unlock(&cbe_spu_info[node].list_mutex);
566 } 568 }
567 569
570 not_found:
571 spu_context_nospu_trace(spu_get_idle__not_found, ctx);
568 return NULL; 572 return NULL;
569 573
570 found: 574 found:
571 spu->alloc_state = SPU_USED; 575 spu->alloc_state = SPU_USED;
572 mutex_unlock(&cbe_spu_info[node].list_mutex); 576 mutex_unlock(&cbe_spu_info[node].list_mutex);
573 pr_debug("Got SPU %d %d\n", spu->number, spu->node); 577 spu_context_trace(spu_get_idle__found, ctx, spu);
574 spu_init_channels(spu); 578 spu_init_channels(spu);
575 return spu; 579 return spu;
576} 580}
@@ -587,6 +591,8 @@ static struct spu *find_victim(struct spu_context *ctx)
587 struct spu *spu; 591 struct spu *spu;
588 int node, n; 592 int node, n;
589 593
594 spu_context_nospu_trace(spu_find_vitim__enter, ctx);
595
590 /* 596 /*
591 * Look for a possible preemption candidate on the local node first. 597 * Look for a possible preemption candidate on the local node first.
592 * If there is no candidate look at the other nodes. This isn't 598 * If there is no candidate look at the other nodes. This isn't
@@ -640,6 +646,8 @@ static struct spu *find_victim(struct spu_context *ctx)
640 goto restart; 646 goto restart;
641 } 647 }
642 648
649 spu_context_trace(__spu_deactivate__unload, ctx, spu);
650
643 mutex_lock(&cbe_spu_info[node].list_mutex); 651 mutex_lock(&cbe_spu_info[node].list_mutex);
644 cbe_spu_info[node].nr_active--; 652 cbe_spu_info[node].nr_active--;
645 spu_unbind_context(spu, victim); 653 spu_unbind_context(spu, victim);
@@ -822,6 +830,7 @@ static int __spu_deactivate(struct spu_context *ctx, int force, int max_prio)
822 */ 830 */
823void spu_deactivate(struct spu_context *ctx) 831void spu_deactivate(struct spu_context *ctx)
824{ 832{
833 spu_context_nospu_trace(spu_deactivate__enter, ctx);
825 __spu_deactivate(ctx, 1, MAX_PRIO); 834 __spu_deactivate(ctx, 1, MAX_PRIO);
826} 835}
827 836
@@ -835,6 +844,7 @@ void spu_deactivate(struct spu_context *ctx)
835 */ 844 */
836void spu_yield(struct spu_context *ctx) 845void spu_yield(struct spu_context *ctx)
837{ 846{
847 spu_context_nospu_trace(spu_yield__enter, ctx);
838 if (!(ctx->flags & SPU_CREATE_NOSCHED)) { 848 if (!(ctx->flags & SPU_CREATE_NOSCHED)) {
839 mutex_lock(&ctx->state_mutex); 849 mutex_lock(&ctx->state_mutex);
840 __spu_deactivate(ctx, 0, MAX_PRIO); 850 __spu_deactivate(ctx, 0, MAX_PRIO);
@@ -864,11 +874,15 @@ static noinline void spusched_tick(struct spu_context *ctx)
864 goto out; 874 goto out;
865 875
866 spu = ctx->spu; 876 spu = ctx->spu;
877
878 spu_context_trace(spusched_tick__preempt, ctx, spu);
879
867 new = grab_runnable_context(ctx->prio + 1, spu->node); 880 new = grab_runnable_context(ctx->prio + 1, spu->node);
868 if (new) { 881 if (new) {
869 spu_unschedule(spu, ctx); 882 spu_unschedule(spu, ctx);
870 spu_add_to_rq(ctx); 883 spu_add_to_rq(ctx);
871 } else { 884 } else {
885 spu_context_nospu_trace(spusched_tick__newslice, ctx);
872 ctx->time_slice++; 886 ctx->time_slice++;
873 } 887 }
874out: 888out:
diff --git a/arch/powerpc/platforms/cell/spufs/spufs.h b/arch/powerpc/platforms/cell/spufs/spufs.h
index 0e114038ea6f..795a1b52538b 100644
--- a/arch/powerpc/platforms/cell/spufs/spufs.h
+++ b/arch/powerpc/platforms/cell/spufs/spufs.h
@@ -325,4 +325,9 @@ extern void spu_free_lscsa(struct spu_state *csa);
325extern void spuctx_switch_state(struct spu_context *ctx, 325extern void spuctx_switch_state(struct spu_context *ctx,
326 enum spu_utilization_state new_state); 326 enum spu_utilization_state new_state);
327 327
328#define spu_context_trace(name, ctx, spu) \
329 trace_mark(name, "%p %p", ctx, spu);
330#define spu_context_nospu_trace(name, ctx) \
331 trace_mark(name, "%p", ctx);
332
328#endif 333#endif
diff --git a/arch/powerpc/platforms/cell/spufs/sputrace.c b/arch/powerpc/platforms/cell/spufs/sputrace.c
new file mode 100644
index 000000000000..2b1953f6f12e
--- /dev/null
+++ b/arch/powerpc/platforms/cell/spufs/sputrace.c
@@ -0,0 +1,250 @@
1/*
2 * Copyright (C) 2007 IBM Deutschland Entwicklung GmbH
3 * Released under GPL v2.
4 *
5 * Partially based on net/ipv4/tcp_probe.c.
6 *
7 * Simple tracing facility for spu contexts.
8 */
9#include <linux/sched.h>
10#include <linux/kernel.h>
11#include <linux/module.h>
12#include <linux/marker.h>
13#include <linux/proc_fs.h>
14#include <linux/wait.h>
15#include <asm/atomic.h>
16#include <asm/uaccess.h>
17#include "spufs.h"
18
19struct spu_probe {
20 const char *name;
21 const char *format;
22 marker_probe_func *probe_func;
23};
24
25struct sputrace {
26 ktime_t tstamp;
27 int owner_tid; /* owner */
28 int curr_tid;
29 const char *name;
30 int number;
31};
32
33static int bufsize __read_mostly = 16384;
34MODULE_PARM_DESC(bufsize, "Log buffer size (number of records)");
35module_param(bufsize, int, 0);
36
37
38static DEFINE_SPINLOCK(sputrace_lock);
39static DECLARE_WAIT_QUEUE_HEAD(sputrace_wait);
40static ktime_t sputrace_start;
41static unsigned long sputrace_head, sputrace_tail;
42static struct sputrace *sputrace_log;
43
44static int sputrace_used(void)
45{
46 return (sputrace_head - sputrace_tail) % bufsize;
47}
48
49static inline int sputrace_avail(void)
50{
51 return bufsize - sputrace_used();
52}
53
54static int sputrace_sprint(char *tbuf, int n)
55{
56 const struct sputrace *t = sputrace_log + sputrace_tail % bufsize;
57 struct timespec tv =
58 ktime_to_timespec(ktime_sub(t->tstamp, sputrace_start));
59
60 return snprintf(tbuf, n,
61 "[%lu.%09lu] %d: %s (thread = %d, spu = %d)\n",
62 (unsigned long) tv.tv_sec,
63 (unsigned long) tv.tv_nsec,
64 t->owner_tid,
65 t->name,
66 t->curr_tid,
67 t->number);
68}
69
70static ssize_t sputrace_read(struct file *file, char __user *buf,
71 size_t len, loff_t *ppos)
72{
73 int error = 0, cnt = 0;
74
75 if (!buf || len < 0)
76 return -EINVAL;
77
78 while (cnt < len) {
79 char tbuf[128];
80 int width;
81
82 error = wait_event_interruptible(sputrace_wait,
83 sputrace_used() > 0);
84 if (error)
85 break;
86
87 spin_lock(&sputrace_lock);
88 if (sputrace_head == sputrace_tail) {
89 spin_unlock(&sputrace_lock);
90 continue;
91 }
92
93 width = sputrace_sprint(tbuf, sizeof(tbuf));
94 if (width < len)
95 sputrace_tail = (sputrace_tail + 1) % bufsize;
96 spin_unlock(&sputrace_lock);
97
98 if (width >= len)
99 break;
100
101 error = copy_to_user(buf + cnt, tbuf, width);
102 if (error)
103 break;
104 cnt += width;
105 }
106
107 return cnt == 0 ? error : cnt;
108}
109
110static int sputrace_open(struct inode *inode, struct file *file)
111{
112 spin_lock(&sputrace_lock);
113 sputrace_head = sputrace_tail = 0;
114 sputrace_start = ktime_get();
115 spin_unlock(&sputrace_lock);
116
117 return 0;
118}
119
120static const struct file_operations sputrace_fops = {
121 .owner = THIS_MODULE,
122 .open = sputrace_open,
123 .read = sputrace_read,
124};
125
126static void sputrace_log_item(const char *name, struct spu_context *ctx,
127 struct spu *spu)
128{
129 spin_lock(&sputrace_lock);
130 if (sputrace_avail() > 1) {
131 struct sputrace *t = sputrace_log + sputrace_head;
132
133 t->tstamp = ktime_get();
134 t->owner_tid = ctx->tid;
135 t->name = name;
136 t->curr_tid = current->pid;
137 t->number = spu ? spu->number : -1;
138
139 sputrace_head = (sputrace_head + 1) % bufsize;
140 } else {
141 printk(KERN_WARNING
142 "sputrace: lost samples due to full buffer.\n");
143 }
144 spin_unlock(&sputrace_lock);
145
146 wake_up(&sputrace_wait);
147}
148
149static void spu_context_event(const struct marker *mdata,
150 void *private, const char *format, ...)
151{
152 struct spu_probe *p = mdata->private;
153 va_list ap;
154 struct spu_context *ctx;
155 struct spu *spu;
156
157 va_start(ap, format);
158 ctx = va_arg(ap, struct spu_context *);
159 spu = va_arg(ap, struct spu *);
160
161 sputrace_log_item(p->name, ctx, spu);
162 va_end(ap);
163}
164
165static void spu_context_nospu_event(const struct marker *mdata,
166 void *private, const char *format, ...)
167{
168 struct spu_probe *p = mdata->private;
169 va_list ap;
170 struct spu_context *ctx;
171
172 va_start(ap, format);
173 ctx = va_arg(ap, struct spu_context *);
174
175 sputrace_log_item(p->name, ctx, NULL);
176 va_end(ap);
177}
178
179struct spu_probe spu_probes[] = {
180 { "spu_bind_context__enter", "%p %p", spu_context_event },
181 { "spu_unbind_context__enter", "%p %p", spu_context_event },
182 { "spu_get_idle__enter", "%p", spu_context_nospu_event },
183 { "spu_get_idle__found", "%p %p", spu_context_event },
184 { "spu_get_idle__not_found", "%p", spu_context_nospu_event },
185 { "spu_find_victim__enter", "%p", spu_context_nospu_event },
186 { "spusched_tick__preempt", "%p %p", spu_context_event },
187 { "spusched_tick__newslice", "%p", spu_context_nospu_event },
188 { "spu_yield__enter", "%p", spu_context_nospu_event },
189 { "spu_deactivate__enter", "%p", spu_context_nospu_event },
190 { "__spu_deactivate__unload", "%p %p", spu_context_event },
191 { "spufs_ps_nopfn__enter", "%p", spu_context_nospu_event },
192 { "spufs_ps_nopfn__sleep", "%p", spu_context_nospu_event },
193 { "spufs_ps_nopfn__wake", "%p %p", spu_context_event },
194 { "spufs_ps_nopfn__insert", "%p %p", spu_context_event },
195 { "spu_acquire_saved__enter", "%p", spu_context_nospu_event },
196 { "destroy_spu_context__enter", "%p", spu_context_nospu_event },
197};
198
199static int __init sputrace_init(void)
200{
201 struct proc_dir_entry *entry;
202 int i, error = -ENOMEM;
203
204 sputrace_log = kcalloc(sizeof(struct sputrace),
205 bufsize, GFP_KERNEL);
206 if (!sputrace_log)
207 goto out;
208
209 entry = create_proc_entry("sputrace", S_IRUSR, NULL);
210 if (!entry)
211 goto out_free_log;
212 entry->proc_fops = &sputrace_fops;
213
214 for (i = 0; i < ARRAY_SIZE(spu_probes); i++) {
215 struct spu_probe *p = &spu_probes[i];
216
217 error = marker_probe_register(p->name, p->format,
218 p->probe_func, p);
219 if (error)
220 printk(KERN_INFO "Unable to register probe %s\n",
221 p->name);
222
223 error = marker_arm(p->name);
224 if (error)
225 printk(KERN_INFO "Unable to arm probe %s\n", p->name);
226 }
227
228 return 0;
229
230out_free_log:
231 kfree(sputrace_log);
232out:
233 return -ENOMEM;
234}
235
236static void __exit sputrace_exit(void)
237{
238 int i;
239
240 for (i = 0; i < ARRAY_SIZE(spu_probes); i++)
241 marker_probe_unregister(spu_probes[i].name);
242
243 remove_proc_entry("sputrace", NULL);
244 kfree(sputrace_log);
245}
246
247module_init(sputrace_init);
248module_exit(sputrace_exit);
249
250MODULE_LICENSE("GPL");
diff --git a/arch/powerpc/platforms/embedded6xx/storcenter.c b/arch/powerpc/platforms/embedded6xx/storcenter.c
index e12e9d298716..8864e4884980 100644
--- a/arch/powerpc/platforms/embedded6xx/storcenter.c
+++ b/arch/powerpc/platforms/embedded6xx/storcenter.c
@@ -132,33 +132,18 @@ static void __init storcenter_init_IRQ(void)
132 132
133 paddr = (phys_addr_t)of_translate_address(dnp, prop); 133 paddr = (phys_addr_t)of_translate_address(dnp, prop);
134 mpic = mpic_alloc(dnp, paddr, MPIC_PRIMARY | MPIC_WANTS_RESET, 134 mpic = mpic_alloc(dnp, paddr, MPIC_PRIMARY | MPIC_WANTS_RESET,
135 4, 32, " EPIC "); 135 16, 32, " OpenPIC ");
136 136
137 of_node_put(dnp); 137 of_node_put(dnp);
138 138
139 BUG_ON(mpic == NULL); 139 BUG_ON(mpic == NULL);
140 140
141 /* PCI IRQs */
142 /* 141 /*
143 * 2.6.12 patch: 142 * 16 Serial Interrupts followed by 16 Internal Interrupts.
144 * openpic_set_sources(0, 5, OpenPIC_Addr + 0x10200); 143 * I2C is the second internal, so it is at 17, 0x11020.
145 * openpic_set_sources(5, 2, OpenPIC_Addr + 0x11120);
146 * first_irq, num_irqs, __iomem first_ISR
147 * o_ss: i, src: 0, fdf50200
148 * o_ss: i, src: 1, fdf50220
149 * o_ss: i, src: 2, fdf50240
150 * o_ss: i, src: 3, fdf50260
151 * o_ss: i, src: 4, fdf50280
152 * o_ss: i, src: 5, fdf51120
153 * o_ss: i, src: 6, fdf51140
154 */ 144 */
155 mpic_assign_isu(mpic, 0, paddr + 0x10200); 145 mpic_assign_isu(mpic, 0, paddr + 0x10200);
156 mpic_assign_isu(mpic, 1, paddr + 0x10220); 146 mpic_assign_isu(mpic, 1, paddr + 0x11000);
157 mpic_assign_isu(mpic, 2, paddr + 0x10240);
158 mpic_assign_isu(mpic, 3, paddr + 0x10260);
159 mpic_assign_isu(mpic, 4, paddr + 0x10280);
160 mpic_assign_isu(mpic, 5, paddr + 0x11120);
161 mpic_assign_isu(mpic, 6, paddr + 0x11140);
162 147
163 mpic_init(mpic); 148 mpic_init(mpic);
164} 149}
@@ -178,7 +163,7 @@ static int __init storcenter_probe(void)
178{ 163{
179 unsigned long root = of_get_flat_dt_root(); 164 unsigned long root = of_get_flat_dt_root();
180 165
181 return of_flat_dt_is_compatible(root, "storcenter"); 166 return of_flat_dt_is_compatible(root, "iomega,storcenter");
182} 167}
183 168
184define_machine(storcenter){ 169define_machine(storcenter){
diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c
index c4ad54e0f288..1f032483c026 100644
--- a/arch/powerpc/platforms/pseries/hotplug-cpu.c
+++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c
@@ -58,7 +58,7 @@ static void pseries_mach_cpu_die(void)
58{ 58{
59 local_irq_disable(); 59 local_irq_disable();
60 idle_task_exit(); 60 idle_task_exit();
61 xics_teardown_cpu(0); 61 xics_teardown_cpu();
62 unregister_slb_shadow(hard_smp_processor_id(), __pa(get_slb_shadow())); 62 unregister_slb_shadow(hard_smp_processor_id(), __pa(get_slb_shadow()));
63 rtas_stop_self(); 63 rtas_stop_self();
64 /* Should never get here... */ 64 /* Should never get here... */
diff --git a/arch/powerpc/platforms/pseries/kexec.c b/arch/powerpc/platforms/pseries/kexec.c
index 412a5e7aff2d..e9dd5fe081c9 100644
--- a/arch/powerpc/platforms/pseries/kexec.c
+++ b/arch/powerpc/platforms/pseries/kexec.c
@@ -54,7 +54,7 @@ void __init setup_kexec_cpu_down_mpic(void)
54static void pseries_kexec_cpu_down_xics(int crash_shutdown, int secondary) 54static void pseries_kexec_cpu_down_xics(int crash_shutdown, int secondary)
55{ 55{
56 pseries_kexec_cpu_down(crash_shutdown, secondary); 56 pseries_kexec_cpu_down(crash_shutdown, secondary);
57 xics_teardown_cpu(secondary); 57 xics_kexec_teardown_cpu(secondary);
58} 58}
59 59
60void __init setup_kexec_cpu_down_xics(void) 60void __init setup_kexec_cpu_down_xics(void)
diff --git a/arch/powerpc/platforms/pseries/reconfig.c b/arch/powerpc/platforms/pseries/reconfig.c
index c02f8742c54d..2800fced8c7c 100644
--- a/arch/powerpc/platforms/pseries/reconfig.c
+++ b/arch/powerpc/platforms/pseries/reconfig.c
@@ -167,6 +167,7 @@ static int pSeries_reconfig_remove_node(struct device_node *np)
167 167
168 if ((child = of_get_next_child(np, NULL))) { 168 if ((child = of_get_next_child(np, NULL))) {
169 of_node_put(child); 169 of_node_put(child);
170 of_node_put(parent);
170 return -EBUSY; 171 return -EBUSY;
171 } 172 }
172 173
diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c
index 8f8dd9c3ca6b..ca52b587166d 100644
--- a/arch/powerpc/platforms/pseries/xics.c
+++ b/arch/powerpc/platforms/pseries/xics.c
@@ -160,6 +160,46 @@ static inline void lpar_qirr_info(int n_cpu , u8 value)
160 160
161/* High level handlers and init code */ 161/* High level handlers and init code */
162 162
163static void xics_update_irq_servers(void)
164{
165 int i, j;
166 struct device_node *np;
167 u32 ilen;
168 const u32 *ireg, *isize;
169 u32 hcpuid;
170
171 /* Find the server numbers for the boot cpu. */
172 np = of_get_cpu_node(boot_cpuid, NULL);
173 BUG_ON(!np);
174
175 ireg = of_get_property(np, "ibm,ppc-interrupt-gserver#s", &ilen);
176 if (!ireg) {
177 of_node_put(np);
178 return;
179 }
180
181 i = ilen / sizeof(int);
182 hcpuid = get_hard_smp_processor_id(boot_cpuid);
183
184 /* Global interrupt distribution server is specified in the last
185 * entry of "ibm,ppc-interrupt-gserver#s" property. Get the last
186 * entry fom this property for current boot cpu id and use it as
187 * default distribution server
188 */
189 for (j = 0; j < i; j += 2) {
190 if (ireg[j] == hcpuid) {
191 default_server = hcpuid;
192 default_distrib_server = ireg[j+1];
193
194 isize = of_get_property(np,
195 "ibm,interrupt-server#-size", NULL);
196 if (isize)
197 interrupt_server_size = *isize;
198 }
199 }
200
201 of_node_put(np);
202}
163 203
164#ifdef CONFIG_SMP 204#ifdef CONFIG_SMP
165static int get_irq_server(unsigned int virq, unsigned int strict_check) 205static int get_irq_server(unsigned int virq, unsigned int strict_check)
@@ -169,6 +209,9 @@ static int get_irq_server(unsigned int virq, unsigned int strict_check)
169 cpumask_t cpumask = irq_desc[virq].affinity; 209 cpumask_t cpumask = irq_desc[virq].affinity;
170 cpumask_t tmp = CPU_MASK_NONE; 210 cpumask_t tmp = CPU_MASK_NONE;
171 211
212 if (! cpu_isset(default_server, cpu_online_map))
213 xics_update_irq_servers();
214
172 if (!distribute_irqs) 215 if (!distribute_irqs)
173 return default_server; 216 return default_server;
174 217
@@ -658,39 +701,11 @@ static void __init xics_setup_8259_cascade(void)
658 set_irq_chained_handler(cascade, pseries_8259_cascade); 701 set_irq_chained_handler(cascade, pseries_8259_cascade);
659} 702}
660 703
661static struct device_node *cpuid_to_of_node(int cpu)
662{
663 struct device_node *np;
664 u32 hcpuid = get_hard_smp_processor_id(cpu);
665
666 for_each_node_by_type(np, "cpu") {
667 int i, len;
668 const u32 *intserv;
669
670 intserv = of_get_property(np, "ibm,ppc-interrupt-server#s",
671 &len);
672
673 if (!intserv)
674 intserv = of_get_property(np, "reg", &len);
675
676 i = len / sizeof(u32);
677
678 while (i--)
679 if (intserv[i] == hcpuid)
680 return np;
681 }
682
683 return NULL;
684}
685
686void __init xics_init_IRQ(void) 704void __init xics_init_IRQ(void)
687{ 705{
688 int i, j;
689 struct device_node *np; 706 struct device_node *np;
690 u32 ilen, indx = 0; 707 u32 indx = 0;
691 const u32 *ireg, *isize;
692 int found = 0; 708 int found = 0;
693 u32 hcpuid;
694 709
695 ppc64_boot_msg(0x20, "XICS Init"); 710 ppc64_boot_msg(0x20, "XICS Init");
696 711
@@ -709,34 +724,7 @@ void __init xics_init_IRQ(void)
709 return; 724 return;
710 725
711 xics_init_host(); 726 xics_init_host();
712 727 xics_update_irq_servers();
713 /* Find the server numbers for the boot cpu. */
714 np = cpuid_to_of_node(boot_cpuid);
715 BUG_ON(!np);
716 ireg = of_get_property(np, "ibm,ppc-interrupt-gserver#s", &ilen);
717 if (!ireg)
718 goto skip_gserver_check;
719 i = ilen / sizeof(int);
720 hcpuid = get_hard_smp_processor_id(boot_cpuid);
721
722 /* Global interrupt distribution server is specified in the last
723 * entry of "ibm,ppc-interrupt-gserver#s" property. Get the last
724 * entry fom this property for current boot cpu id and use it as
725 * default distribution server
726 */
727 for (j = 0; j < i; j += 2) {
728 if (ireg[j] == hcpuid) {
729 default_server = hcpuid;
730 default_distrib_server = ireg[j+1];
731
732 isize = of_get_property(np,
733 "ibm,interrupt-server#-size", NULL);
734 if (isize)
735 interrupt_server_size = *isize;
736 }
737 }
738skip_gserver_check:
739 of_node_put(np);
740 728
741 if (firmware_has_feature(FW_FEATURE_LPAR)) 729 if (firmware_has_feature(FW_FEATURE_LPAR))
742 ppc_md.get_irq = xics_get_irq_lpar; 730 ppc_md.get_irq = xics_get_irq_lpar;
@@ -775,11 +763,9 @@ void xics_request_IPIs(void)
775} 763}
776#endif /* CONFIG_SMP */ 764#endif /* CONFIG_SMP */
777 765
778void xics_teardown_cpu(int secondary) 766void xics_teardown_cpu()
779{ 767{
780 int cpu = smp_processor_id(); 768 int cpu = smp_processor_id();
781 unsigned int ipi;
782 struct irq_desc *desc;
783 769
784 xics_set_cpu_priority(0); 770 xics_set_cpu_priority(0);
785 771
@@ -790,9 +776,17 @@ void xics_teardown_cpu(int secondary)
790 lpar_qirr_info(cpu, 0xff); 776 lpar_qirr_info(cpu, 0xff);
791 else 777 else
792 direct_qirr_info(cpu, 0xff); 778 direct_qirr_info(cpu, 0xff);
779}
780
781void xics_kexec_teardown_cpu(int secondary)
782{
783 unsigned int ipi;
784 struct irq_desc *desc;
785
786 xics_teardown_cpu();
793 787
794 /* 788 /*
795 * we need to EOI the IPI if we got here from kexec down IPI 789 * we need to EOI the IPI
796 * 790 *
797 * probably need to check all the other interrupts too 791 * probably need to check all the other interrupts too
798 * should we be flagging idle loop instead? 792 * should we be flagging idle loop instead?
@@ -880,8 +874,8 @@ void xics_migrate_irqs_away(void)
880 virq, cpu); 874 virq, cpu);
881 875
882 /* Reset affinity to all cpus */ 876 /* Reset affinity to all cpus */
877 irq_desc[virq].affinity = CPU_MASK_ALL;
883 desc->chip->set_affinity(virq, CPU_MASK_ALL); 878 desc->chip->set_affinity(virq, CPU_MASK_ALL);
884 irq_desc[irq].affinity = CPU_MASK_ALL;
885unlock: 879unlock:
886 spin_unlock_irqrestore(&desc->lock, flags); 880 spin_unlock_irqrestore(&desc->lock, flags);
887 } 881 }
diff --git a/arch/powerpc/platforms/pseries/xics.h b/arch/powerpc/platforms/pseries/xics.h
index 9ffd809d29e2..c26bcff47b6d 100644
--- a/arch/powerpc/platforms/pseries/xics.h
+++ b/arch/powerpc/platforms/pseries/xics.h
@@ -16,7 +16,8 @@
16 16
17extern void xics_init_IRQ(void); 17extern void xics_init_IRQ(void);
18extern void xics_setup_cpu(void); 18extern void xics_setup_cpu(void);
19extern void xics_teardown_cpu(int secondary); 19extern void xics_teardown_cpu(void);
20extern void xics_kexec_teardown_cpu(int secondary);
20extern void xics_cause_IPI(int cpu); 21extern void xics_cause_IPI(int cpu);
21extern void xics_request_IPIs(void); 22extern void xics_request_IPIs(void);
22extern void xics_migrate_irqs_away(void); 23extern void xics_migrate_irqs_away(void);
diff --git a/arch/powerpc/sysdev/dcr.c b/arch/powerpc/sysdev/dcr.c
index 427027c7ea0f..437e48d3ae33 100644
--- a/arch/powerpc/sysdev/dcr.c
+++ b/arch/powerpc/sysdev/dcr.c
@@ -137,5 +137,6 @@ void dcr_unmap(dcr_host_t host, unsigned int dcr_c)
137 h.token = NULL; 137 h.token = NULL;
138} 138}
139EXPORT_SYMBOL_GPL(dcr_unmap); 139EXPORT_SYMBOL_GPL(dcr_unmap);
140 140#else /* defined(CONFIG_PPC_DCR_NATIVE) */
141#endif /* !defined(CONFIG_PPC_DCR_NATIVE) */ 141DEFINE_SPINLOCK(dcr_ind_lock);
142#endif /* !defined(CONFIG_PPC_DCR_NATIVE) */
diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c
index e48b20e934ca..2c5388ce902a 100644
--- a/arch/powerpc/sysdev/fsl_soc.c
+++ b/arch/powerpc/sysdev/fsl_soc.c
@@ -1342,7 +1342,7 @@ static int __init of_fsl_spi_probe(char *type, char *compatible, u32 sysclk,
1342 if (ret) 1342 if (ret)
1343 goto unreg; 1343 goto unreg;
1344 1344
1345 ret = platform_device_register(pdev); 1345 ret = platform_device_add(pdev);
1346 if (ret) 1346 if (ret)
1347 goto unreg; 1347 goto unreg;
1348 1348
diff --git a/arch/powerpc/sysdev/mpc8xx_pic.c b/arch/powerpc/sysdev/mpc8xx_pic.c
index 0e74a4bd9827..5d2d5522ef41 100644
--- a/arch/powerpc/sysdev/mpc8xx_pic.c
+++ b/arch/powerpc/sysdev/mpc8xx_pic.c
@@ -174,15 +174,19 @@ int mpc8xx_pic_init(void)
174 goto out; 174 goto out;
175 175
176 siu_reg = ioremap(res.start, res.end - res.start + 1); 176 siu_reg = ioremap(res.start, res.end - res.start + 1);
177 if (siu_reg == NULL) 177 if (siu_reg == NULL) {
178 return -EINVAL; 178 ret = -EINVAL;
179 goto out;
180 }
179 181
180 mpc8xx_pic_host = irq_alloc_host(of_node_get(np), IRQ_HOST_MAP_LINEAR, 182 mpc8xx_pic_host = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR,
181 64, &mpc8xx_pic_host_ops, 64); 183 64, &mpc8xx_pic_host_ops, 64);
182 if (mpc8xx_pic_host == NULL) { 184 if (mpc8xx_pic_host == NULL) {
183 printk(KERN_ERR "MPC8xx PIC: failed to allocate irq host!\n"); 185 printk(KERN_ERR "MPC8xx PIC: failed to allocate irq host!\n");
184 ret = -ENOMEM; 186 ret = -ENOMEM;
187 goto out;
185 } 188 }
189 return 0;
186 190
187out: 191out:
188 of_node_put(np); 192 of_node_put(np);
diff --git a/arch/powerpc/sysdev/qe_lib/qe.c b/arch/powerpc/sysdev/qe_lib/qe.c
index 5ef844da9355..6efbd5e5bb1b 100644
--- a/arch/powerpc/sysdev/qe_lib/qe.c
+++ b/arch/powerpc/sysdev/qe_lib/qe.c
@@ -66,7 +66,7 @@ phys_addr_t get_qe_base(void)
66{ 66{
67 struct device_node *qe; 67 struct device_node *qe;
68 unsigned int size; 68 unsigned int size;
69 const void *prop; 69 const u32 *prop;
70 70
71 if (qebase != -1) 71 if (qebase != -1)
72 return qebase; 72 return qebase;
@@ -79,7 +79,8 @@ phys_addr_t get_qe_base(void)
79 } 79 }
80 80
81 prop = of_get_property(qe, "reg", &size); 81 prop = of_get_property(qe, "reg", &size);
82 qebase = of_translate_address(qe, prop); 82 if (prop && size >= sizeof(*prop))
83 qebase = of_translate_address(qe, prop);
83 of_node_put(qe); 84 of_node_put(qe);
84 85
85 return qebase; 86 return qebase;
@@ -172,10 +173,9 @@ unsigned int get_brg_clk(void)
172 } 173 }
173 174
174 prop = of_get_property(qe, "brg-frequency", &size); 175 prop = of_get_property(qe, "brg-frequency", &size);
175 if (!prop || size != sizeof(*prop)) 176 if (prop && size == sizeof(*prop))
176 return brg_clk; 177 brg_clk = *prop;
177 178
178 brg_clk = *prop;
179 of_node_put(qe); 179 of_node_put(qe);
180 180
181 return brg_clk; 181 return brg_clk;