diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2008-02-07 12:02:26 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2008-02-07 12:02:26 -0500 |
commit | 37969581301e50872a1ae84dc73962b5f7ee6b76 (patch) | |
tree | 35bbd6a07f903f248f4bd209b8d194a922415fe0 /arch | |
parent | 80ff8a805113850a3ffafcc8e6eaa1fdd51b02f3 (diff) | |
parent | 24f1a849614ba1805e26a05da7cc8c6bd67490ea (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')
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 | |||
97 | config COMPAT | 97 | config COMPAT |
98 | bool | 98 | bool |
99 | default y if PPC64 | 99 | default y if PPC64 |
100 | select COMPAT_BINFMT_ELF | ||
100 | 101 | ||
101 | config SYSVIPC_COMPAT | 102 | config 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 | ||
441 | config 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 | |||
460 | endmenu | 442 | endmenu |
461 | 443 | ||
462 | config ISA_DMA_API | 444 | config 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/ | |||
151 | drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/ | 151 | drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/ |
152 | 152 | ||
153 | # Default to zImage, override when needed | 153 | # Default to zImage, override when needed |
154 | defaultimage-y := zImage | 154 | all: zImage |
155 | defaultimage-$(CONFIG_DEFAULT_UIMAGE) := uImage | ||
156 | KBUILD_IMAGE := $(defaultimage-y) | ||
157 | all: $(KBUILD_IMAGE) | ||
158 | 155 | ||
159 | CPPFLAGS_vmlinux.lds := -Upowerpc | 156 | CPPFLAGS_vmlinux.lds := -Upowerpc |
160 | 157 | ||
161 | BOOT_TARGETS = zImage zImage.initrd uImage | 158 | BOOT_TARGETS = zImage zImage.initrd uImage treeImage.% cuImage.% |
162 | 159 | ||
163 | PHONY += $(BOOT_TARGETS) | 160 | PHONY += $(BOOT_TARGETS) |
164 | 161 | ||
@@ -180,7 +177,7 @@ define archhelp | |||
180 | endef | 177 | endef |
181 | 178 | ||
182 | install: vdso_install | 179 | install: vdso_install |
183 | $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) install | 180 | $(Q)$(MAKE) $(build)=$(boot) install |
184 | 181 | ||
185 | vdso_install: | 182 | vdso_install: |
186 | ifeq ($(CONFIG_PPC64),y) | 183 | ifeq ($(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 \ | |||
60 | src-plat := of.c cuboot-52xx.c cuboot-824x.c cuboot-83xx.c cuboot-85xx.c holly.c \ | 60 | src-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 |
67 | src-boot := $(src-wlib) $(src-plat) empty.c | 68 | src-boot := $(src-wlib) $(src-plat) empty.c |
@@ -123,6 +124,8 @@ targets += $(patsubst $(obj)/%,%,$(obj-boot) wrapper.a) | |||
123 | extra-y := $(obj)/wrapper.a $(obj-plat) $(obj)/empty.o \ | 124 | extra-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 | ||
127 | dtstree := $(srctree)/$(src)/dts | ||
128 | |||
126 | wrapper :=$(srctree)/$(src)/wrapper | 129 | wrapper :=$(srctree)/$(src)/wrapper |
127 | wrapperbits := $(extra-y) $(addprefix $(obj)/,addnote hack-coff mktree dtc) \ | 130 | wrapperbits := $(extra-y) $(addprefix $(obj)/,addnote hack-coff mktree dtc) \ |
128 | $(wrapper) FORCE | 131 | $(wrapper) FORCE |
@@ -181,7 +184,7 @@ quiet_cmd_wrap = WRAP $@ | |||
181 | image-$(CONFIG_PPC_PSERIES) += zImage.pseries | 184 | image-$(CONFIG_PPC_PSERIES) += zImage.pseries |
182 | image-$(CONFIG_PPC_MAPLE) += zImage.pseries | 185 | image-$(CONFIG_PPC_MAPLE) += zImage.pseries |
183 | image-$(CONFIG_PPC_IBM_CELL_BLADE) += zImage.pseries | 186 | image-$(CONFIG_PPC_IBM_CELL_BLADE) += zImage.pseries |
184 | image-$(CONFIG_PPC_PS3) += zImage.ps3 | 187 | image-$(CONFIG_PPC_PS3) += zImage-dtb.ps3 |
185 | image-$(CONFIG_PPC_CELLEB) += zImage.pseries | 188 | image-$(CONFIG_PPC_CELLEB) += zImage.pseries |
186 | image-$(CONFIG_PPC_CHRP) += zImage.chrp | 189 | image-$(CONFIG_PPC_CHRP) += zImage.chrp |
187 | image-$(CONFIG_PPC_EFIKA) += zImage.chrp | 190 | image-$(CONFIG_PPC_EFIKA) += zImage.chrp |
@@ -191,33 +194,69 @@ image-$(CONFIG_PPC_PRPMC2800) += zImage.prpmc2800 | |||
191 | image-$(CONFIG_PPC_ISERIES) += zImage.iseries | 194 | image-$(CONFIG_PPC_ISERIES) += zImage.iseries |
192 | image-$(CONFIG_DEFAULT_UIMAGE) += uImage | 195 | image-$(CONFIG_DEFAULT_UIMAGE) += uImage |
193 | 196 | ||
194 | ifneq ($(CONFIG_DEVICE_TREE),"") | 197 | # |
195 | image-$(CONFIG_PPC_8xx) += cuImage.8xx | 198 | # Targets which embed a device tree blob |
196 | image-$(CONFIG_PPC_EP88XC) += zImage.ep88xc | 199 | # |
197 | image-$(CONFIG_EP405) += zImage.ep405 | 200 | # Theses are default targets to build images which embed device tree blobs. |
198 | image-$(CONFIG_8260) += cuImage.pq2 | 201 | # They are only required on boards which do not have FDT support in firmware. |
199 | image-$(CONFIG_EP8248E) += zImage.ep8248e | 202 | # Boards with newish u-boot firmare can use the uImage target above |
200 | image-$(CONFIG_PPC_MPC52xx) += cuImage.52xx | 203 | # |
201 | image-$(CONFIG_STORCENTER) += cuImage.824x | 204 | |
202 | image-$(CONFIG_PPC_83xx) += cuImage.83xx | 205 | # Board ports in arch/powerpc/platform/40x/Kconfig |
203 | image-$(CONFIG_PPC_85xx) += cuImage.85xx | 206 | image-$(CONFIG_EP405) += zImage-dtb.ep405 |
204 | ifeq ($(CONFIG_CPM2),y) | 207 | image-$(CONFIG_WALNUT) += treeImage.walnut |
205 | image-$(CONFIG_PPC_85xx) += cuImage.85xx-cpm2 | 208 | |
206 | endif | 209 | # Board ports in arch/powerpc/platform/44x/Kconfig |
207 | image-$(CONFIG_MPC7448HPC2) += cuImage.hpc2 | ||
208 | image-$(CONFIG_EBONY) += treeImage.ebony cuImage.ebony | 210 | image-$(CONFIG_EBONY) += treeImage.ebony cuImage.ebony |
209 | image-$(CONFIG_BAMBOO) += treeImage.bamboo cuImage.bamboo | 211 | image-$(CONFIG_BAMBOO) += treeImage.bamboo cuImage.bamboo |
210 | image-$(CONFIG_SEQUOIA) += cuImage.sequoia | 212 | image-$(CONFIG_SEQUOIA) += cuImage.sequoia |
211 | image-$(CONFIG_RAINIER) += cuImage.rainier | 213 | image-$(CONFIG_RAINIER) += cuImage.rainier |
212 | image-$(CONFIG_WALNUT) += treeImage.walnut | ||
213 | image-$(CONFIG_TAISHAN) += cuImage.taishan | 214 | image-$(CONFIG_TAISHAN) += cuImage.taishan |
214 | image-$(CONFIG_KATMAI) += cuImage.katmai | 215 | image-$(CONFIG_KATMAI) += cuImage.katmai |
215 | image-$(CONFIG_WARP) += cuImage.warp | 216 | image-$(CONFIG_WARP) += cuImage.warp |
216 | endif | ||
217 | 217 | ||
218 | ifneq ($(CONFIG_REDBOOT),"") | 218 | # Board ports in arch/powerpc/platform/8xx/Kconfig |
219 | image-$(CONFIG_PPC_8xx) += zImage.redboot-8xx | 219 | image-$(CONFIG_PPC_MPC86XADS) += cuImage.mpc866ads |
220 | endif | 220 | image-$(CONFIG_PPC_MPC885ADS) += cuImage.mpc885ads |
221 | image-$(CONFIG_PPC_EP88XC) += zImage-dtb.ep88xc | ||
222 | image-$(CONFIG_PPC_ADDER875) += cuImage.adder875-uboot \ | ||
223 | zImage-dtb.adder875-redboot | ||
224 | |||
225 | # Board ports in arch/powerpc/platform/52xx/Kconfig | ||
226 | image-$(CONFIG_PPC_LITE5200) += cuImage.lite5200 cuImage.lite5200b | ||
227 | |||
228 | # Board ports in arch/powerpc/platform/82xx/Kconfig | ||
229 | image-$(CONFIG_MPC8272_ADS) += cuImage.mpc8272ads | ||
230 | image-$(CONFIG_PQ2FADS) += cuImage.pq2fads | ||
231 | image-$(CONFIG_EP8248E) += zImage-dtb.ep8248e | ||
232 | |||
233 | # Board ports in arch/powerpc/platform/83xx/Kconfig | ||
234 | image-$(CONFIG_MPC832x_MDS) += cuImage.mpc832x_mds | ||
235 | image-$(CONFIG_MPC832x_RDB) += cuImage.mpc832x_rdb | ||
236 | image-$(CONFIG_MPC834x_ITX) += cuImage.mpc8349emitx \ | ||
237 | cuImage.mpc8349emitxgp | ||
238 | image-$(CONFIG_MPC834x_MDS) += cuImage.mpc834x_mds | ||
239 | image-$(CONFIG_MPC836x_MDS) += cuImage.mpc836x_mds | ||
240 | |||
241 | # Board ports in arch/powerpc/platform/85xx/Kconfig | ||
242 | image-$(CONFIG_MPC8540_ADS) += cuImage.mpc8540ads | ||
243 | image-$(CONFIG_MPC8560_ADS) += cuImage.mpc8560ads | ||
244 | image-$(CONFIG_MPC85xx_CDS) += cuImage.mpc8541cds \ | ||
245 | cuImage.mpc8548cds \ | ||
246 | cuImage.mpc8555cds | ||
247 | image-$(CONFIG_MPC85xx_MDS) += cuImage.mpc8568mds | ||
248 | image-$(CONFIG_MPC85xx_DS) += cuImage.mpc8544ds \ | ||
249 | cuImage.mpc8572ds | ||
250 | image-$(CONFIG_TQM8540) += cuImage.tqm8540 | ||
251 | image-$(CONFIG_TQM8541) += cuImage.tqm8541 | ||
252 | image-$(CONFIG_TQM8555) += cuImage.tqm8555 | ||
253 | image-$(CONFIG_TQM8560) += cuImage.tqm8560 | ||
254 | image-$(CONFIG_SBC8548) += cuImage.tqm8548 | ||
255 | image-$(CONFIG_SBC8560) += cuImage.tqm8560 | ||
256 | |||
257 | # Board ports in arch/powerpc/platform/embedded6xx/Kconfig | ||
258 | image-$(CONFIG_STORCENTER) += cuImage.storcenter | ||
259 | image-$(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 | ||
239 | ifeq ($(CONFIG_WANT_DEVICE_TREE),y) | ||
240 | ifneq ($(CONFIG_DEVICE_TREE),"") | ||
241 | dts = $(if $(shell echo $(CONFIG_DEVICE_TREE) | grep '^/'),\ | ||
242 | ,$(srctree)/$(src)/dts/)$(CONFIG_DEVICE_TREE:"%"=%) | ||
243 | endif | ||
244 | endif | ||
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. |
283 | ifeq (,$(image-y)) | 311 | ifeq (,$(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) | |||
158 | cuboot*) | 158 | cuboot*) |
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 | ;; |
162 | ps3) | 185 | ps3) |
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 |
187 | CONFIG_BINFMT_ELF=y | 187 | CONFIG_BINFMT_ELF=y |
188 | # CONFIG_BINFMT_MISC is not set | 188 | # CONFIG_BINFMT_MISC is not set |
189 | # CONFIG_MATH_EMULATION is not set | 189 | CONFIG_MATH_EMULATION=y |
190 | CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y | 190 | CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y |
191 | CONFIG_ARCH_FLATMEM_ENABLE=y | 191 | CONFIG_ARCH_FLATMEM_ENABLE=y |
192 | CONFIG_ARCH_POPULATES_NODE_MAP=y | 192 | CONFIG_ARCH_POPULATES_NODE_MAP=y |
@@ -416,14 +416,14 @@ CONFIG_PHYLIB=y | |||
416 | # MII PHY device drivers | 416 | # MII PHY device drivers |
417 | # | 417 | # |
418 | CONFIG_MARVELL_PHY=y | 418 | CONFIG_MARVELL_PHY=y |
419 | # CONFIG_DAVICOM_PHY is not set | 419 | CONFIG_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 | 423 | CONFIG_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 | 426 | CONFIG_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 |
429 | CONFIG_NET_ETHERNET=y | 429 | CONFIG_NET_ETHERNET=y |
@@ -436,7 +436,7 @@ CONFIG_MII=y | |||
436 | CONFIG_NETDEV_1000=y | 436 | CONFIG_NETDEV_1000=y |
437 | CONFIG_GIANFAR=y | 437 | CONFIG_GIANFAR=y |
438 | # CONFIG_GFAR_NAPI is not set | 438 | # CONFIG_GFAR_NAPI is not set |
439 | # CONFIG_UCC_GETH is not set | 439 | CONFIG_UCC_GETH=y |
440 | CONFIG_NETDEV_10000=y | 440 | CONFIG_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 | ||
5 | CFLAGS_ptrace.o += -DUTS_MACHINE='"$(UTS_MACHINE)"' | ||
6 | |||
5 | ifeq ($(CONFIG_PPC64),y) | 7 | ifeq ($(CONFIG_PPC64),y) |
6 | CFLAGS_prom_init.o += -mno-minimal-toc | 8 | CFLAGS_prom_init.o += -mno-minimal-toc |
7 | endif | 9 | endif |
@@ -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 |
17 | obj-y += vdso32/ | 19 | obj-y += vdso32/ |
18 | obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \ | 20 | obj-$(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 | ||
39 | static 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 | ||
46 | static 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 | ||
59 | static __inline__ void | ||
60 | cputime_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 { | |||
36 | static struct __initdata of_device_id parents[] = { | 36 | static 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 | ||
27 | static void dummy_perf(struct pt_regs *regs) | 27 | static 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 | ||
63 | static unsigned long get_user_msr(struct task_struct *task) | ||
64 | { | ||
65 | return task->thread.regs->msr | task->thread.fpexc_mode; | ||
66 | } | ||
67 | |||
68 | static 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 | */ | ||
79 | static 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 | */ |
64 | unsigned long ptrace_get_reg(struct task_struct *task, int regno) | 88 | unsigned 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 | ||
122 | static 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 | |||
159 | static 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 | ||
106 | static 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, ®, |
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, ®, | ||
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 | |||
214 | static 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 | ||
116 | static int set_fpregs(void __user *data, struct task_struct *task, | 227 | static 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 | /* | 255 | static int vr_active(struct task_struct *target, |
142 | * Get contents of AltiVec register state in task TASK | 256 | const struct user_regset *regset) |
143 | */ | ||
144 | static 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] */ | 262 | static 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 | /* | 293 | static 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) |
170 | static 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 | /* | 338 | static int evr_active(struct task_struct *target, |
207 | * Get contents of SPE register state in task TASK. | 339 | const struct user_regset *regset) |
208 | */ | ||
209 | static 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))) | 345 | static 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 | |||
368 | static 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 | */ |
235 | static int set_evrregs(struct task_struct *task, unsigned long *data) | 396 | enum 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 | |||
407 | static 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 | |||
434 | static 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 | |||
442 | static 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 | |||
494 | static 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 | */ | ||
564 | static 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 | |||
591 | static 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 | |||
597 | const 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 | ||
259 | void user_enable_single_step(struct task_struct *task) | 607 | void user_enable_single_step(struct task_struct *task) |
@@ -323,55 +671,29 @@ void ptrace_disable(struct task_struct *child) | |||
323 | static long arch_ptrace_old(struct task_struct *child, long request, long addr, | 671 | static 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 | ||
377 | long arch_ptrace(struct task_struct *child, long request, long addr, long data) | 699 | long 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 @@ | |||
45 | static long compat_ptrace_old(struct task_struct *child, long request, | 47 | static 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 | ||
87 | long compat_sys_ptrace(int request, int pid, unsigned long addr, | 67 | long 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 | } |
408 | out_tsk: | 312 | |
409 | put_task_struct(child); | ||
410 | out: | ||
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) |
58 | int (*__debugger)(struct pt_regs *regs); | 58 | int (*__debugger)(struct pt_regs *regs); |
59 | int (*__debugger_ipi)(struct pt_regs *regs); | 59 | int (*__debugger_ipi)(struct pt_regs *regs); |
60 | int (*__debugger_bpt)(struct pt_regs *regs); | 60 | int (*__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 | */ |
179 | struct vio_dev * __devinit vio_register_device_node(struct device_node *of_node) | 179 | struct 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 | ||
25 | static int numa_enabled = 1; | 25 | static int numa_enabled = 1; |
26 | 26 | ||
27 | static char *cmdline __initdata; | ||
28 | |||
27 | static int numa_debug; | 29 | static 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]; | |||
39 | static int min_common_depth; | 41 | static int min_common_depth; |
40 | static int n_mem_addr_cells, n_mem_size_cells; | 42 | static int n_mem_addr_cells, n_mem_size_cells; |
41 | 43 | ||
44 | static 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 | |||
42 | static void __cpuinit map_cpu_to_node(int cpu, int node) | 91 | static 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 | ||
479 | void __init dump_numa_cpu_topology(void) | 535 | void __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 | } |
707 | early_param("numa", early_numa); | 767 | early_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 |
17 | oprofile-$(CONFIG_PPC64) += op_model_rs64.o op_model_power4.o op_model_pa6t.o | 17 | oprofile-$(CONFIG_PPC64) += op_model_rs64.o op_model_power4.o op_model_pa6t.o |
18 | oprofile-$(CONFIG_FSL_BOOKE) += op_model_fsl_booke.o | 18 | oprofile-$(CONFIG_FSL_EMB_PERFMON) += op_model_fsl_emb.o |
19 | oprofile-$(CONFIG_6xx) += op_model_7450.o | 19 | oprofile-$(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 | ||
247 | static int fsl_booke_cpu_setup(struct op_counter_config *ctr) | 245 | static 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 | ||
265 | static int fsl_booke_reg_setup(struct op_counter_config *ctr, | 263 | static 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 | ||
284 | static int fsl_booke_start(struct op_counter_config *ctr) | 282 | static 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 | ||
318 | static void fsl_booke_stop(void) | 316 | static 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 | ||
332 | static void fsl_booke_handle_interrupt(struct pt_regs *regs, | 330 | static 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 | ||
365 | struct op_powerpc_model op_model_fsl_booke = { | 363 | struct 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 @@ | |||
1 | config PPC_MPC512x | ||
2 | bool | ||
3 | select FSL_SOC | ||
4 | select IPIC | ||
5 | default n | ||
6 | |||
7 | config PPC_MPC5121 | ||
8 | bool | ||
9 | select PPC_MPC512x | ||
10 | default n | ||
11 | |||
12 | config 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 | # | ||
4 | obj-$(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 | */ | ||
32 | unsigned long | ||
33 | mpc512x_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 | } | ||
53 | EXPORT_SYMBOL(mpc512x_find_ips_freq); | ||
54 | |||
55 | static struct of_device_id __initdata of_bus_ids[] = { | ||
56 | { .name = "soc", }, | ||
57 | { .name = "localbus", }, | ||
58 | {}, | ||
59 | }; | ||
60 | |||
61 | static 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 | |||
69 | static 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 | */ | ||
90 | static 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 | |||
97 | define_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 | ||
25 | struct cpm_pin { | 25 | struct 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 | ||
28 | config PPC_86xx | 29 | config PPC_86xx |
29 | bool "Freescale 86xx" | 30 | bool "Freescale 86xx" |
@@ -41,6 +42,7 @@ config CLASSIC32 | |||
41 | source "arch/powerpc/platforms/pseries/Kconfig" | 42 | source "arch/powerpc/platforms/pseries/Kconfig" |
42 | source "arch/powerpc/platforms/iseries/Kconfig" | 43 | source "arch/powerpc/platforms/iseries/Kconfig" |
43 | source "arch/powerpc/platforms/chrp/Kconfig" | 44 | source "arch/powerpc/platforms/chrp/Kconfig" |
45 | source "arch/powerpc/platforms/512x/Kconfig" | ||
44 | source "arch/powerpc/platforms/52xx/Kconfig" | 46 | source "arch/powerpc/platforms/52xx/Kconfig" |
45 | source "arch/powerpc/platforms/powermac/Kconfig" | 47 | source "arch/powerpc/platforms/powermac/Kconfig" |
46 | source "arch/powerpc/platforms/prep/Kconfig" | 48 | source "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 | ||
24 | config 6xx | 24 | config 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 | ||
28 | config PPC_85xx | 28 | config PPC_85xx |
@@ -94,6 +94,7 @@ config 8xx | |||
94 | bool | 94 | bool |
95 | 95 | ||
96 | config E500 | 96 | config E500 |
97 | select FSL_EMB_PERFMON | ||
97 | bool | 98 | bool |
98 | 99 | ||
99 | config PPC_FPU | 100 | config 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 | ||
119 | config FSL_EMB_PERFMON | ||
120 | bool | ||
121 | |||
118 | config PTE_64BIT | 122 | config 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 | ||
222 | config NOT_COHERENT_CACHE | 226 | config 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 | ||
227 | config CHECK_CACHE_COHERENCY | 231 | config 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 | |||
11 | obj-$(CONFIG_PPC_CHRP) += chrp/ | 11 | obj-$(CONFIG_PPC_CHRP) += chrp/ |
12 | obj-$(CONFIG_40x) += 40x/ | 12 | obj-$(CONFIG_40x) += 40x/ |
13 | obj-$(CONFIG_44x) += 44x/ | 13 | obj-$(CONFIG_44x) += 44x/ |
14 | obj-$(CONFIG_PPC_MPC512x) += 512x/ | ||
14 | obj-$(CONFIG_PPC_MPC52xx) += 52xx/ | 15 | obj-$(CONFIG_PPC_MPC52xx) += 52xx/ |
15 | obj-$(CONFIG_PPC_8xx) += 8xx/ | 16 | obj-$(CONFIG_PPC_8xx) += 8xx/ |
16 | obj-$(CONFIG_PPC_82xx) += 82xx/ | 17 | obj-$(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 | ||
57 | config 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 | |||
57 | config SPU_BASE | 64 | config 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 | ||
66 | struct axon_msic { | 66 | struct 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 | ||
74 | static LIST_HEAD(axon_msic_list); | ||
75 | |||
76 | static void msic_dcr_write(struct axon_msic *msic, unsigned int dcr_n, u32 val) | 74 | static 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 | ||
157 | out_error: | 156 | out_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 | ||
295 | static int axon_msi_notify_reboot(struct notifier_block *nb, | 293 | static 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 | ||
312 | static struct notifier_block axon_msi_reboot_notifier = { | 307 | static 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 | |||
316 | static 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) | |||
394 | out_free_host: | 388 | out_free_host: |
395 | kfree(msic->irq_host); | 389 | kfree(msic->irq_host); |
396 | out_free_fifo: | 390 | out_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); | ||
398 | out_free_msic: | 393 | out_free_msic: |
399 | kfree(msic); | 394 | kfree(msic); |
400 | out: | 395 | out: |
@@ -402,28 +397,24 @@ out: | |||
402 | return -1; | 397 | return -1; |
403 | } | 398 | } |
404 | 399 | ||
405 | static int axon_msi_init(void) | 400 | static 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"); | 407 | static 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; | 416 | static int __init axon_msi_init(void) |
417 | { | ||
418 | return of_register_platform_driver(&axon_msi_driver); | ||
428 | } | 419 | } |
429 | arch_initcall(axon_msi_init); | 420 | subsys_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 | } |
101 | machine_device_initcall(cell, cell_publish_devices); | 101 | machine_subsys_initcall(cell, cell_publish_devices); |
102 | 102 | ||
103 | static void cell_mpic_cascade(unsigned int irq, struct irq_desc *desc) | 103 | static 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 | |||
4 | spufs-y += sched.o backing_ops.o hw_ops.o run.o gang.o | 4 | spufs-y += sched.o backing_ops.o hw_ops.o run.o gang.o |
5 | spufs-y += switch.o fault.o lscsa_alloc.o | 5 | spufs-y += switch.o fault.o lscsa_alloc.o |
6 | 6 | ||
7 | obj-$(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 |
8 | SPU_CROSS := spu- | 10 | SPU_CROSS := spu- |
9 | SPU_CC := $(SPU_CROSS)gcc | 11 | SPU_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(¤t->mm->mmap_sem); | 380 | up_read(¤t->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(¤t->mm->mmap_sem); | 384 | down_read(¤t->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 * | |||
322 | spufs_assert_affinity(unsigned int flags, struct spu_gang *gang, | 322 | spufs_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 | |||
387 | out_put_neighbor: | ||
388 | put_spu_context(neighbor); | ||
389 | return err; | ||
380 | } | 390 | } |
381 | 391 | ||
382 | static void | 392 | static 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 | */ |
217 | static void spu_bind_context(struct spu *spu, struct spu_context *ctx) | 218 | static 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 | */ |
400 | static void spu_unbind_context(struct spu *spu, struct spu_context *ctx) | 401 | static 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 | */ |
823 | void spu_deactivate(struct spu_context *ctx) | 831 | void 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 | */ |
836 | void spu_yield(struct spu_context *ctx) | 845 | void 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 | } |
874 | out: | 888 | out: |
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); | |||
325 | extern void spuctx_switch_state(struct spu_context *ctx, | 325 | extern 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 | |||
19 | struct spu_probe { | ||
20 | const char *name; | ||
21 | const char *format; | ||
22 | marker_probe_func *probe_func; | ||
23 | }; | ||
24 | |||
25 | struct sputrace { | ||
26 | ktime_t tstamp; | ||
27 | int owner_tid; /* owner */ | ||
28 | int curr_tid; | ||
29 | const char *name; | ||
30 | int number; | ||
31 | }; | ||
32 | |||
33 | static int bufsize __read_mostly = 16384; | ||
34 | MODULE_PARM_DESC(bufsize, "Log buffer size (number of records)"); | ||
35 | module_param(bufsize, int, 0); | ||
36 | |||
37 | |||
38 | static DEFINE_SPINLOCK(sputrace_lock); | ||
39 | static DECLARE_WAIT_QUEUE_HEAD(sputrace_wait); | ||
40 | static ktime_t sputrace_start; | ||
41 | static unsigned long sputrace_head, sputrace_tail; | ||
42 | static struct sputrace *sputrace_log; | ||
43 | |||
44 | static int sputrace_used(void) | ||
45 | { | ||
46 | return (sputrace_head - sputrace_tail) % bufsize; | ||
47 | } | ||
48 | |||
49 | static inline int sputrace_avail(void) | ||
50 | { | ||
51 | return bufsize - sputrace_used(); | ||
52 | } | ||
53 | |||
54 | static 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 | |||
70 | static 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 | |||
110 | static 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 | |||
120 | static const struct file_operations sputrace_fops = { | ||
121 | .owner = THIS_MODULE, | ||
122 | .open = sputrace_open, | ||
123 | .read = sputrace_read, | ||
124 | }; | ||
125 | |||
126 | static 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 | |||
149 | static 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 | |||
165 | static 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 | |||
179 | struct 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 | |||
199 | static 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 | |||
230 | out_free_log: | ||
231 | kfree(sputrace_log); | ||
232 | out: | ||
233 | return -ENOMEM; | ||
234 | } | ||
235 | |||
236 | static 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 | |||
247 | module_init(sputrace_init); | ||
248 | module_exit(sputrace_exit); | ||
249 | |||
250 | MODULE_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 | ||
184 | define_machine(storcenter){ | 169 | define_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) | |||
54 | static void pseries_kexec_cpu_down_xics(int crash_shutdown, int secondary) | 54 | static 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 | ||
60 | void __init setup_kexec_cpu_down_xics(void) | 60 | void __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 | ||
163 | static 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 |
165 | static int get_irq_server(unsigned int virq, unsigned int strict_check) | 205 | static 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 | ||
661 | static 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 | |||
686 | void __init xics_init_IRQ(void) | 704 | void __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 | } | ||
738 | skip_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 | ||
778 | void xics_teardown_cpu(int secondary) | 766 | void 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 | |||
781 | void 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; | ||
885 | unlock: | 879 | unlock: |
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 | ||
17 | extern void xics_init_IRQ(void); | 17 | extern void xics_init_IRQ(void); |
18 | extern void xics_setup_cpu(void); | 18 | extern void xics_setup_cpu(void); |
19 | extern void xics_teardown_cpu(int secondary); | 19 | extern void xics_teardown_cpu(void); |
20 | extern void xics_kexec_teardown_cpu(int secondary); | ||
20 | extern void xics_cause_IPI(int cpu); | 21 | extern void xics_cause_IPI(int cpu); |
21 | extern void xics_request_IPIs(void); | 22 | extern void xics_request_IPIs(void); |
22 | extern void xics_migrate_irqs_away(void); | 23 | extern 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 | } |
139 | EXPORT_SYMBOL_GPL(dcr_unmap); | 139 | EXPORT_SYMBOL_GPL(dcr_unmap); |
140 | 140 | #else /* defined(CONFIG_PPC_DCR_NATIVE) */ | |
141 | #endif /* !defined(CONFIG_PPC_DCR_NATIVE) */ | 141 | DEFINE_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 | ||
187 | out: | 191 | out: |
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; |