aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2008-02-07 12:02:26 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2008-02-07 12:02:26 -0500
commit37969581301e50872a1ae84dc73962b5f7ee6b76 (patch)
tree35bbd6a07f903f248f4bd209b8d194a922415fe0
parent80ff8a805113850a3ffafcc8e6eaa1fdd51b02f3 (diff)
parent24f1a849614ba1805e26a05da7cc8c6bd67490ea (diff)
Merge branch 'for-2.6.25' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc
* 'for-2.6.25' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc: (69 commits) [POWERPC] Add SPE registers to core dumps [POWERPC] Use regset code for compat PTRACE_*REGS* calls [POWERPC] Use generic compat_sys_ptrace [POWERPC] Use generic compat_ptrace_request [POWERPC] Use generic ptrace peekdata/pokedata [POWERPC] Use regset code for PTRACE_*REGS* requests [POWERPC] Switch to generic compat_binfmt_elf code [POWERPC] Switch to using user_regset-based core dumps [POWERPC] Add user_regset compat support [POWERPC] Add user_regset_view definitions [POWERPC] Use user_regset accessors for GPRs [POWERPC] ptrace accessors for special regs MSR and TRAP [POWERPC] Use user_regset accessors for SPE regs [POWERPC] Use user_regset accessors for altivec regs [POWERPC] Use user_regset accessors for FP regs [POWERPC] mpc52xx: fix compile error introduce when rebasing patch [POWERPC] 4xx: PCIe indirect DCR spinlock fix. [POWERPC] Add missing native dcr dcr_ind_lock spinlock [POWERPC] 4xx: Fix offset value on Warp board [POWERPC] 4xx: Add 440EPx Sequoia ehci dts entry ...
-rw-r--r--Documentation/powerpc/booting-without-of.txt42
-rw-r--r--arch/powerpc/Kconfig22
-rw-r--r--arch/powerpc/Makefile9
-rw-r--r--arch/powerpc/boot/Makefile126
-rw-r--r--arch/powerpc/boot/cuboot-mpc7448hpc2.c (renamed from arch/powerpc/boot/cuboot-hpc2.c)0
-rw-r--r--arch/powerpc/boot/dts/adder875-redboot.dts1
-rw-r--r--arch/powerpc/boot/dts/adder875-uboot.dts1
-rw-r--r--arch/powerpc/boot/dts/mpc5121ads.dts122
-rw-r--r--arch/powerpc/boot/dts/mpc8313erdb.dts4
-rw-r--r--arch/powerpc/boot/dts/mpc8315erdb.dts2
-rw-r--r--arch/powerpc/boot/dts/mpc834x_mds.dts2
-rw-r--r--arch/powerpc/boot/dts/mpc8572ds.dts12
-rw-r--r--arch/powerpc/boot/dts/mpc885ads.dts1
-rw-r--r--arch/powerpc/boot/dts/sequoia.dts8
-rw-r--r--arch/powerpc/boot/dts/storcenter.dts12
-rwxr-xr-xarch/powerpc/boot/wrapper23
-rw-r--r--arch/powerpc/configs/mpc83xx_defconfig10
-rw-r--r--arch/powerpc/kernel/Makefile4
-rw-r--r--arch/powerpc/kernel/asm-offsets.c3
-rw-r--r--arch/powerpc/kernel/binfmt_elf32.c69
-rw-r--r--arch/powerpc/kernel/cputable.c10
-rw-r--r--arch/powerpc/kernel/legacy_serial.c3
-rw-r--r--arch/powerpc/kernel/pmc.c2
-rw-r--r--arch/powerpc/kernel/ptrace.c727
-rw-r--r--arch/powerpc/kernel/ptrace32.c161
-rw-r--r--arch/powerpc/kernel/traps.c2
-rw-r--r--arch/powerpc/kernel/vio.c2
-rw-r--r--arch/powerpc/mm/mem.c7
-rw-r--r--arch/powerpc/mm/numa.c66
-rw-r--r--arch/powerpc/oprofile/Makefile2
-rw-r--r--arch/powerpc/oprofile/common.c6
-rw-r--r--arch/powerpc/oprofile/op_model_fsl_emb.c (renamed from arch/powerpc/oprofile/op_model_fsl_booke.c)28
-rw-r--r--arch/powerpc/platforms/40x/Kconfig1
-rw-r--r--arch/powerpc/platforms/40x/virtex.c2
-rw-r--r--arch/powerpc/platforms/40x/walnut.c1
-rw-r--r--arch/powerpc/platforms/44x/warp.c2
-rw-r--r--arch/powerpc/platforms/512x/Kconfig20
-rw-r--r--arch/powerpc/platforms/512x/Makefile4
-rw-r--r--arch/powerpc/platforms/512x/mpc5121_ads.c104
-rw-r--r--arch/powerpc/platforms/82xx/mpc8272_ads.c3
-rw-r--r--arch/powerpc/platforms/82xx/pq2fads.c3
-rw-r--r--arch/powerpc/platforms/83xx/mpc832x_rdb.c2
-rw-r--r--arch/powerpc/platforms/83xx/mpc83xx.h2
-rw-r--r--arch/powerpc/platforms/83xx/usb.c17
-rw-r--r--arch/powerpc/platforms/8xx/adder875.c6
-rw-r--r--arch/powerpc/platforms/8xx/ep88xc.c1
-rw-r--r--arch/powerpc/platforms/Kconfig2
-rw-r--r--arch/powerpc/platforms/Kconfig.cputype10
-rw-r--r--arch/powerpc/platforms/Makefile1
-rw-r--r--arch/powerpc/platforms/cell/Kconfig7
-rw-r--r--arch/powerpc/platforms/cell/axon_msi.c99
-rw-r--r--arch/powerpc/platforms/cell/setup.c2
-rw-r--r--arch/powerpc/platforms/cell/spufs/Makefile2
-rw-r--r--arch/powerpc/platforms/cell/spufs/file.c6
-rw-r--r--arch/powerpc/platforms/cell/spufs/inode.c29
-rw-r--r--arch/powerpc/platforms/cell/spufs/run.c7
-rw-r--r--arch/powerpc/platforms/cell/spufs/sched.c28
-rw-r--r--arch/powerpc/platforms/cell/spufs/spufs.h5
-rw-r--r--arch/powerpc/platforms/cell/spufs/sputrace.c250
-rw-r--r--arch/powerpc/platforms/embedded6xx/storcenter.c25
-rw-r--r--arch/powerpc/platforms/pseries/hotplug-cpu.c2
-rw-r--r--arch/powerpc/platforms/pseries/kexec.c2
-rw-r--r--arch/powerpc/platforms/pseries/reconfig.c1
-rw-r--r--arch/powerpc/platforms/pseries/xics.c118
-rw-r--r--arch/powerpc/platforms/pseries/xics.h3
-rw-r--r--arch/powerpc/sysdev/dcr.c5
-rw-r--r--arch/powerpc/sysdev/fsl_soc.c2
-rw-r--r--arch/powerpc/sysdev/mpc8xx_pic.c10
-rw-r--r--arch/powerpc/sysdev/qe_lib/qe.c10
-rw-r--r--drivers/block/xsysace.c6
-rw-r--r--drivers/cdrom/viocd.c2
-rw-r--r--drivers/char/Kconfig10
-rw-r--r--drivers/char/Makefile1
-rw-r--r--drivers/char/xilinx_hwicap/Makefile7
-rw-r--r--drivers/char/xilinx_hwicap/buffer_icap.c380
-rw-r--r--drivers/char/xilinx_hwicap/buffer_icap.h57
-rw-r--r--drivers/char/xilinx_hwicap/fifo_icap.c381
-rw-r--r--drivers/char/xilinx_hwicap/fifo_icap.h62
-rw-r--r--drivers/char/xilinx_hwicap/xilinx_hwicap.c904
-rw-r--r--drivers/char/xilinx_hwicap/xilinx_hwicap.h193
-rw-r--r--drivers/net/Kconfig4
-rw-r--r--drivers/net/cpmac.c55
-rw-r--r--drivers/of/base.c25
-rw-r--r--drivers/of/platform.c10
-rw-r--r--drivers/serial/Kconfig12
-rw-r--r--drivers/serial/mpc52xx_uart.c424
-rw-r--r--drivers/serial/uartlite.c53
-rw-r--r--drivers/video/xilinxfb.c4
-rw-r--r--include/asm-powerpc/cputable.h2
-rw-r--r--include/asm-powerpc/dcr-native.h47
-rw-r--r--include/asm-powerpc/elf.h2
-rw-r--r--include/asm-powerpc/mpc512x.h22
-rw-r--r--include/asm-powerpc/mpc52xx_psc.h48
-rw-r--r--include/asm-powerpc/oprofile_impl.h2
-rw-r--r--include/asm-powerpc/ptrace.h2
-rw-r--r--include/asm-powerpc/reg.h4
-rw-r--r--include/asm-powerpc/reg_booke.h62
-rw-r--r--include/asm-powerpc/reg_fsl_emb.h72
-rw-r--r--include/asm-powerpc/system.h2
-rw-r--r--include/asm-powerpc/vio.h2
-rw-r--r--include/linux/elf.h1
-rw-r--r--include/linux/of.h1
102 files changed, 4173 insertions, 969 deletions
diff --git a/Documentation/powerpc/booting-without-of.txt b/Documentation/powerpc/booting-without-of.txt
index b5e46efeba84..7b4e8a70882c 100644
--- a/Documentation/powerpc/booting-without-of.txt
+++ b/Documentation/powerpc/booting-without-of.txt
@@ -57,6 +57,7 @@ Table of Contents
57 n) 4xx/Axon EMAC ethernet nodes 57 n) 4xx/Axon EMAC ethernet nodes
58 o) Xilinx IP cores 58 o) Xilinx IP cores
59 p) Freescale Synchronous Serial Interface 59 p) Freescale Synchronous Serial Interface
60 q) USB EHCI controllers
60 61
61 VII - Specifying interrupt information for devices 62 VII - Specifying interrupt information for devices
62 1) interrupts property 63 1) interrupts property
@@ -2577,6 +2578,20 @@ platforms are moved over to use the flattened-device-tree model.
2577 Requred properties: 2578 Requred properties:
2578 - current-speed : Baud rate of uartlite 2579 - current-speed : Baud rate of uartlite
2579 2580
2581 v) Xilinx hwicap
2582
2583 Xilinx hwicap devices provide access to the configuration logic
2584 of the FPGA through the Internal Configuration Access Port
2585 (ICAP). The ICAP enables partial reconfiguration of the FPGA,
2586 readback of the configuration information, and some control over
2587 'warm boots' of the FPGA fabric.
2588
2589 Required properties:
2590 - xlnx,family : The family of the FPGA, necessary since the
2591 capabilities of the underlying ICAP hardware
2592 differ between different families. May be
2593 'virtex2p', 'virtex4', or 'virtex5'.
2594
2580 p) Freescale Synchronous Serial Interface 2595 p) Freescale Synchronous Serial Interface
2581 2596
2582 The SSI is a serial device that communicates with audio codecs. It can 2597 The SSI is a serial device that communicates with audio codecs. It can
@@ -2775,6 +2790,33 @@ platforms are moved over to use the flattened-device-tree model.
2775 interrupt-parent = < &ipic >; 2790 interrupt-parent = < &ipic >;
2776 }; 2791 };
2777 2792
2793 q) USB EHCI controllers
2794
2795 Required properties:
2796 - compatible : should be "usb-ehci".
2797 - reg : should contain at least address and length of the standard EHCI
2798 register set for the device. Optional platform-dependent registers
2799 (debug-port or other) can be also specified here, but only after
2800 definition of standard EHCI registers.
2801 - interrupts : one EHCI interrupt should be described here.
2802 If device registers are implemented in big endian mode, the device
2803 node should have "big-endian-regs" property.
2804 If controller implementation operates with big endian descriptors,
2805 "big-endian-desc" property should be specified.
2806 If both big endian registers and descriptors are used by the controller
2807 implementation, "big-endian" property can be specified instead of having
2808 both "big-endian-regs" and "big-endian-desc".
2809
2810 Example (Sequoia 440EPx):
2811 ehci@e0000300 {
2812 compatible = "ibm,usb-ehci-440epx", "usb-ehci";
2813 interrupt-parent = <&UIC0>;
2814 interrupts = <1a 4>;
2815 reg = <0 e0000300 90 0 e0000390 70>;
2816 big-endian;
2817 };
2818
2819
2778 More devices will be defined as this spec matures. 2820 More devices will be defined as this spec matures.
2779 2821
2780VII - Specifying interrupt information for devices 2822VII - Specifying interrupt information for devices
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index cf030b004415..8dcac0b22d68 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -97,6 +97,7 @@ config EARLY_PRINTK
97config COMPAT 97config COMPAT
98 bool 98 bool
99 default y if PPC64 99 default y if PPC64
100 select COMPAT_BINFMT_ELF
100 101
101config SYSVIPC_COMPAT 102config SYSVIPC_COMPAT
102 bool 103 bool
@@ -438,25 +439,6 @@ config WANT_DEVICE_TREE
438 bool 439 bool
439 default n 440 default n
440 441
441config DEVICE_TREE
442 string "Static device tree source file"
443 depends on WANT_DEVICE_TREE
444 help
445 This specifies the device tree source (.dts) file to be
446 compiled and included when building the bootwrapper. If a
447 relative filename is given, then it will be relative to
448 arch/powerpc/boot/dts. If you are not using the bootwrapper,
449 or do not need to build a dts into the bootwrapper, this
450 field is ignored.
451
452 For example, this is required when building a cuImage target
453 for an older U-Boot, which cannot pass a device tree itself.
454 Such a kernel will not work with a newer U-Boot that tries to
455 pass a device tree (unless you tell it not to). If your U-Boot
456 does not mention a device tree in "help bootm", then use the
457 cuImage target and specify a device tree here. Otherwise, use
458 the uImage target and leave this field blank.
459
460endmenu 442endmenu
461 443
462config ISA_DMA_API 444config ISA_DMA_API
@@ -512,7 +494,7 @@ config PCI
512 bool "PCI support" if 40x || CPM2 || PPC_83xx || PPC_85xx || PPC_86xx \ 494 bool "PCI support" if 40x || CPM2 || PPC_83xx || PPC_85xx || PPC_86xx \
513 || PPC_MPC52xx || (EMBEDDED && (PPC_PSERIES || PPC_ISERIES)) \ 495 || PPC_MPC52xx || (EMBEDDED && (PPC_PSERIES || PPC_ISERIES)) \
514 || PPC_PS3 || 44x 496 || PPC_PS3 || 44x
515 default y if !40x && !CPM2 && !8xx && !PPC_83xx \ 497 default y if !40x && !CPM2 && !8xx && !PPC_MPC512x && !PPC_83xx \
516 && !PPC_85xx && !PPC_86xx 498 && !PPC_85xx && !PPC_86xx
517 default PCI_PERMEDIA if !4xx && !CPM2 && !8xx 499 default PCI_PERMEDIA if !4xx && !CPM2 && !8xx
518 default PCI_QSPAN if !4xx && !CPM2 && 8xx 500 default PCI_QSPAN if !4xx && !CPM2 && 8xx
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
index f70df9b64f8f..6845482f0093 100644
--- a/arch/powerpc/Makefile
+++ b/arch/powerpc/Makefile
@@ -151,14 +151,11 @@ core-$(CONFIG_XMON) += arch/powerpc/xmon/
151drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/ 151drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/
152 152
153# Default to zImage, override when needed 153# Default to zImage, override when needed
154defaultimage-y := zImage 154all: zImage
155defaultimage-$(CONFIG_DEFAULT_UIMAGE) := uImage
156KBUILD_IMAGE := $(defaultimage-y)
157all: $(KBUILD_IMAGE)
158 155
159CPPFLAGS_vmlinux.lds := -Upowerpc 156CPPFLAGS_vmlinux.lds := -Upowerpc
160 157
161BOOT_TARGETS = zImage zImage.initrd uImage 158BOOT_TARGETS = zImage zImage.initrd uImage treeImage.% cuImage.%
162 159
163PHONY += $(BOOT_TARGETS) 160PHONY += $(BOOT_TARGETS)
164 161
@@ -180,7 +177,7 @@ define archhelp
180endef 177endef
181 178
182install: vdso_install 179install: vdso_install
183 $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) install 180 $(Q)$(MAKE) $(build)=$(boot) install
184 181
185vdso_install: 182vdso_install:
186ifeq ($(CONFIG_PPC64),y) 183ifeq ($(CONFIG_PPC64),y)
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
index 122a27078998..49797a45416c 100644
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -60,8 +60,9 @@ src-wlib := string.S crt0.S stdio.c main.c \
60src-plat := of.c cuboot-52xx.c cuboot-824x.c cuboot-83xx.c cuboot-85xx.c holly.c \ 60src-plat := of.c cuboot-52xx.c cuboot-824x.c cuboot-83xx.c cuboot-85xx.c holly.c \
61 cuboot-ebony.c treeboot-ebony.c prpmc2800.c \ 61 cuboot-ebony.c treeboot-ebony.c prpmc2800.c \
62 ps3-head.S ps3-hvcall.S ps3.c treeboot-bamboo.c cuboot-8xx.c \ 62 ps3-head.S ps3-hvcall.S ps3.c treeboot-bamboo.c cuboot-8xx.c \
63 cuboot-pq2.c cuboot-sequoia.c treeboot-walnut.c cuboot-bamboo.c \ 63 cuboot-pq2.c cuboot-sequoia.c treeboot-walnut.c \
64 fixed-head.S ep88xc.c cuboot-hpc2.c ep405.c cuboot-taishan.c \ 64 cuboot-bamboo.c cuboot-mpc7448hpc2.c cuboot-taishan.c \
65 fixed-head.S ep88xc.c ep405.c \
65 cuboot-katmai.c cuboot-rainier.c redboot-8xx.c ep8248e.c \ 66 cuboot-katmai.c cuboot-rainier.c redboot-8xx.c ep8248e.c \
66 cuboot-warp.c cuboot-85xx-cpm2.c 67 cuboot-warp.c cuboot-85xx-cpm2.c
67src-boot := $(src-wlib) $(src-plat) empty.c 68src-boot := $(src-wlib) $(src-plat) empty.c
@@ -123,6 +124,8 @@ targets += $(patsubst $(obj)/%,%,$(obj-boot) wrapper.a)
123extra-y := $(obj)/wrapper.a $(obj-plat) $(obj)/empty.o \ 124extra-y := $(obj)/wrapper.a $(obj-plat) $(obj)/empty.o \
124 $(obj)/zImage.lds $(obj)/zImage.coff.lds $(obj)/zImage.ps3.lds 125 $(obj)/zImage.lds $(obj)/zImage.coff.lds $(obj)/zImage.ps3.lds
125 126
127dtstree := $(srctree)/$(src)/dts
128
126wrapper :=$(srctree)/$(src)/wrapper 129wrapper :=$(srctree)/$(src)/wrapper
127wrapperbits := $(extra-y) $(addprefix $(obj)/,addnote hack-coff mktree dtc) \ 130wrapperbits := $(extra-y) $(addprefix $(obj)/,addnote hack-coff mktree dtc) \
128 $(wrapper) FORCE 131 $(wrapper) FORCE
@@ -181,7 +184,7 @@ quiet_cmd_wrap = WRAP $@
181image-$(CONFIG_PPC_PSERIES) += zImage.pseries 184image-$(CONFIG_PPC_PSERIES) += zImage.pseries
182image-$(CONFIG_PPC_MAPLE) += zImage.pseries 185image-$(CONFIG_PPC_MAPLE) += zImage.pseries
183image-$(CONFIG_PPC_IBM_CELL_BLADE) += zImage.pseries 186image-$(CONFIG_PPC_IBM_CELL_BLADE) += zImage.pseries
184image-$(CONFIG_PPC_PS3) += zImage.ps3 187image-$(CONFIG_PPC_PS3) += zImage-dtb.ps3
185image-$(CONFIG_PPC_CELLEB) += zImage.pseries 188image-$(CONFIG_PPC_CELLEB) += zImage.pseries
186image-$(CONFIG_PPC_CHRP) += zImage.chrp 189image-$(CONFIG_PPC_CHRP) += zImage.chrp
187image-$(CONFIG_PPC_EFIKA) += zImage.chrp 190image-$(CONFIG_PPC_EFIKA) += zImage.chrp
@@ -191,33 +194,69 @@ image-$(CONFIG_PPC_PRPMC2800) += zImage.prpmc2800
191image-$(CONFIG_PPC_ISERIES) += zImage.iseries 194image-$(CONFIG_PPC_ISERIES) += zImage.iseries
192image-$(CONFIG_DEFAULT_UIMAGE) += uImage 195image-$(CONFIG_DEFAULT_UIMAGE) += uImage
193 196
194ifneq ($(CONFIG_DEVICE_TREE),"") 197#
195image-$(CONFIG_PPC_8xx) += cuImage.8xx 198# Targets which embed a device tree blob
196image-$(CONFIG_PPC_EP88XC) += zImage.ep88xc 199#
197image-$(CONFIG_EP405) += zImage.ep405 200# Theses are default targets to build images which embed device tree blobs.
198image-$(CONFIG_8260) += cuImage.pq2 201# They are only required on boards which do not have FDT support in firmware.
199image-$(CONFIG_EP8248E) += zImage.ep8248e 202# Boards with newish u-boot firmare can use the uImage target above
200image-$(CONFIG_PPC_MPC52xx) += cuImage.52xx 203#
201image-$(CONFIG_STORCENTER) += cuImage.824x 204
202image-$(CONFIG_PPC_83xx) += cuImage.83xx 205# Board ports in arch/powerpc/platform/40x/Kconfig
203image-$(CONFIG_PPC_85xx) += cuImage.85xx 206image-$(CONFIG_EP405) += zImage-dtb.ep405
204ifeq ($(CONFIG_CPM2),y) 207image-$(CONFIG_WALNUT) += treeImage.walnut
205image-$(CONFIG_PPC_85xx) += cuImage.85xx-cpm2 208
206endif 209# Board ports in arch/powerpc/platform/44x/Kconfig
207image-$(CONFIG_MPC7448HPC2) += cuImage.hpc2
208image-$(CONFIG_EBONY) += treeImage.ebony cuImage.ebony 210image-$(CONFIG_EBONY) += treeImage.ebony cuImage.ebony
209image-$(CONFIG_BAMBOO) += treeImage.bamboo cuImage.bamboo 211image-$(CONFIG_BAMBOO) += treeImage.bamboo cuImage.bamboo
210image-$(CONFIG_SEQUOIA) += cuImage.sequoia 212image-$(CONFIG_SEQUOIA) += cuImage.sequoia
211image-$(CONFIG_RAINIER) += cuImage.rainier 213image-$(CONFIG_RAINIER) += cuImage.rainier
212image-$(CONFIG_WALNUT) += treeImage.walnut
213image-$(CONFIG_TAISHAN) += cuImage.taishan 214image-$(CONFIG_TAISHAN) += cuImage.taishan
214image-$(CONFIG_KATMAI) += cuImage.katmai 215image-$(CONFIG_KATMAI) += cuImage.katmai
215image-$(CONFIG_WARP) += cuImage.warp 216image-$(CONFIG_WARP) += cuImage.warp
216endif
217 217
218ifneq ($(CONFIG_REDBOOT),"") 218# Board ports in arch/powerpc/platform/8xx/Kconfig
219image-$(CONFIG_PPC_8xx) += zImage.redboot-8xx 219image-$(CONFIG_PPC_MPC86XADS) += cuImage.mpc866ads
220endif 220image-$(CONFIG_PPC_MPC885ADS) += cuImage.mpc885ads
221image-$(CONFIG_PPC_EP88XC) += zImage-dtb.ep88xc
222image-$(CONFIG_PPC_ADDER875) += cuImage.adder875-uboot \
223 zImage-dtb.adder875-redboot
224
225# Board ports in arch/powerpc/platform/52xx/Kconfig
226image-$(CONFIG_PPC_LITE5200) += cuImage.lite5200 cuImage.lite5200b
227
228# Board ports in arch/powerpc/platform/82xx/Kconfig
229image-$(CONFIG_MPC8272_ADS) += cuImage.mpc8272ads
230image-$(CONFIG_PQ2FADS) += cuImage.pq2fads
231image-$(CONFIG_EP8248E) += zImage-dtb.ep8248e
232
233# Board ports in arch/powerpc/platform/83xx/Kconfig
234image-$(CONFIG_MPC832x_MDS) += cuImage.mpc832x_mds
235image-$(CONFIG_MPC832x_RDB) += cuImage.mpc832x_rdb
236image-$(CONFIG_MPC834x_ITX) += cuImage.mpc8349emitx \
237 cuImage.mpc8349emitxgp
238image-$(CONFIG_MPC834x_MDS) += cuImage.mpc834x_mds
239image-$(CONFIG_MPC836x_MDS) += cuImage.mpc836x_mds
240
241# Board ports in arch/powerpc/platform/85xx/Kconfig
242image-$(CONFIG_MPC8540_ADS) += cuImage.mpc8540ads
243image-$(CONFIG_MPC8560_ADS) += cuImage.mpc8560ads
244image-$(CONFIG_MPC85xx_CDS) += cuImage.mpc8541cds \
245 cuImage.mpc8548cds \
246 cuImage.mpc8555cds
247image-$(CONFIG_MPC85xx_MDS) += cuImage.mpc8568mds
248image-$(CONFIG_MPC85xx_DS) += cuImage.mpc8544ds \
249 cuImage.mpc8572ds
250image-$(CONFIG_TQM8540) += cuImage.tqm8540
251image-$(CONFIG_TQM8541) += cuImage.tqm8541
252image-$(CONFIG_TQM8555) += cuImage.tqm8555
253image-$(CONFIG_TQM8560) += cuImage.tqm8560
254image-$(CONFIG_SBC8548) += cuImage.tqm8548
255image-$(CONFIG_SBC8560) += cuImage.tqm8560
256
257# Board ports in arch/powerpc/platform/embedded6xx/Kconfig
258image-$(CONFIG_STORCENTER) += cuImage.storcenter
259image-$(CONFIG_MPC7448HPC2) += cuImage.mpc7448hpc2
221 260
222# For 32-bit powermacs, build the COFF and miboot images 261# For 32-bit powermacs, build the COFF and miboot images
223# as well as the ELF images. 262# as well as the ELF images.
@@ -233,24 +272,20 @@ targets += $(image-y) $(initrd-y)
233 272
234$(addprefix $(obj)/, $(initrd-y)): $(obj)/ramdisk.image.gz 273$(addprefix $(obj)/, $(initrd-y)): $(obj)/ramdisk.image.gz
235 274
236# If CONFIG_WANT_DEVICE_TREE is set and CONFIG_DEVICE_TREE isn't an
237# empty string, define 'dts' to be path to the dts
238# CONFIG_DEVICE_TREE will have "" around it, make sure to strip them
239ifeq ($(CONFIG_WANT_DEVICE_TREE),y)
240ifneq ($(CONFIG_DEVICE_TREE),"")
241dts = $(if $(shell echo $(CONFIG_DEVICE_TREE) | grep '^/'),\
242 ,$(srctree)/$(src)/dts/)$(CONFIG_DEVICE_TREE:"%"=%)
243endif
244endif
245
246# Don't put the ramdisk on the pattern rule; when its missing make will try 275# Don't put the ramdisk on the pattern rule; when its missing make will try
247# the pattern rule with less dependencies that also matches (even with the 276# the pattern rule with less dependencies that also matches (even with the
248# hard dependency listed). 277# hard dependency listed).
249$(obj)/zImage.initrd.%: vmlinux $(wrapperbits) $(dts) 278$(obj)/zImage.initrd.%: vmlinux $(wrapperbits)
250 $(call if_changed,wrap,$*,$(dts),,$(obj)/ramdisk.image.gz) 279 $(call if_changed,wrap,$*,,,$(obj)/ramdisk.image.gz)
251 280
252$(obj)/zImage.%: vmlinux $(wrapperbits) $(dts) 281$(obj)/zImage.%: vmlinux $(wrapperbits)
253 $(call if_changed,wrap,$*,$(dts)) 282 $(call if_changed,wrap,$*)
283
284$(obj)/zImage-dtb.initrd.%: vmlinux $(wrapperbits) $(dtstree)/%.dts
285 $(call if_changed,wrap,$*,$(dtstree)/$*.dts,,$(obj)/ramdisk.image.gz)
286
287$(obj)/zImage-dtb.%: vmlinux $(wrapperbits) $(dtstree)/%.dts
288 $(call if_changed,wrap,$*,$(dtstree)/$*.dts)
254 289
255# This cannot be in the root of $(src) as the zImage rule always adds a $(obj) 290# This cannot be in the root of $(src) as the zImage rule always adds a $(obj)
256# prefix 291# prefix
@@ -260,24 +295,17 @@ $(obj)/vmlinux.strip: vmlinux
260$(obj)/zImage.iseries: vmlinux 295$(obj)/zImage.iseries: vmlinux
261 $(STRIP) -s -R .comment $< -o $@ 296 $(STRIP) -s -R .comment $< -o $@
262 297
263$(obj)/zImage.ps3: vmlinux $(wrapper) $(wrapperbits) $(srctree)/$(src)/dts/ps3.dts
264 $(STRIP) -s -R .comment $< -o vmlinux.strip
265 $(call cmd,wrap,ps3,$(srctree)/$(src)/dts/ps3.dts,,)
266
267$(obj)/zImage.initrd.ps3: vmlinux $(wrapper) $(wrapperbits) $(srctree)/$(src)/dts/ps3.dts $(obj)/ramdisk.image.gz
268 $(call cmd,wrap,ps3,$(srctree)/$(src)/dts/ps3.dts,,$(obj)/ramdisk.image.gz)
269
270$(obj)/uImage: vmlinux $(wrapperbits) 298$(obj)/uImage: vmlinux $(wrapperbits)
271 $(call if_changed,wrap,uboot) 299 $(call if_changed,wrap,uboot)
272 300
273$(obj)/cuImage.%: vmlinux $(dts) $(wrapperbits) 301$(obj)/cuImage.%: vmlinux $(dtstree)/%.dts $(wrapperbits)
274 $(call if_changed,wrap,cuboot-$*,$(dts)) 302 $(call if_changed,wrap,cuboot-$*,$(dtstree)/$*.dts)
275 303
276$(obj)/treeImage.initrd.%: vmlinux $(dts) $(wrapperbits) 304$(obj)/treeImage.initrd.%: vmlinux $(dtstree)/%.dts $(wrapperbits)
277 $(call if_changed,wrap,treeboot-$*,$(dts),,$(obj)/ramdisk.image.gz) 305 $(call if_changed,wrap,treeboot-$*,$(dtstree)/$*.dts,,$(obj)/ramdisk.image.gz)
278 306
279$(obj)/treeImage.%: vmlinux $(dts) $(wrapperbits) 307$(obj)/treeImage.%: vmlinux $(dtstree)/%.dts $(wrapperbits)
280 $(call if_changed,wrap,treeboot-$*,$(dts)) 308 $(call if_changed,wrap,treeboot-$*,$(dtstree)/$*.dts)
281 309
282# If there isn't a platform selected then just strip the vmlinux. 310# If there isn't a platform selected then just strip the vmlinux.
283ifeq (,$(image-y)) 311ifeq (,$(image-y))
diff --git a/arch/powerpc/boot/cuboot-hpc2.c b/arch/powerpc/boot/cuboot-mpc7448hpc2.c
index 1b8953259d75..1b8953259d75 100644
--- a/arch/powerpc/boot/cuboot-hpc2.c
+++ b/arch/powerpc/boot/cuboot-mpc7448hpc2.c
diff --git a/arch/powerpc/boot/dts/adder875-redboot.dts b/arch/powerpc/boot/dts/adder875-redboot.dts
index 930bfb3894eb..28e9cd3d7a21 100644
--- a/arch/powerpc/boot/dts/adder875-redboot.dts
+++ b/arch/powerpc/boot/dts/adder875-redboot.dts
@@ -151,6 +151,7 @@
151 compatible = "fsl,mpc875-brg", 151 compatible = "fsl,mpc875-brg",
152 "fsl,cpm1-brg", 152 "fsl,cpm1-brg",
153 "fsl,cpm-brg"; 153 "fsl,cpm-brg";
154 clock-frequency = <50000000>;
154 reg = <0x9f0 0x10>; 155 reg = <0x9f0 0x10>;
155 }; 156 };
156 157
diff --git a/arch/powerpc/boot/dts/adder875-uboot.dts b/arch/powerpc/boot/dts/adder875-uboot.dts
index 0197242dacfb..54fb60ec03e5 100644
--- a/arch/powerpc/boot/dts/adder875-uboot.dts
+++ b/arch/powerpc/boot/dts/adder875-uboot.dts
@@ -150,6 +150,7 @@
150 compatible = "fsl,mpc875-brg", 150 compatible = "fsl,mpc875-brg",
151 "fsl,cpm1-brg", 151 "fsl,cpm1-brg",
152 "fsl,cpm-brg"; 152 "fsl,cpm-brg";
153 clock-frequency = <50000000>;
153 reg = <0x9f0 0x10>; 154 reg = <0x9f0 0x10>;
154 }; 155 };
155 156
diff --git a/arch/powerpc/boot/dts/mpc5121ads.dts b/arch/powerpc/boot/dts/mpc5121ads.dts
new file mode 100644
index 000000000000..94ad7b2b241e
--- /dev/null
+++ b/arch/powerpc/boot/dts/mpc5121ads.dts
@@ -0,0 +1,122 @@
1/*
2 * MPC5121E MDS Device Tree Source
3 *
4 * Copyright 2007 Freescale Semiconductor Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 */
11
12/dts-v1/;
13
14/ {
15 model = "mpc5121ads";
16 compatible = "fsl,mpc5121ads";
17 #address-cells = <1>;
18 #size-cells = <1>;
19
20 cpus {
21 #address-cells = <1>;
22 #size-cells = <0>;
23
24 PowerPC,5121@0 {
25 device_type = "cpu";
26 reg = <0>;
27 d-cache-line-size = <0x20>; // 32 bytes
28 i-cache-line-size = <0x20>; // 32 bytes
29 d-cache-size = <0x8000>; // L1, 32K
30 i-cache-size = <0x8000>; // L1, 32K
31 timebase-frequency = <49500000>;// 49.5 MHz (csb/4)
32 bus-frequency = <198000000>; // 198 MHz csb bus
33 clock-frequency = <396000000>; // 396 MHz ppc core
34 };
35 };
36
37 memory {
38 device_type = "memory";
39 reg = <0x00000000 0x10000000>; // 256MB at 0
40 };
41
42 localbus@80000020 {
43 compatible = "fsl,mpc5121ads-localbus";
44 #address-cells = <2>;
45 #size-cells = <1>;
46 reg = <0x80000020 0x40>;
47
48 ranges = <0x0 0x0 0xfc000000 0x04000000
49 0x2 0x0 0x82000000 0x00008000>;
50
51 flash@0,0 {
52 compatible = "cfi-flash";
53 reg = <0 0x0 0x4000000>;
54 bank-width = <4>;
55 device-width = <1>;
56 };
57
58 board-control@2,0 {
59 compatible = "fsl,mpc5121ads-cpld";
60 reg = <0x2 0x0 0x8000>;
61 };
62 };
63
64 soc@80000000 {
65 compatible = "fsl,mpc5121-immr";
66 #address-cells = <1>;
67 #size-cells = <1>;
68 #interrupt-cells = <2>;
69 ranges = <0x0 0x80000000 0x400000>;
70 reg = <0x80000000 0x400000>;
71 bus-frequency = <66000000>; // 66 MHz ips bus
72
73
74 // IPIC
75 // interrupts cell = <intr #, sense>
76 // sense values match linux IORESOURCE_IRQ_* defines:
77 // sense == 8: Level, low assertion
78 // sense == 2: Edge, high-to-low change
79 //
80 ipic: interrupt-controller@c00 {
81 compatible = "fsl,mpc5121-ipic", "fsl,ipic";
82 interrupt-controller;
83 #address-cells = <0>;
84 #interrupt-cells = <2>;
85 reg = <0xc00 0x100>;
86 };
87
88 // 512x PSCs are not 52xx PSCs compatible
89 // PSC3 serial port A aka ttyPSC0
90 serial@11300 {
91 device_type = "serial";
92 compatible = "fsl,mpc5121-psc-uart";
93 // Logical port assignment needed until driver
94 // learns to use aliases
95 port-number = <0>;
96 cell-index = <3>;
97 reg = <0x11300 0x100>;
98 interrupts = <0x28 0x8>; // actually the fifo irq
99 interrupt-parent = < &ipic >;
100 };
101
102 // PSC4 serial port B aka ttyPSC1
103 serial@11400 {
104 device_type = "serial";
105 compatible = "fsl,mpc5121-psc-uart";
106 // Logical port assignment needed until driver
107 // learns to use aliases
108 port-number = <1>;
109 cell-index = <4>;
110 reg = <0x11400 0x100>;
111 interrupts = <0x28 0x8>; // actually the fifo irq
112 interrupt-parent = < &ipic >;
113 };
114
115 pscsfifo@11f00 {
116 compatible = "fsl,mpc5121-psc-fifo";
117 reg = <0x11f00 0x100>;
118 interrupts = <0x28 0x8>;
119 interrupt-parent = < &ipic >;
120 };
121 };
122};
diff --git a/arch/powerpc/boot/dts/mpc8313erdb.dts b/arch/powerpc/boot/dts/mpc8313erdb.dts
index 2d6653fe72ff..e1f0dca8ac39 100644
--- a/arch/powerpc/boot/dts/mpc8313erdb.dts
+++ b/arch/powerpc/boot/dts/mpc8313erdb.dts
@@ -118,6 +118,10 @@
118 interrupts = <14 0x8>; 118 interrupts = <14 0x8>;
119 interrupt-parent = <&ipic>; 119 interrupt-parent = <&ipic>;
120 dfsrr; 120 dfsrr;
121 rtc@68 {
122 compatible = "dallas,ds1339";
123 reg = <0x68>;
124 };
121 }; 125 };
122 126
123 i2c@3100 { 127 i2c@3100 {
diff --git a/arch/powerpc/boot/dts/mpc8315erdb.dts b/arch/powerpc/boot/dts/mpc8315erdb.dts
index b582032ba3d6..d7a1ececa30f 100644
--- a/arch/powerpc/boot/dts/mpc8315erdb.dts
+++ b/arch/powerpc/boot/dts/mpc8315erdb.dts
@@ -96,7 +96,7 @@
96 #address-cells = <1>; 96 #address-cells = <1>;
97 #size-cells = <1>; 97 #size-cells = <1>;
98 device_type = "soc"; 98 device_type = "soc";
99 compatible = "simple-bus"; 99 compatible = "fsl,mpc8315-immr", "simple-bus";
100 ranges = <0 0xe0000000 0x00100000>; 100 ranges = <0 0xe0000000 0x00100000>;
101 reg = <0xe0000000 0x00000200>; 101 reg = <0xe0000000 0x00000200>;
102 bus-frequency = <0>; 102 bus-frequency = <0>;
diff --git a/arch/powerpc/boot/dts/mpc834x_mds.dts b/arch/powerpc/boot/dts/mpc834x_mds.dts
index 7480edae85ed..0199c5c548d8 100644
--- a/arch/powerpc/boot/dts/mpc834x_mds.dts
+++ b/arch/powerpc/boot/dts/mpc834x_mds.dts
@@ -332,7 +332,7 @@
332 0xc000 0x0 0x0 0x3 &ipic 23 0x8 332 0xc000 0x0 0x0 0x3 &ipic 23 0x8
333 0xc000 0x0 0x0 0x4 &ipic 20 0x8>; 333 0xc000 0x0 0x0 0x4 &ipic 20 0x8>;
334 interrupt-parent = <&ipic>; 334 interrupt-parent = <&ipic>;
335 interrupts = <66 0x8>; 335 interrupts = <67 0x8>;
336 bus-range = <0 0>; 336 bus-range = <0 0>;
337 ranges = <0x02000000 0x0 0xb0000000 0xb0000000 0x0 0x10000000 337 ranges = <0x02000000 0x0 0xb0000000 0xb0000000 0x0 0x10000000
338 0x42000000 0x0 0xa0000000 0xa0000000 0x0 0x10000000 338 0x42000000 0x0 0xa0000000 0xa0000000 0x0 0x10000000
diff --git a/arch/powerpc/boot/dts/mpc8572ds.dts b/arch/powerpc/boot/dts/mpc8572ds.dts
index 813c259abbe5..db37214aee37 100644
--- a/arch/powerpc/boot/dts/mpc8572ds.dts
+++ b/arch/powerpc/boot/dts/mpc8572ds.dts
@@ -42,6 +42,18 @@
42 bus-frequency = <0>; 42 bus-frequency = <0>;
43 clock-frequency = <0>; 43 clock-frequency = <0>;
44 }; 44 };
45
46 PowerPC,8572@1 {
47 device_type = "cpu";
48 reg = <1>;
49 d-cache-line-size = <20>; // 32 bytes
50 i-cache-line-size = <20>; // 32 bytes
51 d-cache-size = <8000>; // L1, 32K
52 i-cache-size = <8000>; // L1, 32K
53 timebase-frequency = <0>;
54 bus-frequency = <0>;
55 clock-frequency = <0>;
56 };
45 }; 57 };
46 58
47 memory { 59 memory {
diff --git a/arch/powerpc/boot/dts/mpc885ads.dts b/arch/powerpc/boot/dts/mpc885ads.dts
index 8848e637293e..d84a012c2aaf 100644
--- a/arch/powerpc/boot/dts/mpc885ads.dts
+++ b/arch/powerpc/boot/dts/mpc885ads.dts
@@ -166,6 +166,7 @@
166 compatible = "fsl,mpc885-brg", 166 compatible = "fsl,mpc885-brg",
167 "fsl,cpm1-brg", 167 "fsl,cpm1-brg",
168 "fsl,cpm-brg"; 168 "fsl,cpm-brg";
169 clock-frequency = <0>;
169 reg = <9f0 10>; 170 reg = <9f0 10>;
170 }; 171 };
171 172
diff --git a/arch/powerpc/boot/dts/sequoia.dts b/arch/powerpc/boot/dts/sequoia.dts
index d9046c1adcbe..5c13d46f441d 100644
--- a/arch/powerpc/boot/dts/sequoia.dts
+++ b/arch/powerpc/boot/dts/sequoia.dts
@@ -138,6 +138,14 @@
138 interrupts = <15 8>; 138 interrupts = <15 8>;
139 }; 139 };
140 140
141 USB0: ehci@e0000300 {
142 compatible = "ibm,usb-ehci-440epx", "usb-ehci";
143 interrupt-parent = <&UIC0>;
144 interrupts = <1a 4>;
145 reg = <0 e0000300 90 0 e0000390 70>;
146 big-endian;
147 };
148
141 POB0: opb { 149 POB0: opb {
142 compatible = "ibm,opb-440epx", "ibm,opb"; 150 compatible = "ibm,opb-440epx", "ibm,opb";
143 #address-cells = <1>; 151 #address-cells = <1>;
diff --git a/arch/powerpc/boot/dts/storcenter.dts b/arch/powerpc/boot/dts/storcenter.dts
index 2204874ac5f3..5893816c0bce 100644
--- a/arch/powerpc/boot/dts/storcenter.dts
+++ b/arch/powerpc/boot/dts/storcenter.dts
@@ -15,7 +15,7 @@
15 15
16/ { 16/ {
17 model = "StorCenter"; 17 model = "StorCenter";
18 compatible = "storcenter"; 18 compatible = "iomega,storcenter";
19 #address-cells = <1>; 19 #address-cells = <1>;
20 #size-cells = <1>; 20 #size-cells = <1>;
21 21
@@ -62,12 +62,12 @@
62 #size-cells = <0>; 62 #size-cells = <0>;
63 compatible = "fsl-i2c"; 63 compatible = "fsl-i2c";
64 reg = <0x3000 0x100>; 64 reg = <0x3000 0x100>;
65 interrupts = <5 2>; 65 interrupts = <17 2>;
66 interrupt-parent = <&mpic>; 66 interrupt-parent = <&mpic>;
67 67
68 rtc@68 { 68 rtc@68 {
69 compatible = "dallas,ds1337"; 69 compatible = "dallas,ds1337";
70 reg = <68>; 70 reg = <0x68>;
71 }; 71 };
72 }; 72 };
73 73
@@ -78,7 +78,7 @@
78 reg = <0x4500 0x20>; 78 reg = <0x4500 0x20>;
79 clock-frequency = <97553800>; /* Hz */ 79 clock-frequency = <97553800>; /* Hz */
80 current-speed = <115200>; 80 current-speed = <115200>;
81 interrupts = <9 2>; 81 interrupts = <25 2>;
82 interrupt-parent = <&mpic>; 82 interrupt-parent = <&mpic>;
83 }; 83 };
84 84
@@ -89,7 +89,7 @@
89 reg = <0x4600 0x20>; 89 reg = <0x4600 0x20>;
90 clock-frequency = <97553800>; /* Hz */ 90 clock-frequency = <97553800>; /* Hz */
91 current-speed = <9600>; 91 current-speed = <9600>;
92 interrupts = <10 2>; 92 interrupts = <26 2>;
93 interrupt-parent = <&mpic>; 93 interrupt-parent = <&mpic>;
94 }; 94 };
95 95
@@ -136,6 +136,6 @@
136 }; 136 };
137 137
138 chosen { 138 chosen {
139 linux,stdout-path = "/soc/serial@4500"; 139 linux,stdout-path = &serial0;
140 }; 140 };
141}; 141};
diff --git a/arch/powerpc/boot/wrapper b/arch/powerpc/boot/wrapper
index 763a0c46f441..c3178155311b 100755
--- a/arch/powerpc/boot/wrapper
+++ b/arch/powerpc/boot/wrapper
@@ -158,6 +158,29 @@ miboot|uboot)
158cuboot*) 158cuboot*)
159 binary=y 159 binary=y
160 gzip= 160 gzip=
161 case "$platform" in
162 *-mpc885ads|*-adder875*|*-ep88xc)
163 platformo=$object/cuboot-8xx.o
164 ;;
165 *5200*|*-motionpro)
166 platformo=$object/cuboot-52xx.o
167 ;;
168 *-pq2fads|*-ep8248e|*-mpc8272*|*-storcenter)
169 platformo=$object/cuboot-pq2.o
170 ;;
171 *-mpc824*)
172 platformo=$object/cuboot-824x.o
173 ;;
174 *-mpc83*)
175 platformo=$object/cuboot-83xx.o
176 ;;
177 *-tqm8541|*-mpc8560*|*-tqm8560|*-tqm8555*)
178 platformo=$object/cuboot-85xx-cpm2.o
179 ;;
180 *-mpc85*)
181 platformo=$object/cuboot-85xx.o
182 ;;
183 esac
161 ;; 184 ;;
162ps3) 185ps3)
163 platformo="$object/ps3-head.o $object/ps3-hvcall.o $object/ps3.o" 186 platformo="$object/ps3-head.o $object/ps3-hvcall.o $object/ps3.o"
diff --git a/arch/powerpc/configs/mpc83xx_defconfig b/arch/powerpc/configs/mpc83xx_defconfig
index 31bdbf3f7566..a9807f083bc4 100644
--- a/arch/powerpc/configs/mpc83xx_defconfig
+++ b/arch/powerpc/configs/mpc83xx_defconfig
@@ -186,7 +186,7 @@ CONFIG_PREEMPT_NONE=y
186# CONFIG_PREEMPT is not set 186# CONFIG_PREEMPT is not set
187CONFIG_BINFMT_ELF=y 187CONFIG_BINFMT_ELF=y
188# CONFIG_BINFMT_MISC is not set 188# CONFIG_BINFMT_MISC is not set
189# CONFIG_MATH_EMULATION is not set 189CONFIG_MATH_EMULATION=y
190CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y 190CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
191CONFIG_ARCH_FLATMEM_ENABLE=y 191CONFIG_ARCH_FLATMEM_ENABLE=y
192CONFIG_ARCH_POPULATES_NODE_MAP=y 192CONFIG_ARCH_POPULATES_NODE_MAP=y
@@ -416,14 +416,14 @@ CONFIG_PHYLIB=y
416# MII PHY device drivers 416# MII PHY device drivers
417# 417#
418CONFIG_MARVELL_PHY=y 418CONFIG_MARVELL_PHY=y
419# CONFIG_DAVICOM_PHY is not set 419CONFIG_DAVICOM_PHY=y
420# CONFIG_QSEMI_PHY is not set 420# CONFIG_QSEMI_PHY is not set
421# CONFIG_LXT_PHY is not set 421# CONFIG_LXT_PHY is not set
422# CONFIG_CICADA_PHY is not set 422# CONFIG_CICADA_PHY is not set
423# CONFIG_VITESSE_PHY is not set 423CONFIG_VITESSE_PHY=y
424# CONFIG_SMSC_PHY is not set 424# CONFIG_SMSC_PHY is not set
425# CONFIG_BROADCOM_PHY is not set 425# CONFIG_BROADCOM_PHY is not set
426# CONFIG_ICPLUS_PHY is not set 426CONFIG_ICPLUS_PHY=y
427# CONFIG_FIXED_PHY is not set 427# CONFIG_FIXED_PHY is not set
428# CONFIG_MDIO_BITBANG is not set 428# CONFIG_MDIO_BITBANG is not set
429CONFIG_NET_ETHERNET=y 429CONFIG_NET_ETHERNET=y
@@ -436,7 +436,7 @@ CONFIG_MII=y
436CONFIG_NETDEV_1000=y 436CONFIG_NETDEV_1000=y
437CONFIG_GIANFAR=y 437CONFIG_GIANFAR=y
438# CONFIG_GFAR_NAPI is not set 438# CONFIG_GFAR_NAPI is not set
439# CONFIG_UCC_GETH is not set 439CONFIG_UCC_GETH=y
440CONFIG_NETDEV_10000=y 440CONFIG_NETDEV_10000=y
441 441
442# 442#
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 58dbfeff9b4d..0662ae46f724 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -2,6 +2,8 @@
2# Makefile for the linux kernel. 2# Makefile for the linux kernel.
3# 3#
4 4
5CFLAGS_ptrace.o += -DUTS_MACHINE='"$(UTS_MACHINE)"'
6
5ifeq ($(CONFIG_PPC64),y) 7ifeq ($(CONFIG_PPC64),y)
6CFLAGS_prom_init.o += -mno-minimal-toc 8CFLAGS_prom_init.o += -mno-minimal-toc
7endif 9endif
@@ -15,7 +17,7 @@ obj-y := semaphore.o cputable.o ptrace.o syscalls.o \
15 init_task.o process.o systbl.o idle.o \ 17 init_task.o process.o systbl.o idle.o \
16 signal.o 18 signal.o
17obj-y += vdso32/ 19obj-y += vdso32/
18obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \ 20obj-$(CONFIG_PPC64) += setup_64.o sys_ppc32.o \
19 signal_64.o ptrace32.o \ 21 signal_64.o ptrace32.o \
20 paca.o cpu_setup_ppc970.o \ 22 paca.o cpu_setup_ppc970.o \
21 cpu_setup_pa6t.o \ 23 cpu_setup_pa6t.o \
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index ed083feaf6f9..e6e49289f788 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -22,6 +22,7 @@
22#include <linux/mman.h> 22#include <linux/mman.h>
23#include <linux/mm.h> 23#include <linux/mm.h>
24#include <linux/suspend.h> 24#include <linux/suspend.h>
25#include <linux/hrtimer.h>
25#ifdef CONFIG_PPC64 26#ifdef CONFIG_PPC64
26#include <linux/time.h> 27#include <linux/time.h>
27#include <linux/hardirq.h> 28#include <linux/hardirq.h>
@@ -312,7 +313,7 @@ int main(void)
312 DEFINE(CLOCK_REALTIME, CLOCK_REALTIME); 313 DEFINE(CLOCK_REALTIME, CLOCK_REALTIME);
313 DEFINE(CLOCK_MONOTONIC, CLOCK_MONOTONIC); 314 DEFINE(CLOCK_MONOTONIC, CLOCK_MONOTONIC);
314 DEFINE(NSEC_PER_SEC, NSEC_PER_SEC); 315 DEFINE(NSEC_PER_SEC, NSEC_PER_SEC);
315 DEFINE(CLOCK_REALTIME_RES, TICK_NSEC); 316 DEFINE(CLOCK_REALTIME_RES, (KTIME_MONOTONIC_RES).tv64);
316 317
317#ifdef CONFIG_BUG 318#ifdef CONFIG_BUG
318 DEFINE(BUG_ENTRY_SIZE, sizeof(struct bug_entry)); 319 DEFINE(BUG_ENTRY_SIZE, sizeof(struct bug_entry));
diff --git a/arch/powerpc/kernel/binfmt_elf32.c b/arch/powerpc/kernel/binfmt_elf32.c
deleted file mode 100644
index 1d45d7782d4e..000000000000
--- a/arch/powerpc/kernel/binfmt_elf32.c
+++ /dev/null
@@ -1,69 +0,0 @@
1/*
2 * binfmt_elf32.c: Support 32-bit PPC ELF binaries on Power3 and followons.
3 * based on the SPARC64 version.
4 * Copyright (C) 1995, 1996, 1997, 1998 David S. Miller (davem@redhat.com)
5 * Copyright (C) 1995, 1996, 1997, 1998 Jakub Jelinek (jj@ultra.linux.cz)
6 *
7 * Copyright (C) 2000,2001 Ken Aaker (kdaaker@rchland.vnet.ibm.com), IBM Corp
8 * Copyright (C) 2001 Anton Blanchard (anton@au.ibm.com), IBM
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version
13 * 2 of the License, or (at your option) any later version.
14 */
15
16#include <asm/processor.h>
17#include <linux/module.h>
18#include <linux/compat.h>
19#include <linux/elfcore-compat.h>
20
21#undef ELF_ARCH
22#undef ELF_CLASS
23#define ELF_CLASS ELFCLASS32
24#define ELF_ARCH EM_PPC
25
26#undef elfhdr
27#undef elf_phdr
28#undef elf_note
29#undef elf_addr_t
30#define elfhdr elf32_hdr
31#define elf_phdr elf32_phdr
32#define elf_note elf32_note
33#define elf_addr_t Elf32_Off
34
35#define elf_prstatus compat_elf_prstatus
36#define elf_prpsinfo compat_elf_prpsinfo
37
38#define elf_core_copy_regs compat_elf_core_copy_regs
39static inline void compat_elf_core_copy_regs(compat_elf_gregset_t *elf_regs,
40 struct pt_regs *regs)
41{
42 PPC_ELF_CORE_COPY_REGS((*elf_regs), regs);
43}
44
45#define elf_core_copy_task_regs compat_elf_core_copy_task_regs
46static int compat_elf_core_copy_task_regs(struct task_struct *tsk,
47 compat_elf_gregset_t *elf_regs)
48{
49 struct pt_regs *regs = tsk->thread.regs;
50 if (regs)
51 compat_elf_core_copy_regs(elf_regs, regs);
52 return 1;
53}
54
55#include <linux/time.h>
56
57#undef cputime_to_timeval
58#define cputime_to_timeval cputime_to_compat_timeval
59static __inline__ void
60cputime_to_compat_timeval(const cputime_t cputime, struct compat_timeval *value)
61{
62 unsigned long jiffies = cputime_to_jiffies(cputime);
63 value->tv_usec = (jiffies % HZ) * (1000000L / HZ);
64 value->tv_sec = jiffies / HZ;
65}
66
67#define init_elf_binfmt init_elf32_binfmt
68
69#include "../../../fs/binfmt_elf.c"
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index a4c2771b5e62..2a8f5cc5184f 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -959,6 +959,9 @@ static struct cpu_spec __initdata cpu_specs[] = {
959 .icache_bsize = 32, 959 .icache_bsize = 32,
960 .dcache_bsize = 32, 960 .dcache_bsize = 32,
961 .cpu_setup = __setup_cpu_603, 961 .cpu_setup = __setup_cpu_603,
962 .num_pmcs = 4,
963 .oprofile_cpu_type = "ppc/e300",
964 .oprofile_type = PPC_OPROFILE_FSL_EMB,
962 .platform = "ppc603", 965 .platform = "ppc603",
963 }, 966 },
964 { /* e300c4 (e300c1, plus one IU) */ 967 { /* e300c4 (e300c1, plus one IU) */
@@ -971,6 +974,9 @@ static struct cpu_spec __initdata cpu_specs[] = {
971 .dcache_bsize = 32, 974 .dcache_bsize = 32,
972 .cpu_setup = __setup_cpu_603, 975 .cpu_setup = __setup_cpu_603,
973 .machine_check = machine_check_generic, 976 .machine_check = machine_check_generic,
977 .num_pmcs = 4,
978 .oprofile_cpu_type = "ppc/e300",
979 .oprofile_type = PPC_OPROFILE_FSL_EMB,
974 .platform = "ppc603", 980 .platform = "ppc603",
975 }, 981 },
976 { /* default match, we assume split I/D cache & TB (non-601)... */ 982 { /* default match, we assume split I/D cache & TB (non-601)... */
@@ -1435,7 +1441,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
1435 .dcache_bsize = 32, 1441 .dcache_bsize = 32,
1436 .num_pmcs = 4, 1442 .num_pmcs = 4,
1437 .oprofile_cpu_type = "ppc/e500", 1443 .oprofile_cpu_type = "ppc/e500",
1438 .oprofile_type = PPC_OPROFILE_BOOKE, 1444 .oprofile_type = PPC_OPROFILE_FSL_EMB,
1439 .machine_check = machine_check_e500, 1445 .machine_check = machine_check_e500,
1440 .platform = "ppc8540", 1446 .platform = "ppc8540",
1441 }, 1447 },
@@ -1453,7 +1459,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
1453 .dcache_bsize = 32, 1459 .dcache_bsize = 32,
1454 .num_pmcs = 4, 1460 .num_pmcs = 4,
1455 .oprofile_cpu_type = "ppc/e500", 1461 .oprofile_cpu_type = "ppc/e500",
1456 .oprofile_type = PPC_OPROFILE_BOOKE, 1462 .oprofile_type = PPC_OPROFILE_FSL_EMB,
1457 .machine_check = machine_check_e500, 1463 .machine_check = machine_check_e500,
1458 .platform = "ppc8548", 1464 .platform = "ppc8548",
1459 }, 1465 },
diff --git a/arch/powerpc/kernel/legacy_serial.c b/arch/powerpc/kernel/legacy_serial.c
index 76b862bd1fe9..61dd17449ddc 100644
--- a/arch/powerpc/kernel/legacy_serial.c
+++ b/arch/powerpc/kernel/legacy_serial.c
@@ -36,7 +36,8 @@ static struct legacy_serial_info {
36static struct __initdata of_device_id parents[] = { 36static struct __initdata of_device_id parents[] = {
37 {.type = "soc",}, 37 {.type = "soc",},
38 {.type = "tsi-bridge",}, 38 {.type = "tsi-bridge",},
39 {.type = "opb", .compatible = "ibm,opb",}, 39 {.type = "opb", },
40 {.compatible = "ibm,opb",},
40 {.compatible = "simple-bus",}, 41 {.compatible = "simple-bus",},
41 {.compatible = "wrs,epld-localbus",}, 42 {.compatible = "wrs,epld-localbus",},
42}; 43};
diff --git a/arch/powerpc/kernel/pmc.c b/arch/powerpc/kernel/pmc.c
index ea04e0ab3f2f..0516e2d3e02e 100644
--- a/arch/powerpc/kernel/pmc.c
+++ b/arch/powerpc/kernel/pmc.c
@@ -26,7 +26,7 @@
26 26
27static void dummy_perf(struct pt_regs *regs) 27static void dummy_perf(struct pt_regs *regs)
28{ 28{
29#if defined(CONFIG_FSL_BOOKE) && !defined(CONFIG_E200) 29#if defined(CONFIG_FSL_EMB_PERFMON)
30 mtpmr(PMRN_PMGC0, mfpmr(PMRN_PMGC0) & ~PMGC0_PMIE); 30 mtpmr(PMRN_PMGC0, mfpmr(PMRN_PMGC0) & ~PMGC0_PMIE);
31#elif defined(CONFIG_PPC64) || defined(CONFIG_6xx) 31#elif defined(CONFIG_PPC64) || defined(CONFIG_6xx)
32 if (cur_cpu_spec->pmc_type == PPC_PMC_IBM) 32 if (cur_cpu_spec->pmc_type == PPC_PMC_IBM)
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index 8b056d2295cc..7673e9865733 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -21,6 +21,8 @@
21#include <linux/smp.h> 21#include <linux/smp.h>
22#include <linux/errno.h> 22#include <linux/errno.h>
23#include <linux/ptrace.h> 23#include <linux/ptrace.h>
24#include <linux/regset.h>
25#include <linux/elf.h>
24#include <linux/user.h> 26#include <linux/user.h>
25#include <linux/security.h> 27#include <linux/security.h>
26#include <linux/signal.h> 28#include <linux/signal.h>
@@ -58,20 +60,38 @@
58#define PT_MAX_PUT_REG PT_CCR 60#define PT_MAX_PUT_REG PT_CCR
59#endif 61#endif
60 62
63static unsigned long get_user_msr(struct task_struct *task)
64{
65 return task->thread.regs->msr | task->thread.fpexc_mode;
66}
67
68static int set_user_msr(struct task_struct *task, unsigned long msr)
69{
70 task->thread.regs->msr &= ~MSR_DEBUGCHANGE;
71 task->thread.regs->msr |= msr & MSR_DEBUGCHANGE;
72 return 0;
73}
74
75/*
76 * We prevent mucking around with the reserved area of trap
77 * which are used internally by the kernel.
78 */
79static int set_user_trap(struct task_struct *task, unsigned long trap)
80{
81 task->thread.regs->trap = trap & 0xfff0;
82 return 0;
83}
84
61/* 85/*
62 * Get contents of register REGNO in task TASK. 86 * Get contents of register REGNO in task TASK.
63 */ 87 */
64unsigned long ptrace_get_reg(struct task_struct *task, int regno) 88unsigned long ptrace_get_reg(struct task_struct *task, int regno)
65{ 89{
66 unsigned long tmp = 0;
67
68 if (task->thread.regs == NULL) 90 if (task->thread.regs == NULL)
69 return -EIO; 91 return -EIO;
70 92
71 if (regno == PT_MSR) { 93 if (regno == PT_MSR)
72 tmp = ((unsigned long *)task->thread.regs)[PT_MSR]; 94 return get_user_msr(task);
73 return tmp | task->thread.fpexc_mode;
74 }
75 95
76 if (regno < (sizeof(struct pt_regs) / sizeof(unsigned long))) 96 if (regno < (sizeof(struct pt_regs) / sizeof(unsigned long)))
77 return ((unsigned long *)task->thread.regs)[regno]; 97 return ((unsigned long *)task->thread.regs)[regno];
@@ -87,40 +107,134 @@ int ptrace_put_reg(struct task_struct *task, int regno, unsigned long data)
87 if (task->thread.regs == NULL) 107 if (task->thread.regs == NULL)
88 return -EIO; 108 return -EIO;
89 109
90 if (regno <= PT_MAX_PUT_REG || regno == PT_TRAP) { 110 if (regno == PT_MSR)
91 if (regno == PT_MSR) 111 return set_user_msr(task, data);
92 data = (data & MSR_DEBUGCHANGE) 112 if (regno == PT_TRAP)
93 | (task->thread.regs->msr & ~MSR_DEBUGCHANGE); 113 return set_user_trap(task, data);
94 /* We prevent mucking around with the reserved area of trap 114
95 * which are used internally by the kernel 115 if (regno <= PT_MAX_PUT_REG) {
96 */
97 if (regno == PT_TRAP)
98 data &= 0xfff0;
99 ((unsigned long *)task->thread.regs)[regno] = data; 116 ((unsigned long *)task->thread.regs)[regno] = data;
100 return 0; 117 return 0;
101 } 118 }
102 return -EIO; 119 return -EIO;
103} 120}
104 121
122static int gpr_get(struct task_struct *target, const struct user_regset *regset,
123 unsigned int pos, unsigned int count,
124 void *kbuf, void __user *ubuf)
125{
126 int ret;
127
128 if (target->thread.regs == NULL)
129 return -EIO;
130
131 CHECK_FULL_REGS(target->thread.regs);
132
133 ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
134 target->thread.regs,
135 0, offsetof(struct pt_regs, msr));
136 if (!ret) {
137 unsigned long msr = get_user_msr(target);
138 ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &msr,
139 offsetof(struct pt_regs, msr),
140 offsetof(struct pt_regs, msr) +
141 sizeof(msr));
142 }
143
144 BUILD_BUG_ON(offsetof(struct pt_regs, orig_gpr3) !=
145 offsetof(struct pt_regs, msr) + sizeof(long));
146
147 if (!ret)
148 ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
149 &target->thread.regs->orig_gpr3,
150 offsetof(struct pt_regs, orig_gpr3),
151 sizeof(struct pt_regs));
152 if (!ret)
153 ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
154 sizeof(struct pt_regs), -1);
155
156 return ret;
157}
158
159static int gpr_set(struct task_struct *target, const struct user_regset *regset,
160 unsigned int pos, unsigned int count,
161 const void *kbuf, const void __user *ubuf)
162{
163 unsigned long reg;
164 int ret;
165
166 if (target->thread.regs == NULL)
167 return -EIO;
168
169 CHECK_FULL_REGS(target->thread.regs);
170
171 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
172 target->thread.regs,
173 0, PT_MSR * sizeof(reg));
105 174
106static int get_fpregs(void __user *data, struct task_struct *task, 175 if (!ret && count > 0) {
107 int has_fpscr) 176 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &reg,
177 PT_MSR * sizeof(reg),
178 (PT_MSR + 1) * sizeof(reg));
179 if (!ret)
180 ret = set_user_msr(target, reg);
181 }
182
183 BUILD_BUG_ON(offsetof(struct pt_regs, orig_gpr3) !=
184 offsetof(struct pt_regs, msr) + sizeof(long));
185
186 if (!ret)
187 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
188 &target->thread.regs->orig_gpr3,
189 PT_ORIG_R3 * sizeof(reg),
190 (PT_MAX_PUT_REG + 1) * sizeof(reg));
191
192 if (PT_MAX_PUT_REG + 1 < PT_TRAP && !ret)
193 ret = user_regset_copyin_ignore(
194 &pos, &count, &kbuf, &ubuf,
195 (PT_MAX_PUT_REG + 1) * sizeof(reg),
196 PT_TRAP * sizeof(reg));
197
198 if (!ret && count > 0) {
199 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &reg,
200 PT_TRAP * sizeof(reg),
201 (PT_TRAP + 1) * sizeof(reg));
202 if (!ret)
203 ret = set_user_trap(target, reg);
204 }
205
206 if (!ret)
207 ret = user_regset_copyin_ignore(
208 &pos, &count, &kbuf, &ubuf,
209 (PT_TRAP + 1) * sizeof(reg), -1);
210
211 return ret;
212}
213
214static int fpr_get(struct task_struct *target, const struct user_regset *regset,
215 unsigned int pos, unsigned int count,
216 void *kbuf, void __user *ubuf)
108{ 217{
109 unsigned int count = has_fpscr ? 33 : 32; 218 flush_fp_to_thread(target);
110 219
111 if (copy_to_user(data, task->thread.fpr, count * sizeof(double))) 220 BUILD_BUG_ON(offsetof(struct thread_struct, fpscr) !=
112 return -EFAULT; 221 offsetof(struct thread_struct, fpr[32]));
113 return 0; 222
223 return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
224 &target->thread.fpr, 0, -1);
114} 225}
115 226
116static int set_fpregs(void __user *data, struct task_struct *task, 227static int fpr_set(struct task_struct *target, const struct user_regset *regset,
117 int has_fpscr) 228 unsigned int pos, unsigned int count,
229 const void *kbuf, const void __user *ubuf)
118{ 230{
119 unsigned int count = has_fpscr ? 33 : 32; 231 flush_fp_to_thread(target);
120 232
121 if (copy_from_user(task->thread.fpr, data, count * sizeof(double))) 233 BUILD_BUG_ON(offsetof(struct thread_struct, fpscr) !=
122 return -EFAULT; 234 offsetof(struct thread_struct, fpr[32]));
123 return 0; 235
236 return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
237 &target->thread.fpr, 0, -1);
124} 238}
125 239
126 240
@@ -138,56 +252,74 @@ static int set_fpregs(void __user *data, struct task_struct *task,
138 * (combined (32- and 64-bit) gdb. 252 * (combined (32- and 64-bit) gdb.
139 */ 253 */
140 254
141/* 255static int vr_active(struct task_struct *target,
142 * Get contents of AltiVec register state in task TASK 256 const struct user_regset *regset)
143 */
144static int get_vrregs(unsigned long __user *data, struct task_struct *task)
145{ 257{
146 unsigned long regsize; 258 flush_altivec_to_thread(target);
259 return target->thread.used_vr ? regset->n : 0;
260}
147 261
148 /* copy AltiVec registers VR[0] .. VR[31] */ 262static int vr_get(struct task_struct *target, const struct user_regset *regset,
149 regsize = 32 * sizeof(vector128); 263 unsigned int pos, unsigned int count,
150 if (copy_to_user(data, task->thread.vr, regsize)) 264 void *kbuf, void __user *ubuf)
151 return -EFAULT; 265{
152 data += (regsize / sizeof(unsigned long)); 266 int ret;
153 267
154 /* copy VSCR */ 268 flush_altivec_to_thread(target);
155 regsize = 1 * sizeof(vector128);
156 if (copy_to_user(data, &task->thread.vscr, regsize))
157 return -EFAULT;
158 data += (regsize / sizeof(unsigned long));
159 269
160 /* copy VRSAVE */ 270 BUILD_BUG_ON(offsetof(struct thread_struct, vscr) !=
161 if (put_user(task->thread.vrsave, (u32 __user *)data)) 271 offsetof(struct thread_struct, vr[32]));
162 return -EFAULT;
163 272
164 return 0; 273 ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
274 &target->thread.vr, 0,
275 33 * sizeof(vector128));
276 if (!ret) {
277 /*
278 * Copy out only the low-order word of vrsave.
279 */
280 union {
281 elf_vrreg_t reg;
282 u32 word;
283 } vrsave;
284 memset(&vrsave, 0, sizeof(vrsave));
285 vrsave.word = target->thread.vrsave;
286 ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &vrsave,
287 33 * sizeof(vector128), -1);
288 }
289
290 return ret;
165} 291}
166 292
167/* 293static int vr_set(struct task_struct *target, const struct user_regset *regset,
168 * Write contents of AltiVec register state into task TASK. 294 unsigned int pos, unsigned int count,
169 */ 295 const void *kbuf, const void __user *ubuf)
170static int set_vrregs(struct task_struct *task, unsigned long __user *data)
171{ 296{
172 unsigned long regsize; 297 int ret;
173 298
174 /* copy AltiVec registers VR[0] .. VR[31] */ 299 flush_altivec_to_thread(target);
175 regsize = 32 * sizeof(vector128);
176 if (copy_from_user(task->thread.vr, data, regsize))
177 return -EFAULT;
178 data += (regsize / sizeof(unsigned long));
179 300
180 /* copy VSCR */ 301 BUILD_BUG_ON(offsetof(struct thread_struct, vscr) !=
181 regsize = 1 * sizeof(vector128); 302 offsetof(struct thread_struct, vr[32]));
182 if (copy_from_user(&task->thread.vscr, data, regsize))
183 return -EFAULT;
184 data += (regsize / sizeof(unsigned long));
185 303
186 /* copy VRSAVE */ 304 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
187 if (get_user(task->thread.vrsave, (u32 __user *)data)) 305 &target->thread.vr, 0, 33 * sizeof(vector128));
188 return -EFAULT; 306 if (!ret && count > 0) {
307 /*
308 * We use only the first word of vrsave.
309 */
310 union {
311 elf_vrreg_t reg;
312 u32 word;
313 } vrsave;
314 memset(&vrsave, 0, sizeof(vrsave));
315 vrsave.word = target->thread.vrsave;
316 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &vrsave,
317 33 * sizeof(vector128), -1);
318 if (!ret)
319 target->thread.vrsave = vrsave.word;
320 }
189 321
190 return 0; 322 return ret;
191} 323}
192#endif /* CONFIG_ALTIVEC */ 324#endif /* CONFIG_ALTIVEC */
193 325
@@ -203,57 +335,273 @@ static int set_vrregs(struct task_struct *task, unsigned long __user *data)
203 * } 335 * }
204 */ 336 */
205 337
206/* 338static int evr_active(struct task_struct *target,
207 * Get contents of SPE register state in task TASK. 339 const struct user_regset *regset)
208 */
209static int get_evrregs(unsigned long *data, struct task_struct *task)
210{ 340{
211 int i; 341 flush_spe_to_thread(target);
342 return target->thread.used_spe ? regset->n : 0;
343}
212 344
213 if (!access_ok(VERIFY_WRITE, data, 35 * sizeof(unsigned long))) 345static int evr_get(struct task_struct *target, const struct user_regset *regset,
214 return -EFAULT; 346 unsigned int pos, unsigned int count,
347 void *kbuf, void __user *ubuf)
348{
349 int ret;
215 350
216 /* copy SPEFSCR */ 351 flush_spe_to_thread(target);
217 if (__put_user(task->thread.spefscr, &data[34]))
218 return -EFAULT;
219 352
220 /* copy SPE registers EVR[0] .. EVR[31] */ 353 ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
221 for (i = 0; i < 32; i++, data++) 354 &target->thread.evr,
222 if (__put_user(task->thread.evr[i], data)) 355 0, sizeof(target->thread.evr));
223 return -EFAULT;
224 356
225 /* copy ACC */ 357 BUILD_BUG_ON(offsetof(struct thread_struct, acc) + sizeof(u64) !=
226 if (__put_user64(task->thread.acc, (unsigned long long *)data)) 358 offsetof(struct thread_struct, spefscr));
227 return -EFAULT;
228 359
229 return 0; 360 if (!ret)
361 ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
362 &target->thread.acc,
363 sizeof(target->thread.evr), -1);
364
365 return ret;
366}
367
368static int evr_set(struct task_struct *target, const struct user_regset *regset,
369 unsigned int pos, unsigned int count,
370 const void *kbuf, const void __user *ubuf)
371{
372 int ret;
373
374 flush_spe_to_thread(target);
375
376 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
377 &target->thread.evr,
378 0, sizeof(target->thread.evr));
379
380 BUILD_BUG_ON(offsetof(struct thread_struct, acc) + sizeof(u64) !=
381 offsetof(struct thread_struct, spefscr));
382
383 if (!ret)
384 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
385 &target->thread.acc,
386 sizeof(target->thread.evr), -1);
387
388 return ret;
230} 389}
390#endif /* CONFIG_SPE */
391
231 392
232/* 393/*
233 * Write contents of SPE register state into task TASK. 394 * These are our native regset flavors.
234 */ 395 */
235static int set_evrregs(struct task_struct *task, unsigned long *data) 396enum powerpc_regset {
397 REGSET_GPR,
398 REGSET_FPR,
399#ifdef CONFIG_ALTIVEC
400 REGSET_VMX,
401#endif
402#ifdef CONFIG_SPE
403 REGSET_SPE,
404#endif
405};
406
407static const struct user_regset native_regsets[] = {
408 [REGSET_GPR] = {
409 .core_note_type = NT_PRSTATUS, .n = ELF_NGREG,
410 .size = sizeof(long), .align = sizeof(long),
411 .get = gpr_get, .set = gpr_set
412 },
413 [REGSET_FPR] = {
414 .core_note_type = NT_PRFPREG, .n = ELF_NFPREG,
415 .size = sizeof(double), .align = sizeof(double),
416 .get = fpr_get, .set = fpr_set
417 },
418#ifdef CONFIG_ALTIVEC
419 [REGSET_VMX] = {
420 .core_note_type = NT_PPC_VMX, .n = 34,
421 .size = sizeof(vector128), .align = sizeof(vector128),
422 .active = vr_active, .get = vr_get, .set = vr_set
423 },
424#endif
425#ifdef CONFIG_SPE
426 [REGSET_SPE] = {
427 .n = 35,
428 .size = sizeof(u32), .align = sizeof(u32),
429 .active = evr_active, .get = evr_get, .set = evr_set
430 },
431#endif
432};
433
434static const struct user_regset_view user_ppc_native_view = {
435 .name = UTS_MACHINE, .e_machine = ELF_ARCH, .ei_osabi = ELF_OSABI,
436 .regsets = native_regsets, .n = ARRAY_SIZE(native_regsets)
437};
438
439#ifdef CONFIG_PPC64
440#include <linux/compat.h>
441
442static int gpr32_get(struct task_struct *target,
443 const struct user_regset *regset,
444 unsigned int pos, unsigned int count,
445 void *kbuf, void __user *ubuf)
236{ 446{
237 int i; 447 const unsigned long *regs = &target->thread.regs->gpr[0];
448 compat_ulong_t *k = kbuf;
449 compat_ulong_t __user *u = ubuf;
450 compat_ulong_t reg;
451
452 if (target->thread.regs == NULL)
453 return -EIO;
454
455 CHECK_FULL_REGS(target->thread.regs);
238 456
239 if (!access_ok(VERIFY_READ, data, 35 * sizeof(unsigned long))) 457 pos /= sizeof(reg);
240 return -EFAULT; 458 count /= sizeof(reg);
241 459
242 /* copy SPEFSCR */ 460 if (kbuf)
243 if (__get_user(task->thread.spefscr, &data[34])) 461 for (; count > 0 && pos < PT_MSR; --count)
244 return -EFAULT; 462 *k++ = regs[pos++];
463 else
464 for (; count > 0 && pos < PT_MSR; --count)
465 if (__put_user((compat_ulong_t) regs[pos++], u++))
466 return -EFAULT;
245 467
246 /* copy SPE registers EVR[0] .. EVR[31] */ 468 if (count > 0 && pos == PT_MSR) {
247 for (i = 0; i < 32; i++, data++) 469 reg = get_user_msr(target);
248 if (__get_user(task->thread.evr[i], data)) 470 if (kbuf)
471 *k++ = reg;
472 else if (__put_user(reg, u++))
249 return -EFAULT; 473 return -EFAULT;
250 /* copy ACC */ 474 ++pos;
251 if (__get_user64(task->thread.acc, (unsigned long long*)data)) 475 --count;
252 return -EFAULT; 476 }
253 477
254 return 0; 478 if (kbuf)
479 for (; count > 0 && pos < PT_REGS_COUNT; --count)
480 *k++ = regs[pos++];
481 else
482 for (; count > 0 && pos < PT_REGS_COUNT; --count)
483 if (__put_user((compat_ulong_t) regs[pos++], u++))
484 return -EFAULT;
485
486 kbuf = k;
487 ubuf = u;
488 pos *= sizeof(reg);
489 count *= sizeof(reg);
490 return user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
491 PT_REGS_COUNT * sizeof(reg), -1);
492}
493
494static int gpr32_set(struct task_struct *target,
495 const struct user_regset *regset,
496 unsigned int pos, unsigned int count,
497 const void *kbuf, const void __user *ubuf)
498{
499 unsigned long *regs = &target->thread.regs->gpr[0];
500 const compat_ulong_t *k = kbuf;
501 const compat_ulong_t __user *u = ubuf;
502 compat_ulong_t reg;
503
504 if (target->thread.regs == NULL)
505 return -EIO;
506
507 CHECK_FULL_REGS(target->thread.regs);
508
509 pos /= sizeof(reg);
510 count /= sizeof(reg);
511
512 if (kbuf)
513 for (; count > 0 && pos < PT_MSR; --count)
514 regs[pos++] = *k++;
515 else
516 for (; count > 0 && pos < PT_MSR; --count) {
517 if (__get_user(reg, u++))
518 return -EFAULT;
519 regs[pos++] = reg;
520 }
521
522
523 if (count > 0 && pos == PT_MSR) {
524 if (kbuf)
525 reg = *k++;
526 else if (__get_user(reg, u++))
527 return -EFAULT;
528 set_user_msr(target, reg);
529 ++pos;
530 --count;
531 }
532
533 if (kbuf)
534 for (; count > 0 && pos <= PT_MAX_PUT_REG; --count)
535 regs[pos++] = *k++;
536 else
537 for (; count > 0 && pos <= PT_MAX_PUT_REG; --count) {
538 if (__get_user(reg, u++))
539 return -EFAULT;
540 regs[pos++] = reg;
541 }
542
543 if (count > 0 && pos == PT_TRAP) {
544 if (kbuf)
545 reg = *k++;
546 else if (__get_user(reg, u++))
547 return -EFAULT;
548 set_user_trap(target, reg);
549 ++pos;
550 --count;
551 }
552
553 kbuf = k;
554 ubuf = u;
555 pos *= sizeof(reg);
556 count *= sizeof(reg);
557 return user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
558 (PT_TRAP + 1) * sizeof(reg), -1);
559}
560
561/*
562 * These are the regset flavors matching the CONFIG_PPC32 native set.
563 */
564static const struct user_regset compat_regsets[] = {
565 [REGSET_GPR] = {
566 .core_note_type = NT_PRSTATUS, .n = ELF_NGREG,
567 .size = sizeof(compat_long_t), .align = sizeof(compat_long_t),
568 .get = gpr32_get, .set = gpr32_set
569 },
570 [REGSET_FPR] = {
571 .core_note_type = NT_PRFPREG, .n = ELF_NFPREG,
572 .size = sizeof(double), .align = sizeof(double),
573 .get = fpr_get, .set = fpr_set
574 },
575#ifdef CONFIG_ALTIVEC
576 [REGSET_VMX] = {
577 .core_note_type = NT_PPC_VMX, .n = 34,
578 .size = sizeof(vector128), .align = sizeof(vector128),
579 .active = vr_active, .get = vr_get, .set = vr_set
580 },
581#endif
582#ifdef CONFIG_SPE
583 [REGSET_SPE] = {
584 .core_note_type = NT_PPC_SPE, .n = 35,
585 .size = sizeof(u32), .align = sizeof(u32),
586 .active = evr_active, .get = evr_get, .set = evr_set
587 },
588#endif
589};
590
591static const struct user_regset_view user_ppc_compat_view = {
592 .name = "ppc", .e_machine = EM_PPC, .ei_osabi = ELF_OSABI,
593 .regsets = compat_regsets, .n = ARRAY_SIZE(compat_regsets)
594};
595#endif /* CONFIG_PPC64 */
596
597const struct user_regset_view *task_user_regset_view(struct task_struct *task)
598{
599#ifdef CONFIG_PPC64
600 if (test_tsk_thread_flag(task, TIF_32BIT))
601 return &user_ppc_compat_view;
602#endif
603 return &user_ppc_native_view;
255} 604}
256#endif /* CONFIG_SPE */
257 605
258 606
259void user_enable_single_step(struct task_struct *task) 607void user_enable_single_step(struct task_struct *task)
@@ -323,55 +671,29 @@ void ptrace_disable(struct task_struct *child)
323static long arch_ptrace_old(struct task_struct *child, long request, long addr, 671static long arch_ptrace_old(struct task_struct *child, long request, long addr,
324 long data) 672 long data)
325{ 673{
326 int ret = -EPERM; 674 switch (request) {
327 675 case PPC_PTRACE_GETREGS: /* Get GPRs 0 - 31. */
328 switch(request) { 676 return copy_regset_to_user(child, &user_ppc_native_view,
329 case PPC_PTRACE_GETREGS: { /* Get GPRs 0 - 31. */ 677 REGSET_GPR, 0, 32 * sizeof(long),
330 int i; 678 (void __user *) data);
331 unsigned long *reg = &((unsigned long *)child->thread.regs)[0]; 679
332 unsigned long __user *tmp = (unsigned long __user *)addr; 680 case PPC_PTRACE_SETREGS: /* Set GPRs 0 - 31. */
333 681 return copy_regset_from_user(child, &user_ppc_native_view,
334 CHECK_FULL_REGS(child->thread.regs); 682 REGSET_GPR, 0, 32 * sizeof(long),
335 for (i = 0; i < 32; i++) { 683 (const void __user *) data);
336 ret = put_user(*reg, tmp); 684
337 if (ret) 685 case PPC_PTRACE_GETFPREGS: /* Get FPRs 0 - 31. */
338 break; 686 return copy_regset_to_user(child, &user_ppc_native_view,
339 reg++; 687 REGSET_FPR, 0, 32 * sizeof(double),
340 tmp++; 688 (void __user *) data);
341 } 689
342 break; 690 case PPC_PTRACE_SETFPREGS: /* Set FPRs 0 - 31. */
343 } 691 return copy_regset_from_user(child, &user_ppc_native_view,
344 692 REGSET_FPR, 0, 32 * sizeof(double),
345 case PPC_PTRACE_SETREGS: { /* Set GPRs 0 - 31. */ 693 (const void __user *) data);
346 int i;
347 unsigned long *reg = &((unsigned long *)child->thread.regs)[0];
348 unsigned long __user *tmp = (unsigned long __user *)addr;
349
350 CHECK_FULL_REGS(child->thread.regs);
351 for (i = 0; i < 32; i++) {
352 ret = get_user(*reg, tmp);
353 if (ret)
354 break;
355 reg++;
356 tmp++;
357 }
358 break;
359 }
360
361 case PPC_PTRACE_GETFPREGS: { /* Get FPRs 0 - 31. */
362 flush_fp_to_thread(child);
363 ret = get_fpregs((void __user *)addr, child, 0);
364 break;
365 }
366
367 case PPC_PTRACE_SETFPREGS: { /* Get FPRs 0 - 31. */
368 flush_fp_to_thread(child);
369 ret = set_fpregs((void __user *)addr, child, 0);
370 break;
371 } 694 }
372 695
373 } 696 return -EPERM;
374 return ret;
375} 697}
376 698
377long arch_ptrace(struct task_struct *child, long request, long addr, long data) 699long arch_ptrace(struct task_struct *child, long request, long addr, long data)
@@ -379,12 +701,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
379 int ret = -EPERM; 701 int ret = -EPERM;
380 702
381 switch (request) { 703 switch (request) {
382 /* when I and D space are separate, these will need to be fixed. */
383 case PTRACE_PEEKTEXT: /* read word at location addr. */
384 case PTRACE_PEEKDATA:
385 ret = generic_ptrace_peekdata(child, addr, data);
386 break;
387
388 /* read the word at location addr in the USER area. */ 704 /* read the word at location addr in the USER area. */
389 case PTRACE_PEEKUSR: { 705 case PTRACE_PEEKUSR: {
390 unsigned long index, tmp; 706 unsigned long index, tmp;
@@ -412,12 +728,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
412 break; 728 break;
413 } 729 }
414 730
415 /* If I and D space are separate, this will have to be fixed. */
416 case PTRACE_POKETEXT: /* write the word at location addr. */
417 case PTRACE_POKEDATA:
418 ret = generic_ptrace_pokedata(child, addr, data);
419 break;
420
421 /* write the word at location addr in the USER area */ 731 /* write the word at location addr in the USER area */
422 case PTRACE_POKEUSR: { 732 case PTRACE_POKEUSR: {
423 unsigned long index; 733 unsigned long index;
@@ -462,85 +772,60 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
462#ifdef CONFIG_PPC64 772#ifdef CONFIG_PPC64
463 case PTRACE_GETREGS64: 773 case PTRACE_GETREGS64:
464#endif 774#endif
465 case PTRACE_GETREGS: { /* Get all pt_regs from the child. */ 775 case PTRACE_GETREGS: /* Get all pt_regs from the child. */
466 int ui; 776 return copy_regset_to_user(child, &user_ppc_native_view,
467 if (!access_ok(VERIFY_WRITE, (void __user *)data, 777 REGSET_GPR,
468 sizeof(struct pt_regs))) { 778 0, sizeof(struct pt_regs),
469 ret = -EIO; 779 (void __user *) data);
470 break;
471 }
472 CHECK_FULL_REGS(child->thread.regs);
473 ret = 0;
474 for (ui = 0; ui < PT_REGS_COUNT; ui ++) {
475 ret |= __put_user(ptrace_get_reg(child, ui),
476 (unsigned long __user *) data);
477 data += sizeof(long);
478 }
479 break;
480 }
481 780
482#ifdef CONFIG_PPC64 781#ifdef CONFIG_PPC64
483 case PTRACE_SETREGS64: 782 case PTRACE_SETREGS64:
484#endif 783#endif
485 case PTRACE_SETREGS: { /* Set all gp regs in the child. */ 784 case PTRACE_SETREGS: /* Set all gp regs in the child. */
486 unsigned long tmp; 785 return copy_regset_from_user(child, &user_ppc_native_view,
487 int ui; 786 REGSET_GPR,
488 if (!access_ok(VERIFY_READ, (void __user *)data, 787 0, sizeof(struct pt_regs),
489 sizeof(struct pt_regs))) { 788 (const void __user *) data);
490 ret = -EIO; 789
491 break; 790 case PTRACE_GETFPREGS: /* Get the child FPU state (FPR0...31 + FPSCR) */
492 } 791 return copy_regset_to_user(child, &user_ppc_native_view,
493 CHECK_FULL_REGS(child->thread.regs); 792 REGSET_FPR,
494 ret = 0; 793 0, sizeof(elf_fpregset_t),
495 for (ui = 0; ui < PT_REGS_COUNT; ui ++) { 794 (void __user *) data);
496 ret = __get_user(tmp, (unsigned long __user *) data); 795
497 if (ret) 796 case PTRACE_SETFPREGS: /* Set the child FPU state (FPR0...31 + FPSCR) */
498 break; 797 return copy_regset_from_user(child, &user_ppc_native_view,
499 ptrace_put_reg(child, ui, tmp); 798 REGSET_FPR,
500 data += sizeof(long); 799 0, sizeof(elf_fpregset_t),
501 } 800 (const void __user *) data);
502 break;
503 }
504
505 case PTRACE_GETFPREGS: { /* Get the child FPU state (FPR0...31 + FPSCR) */
506 flush_fp_to_thread(child);
507 ret = get_fpregs((void __user *)data, child, 1);
508 break;
509 }
510
511 case PTRACE_SETFPREGS: { /* Set the child FPU state (FPR0...31 + FPSCR) */
512 flush_fp_to_thread(child);
513 ret = set_fpregs((void __user *)data, child, 1);
514 break;
515 }
516 801
517#ifdef CONFIG_ALTIVEC 802#ifdef CONFIG_ALTIVEC
518 case PTRACE_GETVRREGS: 803 case PTRACE_GETVRREGS:
519 /* Get the child altivec register state. */ 804 return copy_regset_to_user(child, &user_ppc_native_view,
520 flush_altivec_to_thread(child); 805 REGSET_VMX,
521 ret = get_vrregs((unsigned long __user *)data, child); 806 0, (33 * sizeof(vector128) +
522 break; 807 sizeof(u32)),
808 (void __user *) data);
523 809
524 case PTRACE_SETVRREGS: 810 case PTRACE_SETVRREGS:
525 /* Set the child altivec register state. */ 811 return copy_regset_from_user(child, &user_ppc_native_view,
526 flush_altivec_to_thread(child); 812 REGSET_VMX,
527 ret = set_vrregs(child, (unsigned long __user *)data); 813 0, (33 * sizeof(vector128) +
528 break; 814 sizeof(u32)),
815 (const void __user *) data);
529#endif 816#endif
530#ifdef CONFIG_SPE 817#ifdef CONFIG_SPE
531 case PTRACE_GETEVRREGS: 818 case PTRACE_GETEVRREGS:
532 /* Get the child spe register state. */ 819 /* Get the child spe register state. */
533 flush_spe_to_thread(child); 820 return copy_regset_to_user(child, &user_ppc_native_view,
534 ret = get_evrregs((unsigned long __user *)data, child); 821 REGSET_SPE, 0, 35 * sizeof(u32),
535 break; 822 (void __user *) data);
536 823
537 case PTRACE_SETEVRREGS: 824 case PTRACE_SETEVRREGS:
538 /* Set the child spe register state. */ 825 /* Set the child spe register state. */
539 /* this is to clear the MSR_SPE bit to force a reload 826 return copy_regset_from_user(child, &user_ppc_native_view,
540 * of register state from memory */ 827 REGSET_SPE, 0, 35 * sizeof(u32),
541 flush_spe_to_thread(child); 828 (const void __user *) data);
542 ret = set_evrregs(child, (unsigned long __user *)data);
543 break;
544#endif 829#endif
545 830
546 /* Old reverse args ptrace callss */ 831 /* Old reverse args ptrace callss */
diff --git a/arch/powerpc/kernel/ptrace32.c b/arch/powerpc/kernel/ptrace32.c
index fea6206ff90f..4c1de6af4c09 100644
--- a/arch/powerpc/kernel/ptrace32.c
+++ b/arch/powerpc/kernel/ptrace32.c
@@ -24,9 +24,11 @@
24#include <linux/smp_lock.h> 24#include <linux/smp_lock.h>
25#include <linux/errno.h> 25#include <linux/errno.h>
26#include <linux/ptrace.h> 26#include <linux/ptrace.h>
27#include <linux/regset.h>
27#include <linux/user.h> 28#include <linux/user.h>
28#include <linux/security.h> 29#include <linux/security.h>
29#include <linux/signal.h> 30#include <linux/signal.h>
31#include <linux/compat.h>
30 32
31#include <asm/uaccess.h> 33#include <asm/uaccess.h>
32#include <asm/page.h> 34#include <asm/page.h>
@@ -45,87 +47,31 @@
45static long compat_ptrace_old(struct task_struct *child, long request, 47static long compat_ptrace_old(struct task_struct *child, long request,
46 long addr, long data) 48 long addr, long data)
47{ 49{
48 int ret = -EPERM; 50 switch (request) {
49 51 case PPC_PTRACE_GETREGS: /* Get GPRs 0 - 31. */
50 switch(request) { 52 return copy_regset_to_user(child,
51 case PPC_PTRACE_GETREGS: { /* Get GPRs 0 - 31. */ 53 task_user_regset_view(current), 0,
52 int i; 54 0, 32 * sizeof(compat_long_t),
53 unsigned long *reg = &((unsigned long *)child->thread.regs)[0]; 55 compat_ptr(data));
54 unsigned int __user *tmp = (unsigned int __user *)addr; 56
55 57 case PPC_PTRACE_SETREGS: /* Set GPRs 0 - 31. */
56 CHECK_FULL_REGS(child->thread.regs); 58 return copy_regset_from_user(child,
57 for (i = 0; i < 32; i++) { 59 task_user_regset_view(current), 0,
58 ret = put_user(*reg, tmp); 60 0, 32 * sizeof(compat_long_t),
59 if (ret) 61 compat_ptr(data));
60 break;
61 reg++;
62 tmp++;
63 }
64 break;
65 }
66
67 case PPC_PTRACE_SETREGS: { /* Set GPRs 0 - 31. */
68 int i;
69 unsigned long *reg = &((unsigned long *)child->thread.regs)[0];
70 unsigned int __user *tmp = (unsigned int __user *)addr;
71
72 CHECK_FULL_REGS(child->thread.regs);
73 for (i = 0; i < 32; i++) {
74 ret = get_user(*reg, tmp);
75 if (ret)
76 break;
77 reg++;
78 tmp++;
79 }
80 break;
81 } 62 }
82 63
83 } 64 return -EPERM;
84 return ret;
85} 65}
86 66
87long compat_sys_ptrace(int request, int pid, unsigned long addr, 67long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
88 unsigned long data) 68 compat_ulong_t caddr, compat_ulong_t cdata)
89{ 69{
90 struct task_struct *child; 70 unsigned long addr = caddr;
71 unsigned long data = cdata;
91 int ret; 72 int ret;
92 73
93 lock_kernel();
94 if (request == PTRACE_TRACEME) {
95 ret = ptrace_traceme();
96 goto out;
97 }
98
99 child = ptrace_get_task_struct(pid);
100 if (IS_ERR(child)) {
101 ret = PTR_ERR(child);
102 goto out;
103 }
104
105 if (request == PTRACE_ATTACH) {
106 ret = ptrace_attach(child);
107 goto out_tsk;
108 }
109
110 ret = ptrace_check_attach(child, request == PTRACE_KILL);
111 if (ret < 0)
112 goto out_tsk;
113
114 switch (request) { 74 switch (request) {
115 /* when I and D space are separate, these will need to be fixed. */
116 case PTRACE_PEEKTEXT: /* read word at location addr. */
117 case PTRACE_PEEKDATA: {
118 unsigned int tmp;
119 int copied;
120
121 copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
122 ret = -EIO;
123 if (copied != sizeof(tmp))
124 break;
125 ret = put_user(tmp, (u32 __user *)data);
126 break;
127 }
128
129 /* 75 /*
130 * Read 4 bytes of the other process' storage 76 * Read 4 bytes of the other process' storage
131 * data is a pointer specifying where the user wants the 77 * data is a pointer specifying where the user wants the
@@ -225,19 +171,6 @@ long compat_sys_ptrace(int request, int pid, unsigned long addr,
225 break; 171 break;
226 } 172 }
227 173
228 /* If I and D space are separate, this will have to be fixed. */
229 case PTRACE_POKETEXT: /* write the word at location addr. */
230 case PTRACE_POKEDATA: {
231 unsigned int tmp;
232 tmp = data;
233 ret = 0;
234 if (access_process_vm(child, addr, &tmp, sizeof(tmp), 1)
235 == sizeof(tmp))
236 break;
237 ret = -EIO;
238 break;
239 }
240
241 /* 174 /*
242 * Write 4 bytes into the other process' storage 175 * Write 4 bytes into the other process' storage
243 * data is the 4 bytes that the user wants written 176 * data is the 4 bytes that the user wants written
@@ -337,46 +270,17 @@ long compat_sys_ptrace(int request, int pid, unsigned long addr,
337 break; 270 break;
338 } 271 }
339 272
340 case PTRACE_GETEVENTMSG: 273 case PTRACE_GETREGS: /* Get all pt_regs from the child. */
341 ret = put_user(child->ptrace_message, (unsigned int __user *) data); 274 return copy_regset_to_user(
342 break; 275 child, task_user_regset_view(current), 0,
276 0, PT_REGS_COUNT * sizeof(compat_long_t),
277 compat_ptr(data));
343 278
344 case PTRACE_GETREGS: { /* Get all pt_regs from the child. */ 279 case PTRACE_SETREGS: /* Set all gp regs in the child. */
345 int ui; 280 return copy_regset_from_user(
346 if (!access_ok(VERIFY_WRITE, (void __user *)data, 281 child, task_user_regset_view(current), 0,
347 PT_REGS_COUNT * sizeof(int))) { 282 0, PT_REGS_COUNT * sizeof(compat_long_t),
348 ret = -EIO; 283 compat_ptr(data));
349 break;
350 }
351 CHECK_FULL_REGS(child->thread.regs);
352 ret = 0;
353 for (ui = 0; ui < PT_REGS_COUNT; ui ++) {
354 ret |= __put_user(ptrace_get_reg(child, ui),
355 (unsigned int __user *) data);
356 data += sizeof(int);
357 }
358 break;
359 }
360
361 case PTRACE_SETREGS: { /* Set all gp regs in the child. */
362 unsigned long tmp;
363 int ui;
364 if (!access_ok(VERIFY_READ, (void __user *)data,
365 PT_REGS_COUNT * sizeof(int))) {
366 ret = -EIO;
367 break;
368 }
369 CHECK_FULL_REGS(child->thread.regs);
370 ret = 0;
371 for (ui = 0; ui < PT_REGS_COUNT; ui ++) {
372 ret = __get_user(tmp, (unsigned int __user *) data);
373 if (ret)
374 break;
375 ptrace_put_reg(child, ui, tmp);
376 data += sizeof(int);
377 }
378 break;
379 }
380 284
381 case PTRACE_GETFPREGS: 285 case PTRACE_GETFPREGS:
382 case PTRACE_SETFPREGS: 286 case PTRACE_SETFPREGS:
@@ -402,12 +306,9 @@ long compat_sys_ptrace(int request, int pid, unsigned long addr,
402 break; 306 break;
403 307
404 default: 308 default:
405 ret = ptrace_request(child, request, addr, data); 309 ret = compat_ptrace_request(child, request, addr, data);
406 break; 310 break;
407 } 311 }
408out_tsk: 312
409 put_task_struct(child);
410out:
411 unlock_kernel();
412 return ret; 313 return ret;
413} 314}
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 848a20475db8..4b5b7ff4f78b 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -54,7 +54,7 @@
54#endif 54#endif
55#include <asm/kexec.h> 55#include <asm/kexec.h>
56 56
57#ifdef CONFIG_DEBUGGER 57#if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC)
58int (*__debugger)(struct pt_regs *regs); 58int (*__debugger)(struct pt_regs *regs);
59int (*__debugger_ipi)(struct pt_regs *regs); 59int (*__debugger_ipi)(struct pt_regs *regs);
60int (*__debugger_bpt)(struct pt_regs *regs); 60int (*__debugger_bpt)(struct pt_regs *regs);
diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c
index f0bad7070fb5..f98867252ee2 100644
--- a/arch/powerpc/kernel/vio.c
+++ b/arch/powerpc/kernel/vio.c
@@ -176,7 +176,7 @@ static void __devinit vio_dev_release(struct device *dev)
176 * Returns a pointer to the created vio_dev or NULL if node has 176 * Returns a pointer to the created vio_dev or NULL if node has
177 * NULL device_type or compatible fields. 177 * NULL device_type or compatible fields.
178 */ 178 */
179struct vio_dev * __devinit vio_register_device_node(struct device_node *of_node) 179struct vio_dev *vio_register_device_node(struct device_node *of_node)
180{ 180{
181 struct vio_dev *viodev; 181 struct vio_dev *viodev;
182 const unsigned int *unit_address; 182 const unsigned int *unit_address;
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index ff5debf5eedd..93a5c53e3423 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -485,7 +485,12 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address,
485 */ 485 */
486 _tlbie(address, 0 /* 8xx doesn't care about PID */); 486 _tlbie(address, 0 /* 8xx doesn't care about PID */);
487#endif 487#endif
488 if (!PageReserved(page) 488 /* The _PAGE_USER test should really be _PAGE_EXEC, but
489 * older glibc versions execute some code from no-exec
490 * pages, which for now we are supporting. If exec-only
491 * pages are ever implemented, this will have to change.
492 */
493 if (!PageReserved(page) && (pte_val(pte) & _PAGE_USER)
489 && !test_bit(PG_arch_1, &page->flags)) { 494 && !test_bit(PG_arch_1, &page->flags)) {
490 if (vma->vm_mm == current->active_mm) { 495 if (vma->vm_mm == current->active_mm) {
491 __flush_dcache_icache((void *) address); 496 __flush_dcache_icache((void *) address);
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index bc60322d2436..a300d254aac6 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -24,6 +24,8 @@
24 24
25static int numa_enabled = 1; 25static int numa_enabled = 1;
26 26
27static char *cmdline __initdata;
28
27static int numa_debug; 29static int numa_debug;
28#define dbg(args...) if (numa_debug) { printk(KERN_INFO args); } 30#define dbg(args...) if (numa_debug) { printk(KERN_INFO args); }
29 31
@@ -39,6 +41,53 @@ static bootmem_data_t __initdata plat_node_bdata[MAX_NUMNODES];
39static int min_common_depth; 41static int min_common_depth;
40static int n_mem_addr_cells, n_mem_size_cells; 42static int n_mem_addr_cells, n_mem_size_cells;
41 43
44static int __cpuinit fake_numa_create_new_node(unsigned long end_pfn,
45 unsigned int *nid)
46{
47 unsigned long long mem;
48 char *p = cmdline;
49 static unsigned int fake_nid;
50 static unsigned long long curr_boundary;
51
52 /*
53 * Modify node id, iff we started creating NUMA nodes
54 * We want to continue from where we left of the last time
55 */
56 if (fake_nid)
57 *nid = fake_nid;
58 /*
59 * In case there are no more arguments to parse, the
60 * node_id should be the same as the last fake node id
61 * (we've handled this above).
62 */
63 if (!p)
64 return 0;
65
66 mem = memparse(p, &p);
67 if (!mem)
68 return 0;
69
70 if (mem < curr_boundary)
71 return 0;
72
73 curr_boundary = mem;
74
75 if ((end_pfn << PAGE_SHIFT) > mem) {
76 /*
77 * Skip commas and spaces
78 */
79 while (*p == ',' || *p == ' ' || *p == '\t')
80 p++;
81
82 cmdline = p;
83 fake_nid++;
84 *nid = fake_nid;
85 dbg("created new fake_node with id %d\n", fake_nid);
86 return 1;
87 }
88 return 0;
89}
90
42static void __cpuinit map_cpu_to_node(int cpu, int node) 91static void __cpuinit map_cpu_to_node(int cpu, int node)
43{ 92{
44 numa_cpu_lookup_table[cpu] = node; 93 numa_cpu_lookup_table[cpu] = node;
@@ -344,6 +393,9 @@ static void __init parse_drconf_memory(struct device_node *memory)
344 if (nid == 0xffff || nid >= MAX_NUMNODES) 393 if (nid == 0xffff || nid >= MAX_NUMNODES)
345 nid = default_nid; 394 nid = default_nid;
346 } 395 }
396
397 fake_numa_create_new_node(((start + lmb_size) >> PAGE_SHIFT),
398 &nid);
347 node_set_online(nid); 399 node_set_online(nid);
348 400
349 size = numa_enforce_memory_limit(start, lmb_size); 401 size = numa_enforce_memory_limit(start, lmb_size);
@@ -429,6 +481,8 @@ new_range:
429 nid = of_node_to_nid_single(memory); 481 nid = of_node_to_nid_single(memory);
430 if (nid < 0) 482 if (nid < 0)
431 nid = default_nid; 483 nid = default_nid;
484
485 fake_numa_create_new_node(((start + size) >> PAGE_SHIFT), &nid);
432 node_set_online(nid); 486 node_set_online(nid);
433 487
434 if (!(size = numa_enforce_memory_limit(start, size))) { 488 if (!(size = numa_enforce_memory_limit(start, size))) {
@@ -461,7 +515,7 @@ static void __init setup_nonnuma(void)
461 unsigned long top_of_ram = lmb_end_of_DRAM(); 515 unsigned long top_of_ram = lmb_end_of_DRAM();
462 unsigned long total_ram = lmb_phys_mem_size(); 516 unsigned long total_ram = lmb_phys_mem_size();
463 unsigned long start_pfn, end_pfn; 517 unsigned long start_pfn, end_pfn;
464 unsigned int i; 518 unsigned int i, nid = 0;
465 519
466 printk(KERN_DEBUG "Top of RAM: 0x%lx, Total RAM: 0x%lx\n", 520 printk(KERN_DEBUG "Top of RAM: 0x%lx, Total RAM: 0x%lx\n",
467 top_of_ram, total_ram); 521 top_of_ram, total_ram);
@@ -471,9 +525,11 @@ static void __init setup_nonnuma(void)
471 for (i = 0; i < lmb.memory.cnt; ++i) { 525 for (i = 0; i < lmb.memory.cnt; ++i) {
472 start_pfn = lmb.memory.region[i].base >> PAGE_SHIFT; 526 start_pfn = lmb.memory.region[i].base >> PAGE_SHIFT;
473 end_pfn = start_pfn + lmb_size_pages(&lmb.memory, i); 527 end_pfn = start_pfn + lmb_size_pages(&lmb.memory, i);
474 add_active_range(0, start_pfn, end_pfn); 528
529 fake_numa_create_new_node(end_pfn, &nid);
530 add_active_range(nid, start_pfn, end_pfn);
531 node_set_online(nid);
475 } 532 }
476 node_set_online(0);
477} 533}
478 534
479void __init dump_numa_cpu_topology(void) 535void __init dump_numa_cpu_topology(void)
@@ -702,6 +758,10 @@ static int __init early_numa(char *p)
702 if (strstr(p, "debug")) 758 if (strstr(p, "debug"))
703 numa_debug = 1; 759 numa_debug = 1;
704 760
761 p = strstr(p, "fake=");
762 if (p)
763 cmdline = p + strlen("fake=");
764
705 return 0; 765 return 0;
706} 766}
707early_param("numa", early_numa); 767early_param("numa", early_numa);
diff --git a/arch/powerpc/oprofile/Makefile b/arch/powerpc/oprofile/Makefile
index c5f64c3bd668..2ef6b0dddd8c 100644
--- a/arch/powerpc/oprofile/Makefile
+++ b/arch/powerpc/oprofile/Makefile
@@ -15,5 +15,5 @@ oprofile-$(CONFIG_OPROFILE_CELL) += op_model_cell.o \
15 cell/spu_profiler.o cell/vma_map.o \ 15 cell/spu_profiler.o cell/vma_map.o \
16 cell/spu_task_sync.o 16 cell/spu_task_sync.o
17oprofile-$(CONFIG_PPC64) += op_model_rs64.o op_model_power4.o op_model_pa6t.o 17oprofile-$(CONFIG_PPC64) += op_model_rs64.o op_model_power4.o op_model_pa6t.o
18oprofile-$(CONFIG_FSL_BOOKE) += op_model_fsl_booke.o 18oprofile-$(CONFIG_FSL_EMB_PERFMON) += op_model_fsl_emb.o
19oprofile-$(CONFIG_6xx) += op_model_7450.o 19oprofile-$(CONFIG_6xx) += op_model_7450.o
diff --git a/arch/powerpc/oprofile/common.c b/arch/powerpc/oprofile/common.c
index a28cce1d6c24..4908dc98f9ca 100644
--- a/arch/powerpc/oprofile/common.c
+++ b/arch/powerpc/oprofile/common.c
@@ -202,9 +202,9 @@ int __init oprofile_arch_init(struct oprofile_operations *ops)
202 model = &op_model_7450; 202 model = &op_model_7450;
203 break; 203 break;
204#endif 204#endif
205#ifdef CONFIG_FSL_BOOKE 205#if defined(CONFIG_FSL_EMB_PERFMON)
206 case PPC_OPROFILE_BOOKE: 206 case PPC_OPROFILE_FSL_EMB:
207 model = &op_model_fsl_booke; 207 model = &op_model_fsl_emb;
208 break; 208 break;
209#endif 209#endif
210 default: 210 default:
diff --git a/arch/powerpc/oprofile/op_model_fsl_booke.c b/arch/powerpc/oprofile/op_model_fsl_emb.c
index 183a28bb1812..91596f6ba1f4 100644
--- a/arch/powerpc/oprofile/op_model_fsl_booke.c
+++ b/arch/powerpc/oprofile/op_model_fsl_emb.c
@@ -1,7 +1,5 @@
1/* 1/*
2 * arch/powerpc/oprofile/op_model_fsl_booke.c 2 * Freescale Embedded oprofile support, based on ppc64 oprofile support
3 *
4 * Freescale Book-E oprofile support, based on ppc64 oprofile support
5 * Copyright (C) 2004 Anton Blanchard <anton@au.ibm.com>, IBM 3 * Copyright (C) 2004 Anton Blanchard <anton@au.ibm.com>, IBM
6 * 4 *
7 * Copyright (c) 2004 Freescale Semiconductor, Inc 5 * Copyright (c) 2004 Freescale Semiconductor, Inc
@@ -22,7 +20,7 @@
22#include <asm/system.h> 20#include <asm/system.h>
23#include <asm/processor.h> 21#include <asm/processor.h>
24#include <asm/cputable.h> 22#include <asm/cputable.h>
25#include <asm/reg_booke.h> 23#include <asm/reg_fsl_emb.h>
26#include <asm/page.h> 24#include <asm/page.h>
27#include <asm/pmc.h> 25#include <asm/pmc.h>
28#include <asm/oprofile_impl.h> 26#include <asm/oprofile_impl.h>
@@ -244,7 +242,7 @@ static void dump_pmcs(void)
244 mfpmr(PMRN_PMLCA3), mfpmr(PMRN_PMLCB3)); 242 mfpmr(PMRN_PMLCA3), mfpmr(PMRN_PMLCB3));
245} 243}
246 244
247static int fsl_booke_cpu_setup(struct op_counter_config *ctr) 245static int fsl_emb_cpu_setup(struct op_counter_config *ctr)
248{ 246{
249 int i; 247 int i;
250 248
@@ -262,7 +260,7 @@ static int fsl_booke_cpu_setup(struct op_counter_config *ctr)
262 return 0; 260 return 0;
263} 261}
264 262
265static int fsl_booke_reg_setup(struct op_counter_config *ctr, 263static int fsl_emb_reg_setup(struct op_counter_config *ctr,
266 struct op_system_config *sys, 264 struct op_system_config *sys,
267 int num_ctrs) 265 int num_ctrs)
268{ 266{
@@ -281,7 +279,7 @@ static int fsl_booke_reg_setup(struct op_counter_config *ctr,
281 return 0; 279 return 0;
282} 280}
283 281
284static int fsl_booke_start(struct op_counter_config *ctr) 282static int fsl_emb_start(struct op_counter_config *ctr)
285{ 283{
286 int i; 284 int i;
287 285
@@ -315,7 +313,7 @@ static int fsl_booke_start(struct op_counter_config *ctr)
315 return 0; 313 return 0;
316} 314}
317 315
318static void fsl_booke_stop(void) 316static void fsl_emb_stop(void)
319{ 317{
320 /* freeze counters */ 318 /* freeze counters */
321 pmc_stop_ctrs(); 319 pmc_stop_ctrs();
@@ -329,7 +327,7 @@ static void fsl_booke_stop(void)
329} 327}
330 328
331 329
332static void fsl_booke_handle_interrupt(struct pt_regs *regs, 330static void fsl_emb_handle_interrupt(struct pt_regs *regs,
333 struct op_counter_config *ctr) 331 struct op_counter_config *ctr)
334{ 332{
335 unsigned long pc; 333 unsigned long pc;
@@ -362,10 +360,10 @@ static void fsl_booke_handle_interrupt(struct pt_regs *regs,
362 pmc_start_ctrs(1); 360 pmc_start_ctrs(1);
363} 361}
364 362
365struct op_powerpc_model op_model_fsl_booke = { 363struct op_powerpc_model op_model_fsl_emb = {
366 .reg_setup = fsl_booke_reg_setup, 364 .reg_setup = fsl_emb_reg_setup,
367 .cpu_setup = fsl_booke_cpu_setup, 365 .cpu_setup = fsl_emb_cpu_setup,
368 .start = fsl_booke_start, 366 .start = fsl_emb_start,
369 .stop = fsl_booke_stop, 367 .stop = fsl_emb_stop,
370 .handle_interrupt = fsl_booke_handle_interrupt, 368 .handle_interrupt = fsl_emb_handle_interrupt,
371}; 369};
diff --git a/arch/powerpc/platforms/40x/Kconfig b/arch/powerpc/platforms/40x/Kconfig
index 74f31177e47a..a9260e21451e 100644
--- a/arch/powerpc/platforms/40x/Kconfig
+++ b/arch/powerpc/platforms/40x/Kconfig
@@ -72,6 +72,7 @@ config WALNUT
72 default y 72 default y
73 select 405GP 73 select 405GP
74 select PCI 74 select PCI
75 select OF_RTC
75 help 76 help
76 This option enables support for the IBM PPC405GP evaluation board. 77 This option enables support for the IBM PPC405GP evaluation board.
77 78
diff --git a/arch/powerpc/platforms/40x/virtex.c b/arch/powerpc/platforms/40x/virtex.c
index 88b66444dfb2..0422590040db 100644
--- a/arch/powerpc/platforms/40x/virtex.c
+++ b/arch/powerpc/platforms/40x/virtex.c
@@ -37,7 +37,7 @@ static int __init virtex_probe(void)
37{ 37{
38 unsigned long root = of_get_flat_dt_root(); 38 unsigned long root = of_get_flat_dt_root();
39 39
40 if (!of_flat_dt_is_compatible(root, "xilinx,virtex")) 40 if (!of_flat_dt_is_compatible(root, "xlnx,virtex"))
41 return 0; 41 return 0;
42 42
43 return 1; 43 return 1;
diff --git a/arch/powerpc/platforms/40x/walnut.c b/arch/powerpc/platforms/40x/walnut.c
index 5d9edd917f92..b8b257efeb77 100644
--- a/arch/powerpc/platforms/40x/walnut.c
+++ b/arch/powerpc/platforms/40x/walnut.c
@@ -18,6 +18,7 @@
18 18
19#include <linux/init.h> 19#include <linux/init.h>
20#include <linux/of_platform.h> 20#include <linux/of_platform.h>
21#include <linux/rtc.h>
21 22
22#include <asm/machdep.h> 23#include <asm/machdep.h>
23#include <asm/prom.h> 24#include <asm/prom.h>
diff --git a/arch/powerpc/platforms/44x/warp.c b/arch/powerpc/platforms/44x/warp.c
index 8f01563dbd2a..da5b7b7599db 100644
--- a/arch/powerpc/platforms/44x/warp.c
+++ b/arch/powerpc/platforms/44x/warp.c
@@ -137,7 +137,7 @@ static int __init pika_dtm_start(void)
137 } 137 }
138 of_node_put(np); 138 of_node_put(np);
139 139
140 fpga = ioremap(res.start + 0x20, 4); 140 fpga = ioremap(res.start, 0x24);
141 if (fpga == NULL) 141 if (fpga == NULL)
142 return -ENOENT; 142 return -ENOENT;
143 143
diff --git a/arch/powerpc/platforms/512x/Kconfig b/arch/powerpc/platforms/512x/Kconfig
new file mode 100644
index 000000000000..c6fa49e23dc0
--- /dev/null
+++ b/arch/powerpc/platforms/512x/Kconfig
@@ -0,0 +1,20 @@
1config PPC_MPC512x
2 bool
3 select FSL_SOC
4 select IPIC
5 default n
6
7config PPC_MPC5121
8 bool
9 select PPC_MPC512x
10 default n
11
12config MPC5121_ADS
13 bool "Freescale MPC5121E ADS"
14 depends on PPC_MULTIPLATFORM && PPC32
15 select DEFAULT_UIMAGE
16 select WANT_DEVICE_TREE
17 select PPC_MPC5121
18 help
19 This option enables support for the MPC5121E ADS board.
20 default n
diff --git a/arch/powerpc/platforms/512x/Makefile b/arch/powerpc/platforms/512x/Makefile
new file mode 100644
index 000000000000..232c89f2039a
--- /dev/null
+++ b/arch/powerpc/platforms/512x/Makefile
@@ -0,0 +1,4 @@
1#
2# Makefile for the Freescale PowerPC 512x linux kernel.
3#
4obj-$(CONFIG_MPC5121_ADS) += mpc5121_ads.o
diff --git a/arch/powerpc/platforms/512x/mpc5121_ads.c b/arch/powerpc/platforms/512x/mpc5121_ads.c
new file mode 100644
index 000000000000..50bd3a319022
--- /dev/null
+++ b/arch/powerpc/platforms/512x/mpc5121_ads.c
@@ -0,0 +1,104 @@
1/*
2 * Copyright (C) 2007 Freescale Semiconductor, Inc. All rights reserved.
3 *
4 * Author: John Rigby, <jrigby@freescale.com>, Thur Mar 29 2007
5 *
6 * Description:
7 * MPC5121 ADS board setup
8 *
9 * This is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 */
15
16#include <linux/kernel.h>
17#include <linux/io.h>
18#include <linux/irq.h>
19#include <linux/of_platform.h>
20
21#include <asm/machdep.h>
22#include <asm/ipic.h>
23#include <asm/prom.h>
24#include <asm/time.h>
25
26/**
27 * mpc512x_find_ips_freq - Find the IPS bus frequency for a device
28 * @node: device node
29 *
30 * Returns IPS bus frequency, or 0 if the bus frequency cannot be found.
31 */
32unsigned long
33mpc512x_find_ips_freq(struct device_node *node)
34{
35 struct device_node *np;
36 const unsigned int *p_ips_freq = NULL;
37
38 of_node_get(node);
39 while (node) {
40 p_ips_freq = of_get_property(node, "bus-frequency", NULL);
41 if (p_ips_freq)
42 break;
43
44 np = of_get_parent(node);
45 of_node_put(node);
46 node = np;
47 }
48 if (node)
49 of_node_put(node);
50
51 return p_ips_freq ? *p_ips_freq : 0;
52}
53EXPORT_SYMBOL(mpc512x_find_ips_freq);
54
55static struct of_device_id __initdata of_bus_ids[] = {
56 { .name = "soc", },
57 { .name = "localbus", },
58 {},
59};
60
61static void __init mpc5121_ads_declare_of_platform_devices(void)
62{
63 /* Find every child of the SOC node and add it to of_platform */
64 if (of_platform_bus_probe(NULL, of_bus_ids, NULL))
65 printk(KERN_ERR __FILE__ ": "
66 "Error while probing of_platform bus\n");
67}
68
69static void __init mpc5121_ads_init_IRQ(void)
70{
71 struct device_node *np;
72
73 np = of_find_compatible_node(NULL, NULL, "fsl,ipic");
74 if (!np)
75 return;
76
77 ipic_init(np, 0);
78 of_node_put(np);
79
80 /*
81 * Initialize the default interrupt mapping priorities,
82 * in case the boot rom changed something on us.
83 */
84 ipic_set_default_priority();
85}
86
87/*
88 * Called very early, MMU is off, device-tree isn't unflattened
89 */
90static int __init mpc5121_ads_probe(void)
91{
92 unsigned long root = of_get_flat_dt_root();
93
94 return of_flat_dt_is_compatible(root, "fsl,mpc5121ads");
95}
96
97define_machine(mpc5121_ads) {
98 .name = "MPC5121 ADS",
99 .probe = mpc5121_ads_probe,
100 .init = mpc5121_ads_declare_of_platform_devices,
101 .init_IRQ = mpc5121_ads_init_IRQ,
102 .get_irq = ipic_get_irq,
103 .calibrate_decr = generic_calibrate_decr,
104};
diff --git a/arch/powerpc/platforms/82xx/mpc8272_ads.c b/arch/powerpc/platforms/82xx/mpc8272_ads.c
index 3fce6b375dbc..7d3018751988 100644
--- a/arch/powerpc/platforms/82xx/mpc8272_ads.c
+++ b/arch/powerpc/platforms/82xx/mpc8272_ads.c
@@ -134,13 +134,12 @@ static void __init mpc8272_ads_setup_arch(void)
134 } 134 }
135 135
136 bcsr = of_iomap(np, 0); 136 bcsr = of_iomap(np, 0);
137 of_node_put(np);
137 if (!bcsr) { 138 if (!bcsr) {
138 printk(KERN_ERR "Cannot map BCSR registers\n"); 139 printk(KERN_ERR "Cannot map BCSR registers\n");
139 return; 140 return;
140 } 141 }
141 142
142 of_node_put(np);
143
144 clrbits32(&bcsr[1], BCSR1_RS232_EN1 | BCSR1_RS232_EN2 | BCSR1_FETHIEN); 143 clrbits32(&bcsr[1], BCSR1_RS232_EN1 | BCSR1_RS232_EN2 | BCSR1_FETHIEN);
145 setbits32(&bcsr[1], BCSR1_FETH_RST); 144 setbits32(&bcsr[1], BCSR1_FETH_RST);
146 145
diff --git a/arch/powerpc/platforms/82xx/pq2fads.c b/arch/powerpc/platforms/82xx/pq2fads.c
index 68196e349994..e1dceeec4994 100644
--- a/arch/powerpc/platforms/82xx/pq2fads.c
+++ b/arch/powerpc/platforms/82xx/pq2fads.c
@@ -130,13 +130,12 @@ static void __init pq2fads_setup_arch(void)
130 } 130 }
131 131
132 bcsr = of_iomap(np, 0); 132 bcsr = of_iomap(np, 0);
133 of_node_put(np);
133 if (!bcsr) { 134 if (!bcsr) {
134 printk(KERN_ERR "Cannot map BCSR registers\n"); 135 printk(KERN_ERR "Cannot map BCSR registers\n");
135 return; 136 return;
136 } 137 }
137 138
138 of_node_put(np);
139
140 /* Enable the serial and ethernet ports */ 139 /* Enable the serial and ethernet ports */
141 140
142 clrbits32(&bcsr[1], BCSR1_RS232_EN1 | BCSR1_RS232_EN2 | BCSR1_FETHIEN); 141 clrbits32(&bcsr[1], BCSR1_RS232_EN1 | BCSR1_RS232_EN2 | BCSR1_FETHIEN);
diff --git a/arch/powerpc/platforms/83xx/mpc832x_rdb.c b/arch/powerpc/platforms/83xx/mpc832x_rdb.c
index 9f0fd88b2b1f..e7f706b624fe 100644
--- a/arch/powerpc/platforms/83xx/mpc832x_rdb.c
+++ b/arch/powerpc/platforms/83xx/mpc832x_rdb.c
@@ -101,7 +101,7 @@ static void __init mpc832x_rdb_setup_arch(void)
101#ifdef CONFIG_QUICC_ENGINE 101#ifdef CONFIG_QUICC_ENGINE
102 qe_reset(); 102 qe_reset();
103 103
104 if ((np = of_find_node_by_name(np, "par_io")) != NULL) { 104 if ((np = of_find_node_by_name(NULL, "par_io")) != NULL) {
105 par_io_init(np); 105 par_io_init(np);
106 of_node_put(np); 106 of_node_put(np);
107 107
diff --git a/arch/powerpc/platforms/83xx/mpc83xx.h b/arch/powerpc/platforms/83xx/mpc83xx.h
index 88bb748aff0d..68065e62fc3d 100644
--- a/arch/powerpc/platforms/83xx/mpc83xx.h
+++ b/arch/powerpc/platforms/83xx/mpc83xx.h
@@ -14,6 +14,8 @@
14#define MPC83XX_SCCR_USB_DRCM_11 0x00300000 14#define MPC83XX_SCCR_USB_DRCM_11 0x00300000
15#define MPC83XX_SCCR_USB_DRCM_01 0x00100000 15#define MPC83XX_SCCR_USB_DRCM_01 0x00100000
16#define MPC83XX_SCCR_USB_DRCM_10 0x00200000 16#define MPC83XX_SCCR_USB_DRCM_10 0x00200000
17#define MPC8315_SCCR_USB_MASK 0x00c00000
18#define MPC8315_SCCR_USB_DRCM_11 0x00c00000
17#define MPC837X_SCCR_USB_DRCM_11 0x00c00000 19#define MPC837X_SCCR_USB_DRCM_11 0x00c00000
18 20
19/* system i/o configuration register low */ 21/* system i/o configuration register low */
diff --git a/arch/powerpc/platforms/83xx/usb.c b/arch/powerpc/platforms/83xx/usb.c
index 681230a30acd..471fdd8f4108 100644
--- a/arch/powerpc/platforms/83xx/usb.c
+++ b/arch/powerpc/platforms/83xx/usb.c
@@ -104,6 +104,7 @@ int mpc831x_usb_cfg(void)
104 u32 temp; 104 u32 temp;
105 void __iomem *immap, *usb_regs; 105 void __iomem *immap, *usb_regs;
106 struct device_node *np = NULL; 106 struct device_node *np = NULL;
107 struct device_node *immr_node = NULL;
107 const void *prop; 108 const void *prop;
108 struct resource res; 109 struct resource res;
109 int ret = 0; 110 int ret = 0;
@@ -124,10 +125,15 @@ int mpc831x_usb_cfg(void)
124 } 125 }
125 126
126 /* Configure clock */ 127 /* Configure clock */
127 temp = in_be32(immap + MPC83XX_SCCR_OFFS); 128 immr_node = of_get_parent(np);
128 temp &= ~MPC83XX_SCCR_USB_MASK; 129 if (immr_node && of_device_is_compatible(immr_node, "fsl,mpc8315-immr"))
129 temp |= MPC83XX_SCCR_USB_DRCM_11; /* 1:3 */ 130 clrsetbits_be32(immap + MPC83XX_SCCR_OFFS,
130 out_be32(immap + MPC83XX_SCCR_OFFS, temp); 131 MPC8315_SCCR_USB_MASK,
132 MPC8315_SCCR_USB_DRCM_11);
133 else
134 clrsetbits_be32(immap + MPC83XX_SCCR_OFFS,
135 MPC83XX_SCCR_USB_MASK,
136 MPC83XX_SCCR_USB_DRCM_11);
131 137
132 /* Configure pin mux for ULPI. There is no pin mux for UTMI */ 138 /* Configure pin mux for ULPI. There is no pin mux for UTMI */
133 if (prop && !strcmp(prop, "ulpi")) { 139 if (prop && !strcmp(prop, "ulpi")) {
@@ -144,6 +150,9 @@ int mpc831x_usb_cfg(void)
144 150
145 iounmap(immap); 151 iounmap(immap);
146 152
153 if (immr_node)
154 of_node_put(immr_node);
155
147 /* Map USB SOC space */ 156 /* Map USB SOC space */
148 ret = of_address_to_resource(np, 0, &res); 157 ret = of_address_to_resource(np, 0, &res);
149 if (ret) { 158 if (ret) {
diff --git a/arch/powerpc/platforms/8xx/adder875.c b/arch/powerpc/platforms/8xx/adder875.c
index c6bc0783c3b0..82363e98f50e 100644
--- a/arch/powerpc/platforms/8xx/adder875.c
+++ b/arch/powerpc/platforms/8xx/adder875.c
@@ -15,12 +15,12 @@
15 15
16#include <asm/time.h> 16#include <asm/time.h>
17#include <asm/machdep.h> 17#include <asm/machdep.h>
18#include <asm/commproc.h> 18#include <asm/cpm1.h>
19#include <asm/fs_pd.h> 19#include <asm/fs_pd.h>
20#include <asm/udbg.h> 20#include <asm/udbg.h>
21#include <asm/prom.h> 21#include <asm/prom.h>
22 22
23#include <sysdev/commproc.h> 23#include "mpc8xx.h"
24 24
25struct cpm_pin { 25struct cpm_pin {
26 int port, pin, flags; 26 int port, pin, flags;
@@ -108,7 +108,7 @@ define_machine(adder875) {
108 .name = "Adder MPC875", 108 .name = "Adder MPC875",
109 .probe = adder875_probe, 109 .probe = adder875_probe,
110 .setup_arch = adder875_setup, 110 .setup_arch = adder875_setup,
111 .init_IRQ = m8xx_pic_init, 111 .init_IRQ = mpc8xx_pics_init,
112 .get_irq = mpc8xx_get_irq, 112 .get_irq = mpc8xx_get_irq,
113 .restart = mpc8xx_restart, 113 .restart = mpc8xx_restart,
114 .calibrate_decr = generic_calibrate_decr, 114 .calibrate_decr = generic_calibrate_decr,
diff --git a/arch/powerpc/platforms/8xx/ep88xc.c b/arch/powerpc/platforms/8xx/ep88xc.c
index a8dffa005775..7d9ac6040d63 100644
--- a/arch/powerpc/platforms/8xx/ep88xc.c
+++ b/arch/powerpc/platforms/8xx/ep88xc.c
@@ -15,7 +15,6 @@
15#include <asm/machdep.h> 15#include <asm/machdep.h>
16#include <asm/io.h> 16#include <asm/io.h>
17#include <asm/udbg.h> 17#include <asm/udbg.h>
18#include <asm/commproc.h>
19#include <asm/cpm1.h> 18#include <asm/cpm1.h>
20 19
21#include "mpc8xx.h" 20#include "mpc8xx.h"
diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig
index fdce10c4f074..fcedbec07f94 100644
--- a/arch/powerpc/platforms/Kconfig
+++ b/arch/powerpc/platforms/Kconfig
@@ -24,6 +24,7 @@ config PPC_83xx
24 select MPC83xx 24 select MPC83xx
25 select IPIC 25 select IPIC
26 select WANT_DEVICE_TREE 26 select WANT_DEVICE_TREE
27 select FSL_EMB_PERFMON
27 28
28config PPC_86xx 29config PPC_86xx
29 bool "Freescale 86xx" 30 bool "Freescale 86xx"
@@ -41,6 +42,7 @@ config CLASSIC32
41source "arch/powerpc/platforms/pseries/Kconfig" 42source "arch/powerpc/platforms/pseries/Kconfig"
42source "arch/powerpc/platforms/iseries/Kconfig" 43source "arch/powerpc/platforms/iseries/Kconfig"
43source "arch/powerpc/platforms/chrp/Kconfig" 44source "arch/powerpc/platforms/chrp/Kconfig"
45source "arch/powerpc/platforms/512x/Kconfig"
44source "arch/powerpc/platforms/52xx/Kconfig" 46source "arch/powerpc/platforms/52xx/Kconfig"
45source "arch/powerpc/platforms/powermac/Kconfig" 47source "arch/powerpc/platforms/powermac/Kconfig"
46source "arch/powerpc/platforms/prep/Kconfig" 48source "arch/powerpc/platforms/prep/Kconfig"
diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype
index 7fc41104d53e..69941ba70975 100644
--- a/arch/powerpc/platforms/Kconfig.cputype
+++ b/arch/powerpc/platforms/Kconfig.cputype
@@ -14,7 +14,7 @@ choice
14 There are five families of 32 bit PowerPC chips supported. 14 There are five families of 32 bit PowerPC chips supported.
15 The most common ones are the desktop and server CPUs (601, 603, 15 The most common ones are the desktop and server CPUs (601, 603,
16 604, 740, 750, 74xx) CPUs from Freescale and IBM, with their 16 604, 740, 750, 74xx) CPUs from Freescale and IBM, with their
17 embedded 52xx/82xx/83xx/86xx counterparts. 17 embedded 512x/52xx/82xx/83xx/86xx counterparts.
18 The other embeeded parts, namely 4xx, 8xx, e200 (55xx) and e500 18 The other embeeded parts, namely 4xx, 8xx, e200 (55xx) and e500
19 (85xx) each form a family of their own that is not compatible 19 (85xx) each form a family of their own that is not compatible
20 with the others. 20 with the others.
@@ -22,7 +22,7 @@ choice
22 If unsure, select 52xx/6xx/7xx/74xx/82xx/83xx/86xx. 22 If unsure, select 52xx/6xx/7xx/74xx/82xx/83xx/86xx.
23 23
24config 6xx 24config 6xx
25 bool "52xx/6xx/7xx/74xx/82xx/83xx/86xx" 25 bool "512x/52xx/6xx/7xx/74xx/82xx/83xx/86xx"
26 select PPC_FPU 26 select PPC_FPU
27 27
28config PPC_85xx 28config PPC_85xx
@@ -94,6 +94,7 @@ config 8xx
94 bool 94 bool
95 95
96config E500 96config E500
97 select FSL_EMB_PERFMON
97 bool 98 bool
98 99
99config PPC_FPU 100config PPC_FPU
@@ -115,6 +116,9 @@ config FSL_BOOKE
115 depends on E200 || E500 116 depends on E200 || E500
116 default y 117 default y
117 118
119config FSL_EMB_PERFMON
120 bool
121
118config PTE_64BIT 122config PTE_64BIT
119 bool 123 bool
120 depends on 44x || E500 124 depends on 44x || E500
@@ -221,7 +225,7 @@ config NR_CPUS
221 225
222config NOT_COHERENT_CACHE 226config NOT_COHERENT_CACHE
223 bool 227 bool
224 depends on 4xx || 8xx || E200 228 depends on 4xx || 8xx || E200 || PPC_MPC512x
225 default y 229 default y
226 230
227config CHECK_CACHE_COHERENCY 231config CHECK_CACHE_COHERENCY
diff --git a/arch/powerpc/platforms/Makefile b/arch/powerpc/platforms/Makefile
index 6d9079da5f5a..a984894466d9 100644
--- a/arch/powerpc/platforms/Makefile
+++ b/arch/powerpc/platforms/Makefile
@@ -11,6 +11,7 @@ endif
11obj-$(CONFIG_PPC_CHRP) += chrp/ 11obj-$(CONFIG_PPC_CHRP) += chrp/
12obj-$(CONFIG_40x) += 40x/ 12obj-$(CONFIG_40x) += 40x/
13obj-$(CONFIG_44x) += 44x/ 13obj-$(CONFIG_44x) += 44x/
14obj-$(CONFIG_PPC_MPC512x) += 512x/
14obj-$(CONFIG_PPC_MPC52xx) += 52xx/ 15obj-$(CONFIG_PPC_MPC52xx) += 52xx/
15obj-$(CONFIG_PPC_8xx) += 8xx/ 16obj-$(CONFIG_PPC_8xx) += 8xx/
16obj-$(CONFIG_PPC_82xx) += 82xx/ 17obj-$(CONFIG_PPC_82xx) += 82xx/
diff --git a/arch/powerpc/platforms/cell/Kconfig b/arch/powerpc/platforms/cell/Kconfig
index 3a963b4a9be0..2f169991896d 100644
--- a/arch/powerpc/platforms/cell/Kconfig
+++ b/arch/powerpc/platforms/cell/Kconfig
@@ -54,6 +54,13 @@ config SPU_FS_64K_LS
54 uses 4K pages. This can improve performances of applications 54 uses 4K pages. This can improve performances of applications
55 using multiple SPEs by lowering the TLB pressure on them. 55 using multiple SPEs by lowering the TLB pressure on them.
56 56
57config SPU_TRACE
58 tristate "SPU event tracing support"
59 depends on SPU_FS && MARKERS
60 help
61 This option allows reading a trace of spu-related events through
62 the sputrace file in procfs.
63
57config SPU_BASE 64config SPU_BASE
58 bool 65 bool
59 default n 66 default n
diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c
index 095988f13bf4..d95e71dee91f 100644
--- a/arch/powerpc/platforms/cell/axon_msi.c
+++ b/arch/powerpc/platforms/cell/axon_msi.c
@@ -13,7 +13,7 @@
13#include <linux/kernel.h> 13#include <linux/kernel.h>
14#include <linux/pci.h> 14#include <linux/pci.h>
15#include <linux/msi.h> 15#include <linux/msi.h>
16#include <linux/reboot.h> 16#include <linux/of_platform.h>
17 17
18#include <asm/dcr.h> 18#include <asm/dcr.h>
19#include <asm/machdep.h> 19#include <asm/machdep.h>
@@ -65,14 +65,12 @@
65 65
66struct axon_msic { 66struct axon_msic {
67 struct irq_host *irq_host; 67 struct irq_host *irq_host;
68 __le32 *fifo; 68 __le32 *fifo_virt;
69 dma_addr_t fifo_phys;
69 dcr_host_t dcr_host; 70 dcr_host_t dcr_host;
70 struct list_head list;
71 u32 read_offset; 71 u32 read_offset;
72}; 72};
73 73
74static LIST_HEAD(axon_msic_list);
75
76static void msic_dcr_write(struct axon_msic *msic, unsigned int dcr_n, u32 val) 74static void msic_dcr_write(struct axon_msic *msic, unsigned int dcr_n, u32 val)
77{ 75{
78 pr_debug("axon_msi: dcr_write(0x%x, 0x%x)\n", val, dcr_n); 76 pr_debug("axon_msi: dcr_write(0x%x, 0x%x)\n", val, dcr_n);
@@ -94,7 +92,7 @@ static void axon_msi_cascade(unsigned int irq, struct irq_desc *desc)
94 92
95 while (msic->read_offset != write_offset) { 93 while (msic->read_offset != write_offset) {
96 idx = msic->read_offset / sizeof(__le32); 94 idx = msic->read_offset / sizeof(__le32);
97 msi = le32_to_cpu(msic->fifo[idx]); 95 msi = le32_to_cpu(msic->fifo_virt[idx]);
98 msi &= 0xFFFF; 96 msi &= 0xFFFF;
99 97
100 pr_debug("axon_msi: woff %x roff %x msi %x\n", 98 pr_debug("axon_msi: woff %x roff %x msi %x\n",
@@ -139,6 +137,7 @@ static struct axon_msic *find_msi_translator(struct pci_dev *dev)
139 137
140 tmp = dn; 138 tmp = dn;
141 dn = of_find_node_by_phandle(*ph); 139 dn = of_find_node_by_phandle(*ph);
140 of_node_put(tmp);
142 if (!dn) { 141 if (!dn) {
143 dev_dbg(&dev->dev, 142 dev_dbg(&dev->dev,
144 "axon_msi: msi-translator doesn't point to a node\n"); 143 "axon_msi: msi-translator doesn't point to a node\n");
@@ -156,7 +155,6 @@ static struct axon_msic *find_msi_translator(struct pci_dev *dev)
156 155
157out_error: 156out_error:
158 of_node_put(dn); 157 of_node_put(dn);
159 of_node_put(tmp);
160 158
161 return msic; 159 return msic;
162} 160}
@@ -292,30 +290,24 @@ static struct irq_host_ops msic_host_ops = {
292 .map = msic_host_map, 290 .map = msic_host_map,
293}; 291};
294 292
295static int axon_msi_notify_reboot(struct notifier_block *nb, 293static int axon_msi_shutdown(struct of_device *device)
296 unsigned long code, void *data)
297{ 294{
298 struct axon_msic *msic; 295 struct axon_msic *msic = device->dev.platform_data;
299 u32 tmp; 296 u32 tmp;
300 297
301 list_for_each_entry(msic, &axon_msic_list, list) { 298 pr_debug("axon_msi: disabling %s\n",
302 pr_debug("axon_msi: disabling %s\n", 299 msic->irq_host->of_node->full_name);
303 msic->irq_host->of_node->full_name); 300 tmp = dcr_read(msic->dcr_host, MSIC_CTRL_REG);
304 tmp = dcr_read(msic->dcr_host, MSIC_CTRL_REG); 301 tmp &= ~MSIC_CTRL_ENABLE & ~MSIC_CTRL_IRQ_ENABLE;
305 tmp &= ~MSIC_CTRL_ENABLE & ~MSIC_CTRL_IRQ_ENABLE; 302 msic_dcr_write(msic, MSIC_CTRL_REG, tmp);
306 msic_dcr_write(msic, MSIC_CTRL_REG, tmp);
307 }
308 303
309 return 0; 304 return 0;
310} 305}
311 306
312static struct notifier_block axon_msi_reboot_notifier = { 307static int axon_msi_probe(struct of_device *device,
313 .notifier_call = axon_msi_notify_reboot 308 const struct of_device_id *device_id)
314};
315
316static int axon_msi_setup_one(struct device_node *dn)
317{ 309{
318 struct page *page; 310 struct device_node *dn = device->node;
319 struct axon_msic *msic; 311 struct axon_msic *msic;
320 unsigned int virq; 312 unsigned int virq;
321 int dcr_base, dcr_len; 313 int dcr_base, dcr_len;
@@ -346,16 +338,14 @@ static int axon_msi_setup_one(struct device_node *dn)
346 goto out_free_msic; 338 goto out_free_msic;
347 } 339 }
348 340
349 page = alloc_pages_node(of_node_to_nid(dn), GFP_KERNEL, 341 msic->fifo_virt = dma_alloc_coherent(&device->dev, MSIC_FIFO_SIZE_BYTES,
350 get_order(MSIC_FIFO_SIZE_BYTES)); 342 &msic->fifo_phys, GFP_KERNEL);
351 if (!page) { 343 if (!msic->fifo_virt) {
352 printk(KERN_ERR "axon_msi: couldn't allocate fifo for %s\n", 344 printk(KERN_ERR "axon_msi: couldn't allocate fifo for %s\n",
353 dn->full_name); 345 dn->full_name);
354 goto out_free_msic; 346 goto out_free_msic;
355 } 347 }
356 348
357 msic->fifo = page_address(page);
358
359 msic->irq_host = irq_alloc_host(of_node_get(dn), IRQ_HOST_MAP_NOMAP, 349 msic->irq_host = irq_alloc_host(of_node_get(dn), IRQ_HOST_MAP_NOMAP,
360 NR_IRQS, &msic_host_ops, 0); 350 NR_IRQS, &msic_host_ops, 0);
361 if (!msic->irq_host) { 351 if (!msic->irq_host) {
@@ -378,14 +368,18 @@ static int axon_msi_setup_one(struct device_node *dn)
378 pr_debug("axon_msi: irq 0x%x setup for axon_msi\n", virq); 368 pr_debug("axon_msi: irq 0x%x setup for axon_msi\n", virq);
379 369
380 /* Enable the MSIC hardware */ 370 /* Enable the MSIC hardware */
381 msic_dcr_write(msic, MSIC_BASE_ADDR_HI_REG, (u64)msic->fifo >> 32); 371 msic_dcr_write(msic, MSIC_BASE_ADDR_HI_REG, msic->fifo_phys >> 32);
382 msic_dcr_write(msic, MSIC_BASE_ADDR_LO_REG, 372 msic_dcr_write(msic, MSIC_BASE_ADDR_LO_REG,
383 (u64)msic->fifo & 0xFFFFFFFF); 373 msic->fifo_phys & 0xFFFFFFFF);
384 msic_dcr_write(msic, MSIC_CTRL_REG, 374 msic_dcr_write(msic, MSIC_CTRL_REG,
385 MSIC_CTRL_IRQ_ENABLE | MSIC_CTRL_ENABLE | 375 MSIC_CTRL_IRQ_ENABLE | MSIC_CTRL_ENABLE |
386 MSIC_CTRL_FIFO_SIZE); 376 MSIC_CTRL_FIFO_SIZE);
387 377
388 list_add(&msic->list, &axon_msic_list); 378 device->dev.platform_data = msic;
379
380 ppc_md.setup_msi_irqs = axon_msi_setup_msi_irqs;
381 ppc_md.teardown_msi_irqs = axon_msi_teardown_msi_irqs;
382 ppc_md.msi_check_device = axon_msi_check_device;
389 383
390 printk(KERN_DEBUG "axon_msi: setup MSIC on %s\n", dn->full_name); 384 printk(KERN_DEBUG "axon_msi: setup MSIC on %s\n", dn->full_name);
391 385
@@ -394,7 +388,8 @@ static int axon_msi_setup_one(struct device_node *dn)
394out_free_host: 388out_free_host:
395 kfree(msic->irq_host); 389 kfree(msic->irq_host);
396out_free_fifo: 390out_free_fifo:
397 __free_pages(virt_to_page(msic->fifo), get_order(MSIC_FIFO_SIZE_BYTES)); 391 dma_free_coherent(&device->dev, MSIC_FIFO_SIZE_BYTES, msic->fifo_virt,
392 msic->fifo_phys);
398out_free_msic: 393out_free_msic:
399 kfree(msic); 394 kfree(msic);
400out: 395out:
@@ -402,28 +397,24 @@ out:
402 return -1; 397 return -1;
403} 398}
404 399
405static int axon_msi_init(void) 400static const struct of_device_id axon_msi_device_id[] = {
406{ 401 {
407 struct device_node *dn; 402 .compatible = "ibm,axon-msic"
408 int found = 0; 403 },
409 404 {}
410 pr_debug("axon_msi: initialising ...\n"); 405};
411
412 for_each_compatible_node(dn, NULL, "ibm,axon-msic") {
413 if (axon_msi_setup_one(dn) == 0)
414 found++;
415 }
416
417 if (found) {
418 ppc_md.setup_msi_irqs = axon_msi_setup_msi_irqs;
419 ppc_md.teardown_msi_irqs = axon_msi_teardown_msi_irqs;
420 ppc_md.msi_check_device = axon_msi_check_device;
421
422 register_reboot_notifier(&axon_msi_reboot_notifier);
423 406
424 pr_debug("axon_msi: registered callbacks!\n"); 407static struct of_platform_driver axon_msi_driver = {
425 } 408 .match_table = axon_msi_device_id,
409 .probe = axon_msi_probe,
410 .shutdown = axon_msi_shutdown,
411 .driver = {
412 .name = "axon-msi"
413 },
414};
426 415
427 return 0; 416static int __init axon_msi_init(void)
417{
418 return of_register_platform_driver(&axon_msi_driver);
428} 419}
429arch_initcall(axon_msi_init); 420subsys_initcall(axon_msi_init);
diff --git a/arch/powerpc/platforms/cell/setup.c b/arch/powerpc/platforms/cell/setup.c
index e6534b519c9a..a7f609b3b876 100644
--- a/arch/powerpc/platforms/cell/setup.c
+++ b/arch/powerpc/platforms/cell/setup.c
@@ -98,7 +98,7 @@ static int __init cell_publish_devices(void)
98 } 98 }
99 return 0; 99 return 0;
100} 100}
101machine_device_initcall(cell, cell_publish_devices); 101machine_subsys_initcall(cell, cell_publish_devices);
102 102
103static void cell_mpic_cascade(unsigned int irq, struct irq_desc *desc) 103static void cell_mpic_cascade(unsigned int irq, struct irq_desc *desc)
104{ 104{
diff --git a/arch/powerpc/platforms/cell/spufs/Makefile b/arch/powerpc/platforms/cell/spufs/Makefile
index d3a349fb42e5..99610a6361f2 100644
--- a/arch/powerpc/platforms/cell/spufs/Makefile
+++ b/arch/powerpc/platforms/cell/spufs/Makefile
@@ -4,6 +4,8 @@ spufs-y += inode.o file.o context.o syscalls.o coredump.o
4spufs-y += sched.o backing_ops.o hw_ops.o run.o gang.o 4spufs-y += sched.o backing_ops.o hw_ops.o run.o gang.o
5spufs-y += switch.o fault.o lscsa_alloc.o 5spufs-y += switch.o fault.o lscsa_alloc.o
6 6
7obj-$(CONFIG_SPU_TRACE) += sputrace.o
8
7# Rules to build switch.o with the help of SPU tool chain 9# Rules to build switch.o with the help of SPU tool chain
8SPU_CROSS := spu- 10SPU_CROSS := spu-
9SPU_CC := $(SPU_CROSS)gcc 11SPU_CC := $(SPU_CROSS)gcc
diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c
index 3fcd06418b01..1018acd1746b 100644
--- a/arch/powerpc/platforms/cell/spufs/file.c
+++ b/arch/powerpc/platforms/cell/spufs/file.c
@@ -29,6 +29,7 @@
29#include <linux/poll.h> 29#include <linux/poll.h>
30#include <linux/ptrace.h> 30#include <linux/ptrace.h>
31#include <linux/seq_file.h> 31#include <linux/seq_file.h>
32#include <linux/marker.h>
32 33
33#include <asm/io.h> 34#include <asm/io.h>
34#include <asm/semaphore.h> 35#include <asm/semaphore.h>
@@ -358,6 +359,8 @@ static unsigned long spufs_ps_nopfn(struct vm_area_struct *vma,
358 struct spu_context *ctx = vma->vm_file->private_data; 359 struct spu_context *ctx = vma->vm_file->private_data;
359 unsigned long area, offset = address - vma->vm_start; 360 unsigned long area, offset = address - vma->vm_start;
360 361
362 spu_context_nospu_trace(spufs_ps_nopfn__enter, ctx);
363
361 offset += vma->vm_pgoff << PAGE_SHIFT; 364 offset += vma->vm_pgoff << PAGE_SHIFT;
362 if (offset >= ps_size) 365 if (offset >= ps_size)
363 return NOPFN_SIGBUS; 366 return NOPFN_SIGBUS;
@@ -375,11 +378,14 @@ static unsigned long spufs_ps_nopfn(struct vm_area_struct *vma,
375 378
376 if (ctx->state == SPU_STATE_SAVED) { 379 if (ctx->state == SPU_STATE_SAVED) {
377 up_read(&current->mm->mmap_sem); 380 up_read(&current->mm->mmap_sem);
381 spu_context_nospu_trace(spufs_ps_nopfn__sleep, ctx);
378 spufs_wait(ctx->run_wq, ctx->state == SPU_STATE_RUNNABLE); 382 spufs_wait(ctx->run_wq, ctx->state == SPU_STATE_RUNNABLE);
383 spu_context_trace(spufs_ps_nopfn__wake, ctx, ctx->spu);
379 down_read(&current->mm->mmap_sem); 384 down_read(&current->mm->mmap_sem);
380 } else { 385 } else {
381 area = ctx->spu->problem_phys + ps_offs; 386 area = ctx->spu->problem_phys + ps_offs;
382 vm_insert_pfn(vma, address, (area + offset) >> PAGE_SHIFT); 387 vm_insert_pfn(vma, address, (area + offset) >> PAGE_SHIFT);
388 spu_context_trace(spufs_ps_nopfn__insert, ctx, ctx->spu);
383 } 389 }
384 390
385 spu_release(ctx); 391 spu_release(ctx);
diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c
index c0e968a4c211..90784c029f25 100644
--- a/arch/powerpc/platforms/cell/spufs/inode.c
+++ b/arch/powerpc/platforms/cell/spufs/inode.c
@@ -322,7 +322,7 @@ static struct spu_context *
322spufs_assert_affinity(unsigned int flags, struct spu_gang *gang, 322spufs_assert_affinity(unsigned int flags, struct spu_gang *gang,
323 struct file *filp) 323 struct file *filp)
324{ 324{
325 struct spu_context *tmp, *neighbor; 325 struct spu_context *tmp, *neighbor, *err;
326 int count, node; 326 int count, node;
327 int aff_supp; 327 int aff_supp;
328 328
@@ -354,11 +354,15 @@ spufs_assert_affinity(unsigned int flags, struct spu_gang *gang,
354 if (!list_empty(&neighbor->aff_list) && !(neighbor->aff_head) && 354 if (!list_empty(&neighbor->aff_list) && !(neighbor->aff_head) &&
355 !list_is_last(&neighbor->aff_list, &gang->aff_list_head) && 355 !list_is_last(&neighbor->aff_list, &gang->aff_list_head) &&
356 !list_entry(neighbor->aff_list.next, struct spu_context, 356 !list_entry(neighbor->aff_list.next, struct spu_context,
357 aff_list)->aff_head) 357 aff_list)->aff_head) {
358 return ERR_PTR(-EEXIST); 358 err = ERR_PTR(-EEXIST);
359 goto out_put_neighbor;
360 }
359 361
360 if (gang != neighbor->gang) 362 if (gang != neighbor->gang) {
361 return ERR_PTR(-EINVAL); 363 err = ERR_PTR(-EINVAL);
364 goto out_put_neighbor;
365 }
362 366
363 count = 1; 367 count = 1;
364 list_for_each_entry(tmp, &gang->aff_list_head, aff_list) 368 list_for_each_entry(tmp, &gang->aff_list_head, aff_list)
@@ -372,11 +376,17 @@ spufs_assert_affinity(unsigned int flags, struct spu_gang *gang,
372 break; 376 break;
373 } 377 }
374 378
375 if (node == MAX_NUMNODES) 379 if (node == MAX_NUMNODES) {
376 return ERR_PTR(-EEXIST); 380 err = ERR_PTR(-EEXIST);
381 goto out_put_neighbor;
382 }
377 } 383 }
378 384
379 return neighbor; 385 return neighbor;
386
387out_put_neighbor:
388 put_spu_context(neighbor);
389 return err;
380} 390}
381 391
382static void 392static void
@@ -454,9 +464,12 @@ spufs_create_context(struct inode *inode, struct dentry *dentry,
454 if (ret) 464 if (ret)
455 goto out_aff_unlock; 465 goto out_aff_unlock;
456 466
457 if (affinity) 467 if (affinity) {
458 spufs_set_affinity(flags, SPUFS_I(dentry->d_inode)->i_ctx, 468 spufs_set_affinity(flags, SPUFS_I(dentry->d_inode)->i_ctx,
459 neighbor); 469 neighbor);
470 if (neighbor)
471 put_spu_context(neighbor);
472 }
460 473
461 /* 474 /*
462 * get references for dget and mntget, will be released 475 * get references for dget and mntget, will be released
diff --git a/arch/powerpc/platforms/cell/spufs/run.c b/arch/powerpc/platforms/cell/spufs/run.c
index c01a09da1e56..b4814c740d8a 100644
--- a/arch/powerpc/platforms/cell/spufs/run.c
+++ b/arch/powerpc/platforms/cell/spufs/run.c
@@ -410,8 +410,11 @@ long spufs_run_spu(struct spu_context *ctx, u32 *npc, u32 *event)
410 * since we have TIF_SINGLESTEP set, thus the kernel will do 410 * since we have TIF_SINGLESTEP set, thus the kernel will do
411 * it upon return from the syscall anyawy 411 * it upon return from the syscall anyawy
412 */ 412 */
413 if ((status & SPU_STATUS_STOPPED_BY_STOP) 413 if (unlikely(status & SPU_STATUS_SINGLE_STEP))
414 && (status >> SPU_STOP_STATUS_SHIFT) == 0x3fff) { 414 ret = -ERESTARTSYS;
415
416 else if (unlikely((status & SPU_STATUS_STOPPED_BY_STOP)
417 && (status >> SPU_STOP_STATUS_SHIFT) == 0x3fff)) {
415 force_sig(SIGTRAP, current); 418 force_sig(SIGTRAP, current);
416 ret = -ERESTARTSYS; 419 ret = -ERESTARTSYS;
417 } 420 }
diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c
index 00d914232af1..5915343e2599 100644
--- a/arch/powerpc/platforms/cell/spufs/sched.c
+++ b/arch/powerpc/platforms/cell/spufs/sched.c
@@ -39,6 +39,7 @@
39#include <linux/pid_namespace.h> 39#include <linux/pid_namespace.h>
40#include <linux/proc_fs.h> 40#include <linux/proc_fs.h>
41#include <linux/seq_file.h> 41#include <linux/seq_file.h>
42#include <linux/marker.h>
42 43
43#include <asm/io.h> 44#include <asm/io.h>
44#include <asm/mmu_context.h> 45#include <asm/mmu_context.h>
@@ -216,8 +217,8 @@ void do_notify_spus_active(void)
216 */ 217 */
217static void spu_bind_context(struct spu *spu, struct spu_context *ctx) 218static void spu_bind_context(struct spu *spu, struct spu_context *ctx)
218{ 219{
219 pr_debug("%s: pid=%d SPU=%d NODE=%d\n", __FUNCTION__, current->pid, 220 spu_context_trace(spu_bind_context__enter, ctx, spu);
220 spu->number, spu->node); 221
221 spuctx_switch_state(ctx, SPU_UTIL_SYSTEM); 222 spuctx_switch_state(ctx, SPU_UTIL_SYSTEM);
222 223
223 if (ctx->flags & SPU_CREATE_NOSCHED) 224 if (ctx->flags & SPU_CREATE_NOSCHED)
@@ -399,8 +400,8 @@ static int has_affinity(struct spu_context *ctx)
399 */ 400 */
400static void spu_unbind_context(struct spu *spu, struct spu_context *ctx) 401static void spu_unbind_context(struct spu *spu, struct spu_context *ctx)
401{ 402{
402 pr_debug("%s: unbind pid=%d SPU=%d NODE=%d\n", __FUNCTION__, 403 spu_context_trace(spu_unbind_context__enter, ctx, spu);
403 spu->pid, spu->number, spu->node); 404
404 spuctx_switch_state(ctx, SPU_UTIL_SYSTEM); 405 spuctx_switch_state(ctx, SPU_UTIL_SYSTEM);
405 406
406 if (spu->ctx->flags & SPU_CREATE_NOSCHED) 407 if (spu->ctx->flags & SPU_CREATE_NOSCHED)
@@ -528,6 +529,8 @@ static struct spu *spu_get_idle(struct spu_context *ctx)
528 struct spu *spu, *aff_ref_spu; 529 struct spu *spu, *aff_ref_spu;
529 int node, n; 530 int node, n;
530 531
532 spu_context_nospu_trace(spu_get_idle__enter, ctx);
533
531 if (ctx->gang) { 534 if (ctx->gang) {
532 mutex_lock(&ctx->gang->aff_mutex); 535 mutex_lock(&ctx->gang->aff_mutex);
533 if (has_affinity(ctx)) { 536 if (has_affinity(ctx)) {
@@ -546,8 +549,7 @@ static struct spu *spu_get_idle(struct spu_context *ctx)
546 if (atomic_dec_and_test(&ctx->gang->aff_sched_count)) 549 if (atomic_dec_and_test(&ctx->gang->aff_sched_count))
547 ctx->gang->aff_ref_spu = NULL; 550 ctx->gang->aff_ref_spu = NULL;
548 mutex_unlock(&ctx->gang->aff_mutex); 551 mutex_unlock(&ctx->gang->aff_mutex);
549 552 goto not_found;
550 return NULL;
551 } 553 }
552 mutex_unlock(&ctx->gang->aff_mutex); 554 mutex_unlock(&ctx->gang->aff_mutex);
553 } 555 }
@@ -565,12 +567,14 @@ static struct spu *spu_get_idle(struct spu_context *ctx)
565 mutex_unlock(&cbe_spu_info[node].list_mutex); 567 mutex_unlock(&cbe_spu_info[node].list_mutex);
566 } 568 }
567 569
570 not_found:
571 spu_context_nospu_trace(spu_get_idle__not_found, ctx);
568 return NULL; 572 return NULL;
569 573
570 found: 574 found:
571 spu->alloc_state = SPU_USED; 575 spu->alloc_state = SPU_USED;
572 mutex_unlock(&cbe_spu_info[node].list_mutex); 576 mutex_unlock(&cbe_spu_info[node].list_mutex);
573 pr_debug("Got SPU %d %d\n", spu->number, spu->node); 577 spu_context_trace(spu_get_idle__found, ctx, spu);
574 spu_init_channels(spu); 578 spu_init_channels(spu);
575 return spu; 579 return spu;
576} 580}
@@ -587,6 +591,8 @@ static struct spu *find_victim(struct spu_context *ctx)
587 struct spu *spu; 591 struct spu *spu;
588 int node, n; 592 int node, n;
589 593
594 spu_context_nospu_trace(spu_find_vitim__enter, ctx);
595
590 /* 596 /*
591 * Look for a possible preemption candidate on the local node first. 597 * Look for a possible preemption candidate on the local node first.
592 * If there is no candidate look at the other nodes. This isn't 598 * If there is no candidate look at the other nodes. This isn't
@@ -640,6 +646,8 @@ static struct spu *find_victim(struct spu_context *ctx)
640 goto restart; 646 goto restart;
641 } 647 }
642 648
649 spu_context_trace(__spu_deactivate__unload, ctx, spu);
650
643 mutex_lock(&cbe_spu_info[node].list_mutex); 651 mutex_lock(&cbe_spu_info[node].list_mutex);
644 cbe_spu_info[node].nr_active--; 652 cbe_spu_info[node].nr_active--;
645 spu_unbind_context(spu, victim); 653 spu_unbind_context(spu, victim);
@@ -822,6 +830,7 @@ static int __spu_deactivate(struct spu_context *ctx, int force, int max_prio)
822 */ 830 */
823void spu_deactivate(struct spu_context *ctx) 831void spu_deactivate(struct spu_context *ctx)
824{ 832{
833 spu_context_nospu_trace(spu_deactivate__enter, ctx);
825 __spu_deactivate(ctx, 1, MAX_PRIO); 834 __spu_deactivate(ctx, 1, MAX_PRIO);
826} 835}
827 836
@@ -835,6 +844,7 @@ void spu_deactivate(struct spu_context *ctx)
835 */ 844 */
836void spu_yield(struct spu_context *ctx) 845void spu_yield(struct spu_context *ctx)
837{ 846{
847 spu_context_nospu_trace(spu_yield__enter, ctx);
838 if (!(ctx->flags & SPU_CREATE_NOSCHED)) { 848 if (!(ctx->flags & SPU_CREATE_NOSCHED)) {
839 mutex_lock(&ctx->state_mutex); 849 mutex_lock(&ctx->state_mutex);
840 __spu_deactivate(ctx, 0, MAX_PRIO); 850 __spu_deactivate(ctx, 0, MAX_PRIO);
@@ -864,11 +874,15 @@ static noinline void spusched_tick(struct spu_context *ctx)
864 goto out; 874 goto out;
865 875
866 spu = ctx->spu; 876 spu = ctx->spu;
877
878 spu_context_trace(spusched_tick__preempt, ctx, spu);
879
867 new = grab_runnable_context(ctx->prio + 1, spu->node); 880 new = grab_runnable_context(ctx->prio + 1, spu->node);
868 if (new) { 881 if (new) {
869 spu_unschedule(spu, ctx); 882 spu_unschedule(spu, ctx);
870 spu_add_to_rq(ctx); 883 spu_add_to_rq(ctx);
871 } else { 884 } else {
885 spu_context_nospu_trace(spusched_tick__newslice, ctx);
872 ctx->time_slice++; 886 ctx->time_slice++;
873 } 887 }
874out: 888out:
diff --git a/arch/powerpc/platforms/cell/spufs/spufs.h b/arch/powerpc/platforms/cell/spufs/spufs.h
index 0e114038ea6f..795a1b52538b 100644
--- a/arch/powerpc/platforms/cell/spufs/spufs.h
+++ b/arch/powerpc/platforms/cell/spufs/spufs.h
@@ -325,4 +325,9 @@ extern void spu_free_lscsa(struct spu_state *csa);
325extern void spuctx_switch_state(struct spu_context *ctx, 325extern void spuctx_switch_state(struct spu_context *ctx,
326 enum spu_utilization_state new_state); 326 enum spu_utilization_state new_state);
327 327
328#define spu_context_trace(name, ctx, spu) \
329 trace_mark(name, "%p %p", ctx, spu);
330#define spu_context_nospu_trace(name, ctx) \
331 trace_mark(name, "%p", ctx);
332
328#endif 333#endif
diff --git a/arch/powerpc/platforms/cell/spufs/sputrace.c b/arch/powerpc/platforms/cell/spufs/sputrace.c
new file mode 100644
index 000000000000..2b1953f6f12e
--- /dev/null
+++ b/arch/powerpc/platforms/cell/spufs/sputrace.c
@@ -0,0 +1,250 @@
1/*
2 * Copyright (C) 2007 IBM Deutschland Entwicklung GmbH
3 * Released under GPL v2.
4 *
5 * Partially based on net/ipv4/tcp_probe.c.
6 *
7 * Simple tracing facility for spu contexts.
8 */
9#include <linux/sched.h>
10#include <linux/kernel.h>
11#include <linux/module.h>
12#include <linux/marker.h>
13#include <linux/proc_fs.h>
14#include <linux/wait.h>
15#include <asm/atomic.h>
16#include <asm/uaccess.h>
17#include "spufs.h"
18
19struct spu_probe {
20 const char *name;
21 const char *format;
22 marker_probe_func *probe_func;
23};
24
25struct sputrace {
26 ktime_t tstamp;
27 int owner_tid; /* owner */
28 int curr_tid;
29 const char *name;
30 int number;
31};
32
33static int bufsize __read_mostly = 16384;
34MODULE_PARM_DESC(bufsize, "Log buffer size (number of records)");
35module_param(bufsize, int, 0);
36
37
38static DEFINE_SPINLOCK(sputrace_lock);
39static DECLARE_WAIT_QUEUE_HEAD(sputrace_wait);
40static ktime_t sputrace_start;
41static unsigned long sputrace_head, sputrace_tail;
42static struct sputrace *sputrace_log;
43
44static int sputrace_used(void)
45{
46 return (sputrace_head - sputrace_tail) % bufsize;
47}
48
49static inline int sputrace_avail(void)
50{
51 return bufsize - sputrace_used();
52}
53
54static int sputrace_sprint(char *tbuf, int n)
55{
56 const struct sputrace *t = sputrace_log + sputrace_tail % bufsize;
57 struct timespec tv =
58 ktime_to_timespec(ktime_sub(t->tstamp, sputrace_start));
59
60 return snprintf(tbuf, n,
61 "[%lu.%09lu] %d: %s (thread = %d, spu = %d)\n",
62 (unsigned long) tv.tv_sec,
63 (unsigned long) tv.tv_nsec,
64 t->owner_tid,
65 t->name,
66 t->curr_tid,
67 t->number);
68}
69
70static ssize_t sputrace_read(struct file *file, char __user *buf,
71 size_t len, loff_t *ppos)
72{
73 int error = 0, cnt = 0;
74
75 if (!buf || len < 0)
76 return -EINVAL;
77
78 while (cnt < len) {
79 char tbuf[128];
80 int width;
81
82 error = wait_event_interruptible(sputrace_wait,
83 sputrace_used() > 0);
84 if (error)
85 break;
86
87 spin_lock(&sputrace_lock);
88 if (sputrace_head == sputrace_tail) {
89 spin_unlock(&sputrace_lock);
90 continue;
91 }
92
93 width = sputrace_sprint(tbuf, sizeof(tbuf));
94 if (width < len)
95 sputrace_tail = (sputrace_tail + 1) % bufsize;
96 spin_unlock(&sputrace_lock);
97
98 if (width >= len)
99 break;
100
101 error = copy_to_user(buf + cnt, tbuf, width);
102 if (error)
103 break;
104 cnt += width;
105 }
106
107 return cnt == 0 ? error : cnt;
108}
109
110static int sputrace_open(struct inode *inode, struct file *file)
111{
112 spin_lock(&sputrace_lock);
113 sputrace_head = sputrace_tail = 0;
114 sputrace_start = ktime_get();
115 spin_unlock(&sputrace_lock);
116
117 return 0;
118}
119
120static const struct file_operations sputrace_fops = {
121 .owner = THIS_MODULE,
122 .open = sputrace_open,
123 .read = sputrace_read,
124};
125
126static void sputrace_log_item(const char *name, struct spu_context *ctx,
127 struct spu *spu)
128{
129 spin_lock(&sputrace_lock);
130 if (sputrace_avail() > 1) {
131 struct sputrace *t = sputrace_log + sputrace_head;
132
133 t->tstamp = ktime_get();
134 t->owner_tid = ctx->tid;
135 t->name = name;
136 t->curr_tid = current->pid;
137 t->number = spu ? spu->number : -1;
138
139 sputrace_head = (sputrace_head + 1) % bufsize;
140 } else {
141 printk(KERN_WARNING
142 "sputrace: lost samples due to full buffer.\n");
143 }
144 spin_unlock(&sputrace_lock);
145
146 wake_up(&sputrace_wait);
147}
148
149static void spu_context_event(const struct marker *mdata,
150 void *private, const char *format, ...)
151{
152 struct spu_probe *p = mdata->private;
153 va_list ap;
154 struct spu_context *ctx;
155 struct spu *spu;
156
157 va_start(ap, format);
158 ctx = va_arg(ap, struct spu_context *);
159 spu = va_arg(ap, struct spu *);
160
161 sputrace_log_item(p->name, ctx, spu);
162 va_end(ap);
163}
164
165static void spu_context_nospu_event(const struct marker *mdata,
166 void *private, const char *format, ...)
167{
168 struct spu_probe *p = mdata->private;
169 va_list ap;
170 struct spu_context *ctx;
171
172 va_start(ap, format);
173 ctx = va_arg(ap, struct spu_context *);
174
175 sputrace_log_item(p->name, ctx, NULL);
176 va_end(ap);
177}
178
179struct spu_probe spu_probes[] = {
180 { "spu_bind_context__enter", "%p %p", spu_context_event },
181 { "spu_unbind_context__enter", "%p %p", spu_context_event },
182 { "spu_get_idle__enter", "%p", spu_context_nospu_event },
183 { "spu_get_idle__found", "%p %p", spu_context_event },
184 { "spu_get_idle__not_found", "%p", spu_context_nospu_event },
185 { "spu_find_victim__enter", "%p", spu_context_nospu_event },
186 { "spusched_tick__preempt", "%p %p", spu_context_event },
187 { "spusched_tick__newslice", "%p", spu_context_nospu_event },
188 { "spu_yield__enter", "%p", spu_context_nospu_event },
189 { "spu_deactivate__enter", "%p", spu_context_nospu_event },
190 { "__spu_deactivate__unload", "%p %p", spu_context_event },
191 { "spufs_ps_nopfn__enter", "%p", spu_context_nospu_event },
192 { "spufs_ps_nopfn__sleep", "%p", spu_context_nospu_event },
193 { "spufs_ps_nopfn__wake", "%p %p", spu_context_event },
194 { "spufs_ps_nopfn__insert", "%p %p", spu_context_event },
195 { "spu_acquire_saved__enter", "%p", spu_context_nospu_event },
196 { "destroy_spu_context__enter", "%p", spu_context_nospu_event },
197};
198
199static int __init sputrace_init(void)
200{
201 struct proc_dir_entry *entry;
202 int i, error = -ENOMEM;
203
204 sputrace_log = kcalloc(sizeof(struct sputrace),
205 bufsize, GFP_KERNEL);
206 if (!sputrace_log)
207 goto out;
208
209 entry = create_proc_entry("sputrace", S_IRUSR, NULL);
210 if (!entry)
211 goto out_free_log;
212 entry->proc_fops = &sputrace_fops;
213
214 for (i = 0; i < ARRAY_SIZE(spu_probes); i++) {
215 struct spu_probe *p = &spu_probes[i];
216
217 error = marker_probe_register(p->name, p->format,
218 p->probe_func, p);
219 if (error)
220 printk(KERN_INFO "Unable to register probe %s\n",
221 p->name);
222
223 error = marker_arm(p->name);
224 if (error)
225 printk(KERN_INFO "Unable to arm probe %s\n", p->name);
226 }
227
228 return 0;
229
230out_free_log:
231 kfree(sputrace_log);
232out:
233 return -ENOMEM;
234}
235
236static void __exit sputrace_exit(void)
237{
238 int i;
239
240 for (i = 0; i < ARRAY_SIZE(spu_probes); i++)
241 marker_probe_unregister(spu_probes[i].name);
242
243 remove_proc_entry("sputrace", NULL);
244 kfree(sputrace_log);
245}
246
247module_init(sputrace_init);
248module_exit(sputrace_exit);
249
250MODULE_LICENSE("GPL");
diff --git a/arch/powerpc/platforms/embedded6xx/storcenter.c b/arch/powerpc/platforms/embedded6xx/storcenter.c
index e12e9d298716..8864e4884980 100644
--- a/arch/powerpc/platforms/embedded6xx/storcenter.c
+++ b/arch/powerpc/platforms/embedded6xx/storcenter.c
@@ -132,33 +132,18 @@ static void __init storcenter_init_IRQ(void)
132 132
133 paddr = (phys_addr_t)of_translate_address(dnp, prop); 133 paddr = (phys_addr_t)of_translate_address(dnp, prop);
134 mpic = mpic_alloc(dnp, paddr, MPIC_PRIMARY | MPIC_WANTS_RESET, 134 mpic = mpic_alloc(dnp, paddr, MPIC_PRIMARY | MPIC_WANTS_RESET,
135 4, 32, " EPIC "); 135 16, 32, " OpenPIC ");
136 136
137 of_node_put(dnp); 137 of_node_put(dnp);
138 138
139 BUG_ON(mpic == NULL); 139 BUG_ON(mpic == NULL);
140 140
141 /* PCI IRQs */
142 /* 141 /*
143 * 2.6.12 patch: 142 * 16 Serial Interrupts followed by 16 Internal Interrupts.
144 * openpic_set_sources(0, 5, OpenPIC_Addr + 0x10200); 143 * I2C is the second internal, so it is at 17, 0x11020.
145 * openpic_set_sources(5, 2, OpenPIC_Addr + 0x11120);
146 * first_irq, num_irqs, __iomem first_ISR
147 * o_ss: i, src: 0, fdf50200
148 * o_ss: i, src: 1, fdf50220
149 * o_ss: i, src: 2, fdf50240
150 * o_ss: i, src: 3, fdf50260
151 * o_ss: i, src: 4, fdf50280
152 * o_ss: i, src: 5, fdf51120
153 * o_ss: i, src: 6, fdf51140
154 */ 144 */
155 mpic_assign_isu(mpic, 0, paddr + 0x10200); 145 mpic_assign_isu(mpic, 0, paddr + 0x10200);
156 mpic_assign_isu(mpic, 1, paddr + 0x10220); 146 mpic_assign_isu(mpic, 1, paddr + 0x11000);
157 mpic_assign_isu(mpic, 2, paddr + 0x10240);
158 mpic_assign_isu(mpic, 3, paddr + 0x10260);
159 mpic_assign_isu(mpic, 4, paddr + 0x10280);
160 mpic_assign_isu(mpic, 5, paddr + 0x11120);
161 mpic_assign_isu(mpic, 6, paddr + 0x11140);
162 147
163 mpic_init(mpic); 148 mpic_init(mpic);
164} 149}
@@ -178,7 +163,7 @@ static int __init storcenter_probe(void)
178{ 163{
179 unsigned long root = of_get_flat_dt_root(); 164 unsigned long root = of_get_flat_dt_root();
180 165
181 return of_flat_dt_is_compatible(root, "storcenter"); 166 return of_flat_dt_is_compatible(root, "iomega,storcenter");
182} 167}
183 168
184define_machine(storcenter){ 169define_machine(storcenter){
diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c
index c4ad54e0f288..1f032483c026 100644
--- a/arch/powerpc/platforms/pseries/hotplug-cpu.c
+++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c
@@ -58,7 +58,7 @@ static void pseries_mach_cpu_die(void)
58{ 58{
59 local_irq_disable(); 59 local_irq_disable();
60 idle_task_exit(); 60 idle_task_exit();
61 xics_teardown_cpu(0); 61 xics_teardown_cpu();
62 unregister_slb_shadow(hard_smp_processor_id(), __pa(get_slb_shadow())); 62 unregister_slb_shadow(hard_smp_processor_id(), __pa(get_slb_shadow()));
63 rtas_stop_self(); 63 rtas_stop_self();
64 /* Should never get here... */ 64 /* Should never get here... */
diff --git a/arch/powerpc/platforms/pseries/kexec.c b/arch/powerpc/platforms/pseries/kexec.c
index 412a5e7aff2d..e9dd5fe081c9 100644
--- a/arch/powerpc/platforms/pseries/kexec.c
+++ b/arch/powerpc/platforms/pseries/kexec.c
@@ -54,7 +54,7 @@ void __init setup_kexec_cpu_down_mpic(void)
54static void pseries_kexec_cpu_down_xics(int crash_shutdown, int secondary) 54static void pseries_kexec_cpu_down_xics(int crash_shutdown, int secondary)
55{ 55{
56 pseries_kexec_cpu_down(crash_shutdown, secondary); 56 pseries_kexec_cpu_down(crash_shutdown, secondary);
57 xics_teardown_cpu(secondary); 57 xics_kexec_teardown_cpu(secondary);
58} 58}
59 59
60void __init setup_kexec_cpu_down_xics(void) 60void __init setup_kexec_cpu_down_xics(void)
diff --git a/arch/powerpc/platforms/pseries/reconfig.c b/arch/powerpc/platforms/pseries/reconfig.c
index c02f8742c54d..2800fced8c7c 100644
--- a/arch/powerpc/platforms/pseries/reconfig.c
+++ b/arch/powerpc/platforms/pseries/reconfig.c
@@ -167,6 +167,7 @@ static int pSeries_reconfig_remove_node(struct device_node *np)
167 167
168 if ((child = of_get_next_child(np, NULL))) { 168 if ((child = of_get_next_child(np, NULL))) {
169 of_node_put(child); 169 of_node_put(child);
170 of_node_put(parent);
170 return -EBUSY; 171 return -EBUSY;
171 } 172 }
172 173
diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c
index 8f8dd9c3ca6b..ca52b587166d 100644
--- a/arch/powerpc/platforms/pseries/xics.c
+++ b/arch/powerpc/platforms/pseries/xics.c
@@ -160,6 +160,46 @@ static inline void lpar_qirr_info(int n_cpu , u8 value)
160 160
161/* High level handlers and init code */ 161/* High level handlers and init code */
162 162
163static void xics_update_irq_servers(void)
164{
165 int i, j;
166 struct device_node *np;
167 u32 ilen;
168 const u32 *ireg, *isize;
169 u32 hcpuid;
170
171 /* Find the server numbers for the boot cpu. */
172 np = of_get_cpu_node(boot_cpuid, NULL);
173 BUG_ON(!np);
174
175 ireg = of_get_property(np, "ibm,ppc-interrupt-gserver#s", &ilen);
176 if (!ireg) {
177 of_node_put(np);
178 return;
179 }
180
181 i = ilen / sizeof(int);
182 hcpuid = get_hard_smp_processor_id(boot_cpuid);
183
184 /* Global interrupt distribution server is specified in the last
185 * entry of "ibm,ppc-interrupt-gserver#s" property. Get the last
186 * entry fom this property for current boot cpu id and use it as
187 * default distribution server
188 */
189 for (j = 0; j < i; j += 2) {
190 if (ireg[j] == hcpuid) {
191 default_server = hcpuid;
192 default_distrib_server = ireg[j+1];
193
194 isize = of_get_property(np,
195 "ibm,interrupt-server#-size", NULL);
196 if (isize)
197 interrupt_server_size = *isize;
198 }
199 }
200
201 of_node_put(np);
202}
163 203
164#ifdef CONFIG_SMP 204#ifdef CONFIG_SMP
165static int get_irq_server(unsigned int virq, unsigned int strict_check) 205static int get_irq_server(unsigned int virq, unsigned int strict_check)
@@ -169,6 +209,9 @@ static int get_irq_server(unsigned int virq, unsigned int strict_check)
169 cpumask_t cpumask = irq_desc[virq].affinity; 209 cpumask_t cpumask = irq_desc[virq].affinity;
170 cpumask_t tmp = CPU_MASK_NONE; 210 cpumask_t tmp = CPU_MASK_NONE;
171 211
212 if (! cpu_isset(default_server, cpu_online_map))
213 xics_update_irq_servers();
214
172 if (!distribute_irqs) 215 if (!distribute_irqs)
173 return default_server; 216 return default_server;
174 217
@@ -658,39 +701,11 @@ static void __init xics_setup_8259_cascade(void)
658 set_irq_chained_handler(cascade, pseries_8259_cascade); 701 set_irq_chained_handler(cascade, pseries_8259_cascade);
659} 702}
660 703
661static struct device_node *cpuid_to_of_node(int cpu)
662{
663 struct device_node *np;
664 u32 hcpuid = get_hard_smp_processor_id(cpu);
665
666 for_each_node_by_type(np, "cpu") {
667 int i, len;
668 const u32 *intserv;
669
670 intserv = of_get_property(np, "ibm,ppc-interrupt-server#s",
671 &len);
672
673 if (!intserv)
674 intserv = of_get_property(np, "reg", &len);
675
676 i = len / sizeof(u32);
677
678 while (i--)
679 if (intserv[i] == hcpuid)
680 return np;
681 }
682
683 return NULL;
684}
685
686void __init xics_init_IRQ(void) 704void __init xics_init_IRQ(void)
687{ 705{
688 int i, j;
689 struct device_node *np; 706 struct device_node *np;
690 u32 ilen, indx = 0; 707 u32 indx = 0;
691 const u32 *ireg, *isize;
692 int found = 0; 708 int found = 0;
693 u32 hcpuid;
694 709
695 ppc64_boot_msg(0x20, "XICS Init"); 710 ppc64_boot_msg(0x20, "XICS Init");
696 711
@@ -709,34 +724,7 @@ void __init xics_init_IRQ(void)
709 return; 724 return;
710 725
711 xics_init_host(); 726 xics_init_host();
712 727 xics_update_irq_servers();
713 /* Find the server numbers for the boot cpu. */
714 np = cpuid_to_of_node(boot_cpuid);
715 BUG_ON(!np);
716 ireg = of_get_property(np, "ibm,ppc-interrupt-gserver#s", &ilen);
717 if (!ireg)
718 goto skip_gserver_check;
719 i = ilen / sizeof(int);
720 hcpuid = get_hard_smp_processor_id(boot_cpuid);
721
722 /* Global interrupt distribution server is specified in the last
723 * entry of "ibm,ppc-interrupt-gserver#s" property. Get the last
724 * entry fom this property for current boot cpu id and use it as
725 * default distribution server
726 */
727 for (j = 0; j < i; j += 2) {
728 if (ireg[j] == hcpuid) {
729 default_server = hcpuid;
730 default_distrib_server = ireg[j+1];
731
732 isize = of_get_property(np,
733 "ibm,interrupt-server#-size", NULL);
734 if (isize)
735 interrupt_server_size = *isize;
736 }
737 }
738skip_gserver_check:
739 of_node_put(np);
740 728
741 if (firmware_has_feature(FW_FEATURE_LPAR)) 729 if (firmware_has_feature(FW_FEATURE_LPAR))
742 ppc_md.get_irq = xics_get_irq_lpar; 730 ppc_md.get_irq = xics_get_irq_lpar;
@@ -775,11 +763,9 @@ void xics_request_IPIs(void)
775} 763}
776#endif /* CONFIG_SMP */ 764#endif /* CONFIG_SMP */
777 765
778void xics_teardown_cpu(int secondary) 766void xics_teardown_cpu()
779{ 767{
780 int cpu = smp_processor_id(); 768 int cpu = smp_processor_id();
781 unsigned int ipi;
782 struct irq_desc *desc;
783 769
784 xics_set_cpu_priority(0); 770 xics_set_cpu_priority(0);
785 771
@@ -790,9 +776,17 @@ void xics_teardown_cpu(int secondary)
790 lpar_qirr_info(cpu, 0xff); 776 lpar_qirr_info(cpu, 0xff);
791 else 777 else
792 direct_qirr_info(cpu, 0xff); 778 direct_qirr_info(cpu, 0xff);
779}
780
781void xics_kexec_teardown_cpu(int secondary)
782{
783 unsigned int ipi;
784 struct irq_desc *desc;
785
786 xics_teardown_cpu();
793 787
794 /* 788 /*
795 * we need to EOI the IPI if we got here from kexec down IPI 789 * we need to EOI the IPI
796 * 790 *
797 * probably need to check all the other interrupts too 791 * probably need to check all the other interrupts too
798 * should we be flagging idle loop instead? 792 * should we be flagging idle loop instead?
@@ -880,8 +874,8 @@ void xics_migrate_irqs_away(void)
880 virq, cpu); 874 virq, cpu);
881 875
882 /* Reset affinity to all cpus */ 876 /* Reset affinity to all cpus */
877 irq_desc[virq].affinity = CPU_MASK_ALL;
883 desc->chip->set_affinity(virq, CPU_MASK_ALL); 878 desc->chip->set_affinity(virq, CPU_MASK_ALL);
884 irq_desc[irq].affinity = CPU_MASK_ALL;
885unlock: 879unlock:
886 spin_unlock_irqrestore(&desc->lock, flags); 880 spin_unlock_irqrestore(&desc->lock, flags);
887 } 881 }
diff --git a/arch/powerpc/platforms/pseries/xics.h b/arch/powerpc/platforms/pseries/xics.h
index 9ffd809d29e2..c26bcff47b6d 100644
--- a/arch/powerpc/platforms/pseries/xics.h
+++ b/arch/powerpc/platforms/pseries/xics.h
@@ -16,7 +16,8 @@
16 16
17extern void xics_init_IRQ(void); 17extern void xics_init_IRQ(void);
18extern void xics_setup_cpu(void); 18extern void xics_setup_cpu(void);
19extern void xics_teardown_cpu(int secondary); 19extern void xics_teardown_cpu(void);
20extern void xics_kexec_teardown_cpu(int secondary);
20extern void xics_cause_IPI(int cpu); 21extern void xics_cause_IPI(int cpu);
21extern void xics_request_IPIs(void); 22extern void xics_request_IPIs(void);
22extern void xics_migrate_irqs_away(void); 23extern void xics_migrate_irqs_away(void);
diff --git a/arch/powerpc/sysdev/dcr.c b/arch/powerpc/sysdev/dcr.c
index 427027c7ea0f..437e48d3ae33 100644
--- a/arch/powerpc/sysdev/dcr.c
+++ b/arch/powerpc/sysdev/dcr.c
@@ -137,5 +137,6 @@ void dcr_unmap(dcr_host_t host, unsigned int dcr_c)
137 h.token = NULL; 137 h.token = NULL;
138} 138}
139EXPORT_SYMBOL_GPL(dcr_unmap); 139EXPORT_SYMBOL_GPL(dcr_unmap);
140 140#else /* defined(CONFIG_PPC_DCR_NATIVE) */
141#endif /* !defined(CONFIG_PPC_DCR_NATIVE) */ 141DEFINE_SPINLOCK(dcr_ind_lock);
142#endif /* !defined(CONFIG_PPC_DCR_NATIVE) */
diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c
index e48b20e934ca..2c5388ce902a 100644
--- a/arch/powerpc/sysdev/fsl_soc.c
+++ b/arch/powerpc/sysdev/fsl_soc.c
@@ -1342,7 +1342,7 @@ static int __init of_fsl_spi_probe(char *type, char *compatible, u32 sysclk,
1342 if (ret) 1342 if (ret)
1343 goto unreg; 1343 goto unreg;
1344 1344
1345 ret = platform_device_register(pdev); 1345 ret = platform_device_add(pdev);
1346 if (ret) 1346 if (ret)
1347 goto unreg; 1347 goto unreg;
1348 1348
diff --git a/arch/powerpc/sysdev/mpc8xx_pic.c b/arch/powerpc/sysdev/mpc8xx_pic.c
index 0e74a4bd9827..5d2d5522ef41 100644
--- a/arch/powerpc/sysdev/mpc8xx_pic.c
+++ b/arch/powerpc/sysdev/mpc8xx_pic.c
@@ -174,15 +174,19 @@ int mpc8xx_pic_init(void)
174 goto out; 174 goto out;
175 175
176 siu_reg = ioremap(res.start, res.end - res.start + 1); 176 siu_reg = ioremap(res.start, res.end - res.start + 1);
177 if (siu_reg == NULL) 177 if (siu_reg == NULL) {
178 return -EINVAL; 178 ret = -EINVAL;
179 goto out;
180 }
179 181
180 mpc8xx_pic_host = irq_alloc_host(of_node_get(np), IRQ_HOST_MAP_LINEAR, 182 mpc8xx_pic_host = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR,
181 64, &mpc8xx_pic_host_ops, 64); 183 64, &mpc8xx_pic_host_ops, 64);
182 if (mpc8xx_pic_host == NULL) { 184 if (mpc8xx_pic_host == NULL) {
183 printk(KERN_ERR "MPC8xx PIC: failed to allocate irq host!\n"); 185 printk(KERN_ERR "MPC8xx PIC: failed to allocate irq host!\n");
184 ret = -ENOMEM; 186 ret = -ENOMEM;
187 goto out;
185 } 188 }
189 return 0;
186 190
187out: 191out:
188 of_node_put(np); 192 of_node_put(np);
diff --git a/arch/powerpc/sysdev/qe_lib/qe.c b/arch/powerpc/sysdev/qe_lib/qe.c
index 5ef844da9355..6efbd5e5bb1b 100644
--- a/arch/powerpc/sysdev/qe_lib/qe.c
+++ b/arch/powerpc/sysdev/qe_lib/qe.c
@@ -66,7 +66,7 @@ phys_addr_t get_qe_base(void)
66{ 66{
67 struct device_node *qe; 67 struct device_node *qe;
68 unsigned int size; 68 unsigned int size;
69 const void *prop; 69 const u32 *prop;
70 70
71 if (qebase != -1) 71 if (qebase != -1)
72 return qebase; 72 return qebase;
@@ -79,7 +79,8 @@ phys_addr_t get_qe_base(void)
79 } 79 }
80 80
81 prop = of_get_property(qe, "reg", &size); 81 prop = of_get_property(qe, "reg", &size);
82 qebase = of_translate_address(qe, prop); 82 if (prop && size >= sizeof(*prop))
83 qebase = of_translate_address(qe, prop);
83 of_node_put(qe); 84 of_node_put(qe);
84 85
85 return qebase; 86 return qebase;
@@ -172,10 +173,9 @@ unsigned int get_brg_clk(void)
172 } 173 }
173 174
174 prop = of_get_property(qe, "brg-frequency", &size); 175 prop = of_get_property(qe, "brg-frequency", &size);
175 if (!prop || size != sizeof(*prop)) 176 if (prop && size == sizeof(*prop))
176 return brg_clk; 177 brg_clk = *prop;
177 178
178 brg_clk = *prop;
179 of_node_put(qe); 179 of_node_put(qe);
180 180
181 return brg_clk; 181 return brg_clk;
diff --git a/drivers/block/xsysace.c b/drivers/block/xsysace.c
index 78ebfffc77e3..4a7a059ebaf7 100644
--- a/drivers/block/xsysace.c
+++ b/drivers/block/xsysace.c
@@ -1202,8 +1202,10 @@ static int __devexit ace_of_remove(struct of_device *op)
1202} 1202}
1203 1203
1204/* Match table for of_platform binding */ 1204/* Match table for of_platform binding */
1205static struct of_device_id __devinit ace_of_match[] = { 1205static struct of_device_id ace_of_match[] __devinitdata = {
1206 { .compatible = "xilinx,xsysace", }, 1206 { .compatible = "xlnx,opb-sysace-1.00.b", },
1207 { .compatible = "xlnx,opb-sysace-1.00.c", },
1208 { .compatible = "xlnx,xps-sysace-1.00.a", },
1207 {}, 1209 {},
1208}; 1210};
1209MODULE_DEVICE_TABLE(of, ace_of_match); 1211MODULE_DEVICE_TABLE(of, ace_of_match);
diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c
index 8473b9f1da96..cac06bc1754b 100644
--- a/drivers/cdrom/viocd.c
+++ b/drivers/cdrom/viocd.c
@@ -558,7 +558,7 @@ static struct cdrom_device_ops viocd_dops = {
558 .capability = CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK | CDC_SELECT_SPEED | CDC_SELECT_DISC | CDC_MULTI_SESSION | CDC_MCN | CDC_MEDIA_CHANGED | CDC_PLAY_AUDIO | CDC_RESET | CDC_DRIVE_STATUS | CDC_GENERIC_PACKET | CDC_CD_R | CDC_CD_RW | CDC_DVD | CDC_DVD_R | CDC_DVD_RAM | CDC_RAM 558 .capability = CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK | CDC_SELECT_SPEED | CDC_SELECT_DISC | CDC_MULTI_SESSION | CDC_MCN | CDC_MEDIA_CHANGED | CDC_PLAY_AUDIO | CDC_RESET | CDC_DRIVE_STATUS | CDC_GENERIC_PACKET | CDC_CD_R | CDC_CD_RW | CDC_DVD | CDC_DVD_R | CDC_DVD_RAM | CDC_RAM
559}; 559};
560 560
561static int __init find_capability(const char *type) 561static int find_capability(const char *type)
562{ 562{
563 struct capability_entry *entry; 563 struct capability_entry *entry;
564 564
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index 7927fd0faca3..f01ac9a07bf5 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -830,6 +830,16 @@ config DTLK
830 To compile this driver as a module, choose M here: the 830 To compile this driver as a module, choose M here: the
831 module will be called dtlk. 831 module will be called dtlk.
832 832
833config XILINX_HWICAP
834 tristate "Xilinx HWICAP Support"
835 depends on XILINX_VIRTEX
836 help
837 This option enables support for Xilinx Internal Configuration
838 Access Port (ICAP) driver. The ICAP is used on Xilinx Virtex
839 FPGA platforms to partially reconfigure the FPGA at runtime.
840
841 If unsure, say N.
842
833config R3964 843config R3964
834 tristate "Siemens R3964 line discipline" 844 tristate "Siemens R3964 line discipline"
835 ---help--- 845 ---help---
diff --git a/drivers/char/Makefile b/drivers/char/Makefile
index 4396e37b3d0f..5407b7615614 100644
--- a/drivers/char/Makefile
+++ b/drivers/char/Makefile
@@ -76,6 +76,7 @@ obj-$(CONFIG_EFI_RTC) += efirtc.o
76obj-$(CONFIG_SGI_DS1286) += ds1286.o 76obj-$(CONFIG_SGI_DS1286) += ds1286.o
77obj-$(CONFIG_SGI_IP27_RTC) += ip27-rtc.o 77obj-$(CONFIG_SGI_IP27_RTC) += ip27-rtc.o
78obj-$(CONFIG_DS1302) += ds1302.o 78obj-$(CONFIG_DS1302) += ds1302.o
79obj-$(CONFIG_XILINX_HWICAP) += xilinx_hwicap/
79ifeq ($(CONFIG_GENERIC_NVRAM),y) 80ifeq ($(CONFIG_GENERIC_NVRAM),y)
80 obj-$(CONFIG_NVRAM) += generic_nvram.o 81 obj-$(CONFIG_NVRAM) += generic_nvram.o
81else 82else
diff --git a/drivers/char/xilinx_hwicap/Makefile b/drivers/char/xilinx_hwicap/Makefile
new file mode 100644
index 000000000000..5491cbc42f43
--- /dev/null
+++ b/drivers/char/xilinx_hwicap/Makefile
@@ -0,0 +1,7 @@
1#
2# Makefile for the Xilinx OPB hwicap driver
3#
4
5obj-$(CONFIG_XILINX_HWICAP) += xilinx_hwicap_m.o
6
7xilinx_hwicap_m-y := xilinx_hwicap.o fifo_icap.o buffer_icap.o
diff --git a/drivers/char/xilinx_hwicap/buffer_icap.c b/drivers/char/xilinx_hwicap/buffer_icap.c
new file mode 100644
index 000000000000..dfea2bde162b
--- /dev/null
+++ b/drivers/char/xilinx_hwicap/buffer_icap.c
@@ -0,0 +1,380 @@
1/*****************************************************************************
2 *
3 * Author: Xilinx, Inc.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 *
10 * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
11 * AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
12 * SOLUTIONS FOR XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE,
13 * OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
14 * APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
15 * THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
16 * AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
17 * FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY
18 * WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
19 * IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
20 * REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
21 * INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22 * FOR A PARTICULAR PURPOSE.
23 *
24 * Xilinx products are not intended for use in life support appliances,
25 * devices, or systems. Use in such applications is expressly prohibited.
26 *
27 * (c) Copyright 2003-2008 Xilinx Inc.
28 * All rights reserved.
29 *
30 * You should have received a copy of the GNU General Public License along
31 * with this program; if not, write to the Free Software Foundation, Inc.,
32 * 675 Mass Ave, Cambridge, MA 02139, USA.
33 *
34 *****************************************************************************/
35
36#include "buffer_icap.h"
37
38/* Indicates how many bytes will fit in a buffer. (1 BRAM) */
39#define XHI_MAX_BUFFER_BYTES 2048
40#define XHI_MAX_BUFFER_INTS (XHI_MAX_BUFFER_BYTES >> 2)
41
42/* File access and error constants */
43#define XHI_DEVICE_READ_ERROR -1
44#define XHI_DEVICE_WRITE_ERROR -2
45#define XHI_BUFFER_OVERFLOW_ERROR -3
46
47#define XHI_DEVICE_READ 0x1
48#define XHI_DEVICE_WRITE 0x0
49
50/* Constants for checking transfer status */
51#define XHI_CYCLE_DONE 0
52#define XHI_CYCLE_EXECUTING 1
53
54/* buffer_icap register offsets */
55
56/* Size of transfer, read & write */
57#define XHI_SIZE_REG_OFFSET 0x800L
58/* offset into bram, read & write */
59#define XHI_BRAM_OFFSET_REG_OFFSET 0x804L
60/* Read not Configure, direction of transfer. Write only */
61#define XHI_RNC_REG_OFFSET 0x808L
62/* Indicates transfer complete. Read only */
63#define XHI_STATUS_REG_OFFSET 0x80CL
64
65/* Constants for setting the RNC register */
66#define XHI_CONFIGURE 0x0UL
67#define XHI_READBACK 0x1UL
68
69/* Constants for the Done register */
70#define XHI_NOT_FINISHED 0x0UL
71#define XHI_FINISHED 0x1UL
72
73#define XHI_BUFFER_START 0
74
75/**
76 * buffer_icap_get_status: Get the contents of the status register.
77 * @parameter base_address: is the base address of the device
78 *
79 * The status register contains the ICAP status and the done bit.
80 *
81 * D8 - cfgerr
82 * D7 - dalign
83 * D6 - rip
84 * D5 - in_abort_l
85 * D4 - Always 1
86 * D3 - Always 1
87 * D2 - Always 1
88 * D1 - Always 1
89 * D0 - Done bit
90 **/
91static inline u32 buffer_icap_get_status(void __iomem *base_address)
92{
93 return in_be32(base_address + XHI_STATUS_REG_OFFSET);
94}
95
96/**
97 * buffer_icap_get_bram: Reads data from the storage buffer bram.
98 * @parameter base_address: contains the base address of the component.
99 * @parameter offset: The word offset from which the data should be read.
100 *
101 * A bram is used as a configuration memory cache. One frame of data can
102 * be stored in this "storage buffer".
103 **/
104static inline u32 buffer_icap_get_bram(void __iomem *base_address,
105 u32 offset)
106{
107 return in_be32(base_address + (offset << 2));
108}
109
110/**
111 * buffer_icap_busy: Return true if the icap device is busy
112 * @parameter base_address: is the base address of the device
113 *
114 * The queries the low order bit of the status register, which
115 * indicates whether the current configuration or readback operation
116 * has completed.
117 **/
118static inline bool buffer_icap_busy(void __iomem *base_address)
119{
120 return (buffer_icap_get_status(base_address) & 1) == XHI_NOT_FINISHED;
121}
122
123/**
124 * buffer_icap_busy: Return true if the icap device is not busy
125 * @parameter base_address: is the base address of the device
126 *
127 * The queries the low order bit of the status register, which
128 * indicates whether the current configuration or readback operation
129 * has completed.
130 **/
131static inline bool buffer_icap_done(void __iomem *base_address)
132{
133 return (buffer_icap_get_status(base_address) & 1) == XHI_FINISHED;
134}
135
136/**
137 * buffer_icap_set_size: Set the size register.
138 * @parameter base_address: is the base address of the device
139 * @parameter data: The size in bytes.
140 *
141 * The size register holds the number of 8 bit bytes to transfer between
142 * bram and the icap (or icap to bram).
143 **/
144static inline void buffer_icap_set_size(void __iomem *base_address,
145 u32 data)
146{
147 out_be32(base_address + XHI_SIZE_REG_OFFSET, data);
148}
149
150/**
151 * buffer_icap_mSetoffsetReg: Set the bram offset register.
152 * @parameter base_address: contains the base address of the device.
153 * @parameter data: is the value to be written to the data register.
154 *
155 * The bram offset register holds the starting bram address to transfer
156 * data from during configuration or write data to during readback.
157 **/
158static inline void buffer_icap_set_offset(void __iomem *base_address,
159 u32 data)
160{
161 out_be32(base_address + XHI_BRAM_OFFSET_REG_OFFSET, data);
162}
163
164/**
165 * buffer_icap_set_rnc: Set the RNC (Readback not Configure) register.
166 * @parameter base_address: contains the base address of the device.
167 * @parameter data: is the value to be written to the data register.
168 *
169 * The RNC register determines the direction of the data transfer. It
170 * controls whether a configuration or readback take place. Writing to
171 * this register initiates the transfer. A value of 1 initiates a
172 * readback while writing a value of 0 initiates a configuration.
173 **/
174static inline void buffer_icap_set_rnc(void __iomem *base_address,
175 u32 data)
176{
177 out_be32(base_address + XHI_RNC_REG_OFFSET, data);
178}
179
180/**
181 * buffer_icap_set_bram: Write data to the storage buffer bram.
182 * @parameter base_address: contains the base address of the component.
183 * @parameter offset: The word offset at which the data should be written.
184 * @parameter data: The value to be written to the bram offset.
185 *
186 * A bram is used as a configuration memory cache. One frame of data can
187 * be stored in this "storage buffer".
188 **/
189static inline void buffer_icap_set_bram(void __iomem *base_address,
190 u32 offset, u32 data)
191{
192 out_be32(base_address + (offset << 2), data);
193}
194
195/**
196 * buffer_icap_device_read: Transfer bytes from ICAP to the storage buffer.
197 * @parameter drvdata: a pointer to the drvdata.
198 * @parameter offset: The storage buffer start address.
199 * @parameter count: The number of words (32 bit) to read from the
200 * device (ICAP).
201 **/
202static int buffer_icap_device_read(struct hwicap_drvdata *drvdata,
203 u32 offset, u32 count)
204{
205
206 s32 retries = 0;
207 void __iomem *base_address = drvdata->base_address;
208
209 if (buffer_icap_busy(base_address))
210 return -EBUSY;
211
212 if ((offset + count) > XHI_MAX_BUFFER_INTS)
213 return -EINVAL;
214
215 /* setSize count*4 to get bytes. */
216 buffer_icap_set_size(base_address, (count << 2));
217 buffer_icap_set_offset(base_address, offset);
218 buffer_icap_set_rnc(base_address, XHI_READBACK);
219
220 while (buffer_icap_busy(base_address)) {
221 retries++;
222 if (retries > XHI_MAX_RETRIES)
223 return -EBUSY;
224 }
225 return 0;
226
227};
228
229/**
230 * buffer_icap_device_write: Transfer bytes from ICAP to the storage buffer.
231 * @parameter drvdata: a pointer to the drvdata.
232 * @parameter offset: The storage buffer start address.
233 * @parameter count: The number of words (32 bit) to read from the
234 * device (ICAP).
235 **/
236static int buffer_icap_device_write(struct hwicap_drvdata *drvdata,
237 u32 offset, u32 count)
238{
239
240 s32 retries = 0;
241 void __iomem *base_address = drvdata->base_address;
242
243 if (buffer_icap_busy(base_address))
244 return -EBUSY;
245
246 if ((offset + count) > XHI_MAX_BUFFER_INTS)
247 return -EINVAL;
248
249 /* setSize count*4 to get bytes. */
250 buffer_icap_set_size(base_address, count << 2);
251 buffer_icap_set_offset(base_address, offset);
252 buffer_icap_set_rnc(base_address, XHI_CONFIGURE);
253
254 while (buffer_icap_busy(base_address)) {
255 retries++;
256 if (retries > XHI_MAX_RETRIES)
257 return -EBUSY;
258 }
259 return 0;
260
261};
262
263/**
264 * buffer_icap_reset: Reset the logic of the icap device.
265 * @parameter drvdata: a pointer to the drvdata.
266 *
267 * Writing to the status register resets the ICAP logic in an internal
268 * version of the core. For the version of the core published in EDK,
269 * this is a noop.
270 **/
271void buffer_icap_reset(struct hwicap_drvdata *drvdata)
272{
273 out_be32(drvdata->base_address + XHI_STATUS_REG_OFFSET, 0xFEFE);
274}
275
276/**
277 * buffer_icap_set_configuration: Load a partial bitstream from system memory.
278 * @parameter drvdata: a pointer to the drvdata.
279 * @parameter data: Kernel address of the partial bitstream.
280 * @parameter size: the size of the partial bitstream in 32 bit words.
281 **/
282int buffer_icap_set_configuration(struct hwicap_drvdata *drvdata, u32 *data,
283 u32 size)
284{
285 int status;
286 s32 buffer_count = 0;
287 s32 num_writes = 0;
288 bool dirty = 0;
289 u32 i;
290 void __iomem *base_address = drvdata->base_address;
291
292 /* Loop through all the data */
293 for (i = 0, buffer_count = 0; i < size; i++) {
294
295 /* Copy data to bram */
296 buffer_icap_set_bram(base_address, buffer_count, data[i]);
297 dirty = 1;
298
299 if (buffer_count < XHI_MAX_BUFFER_INTS - 1) {
300 buffer_count++;
301 continue;
302 }
303
304 /* Write data to ICAP */
305 status = buffer_icap_device_write(
306 drvdata,
307 XHI_BUFFER_START,
308 XHI_MAX_BUFFER_INTS);
309 if (status != 0) {
310 /* abort. */
311 buffer_icap_reset(drvdata);
312 return status;
313 }
314
315 buffer_count = 0;
316 num_writes++;
317 dirty = 0;
318 }
319
320 /* Write unwritten data to ICAP */
321 if (dirty) {
322 /* Write data to ICAP */
323 status = buffer_icap_device_write(drvdata, XHI_BUFFER_START,
324 buffer_count);
325 if (status != 0) {
326 /* abort. */
327 buffer_icap_reset(drvdata);
328 }
329 return status;
330 }
331
332 return 0;
333};
334
335/**
336 * buffer_icap_get_configuration: Read configuration data from the device.
337 * @parameter drvdata: a pointer to the drvdata.
338 * @parameter data: Address of the data representing the partial bitstream
339 * @parameter size: the size of the partial bitstream in 32 bit words.
340 **/
341int buffer_icap_get_configuration(struct hwicap_drvdata *drvdata, u32 *data,
342 u32 size)
343{
344 int status;
345 s32 buffer_count = 0;
346 s32 read_count = 0;
347 u32 i;
348 void __iomem *base_address = drvdata->base_address;
349
350 /* Loop through all the data */
351 for (i = 0, buffer_count = XHI_MAX_BUFFER_INTS; i < size; i++) {
352 if (buffer_count == XHI_MAX_BUFFER_INTS) {
353 u32 words_remaining = size - i;
354 u32 words_to_read =
355 words_remaining <
356 XHI_MAX_BUFFER_INTS ? words_remaining :
357 XHI_MAX_BUFFER_INTS;
358
359 /* Read data from ICAP */
360 status = buffer_icap_device_read(
361 drvdata,
362 XHI_BUFFER_START,
363 words_to_read);
364 if (status != 0) {
365 /* abort. */
366 buffer_icap_reset(drvdata);
367 return status;
368 }
369
370 buffer_count = 0;
371 read_count++;
372 }
373
374 /* Copy data from bram */
375 data[i] = buffer_icap_get_bram(base_address, buffer_count);
376 buffer_count++;
377 }
378
379 return 0;
380};
diff --git a/drivers/char/xilinx_hwicap/buffer_icap.h b/drivers/char/xilinx_hwicap/buffer_icap.h
new file mode 100644
index 000000000000..03184959fa00
--- /dev/null
+++ b/drivers/char/xilinx_hwicap/buffer_icap.h
@@ -0,0 +1,57 @@
1/*****************************************************************************
2 *
3 * Author: Xilinx, Inc.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 *
10 * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
11 * AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
12 * SOLUTIONS FOR XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE,
13 * OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
14 * APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
15 * THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
16 * AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
17 * FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY
18 * WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
19 * IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
20 * REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
21 * INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22 * FOR A PARTICULAR PURPOSE.
23 *
24 * Xilinx products are not intended for use in life support appliances,
25 * devices, or systems. Use in such applications is expressly prohibited.
26 *
27 * (c) Copyright 2003-2008 Xilinx Inc.
28 * All rights reserved.
29 *
30 * You should have received a copy of the GNU General Public License along
31 * with this program; if not, write to the Free Software Foundation, Inc.,
32 * 675 Mass Ave, Cambridge, MA 02139, USA.
33 *
34 *****************************************************************************/
35
36#ifndef XILINX_BUFFER_ICAP_H_ /* prevent circular inclusions */
37#define XILINX_BUFFER_ICAP_H_ /* by using protection macros */
38
39#include <linux/types.h>
40#include <linux/cdev.h>
41#include <linux/version.h>
42#include <linux/platform_device.h>
43
44#include <asm/io.h>
45#include "xilinx_hwicap.h"
46
47void buffer_icap_reset(struct hwicap_drvdata *drvdata);
48
49/* Loads a partial bitstream from system memory. */
50int buffer_icap_set_configuration(struct hwicap_drvdata *drvdata, u32 *data,
51 u32 Size);
52
53/* Loads a partial bitstream from system memory. */
54int buffer_icap_get_configuration(struct hwicap_drvdata *drvdata, u32 *data,
55 u32 Size);
56
57#endif
diff --git a/drivers/char/xilinx_hwicap/fifo_icap.c b/drivers/char/xilinx_hwicap/fifo_icap.c
new file mode 100644
index 000000000000..0988314694a6
--- /dev/null
+++ b/drivers/char/xilinx_hwicap/fifo_icap.c
@@ -0,0 +1,381 @@
1/*****************************************************************************
2 *
3 * Author: Xilinx, Inc.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 *
10 * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
11 * AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
12 * SOLUTIONS FOR XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE,
13 * OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
14 * APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
15 * THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
16 * AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
17 * FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY
18 * WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
19 * IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
20 * REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
21 * INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22 * FOR A PARTICULAR PURPOSE.
23 *
24 * Xilinx products are not intended for use in life support appliances,
25 * devices, or systems. Use in such applications is expressly prohibited.
26 *
27 * (c) Copyright 2007-2008 Xilinx Inc.
28 * All rights reserved.
29 *
30 * You should have received a copy of the GNU General Public License along
31 * with this program; if not, write to the Free Software Foundation, Inc.,
32 * 675 Mass Ave, Cambridge, MA 02139, USA.
33 *
34 *****************************************************************************/
35
36#include "fifo_icap.h"
37
38/* Register offsets for the XHwIcap device. */
39#define XHI_GIER_OFFSET 0x1C /* Device Global Interrupt Enable Reg */
40#define XHI_IPISR_OFFSET 0x20 /* Interrupt Status Register */
41#define XHI_IPIER_OFFSET 0x28 /* Interrupt Enable Register */
42#define XHI_WF_OFFSET 0x100 /* Write FIFO */
43#define XHI_RF_OFFSET 0x104 /* Read FIFO */
44#define XHI_SZ_OFFSET 0x108 /* Size Register */
45#define XHI_CR_OFFSET 0x10C /* Control Register */
46#define XHI_SR_OFFSET 0x110 /* Status Register */
47#define XHI_WFV_OFFSET 0x114 /* Write FIFO Vacancy Register */
48#define XHI_RFO_OFFSET 0x118 /* Read FIFO Occupancy Register */
49
50/* Device Global Interrupt Enable Register (GIER) bit definitions */
51
52#define XHI_GIER_GIE_MASK 0x80000000 /* Global Interrupt enable Mask */
53
54/**
55 * HwIcap Device Interrupt Status/Enable Registers
56 *
57 * Interrupt Status Register (IPISR) : This register holds the
58 * interrupt status flags for the device. These bits are toggle on
59 * write.
60 *
61 * Interrupt Enable Register (IPIER) : This register is used to enable
62 * interrupt sources for the device.
63 * Writing a '1' to a bit enables the corresponding interrupt.
64 * Writing a '0' to a bit disables the corresponding interrupt.
65 *
66 * IPISR/IPIER registers have the same bit definitions and are only defined
67 * once.
68 */
69#define XHI_IPIXR_RFULL_MASK 0x00000008 /* Read FIFO Full */
70#define XHI_IPIXR_WEMPTY_MASK 0x00000004 /* Write FIFO Empty */
71#define XHI_IPIXR_RDP_MASK 0x00000002 /* Read FIFO half full */
72#define XHI_IPIXR_WRP_MASK 0x00000001 /* Write FIFO half full */
73#define XHI_IPIXR_ALL_MASK 0x0000000F /* Mask of all interrupts */
74
75/* Control Register (CR) */
76#define XHI_CR_SW_RESET_MASK 0x00000008 /* SW Reset Mask */
77#define XHI_CR_FIFO_CLR_MASK 0x00000004 /* FIFO Clear Mask */
78#define XHI_CR_READ_MASK 0x00000002 /* Read from ICAP to FIFO */
79#define XHI_CR_WRITE_MASK 0x00000001 /* Write from FIFO to ICAP */
80
81/* Status Register (SR) */
82#define XHI_SR_CFGERR_N_MASK 0x00000100 /* Config Error Mask */
83#define XHI_SR_DALIGN_MASK 0x00000080 /* Data Alignment Mask */
84#define XHI_SR_RIP_MASK 0x00000040 /* Read back Mask */
85#define XHI_SR_IN_ABORT_N_MASK 0x00000020 /* Select Map Abort Mask */
86#define XHI_SR_DONE_MASK 0x00000001 /* Done bit Mask */
87
88
89#define XHI_WFO_MAX_VACANCY 1024 /* Max Write FIFO Vacancy, in words */
90#define XHI_RFO_MAX_OCCUPANCY 256 /* Max Read FIFO Occupancy, in words */
91/* The maximum amount we can request from fifo_icap_get_configuration
92 at once, in bytes. */
93#define XHI_MAX_READ_TRANSACTION_WORDS 0xFFF
94
95
96/**
97 * fifo_icap_fifo_write: Write data to the write FIFO.
98 * @parameter drvdata: a pointer to the drvdata.
99 * @parameter data: the 32-bit value to be written to the FIFO.
100 *
101 * This function will silently fail if the fifo is full.
102 **/
103static inline void fifo_icap_fifo_write(struct hwicap_drvdata *drvdata,
104 u32 data)
105{
106 dev_dbg(drvdata->dev, "fifo_write: %x\n", data);
107 out_be32(drvdata->base_address + XHI_WF_OFFSET, data);
108}
109
110/**
111 * fifo_icap_fifo_read: Read data from the Read FIFO.
112 * @parameter drvdata: a pointer to the drvdata.
113 *
114 * This function will silently fail if the fifo is empty.
115 **/
116static inline u32 fifo_icap_fifo_read(struct hwicap_drvdata *drvdata)
117{
118 u32 data = in_be32(drvdata->base_address + XHI_RF_OFFSET);
119 dev_dbg(drvdata->dev, "fifo_read: %x\n", data);
120 return data;
121}
122
123/**
124 * fifo_icap_set_read_size: Set the the size register.
125 * @parameter drvdata: a pointer to the drvdata.
126 * @parameter data: the size of the following read transaction, in words.
127 **/
128static inline void fifo_icap_set_read_size(struct hwicap_drvdata *drvdata,
129 u32 data)
130{
131 out_be32(drvdata->base_address + XHI_SZ_OFFSET, data);
132}
133
134/**
135 * fifo_icap_start_config: Initiate a configuration (write) to the device.
136 * @parameter drvdata: a pointer to the drvdata.
137 **/
138static inline void fifo_icap_start_config(struct hwicap_drvdata *drvdata)
139{
140 out_be32(drvdata->base_address + XHI_CR_OFFSET, XHI_CR_WRITE_MASK);
141 dev_dbg(drvdata->dev, "configuration started\n");
142}
143
144/**
145 * fifo_icap_start_readback: Initiate a readback from the device.
146 * @parameter drvdata: a pointer to the drvdata.
147 **/
148static inline void fifo_icap_start_readback(struct hwicap_drvdata *drvdata)
149{
150 out_be32(drvdata->base_address + XHI_CR_OFFSET, XHI_CR_READ_MASK);
151 dev_dbg(drvdata->dev, "readback started\n");
152}
153
154/**
155 * fifo_icap_busy: Return true if the ICAP is still processing a transaction.
156 * @parameter drvdata: a pointer to the drvdata.
157 **/
158static inline u32 fifo_icap_busy(struct hwicap_drvdata *drvdata)
159{
160 u32 status = in_be32(drvdata->base_address + XHI_SR_OFFSET);
161 dev_dbg(drvdata->dev, "Getting status = %x\n", status);
162 return (status & XHI_SR_DONE_MASK) ? 0 : 1;
163}
164
165/**
166 * fifo_icap_write_fifo_vacancy: Query the write fifo available space.
167 * @parameter drvdata: a pointer to the drvdata.
168 *
169 * Return the number of words that can be safely pushed into the write fifo.
170 **/
171static inline u32 fifo_icap_write_fifo_vacancy(
172 struct hwicap_drvdata *drvdata)
173{
174 return in_be32(drvdata->base_address + XHI_WFV_OFFSET);
175}
176
177/**
178 * fifo_icap_read_fifo_occupancy: Query the read fifo available data.
179 * @parameter drvdata: a pointer to the drvdata.
180 *
181 * Return the number of words that can be safely read from the read fifo.
182 **/
183static inline u32 fifo_icap_read_fifo_occupancy(
184 struct hwicap_drvdata *drvdata)
185{
186 return in_be32(drvdata->base_address + XHI_RFO_OFFSET);
187}
188
189/**
190 * fifo_icap_set_configuration: Send configuration data to the ICAP.
191 * @parameter drvdata: a pointer to the drvdata.
192 * @parameter frame_buffer: a pointer to the data to be written to the
193 * ICAP device.
194 * @parameter num_words: the number of words (32 bit) to write to the ICAP
195 * device.
196
197 * This function writes the given user data to the Write FIFO in
198 * polled mode and starts the transfer of the data to
199 * the ICAP device.
200 **/
201int fifo_icap_set_configuration(struct hwicap_drvdata *drvdata,
202 u32 *frame_buffer, u32 num_words)
203{
204
205 u32 write_fifo_vacancy = 0;
206 u32 retries = 0;
207 u32 remaining_words;
208
209 dev_dbg(drvdata->dev, "fifo_set_configuration\n");
210
211 /*
212 * Check if the ICAP device is Busy with the last Read/Write
213 */
214 if (fifo_icap_busy(drvdata))
215 return -EBUSY;
216
217 /*
218 * Set up the buffer pointer and the words to be transferred.
219 */
220 remaining_words = num_words;
221
222 while (remaining_words > 0) {
223 /*
224 * Wait until we have some data in the fifo.
225 */
226 while (write_fifo_vacancy == 0) {
227 write_fifo_vacancy =
228 fifo_icap_write_fifo_vacancy(drvdata);
229 retries++;
230 if (retries > XHI_MAX_RETRIES)
231 return -EIO;
232 }
233
234 /*
235 * Write data into the Write FIFO.
236 */
237 while ((write_fifo_vacancy != 0) &&
238 (remaining_words > 0)) {
239 fifo_icap_fifo_write(drvdata, *frame_buffer);
240
241 remaining_words--;
242 write_fifo_vacancy--;
243 frame_buffer++;
244 }
245 /* Start pushing whatever is in the FIFO into the ICAP. */
246 fifo_icap_start_config(drvdata);
247 }
248
249 /* Wait until the write has finished. */
250 while (fifo_icap_busy(drvdata)) {
251 retries++;
252 if (retries > XHI_MAX_RETRIES)
253 break;
254 }
255
256 dev_dbg(drvdata->dev, "done fifo_set_configuration\n");
257
258 /*
259 * If the requested number of words have not been read from
260 * the device then indicate failure.
261 */
262 if (remaining_words != 0)
263 return -EIO;
264
265 return 0;
266}
267
268/**
269 * fifo_icap_get_configuration: Read configuration data from the device.
270 * @parameter drvdata: a pointer to the drvdata.
271 * @parameter data: Address of the data representing the partial bitstream
272 * @parameter size: the size of the partial bitstream in 32 bit words.
273 *
274 * This function reads the specified number of words from the ICAP device in
275 * the polled mode.
276 */
277int fifo_icap_get_configuration(struct hwicap_drvdata *drvdata,
278 u32 *frame_buffer, u32 num_words)
279{
280
281 u32 read_fifo_occupancy = 0;
282 u32 retries = 0;
283 u32 *data = frame_buffer;
284 u32 remaining_words;
285 u32 words_to_read;
286
287 dev_dbg(drvdata->dev, "fifo_get_configuration\n");
288
289 /*
290 * Check if the ICAP device is Busy with the last Write/Read
291 */
292 if (fifo_icap_busy(drvdata))
293 return -EBUSY;
294
295 remaining_words = num_words;
296
297 while (remaining_words > 0) {
298 words_to_read = remaining_words;
299 /* The hardware has a limit on the number of words
300 that can be read at one time. */
301 if (words_to_read > XHI_MAX_READ_TRANSACTION_WORDS)
302 words_to_read = XHI_MAX_READ_TRANSACTION_WORDS;
303
304 remaining_words -= words_to_read;
305
306 fifo_icap_set_read_size(drvdata, words_to_read);
307 fifo_icap_start_readback(drvdata);
308
309 while (words_to_read > 0) {
310 /* Wait until we have some data in the fifo. */
311 while (read_fifo_occupancy == 0) {
312 read_fifo_occupancy =
313 fifo_icap_read_fifo_occupancy(drvdata);
314 retries++;
315 if (retries > XHI_MAX_RETRIES)
316 return -EIO;
317 }
318
319 if (read_fifo_occupancy > words_to_read)
320 read_fifo_occupancy = words_to_read;
321
322 words_to_read -= read_fifo_occupancy;
323
324 /* Read the data from the Read FIFO. */
325 while (read_fifo_occupancy != 0) {
326 *data++ = fifo_icap_fifo_read(drvdata);
327 read_fifo_occupancy--;
328 }
329 }
330 }
331
332 dev_dbg(drvdata->dev, "done fifo_get_configuration\n");
333
334 return 0;
335}
336
337/**
338 * buffer_icap_reset: Reset the logic of the icap device.
339 * @parameter drvdata: a pointer to the drvdata.
340 *
341 * This function forces the software reset of the complete HWICAP device.
342 * All the registers will return to the default value and the FIFO is also
343 * flushed as a part of this software reset.
344 */
345void fifo_icap_reset(struct hwicap_drvdata *drvdata)
346{
347 u32 reg_data;
348 /*
349 * Reset the device by setting/clearing the RESET bit in the
350 * Control Register.
351 */
352 reg_data = in_be32(drvdata->base_address + XHI_CR_OFFSET);
353
354 out_be32(drvdata->base_address + XHI_CR_OFFSET,
355 reg_data | XHI_CR_SW_RESET_MASK);
356
357 out_be32(drvdata->base_address + XHI_CR_OFFSET,
358 reg_data & (~XHI_CR_SW_RESET_MASK));
359
360}
361
362/**
363 * fifo_icap_flush_fifo: This function flushes the FIFOs in the device.
364 * @parameter drvdata: a pointer to the drvdata.
365 */
366void fifo_icap_flush_fifo(struct hwicap_drvdata *drvdata)
367{
368 u32 reg_data;
369 /*
370 * Flush the FIFO by setting/clearing the FIFO Clear bit in the
371 * Control Register.
372 */
373 reg_data = in_be32(drvdata->base_address + XHI_CR_OFFSET);
374
375 out_be32(drvdata->base_address + XHI_CR_OFFSET,
376 reg_data | XHI_CR_FIFO_CLR_MASK);
377
378 out_be32(drvdata->base_address + XHI_CR_OFFSET,
379 reg_data & (~XHI_CR_FIFO_CLR_MASK));
380}
381
diff --git a/drivers/char/xilinx_hwicap/fifo_icap.h b/drivers/char/xilinx_hwicap/fifo_icap.h
new file mode 100644
index 000000000000..4d3068dd0405
--- /dev/null
+++ b/drivers/char/xilinx_hwicap/fifo_icap.h
@@ -0,0 +1,62 @@
1/*****************************************************************************
2 *
3 * Author: Xilinx, Inc.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 *
10 * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
11 * AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
12 * SOLUTIONS FOR XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE,
13 * OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
14 * APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
15 * THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
16 * AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
17 * FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY
18 * WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
19 * IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
20 * REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
21 * INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22 * FOR A PARTICULAR PURPOSE.
23 *
24 * Xilinx products are not intended for use in life support appliances,
25 * devices, or systems. Use in such applications is expressly prohibited.
26 *
27 * (c) Copyright 2007-2008 Xilinx Inc.
28 * All rights reserved.
29 *
30 * You should have received a copy of the GNU General Public License along
31 * with this program; if not, write to the Free Software Foundation, Inc.,
32 * 675 Mass Ave, Cambridge, MA 02139, USA.
33 *
34 *****************************************************************************/
35
36#ifndef XILINX_FIFO_ICAP_H_ /* prevent circular inclusions */
37#define XILINX_FIFO_ICAP_H_ /* by using protection macros */
38
39#include <linux/types.h>
40#include <linux/cdev.h>
41#include <linux/version.h>
42#include <linux/platform_device.h>
43
44#include <asm/io.h>
45#include "xilinx_hwicap.h"
46
47/* Reads integers from the device into the storage buffer. */
48int fifo_icap_get_configuration(
49 struct hwicap_drvdata *drvdata,
50 u32 *FrameBuffer,
51 u32 NumWords);
52
53/* Writes integers to the device from the storage buffer. */
54int fifo_icap_set_configuration(
55 struct hwicap_drvdata *drvdata,
56 u32 *FrameBuffer,
57 u32 NumWords);
58
59void fifo_icap_reset(struct hwicap_drvdata *drvdata);
60void fifo_icap_flush_fifo(struct hwicap_drvdata *drvdata);
61
62#endif
diff --git a/drivers/char/xilinx_hwicap/xilinx_hwicap.c b/drivers/char/xilinx_hwicap/xilinx_hwicap.c
new file mode 100644
index 000000000000..24f6aef0fd3c
--- /dev/null
+++ b/drivers/char/xilinx_hwicap/xilinx_hwicap.c
@@ -0,0 +1,904 @@
1/*****************************************************************************
2 *
3 * Author: Xilinx, Inc.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 *
10 * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
11 * AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
12 * SOLUTIONS FOR XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE,
13 * OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
14 * APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
15 * THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
16 * AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
17 * FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY
18 * WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
19 * IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
20 * REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
21 * INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22 * FOR A PARTICULAR PURPOSE.
23 *
24 * Xilinx products are not intended for use in life support appliances,
25 * devices, or systems. Use in such applications is expressly prohibited.
26 *
27 * (c) Copyright 2002 Xilinx Inc., Systems Engineering Group
28 * (c) Copyright 2004 Xilinx Inc., Systems Engineering Group
29 * (c) Copyright 2007-2008 Xilinx Inc.
30 * All rights reserved.
31 *
32 * You should have received a copy of the GNU General Public License along
33 * with this program; if not, write to the Free Software Foundation, Inc.,
34 * 675 Mass Ave, Cambridge, MA 02139, USA.
35 *
36 *****************************************************************************/
37
38/*
39 * This is the code behind /dev/xilinx_icap -- it allows a user-space
40 * application to use the Xilinx ICAP subsystem.
41 *
42 * The following operations are possible:
43 *
44 * open open the port and initialize for access.
45 * release release port
46 * write Write a bitstream to the configuration processor.
47 * read Read a data stream from the configuration processor.
48 *
49 * After being opened, the port is initialized and accessed to avoid a
50 * corrupted first read which may occur with some hardware. The port
51 * is left in a desynched state, requiring that a synch sequence be
52 * transmitted before any valid configuration data. A user will have
53 * exclusive access to the device while it remains open, and the state
54 * of the ICAP cannot be guaranteed after the device is closed. Note
55 * that a complete reset of the core and the state of the ICAP cannot
56 * be performed on many versions of the cores, hence users of this
57 * device should avoid making inconsistent accesses to the device. In
58 * particular, accessing the read interface, without first generating
59 * a write containing a readback packet can leave the ICAP in an
60 * inaccessible state.
61 *
62 * Note that in order to use the read interface, it is first necessary
63 * to write a request packet to the write interface. i.e., it is not
64 * possible to simply readback the bitstream (or any configuration
65 * bits) from a device without specifically requesting them first.
66 * The code to craft such packets is intended to be part of the
67 * user-space application code that uses this device. The simplest
68 * way to use this interface is simply:
69 *
70 * cp foo.bit /dev/xilinx_icap
71 *
72 * Note that unless foo.bit is an appropriately constructed partial
73 * bitstream, this has a high likelyhood of overwriting the design
74 * currently programmed in the FPGA.
75 */
76
77#include <linux/version.h>
78#include <linux/module.h>
79#include <linux/kernel.h>
80#include <linux/types.h>
81#include <linux/ioport.h>
82#include <linux/interrupt.h>
83#include <linux/fcntl.h>
84#include <linux/init.h>
85#include <linux/poll.h>
86#include <linux/proc_fs.h>
87#include <asm/semaphore.h>
88#include <linux/sysctl.h>
89#include <linux/version.h>
90#include <linux/fs.h>
91#include <linux/cdev.h>
92#include <linux/platform_device.h>
93
94#include <asm/io.h>
95#include <asm/uaccess.h>
96#include <asm/system.h>
97
98#ifdef CONFIG_OF
99/* For open firmware. */
100#include <linux/of_device.h>
101#include <linux/of_platform.h>
102#endif
103
104#include "xilinx_hwicap.h"
105#include "buffer_icap.h"
106#include "fifo_icap.h"
107
108#define DRIVER_NAME "xilinx_icap"
109
110#define HWICAP_REGS (0x10000)
111
112/* dynamically allocate device number */
113static int xhwicap_major;
114static int xhwicap_minor;
115#define HWICAP_DEVICES 1
116
117module_param(xhwicap_major, int, S_IRUGO);
118module_param(xhwicap_minor, int, S_IRUGO);
119
120/* An array, which is set to true when the device is registered. */
121static bool probed_devices[HWICAP_DEVICES];
122
123static struct class *icap_class;
124
125#define UNIMPLEMENTED 0xFFFF
126
127static const struct config_registers v2_config_registers = {
128 .CRC = 0,
129 .FAR = 1,
130 .FDRI = 2,
131 .FDRO = 3,
132 .CMD = 4,
133 .CTL = 5,
134 .MASK = 6,
135 .STAT = 7,
136 .LOUT = 8,
137 .COR = 9,
138 .MFWR = 10,
139 .FLR = 11,
140 .KEY = 12,
141 .CBC = 13,
142 .IDCODE = 14,
143 .AXSS = UNIMPLEMENTED,
144 .C0R_1 = UNIMPLEMENTED,
145 .CSOB = UNIMPLEMENTED,
146 .WBSTAR = UNIMPLEMENTED,
147 .TIMER = UNIMPLEMENTED,
148 .BOOTSTS = UNIMPLEMENTED,
149 .CTL_1 = UNIMPLEMENTED,
150};
151
152static const struct config_registers v4_config_registers = {
153 .CRC = 0,
154 .FAR = 1,
155 .FDRI = 2,
156 .FDRO = 3,
157 .CMD = 4,
158 .CTL = 5,
159 .MASK = 6,
160 .STAT = 7,
161 .LOUT = 8,
162 .COR = 9,
163 .MFWR = 10,
164 .FLR = UNIMPLEMENTED,
165 .KEY = UNIMPLEMENTED,
166 .CBC = 11,
167 .IDCODE = 12,
168 .AXSS = 13,
169 .C0R_1 = UNIMPLEMENTED,
170 .CSOB = UNIMPLEMENTED,
171 .WBSTAR = UNIMPLEMENTED,
172 .TIMER = UNIMPLEMENTED,
173 .BOOTSTS = UNIMPLEMENTED,
174 .CTL_1 = UNIMPLEMENTED,
175};
176static const struct config_registers v5_config_registers = {
177 .CRC = 0,
178 .FAR = 1,
179 .FDRI = 2,
180 .FDRO = 3,
181 .CMD = 4,
182 .CTL = 5,
183 .MASK = 6,
184 .STAT = 7,
185 .LOUT = 8,
186 .COR = 9,
187 .MFWR = 10,
188 .FLR = UNIMPLEMENTED,
189 .KEY = UNIMPLEMENTED,
190 .CBC = 11,
191 .IDCODE = 12,
192 .AXSS = 13,
193 .C0R_1 = 14,
194 .CSOB = 15,
195 .WBSTAR = 16,
196 .TIMER = 17,
197 .BOOTSTS = 18,
198 .CTL_1 = 19,
199};
200
201/**
202 * hwicap_command_desync: Send a DESYNC command to the ICAP port.
203 * @parameter drvdata: a pointer to the drvdata.
204 *
205 * This command desynchronizes the ICAP After this command, a
206 * bitstream containing a NULL packet, followed by a SYNCH packet is
207 * required before the ICAP will recognize commands.
208 */
209int hwicap_command_desync(struct hwicap_drvdata *drvdata)
210{
211 u32 buffer[4];
212 u32 index = 0;
213
214 /*
215 * Create the data to be written to the ICAP.
216 */
217 buffer[index++] = hwicap_type_1_write(drvdata->config_regs->CMD) | 1;
218 buffer[index++] = XHI_CMD_DESYNCH;
219 buffer[index++] = XHI_NOOP_PACKET;
220 buffer[index++] = XHI_NOOP_PACKET;
221
222 /*
223 * Write the data to the FIFO and intiate the transfer of data present
224 * in the FIFO to the ICAP device.
225 */
226 return drvdata->config->set_configuration(drvdata,
227 &buffer[0], index);
228}
229
230/**
231 * hwicap_command_capture: Send a CAPTURE command to the ICAP port.
232 * @parameter drvdata: a pointer to the drvdata.
233 *
234 * This command captures all of the flip flop states so they will be
235 * available during readback. One can use this command instead of
236 * enabling the CAPTURE block in the design.
237 */
238int hwicap_command_capture(struct hwicap_drvdata *drvdata)
239{
240 u32 buffer[7];
241 u32 index = 0;
242
243 /*
244 * Create the data to be written to the ICAP.
245 */
246 buffer[index++] = XHI_DUMMY_PACKET;
247 buffer[index++] = XHI_SYNC_PACKET;
248 buffer[index++] = XHI_NOOP_PACKET;
249 buffer[index++] = hwicap_type_1_write(drvdata->config_regs->CMD) | 1;
250 buffer[index++] = XHI_CMD_GCAPTURE;
251 buffer[index++] = XHI_DUMMY_PACKET;
252 buffer[index++] = XHI_DUMMY_PACKET;
253
254 /*
255 * Write the data to the FIFO and intiate the transfer of data
256 * present in the FIFO to the ICAP device.
257 */
258 return drvdata->config->set_configuration(drvdata,
259 &buffer[0], index);
260
261}
262
263/**
264 * hwicap_get_configuration_register: Query a configuration register.
265 * @parameter drvdata: a pointer to the drvdata.
266 * @parameter reg: a constant which represents the configuration
267 * register value to be returned.
268 * Examples: XHI_IDCODE, XHI_FLR.
269 * @parameter RegData: returns the value of the register.
270 *
271 * Sends a query packet to the ICAP and then receives the response.
272 * The icap is left in Synched state.
273 */
274int hwicap_get_configuration_register(struct hwicap_drvdata *drvdata,
275 u32 reg, u32 *RegData)
276{
277 int status;
278 u32 buffer[6];
279 u32 index = 0;
280
281 /*
282 * Create the data to be written to the ICAP.
283 */
284 buffer[index++] = XHI_DUMMY_PACKET;
285 buffer[index++] = XHI_SYNC_PACKET;
286 buffer[index++] = XHI_NOOP_PACKET;
287 buffer[index++] = hwicap_type_1_read(reg) | 1;
288 buffer[index++] = XHI_NOOP_PACKET;
289 buffer[index++] = XHI_NOOP_PACKET;
290
291 /*
292 * Write the data to the FIFO and intiate the transfer of data present
293 * in the FIFO to the ICAP device.
294 */
295 status = drvdata->config->set_configuration(drvdata,
296 &buffer[0], index);
297 if (status)
298 return status;
299
300 /*
301 * Read the configuration register
302 */
303 status = drvdata->config->get_configuration(drvdata, RegData, 1);
304 if (status)
305 return status;
306
307 return 0;
308}
309
310int hwicap_initialize_hwicap(struct hwicap_drvdata *drvdata)
311{
312 int status;
313 u32 idcode;
314
315 dev_dbg(drvdata->dev, "initializing\n");
316
317 /* Abort any current transaction, to make sure we have the
318 * ICAP in a good state. */
319 dev_dbg(drvdata->dev, "Reset...\n");
320 drvdata->config->reset(drvdata);
321
322 dev_dbg(drvdata->dev, "Desync...\n");
323 status = hwicap_command_desync(drvdata);
324 if (status)
325 return status;
326
327 /* Attempt to read the IDCODE from ICAP. This
328 * may not be returned correctly, due to the design of the
329 * hardware.
330 */
331 dev_dbg(drvdata->dev, "Reading IDCODE...\n");
332 status = hwicap_get_configuration_register(
333 drvdata, drvdata->config_regs->IDCODE, &idcode);
334 dev_dbg(drvdata->dev, "IDCODE = %x\n", idcode);
335 if (status)
336 return status;
337
338 dev_dbg(drvdata->dev, "Desync...\n");
339 status = hwicap_command_desync(drvdata);
340 if (status)
341 return status;
342
343 return 0;
344}
345
346static ssize_t
347hwicap_read(struct file *file, char *buf, size_t count, loff_t *ppos)
348{
349 struct hwicap_drvdata *drvdata = file->private_data;
350 ssize_t bytes_to_read = 0;
351 u32 *kbuf;
352 u32 words;
353 u32 bytes_remaining;
354 int status;
355
356 if (down_interruptible(&drvdata->sem))
357 return -ERESTARTSYS;
358
359 if (drvdata->read_buffer_in_use) {
360 /* If there are leftover bytes in the buffer, just */
361 /* return them and don't try to read more from the */
362 /* ICAP device. */
363 bytes_to_read =
364 (count < drvdata->read_buffer_in_use) ? count :
365 drvdata->read_buffer_in_use;
366
367 /* Return the data currently in the read buffer. */
368 if (copy_to_user(buf, drvdata->read_buffer, bytes_to_read)) {
369 status = -EFAULT;
370 goto error;
371 }
372 drvdata->read_buffer_in_use -= bytes_to_read;
373 memcpy(drvdata->read_buffer + bytes_to_read,
374 drvdata->read_buffer, 4 - bytes_to_read);
375 } else {
376 /* Get new data from the ICAP, and return was was requested. */
377 kbuf = (u32 *) get_zeroed_page(GFP_KERNEL);
378 if (!kbuf) {
379 status = -ENOMEM;
380 goto error;
381 }
382
383 /* The ICAP device is only able to read complete */
384 /* words. If a number of bytes that do not correspond */
385 /* to complete words is requested, then we read enough */
386 /* words to get the required number of bytes, and then */
387 /* save the remaining bytes for the next read. */
388
389 /* Determine the number of words to read, rounding up */
390 /* if necessary. */
391 words = ((count + 3) >> 2);
392 bytes_to_read = words << 2;
393
394 if (bytes_to_read > PAGE_SIZE)
395 bytes_to_read = PAGE_SIZE;
396
397 /* Ensure we only read a complete number of words. */
398 bytes_remaining = bytes_to_read & 3;
399 bytes_to_read &= ~3;
400 words = bytes_to_read >> 2;
401
402 status = drvdata->config->get_configuration(drvdata,
403 kbuf, words);
404
405 /* If we didn't read correctly, then bail out. */
406 if (status) {
407 free_page((unsigned long)kbuf);
408 goto error;
409 }
410
411 /* If we fail to return the data to the user, then bail out. */
412 if (copy_to_user(buf, kbuf, bytes_to_read)) {
413 free_page((unsigned long)kbuf);
414 status = -EFAULT;
415 goto error;
416 }
417 memcpy(kbuf, drvdata->read_buffer, bytes_remaining);
418 drvdata->read_buffer_in_use = bytes_remaining;
419 free_page((unsigned long)kbuf);
420 }
421 status = bytes_to_read;
422 error:
423 up(&drvdata->sem);
424 return status;
425}
426
427static ssize_t
428hwicap_write(struct file *file, const char *buf,
429 size_t count, loff_t *ppos)
430{
431 struct hwicap_drvdata *drvdata = file->private_data;
432 ssize_t written = 0;
433 ssize_t left = count;
434 u32 *kbuf;
435 ssize_t len;
436 ssize_t status;
437
438 if (down_interruptible(&drvdata->sem))
439 return -ERESTARTSYS;
440
441 left += drvdata->write_buffer_in_use;
442
443 /* Only write multiples of 4 bytes. */
444 if (left < 4) {
445 status = 0;
446 goto error;
447 }
448
449 kbuf = (u32 *) __get_free_page(GFP_KERNEL);
450 if (!kbuf) {
451 status = -ENOMEM;
452 goto error;
453 }
454
455 while (left > 3) {
456 /* only write multiples of 4 bytes, so there might */
457 /* be as many as 3 bytes left (at the end). */
458 len = left;
459
460 if (len > PAGE_SIZE)
461 len = PAGE_SIZE;
462 len &= ~3;
463
464 if (drvdata->write_buffer_in_use) {
465 memcpy(kbuf, drvdata->write_buffer,
466 drvdata->write_buffer_in_use);
467 if (copy_from_user(
468 (((char *)kbuf) + (drvdata->write_buffer_in_use)),
469 buf + written,
470 len - (drvdata->write_buffer_in_use))) {
471 free_page((unsigned long)kbuf);
472 status = -EFAULT;
473 goto error;
474 }
475 } else {
476 if (copy_from_user(kbuf, buf + written, len)) {
477 free_page((unsigned long)kbuf);
478 status = -EFAULT;
479 goto error;
480 }
481 }
482
483 status = drvdata->config->set_configuration(drvdata,
484 kbuf, len >> 2);
485
486 if (status) {
487 free_page((unsigned long)kbuf);
488 status = -EFAULT;
489 goto error;
490 }
491 if (drvdata->write_buffer_in_use) {
492 len -= drvdata->write_buffer_in_use;
493 left -= drvdata->write_buffer_in_use;
494 drvdata->write_buffer_in_use = 0;
495 }
496 written += len;
497 left -= len;
498 }
499 if ((left > 0) && (left < 4)) {
500 if (!copy_from_user(drvdata->write_buffer,
501 buf + written, left)) {
502 drvdata->write_buffer_in_use = left;
503 written += left;
504 left = 0;
505 }
506 }
507
508 free_page((unsigned long)kbuf);
509 status = written;
510 error:
511 up(&drvdata->sem);
512 return status;
513}
514
515static int hwicap_open(struct inode *inode, struct file *file)
516{
517 struct hwicap_drvdata *drvdata;
518 int status;
519
520 drvdata = container_of(inode->i_cdev, struct hwicap_drvdata, cdev);
521
522 if (down_interruptible(&drvdata->sem))
523 return -ERESTARTSYS;
524
525 if (drvdata->is_open) {
526 status = -EBUSY;
527 goto error;
528 }
529
530 status = hwicap_initialize_hwicap(drvdata);
531 if (status) {
532 dev_err(drvdata->dev, "Failed to open file");
533 goto error;
534 }
535
536 file->private_data = drvdata;
537 drvdata->write_buffer_in_use = 0;
538 drvdata->read_buffer_in_use = 0;
539 drvdata->is_open = 1;
540
541 error:
542 up(&drvdata->sem);
543 return status;
544}
545
546static int hwicap_release(struct inode *inode, struct file *file)
547{
548 struct hwicap_drvdata *drvdata = file->private_data;
549 int i;
550 int status = 0;
551
552 if (down_interruptible(&drvdata->sem))
553 return -ERESTARTSYS;
554
555 if (drvdata->write_buffer_in_use) {
556 /* Flush write buffer. */
557 for (i = drvdata->write_buffer_in_use; i < 4; i++)
558 drvdata->write_buffer[i] = 0;
559
560 status = drvdata->config->set_configuration(drvdata,
561 (u32 *) drvdata->write_buffer, 1);
562 if (status)
563 goto error;
564 }
565
566 status = hwicap_command_desync(drvdata);
567 if (status)
568 goto error;
569
570 error:
571 drvdata->is_open = 0;
572 up(&drvdata->sem);
573 return status;
574}
575
576static struct file_operations hwicap_fops = {
577 .owner = THIS_MODULE,
578 .write = hwicap_write,
579 .read = hwicap_read,
580 .open = hwicap_open,
581 .release = hwicap_release,
582};
583
584static int __devinit hwicap_setup(struct device *dev, int id,
585 const struct resource *regs_res,
586 const struct hwicap_driver_config *config,
587 const struct config_registers *config_regs)
588{
589 dev_t devt;
590 struct hwicap_drvdata *drvdata = NULL;
591 int retval = 0;
592
593 dev_info(dev, "Xilinx icap port driver\n");
594
595 if (id < 0) {
596 for (id = 0; id < HWICAP_DEVICES; id++)
597 if (!probed_devices[id])
598 break;
599 }
600 if (id < 0 || id >= HWICAP_DEVICES) {
601 dev_err(dev, "%s%i too large\n", DRIVER_NAME, id);
602 return -EINVAL;
603 }
604 if (probed_devices[id]) {
605 dev_err(dev, "cannot assign to %s%i; it is already in use\n",
606 DRIVER_NAME, id);
607 return -EBUSY;
608 }
609
610 probed_devices[id] = 1;
611
612 devt = MKDEV(xhwicap_major, xhwicap_minor + id);
613
614 drvdata = kmalloc(sizeof(struct hwicap_drvdata), GFP_KERNEL);
615 if (!drvdata) {
616 dev_err(dev, "Couldn't allocate device private record\n");
617 return -ENOMEM;
618 }
619 memset((void *)drvdata, 0, sizeof(struct hwicap_drvdata));
620 dev_set_drvdata(dev, (void *)drvdata);
621
622 if (!regs_res) {
623 dev_err(dev, "Couldn't get registers resource\n");
624 retval = -EFAULT;
625 goto failed1;
626 }
627
628 drvdata->mem_start = regs_res->start;
629 drvdata->mem_end = regs_res->end;
630 drvdata->mem_size = regs_res->end - regs_res->start + 1;
631
632 if (!request_mem_region(drvdata->mem_start,
633 drvdata->mem_size, DRIVER_NAME)) {
634 dev_err(dev, "Couldn't lock memory region at %p\n",
635 (void *)regs_res->start);
636 retval = -EBUSY;
637 goto failed1;
638 }
639
640 drvdata->devt = devt;
641 drvdata->dev = dev;
642 drvdata->base_address = ioremap(drvdata->mem_start, drvdata->mem_size);
643 if (!drvdata->base_address) {
644 dev_err(dev, "ioremap() failed\n");
645 goto failed2;
646 }
647
648 drvdata->config = config;
649 drvdata->config_regs = config_regs;
650
651 init_MUTEX(&drvdata->sem);
652 drvdata->is_open = 0;
653
654 dev_info(dev, "ioremap %lx to %p with size %x\n",
655 (unsigned long int)drvdata->mem_start,
656 drvdata->base_address, drvdata->mem_size);
657
658 cdev_init(&drvdata->cdev, &hwicap_fops);
659 drvdata->cdev.owner = THIS_MODULE;
660 retval = cdev_add(&drvdata->cdev, devt, 1);
661 if (retval) {
662 dev_err(dev, "cdev_add() failed\n");
663 goto failed3;
664 }
665 /* devfs_mk_cdev(devt, S_IFCHR|S_IRUGO|S_IWUGO, DRIVER_NAME); */
666 class_device_create(icap_class, NULL, devt, NULL, DRIVER_NAME);
667 return 0; /* success */
668
669 failed3:
670 iounmap(drvdata->base_address);
671
672 failed2:
673 release_mem_region(regs_res->start, drvdata->mem_size);
674
675 failed1:
676 kfree(drvdata);
677
678 return retval;
679}
680
681static struct hwicap_driver_config buffer_icap_config = {
682 .get_configuration = buffer_icap_get_configuration,
683 .set_configuration = buffer_icap_set_configuration,
684 .reset = buffer_icap_reset,
685};
686
687static struct hwicap_driver_config fifo_icap_config = {
688 .get_configuration = fifo_icap_get_configuration,
689 .set_configuration = fifo_icap_set_configuration,
690 .reset = fifo_icap_reset,
691};
692
693static int __devexit hwicap_remove(struct device *dev)
694{
695 struct hwicap_drvdata *drvdata;
696
697 drvdata = (struct hwicap_drvdata *)dev_get_drvdata(dev);
698
699 if (!drvdata)
700 return 0;
701
702 class_device_destroy(icap_class, drvdata->devt);
703 cdev_del(&drvdata->cdev);
704 iounmap(drvdata->base_address);
705 release_mem_region(drvdata->mem_start, drvdata->mem_size);
706 kfree(drvdata);
707 dev_set_drvdata(dev, NULL);
708 probed_devices[MINOR(dev->devt)-xhwicap_minor] = 0;
709
710 return 0; /* success */
711}
712
713static int __devinit hwicap_drv_probe(struct platform_device *pdev)
714{
715 struct resource *res;
716 const struct config_registers *regs;
717 const char *family;
718
719 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
720 if (!res)
721 return -ENODEV;
722
723 /* It's most likely that we're using V4, if the family is not
724 specified */
725 regs = &v4_config_registers;
726 family = pdev->dev.platform_data;
727
728 if (family) {
729 if (!strcmp(family, "virtex2p")) {
730 regs = &v2_config_registers;
731 } else if (!strcmp(family, "virtex4")) {
732 regs = &v4_config_registers;
733 } else if (!strcmp(family, "virtex5")) {
734 regs = &v5_config_registers;
735 }
736 }
737
738 return hwicap_setup(&pdev->dev, pdev->id, res,
739 &buffer_icap_config, regs);
740}
741
742static int __devexit hwicap_drv_remove(struct platform_device *pdev)
743{
744 return hwicap_remove(&pdev->dev);
745}
746
747static struct platform_driver hwicap_platform_driver = {
748 .probe = hwicap_drv_probe,
749 .remove = hwicap_drv_remove,
750 .driver = {
751 .owner = THIS_MODULE,
752 .name = DRIVER_NAME,
753 },
754};
755
756/* ---------------------------------------------------------------------
757 * OF bus binding
758 */
759
760#if defined(CONFIG_OF)
761static int __devinit
762hwicap_of_probe(struct of_device *op, const struct of_device_id *match)
763{
764 struct resource res;
765 const unsigned int *id;
766 const char *family;
767 int rc;
768 const struct hwicap_driver_config *config = match->data;
769 const struct config_registers *regs;
770
771 dev_dbg(&op->dev, "hwicap_of_probe(%p, %p)\n", op, match);
772
773 rc = of_address_to_resource(op->node, 0, &res);
774 if (rc) {
775 dev_err(&op->dev, "invalid address\n");
776 return rc;
777 }
778
779 id = of_get_property(op->node, "port-number", NULL);
780
781 /* It's most likely that we're using V4, if the family is not
782 specified */
783 regs = &v4_config_registers;
784 family = of_get_property(op->node, "xlnx,family", NULL);
785
786 if (family) {
787 if (!strcmp(family, "virtex2p")) {
788 regs = &v2_config_registers;
789 } else if (!strcmp(family, "virtex4")) {
790 regs = &v4_config_registers;
791 } else if (!strcmp(family, "virtex5")) {
792 regs = &v5_config_registers;
793 }
794 }
795 return hwicap_setup(&op->dev, id ? *id : -1, &res, config,
796 regs);
797}
798
799static int __devexit hwicap_of_remove(struct of_device *op)
800{
801 return hwicap_remove(&op->dev);
802}
803
804/* Match table for of_platform binding */
805static const struct of_device_id __devinit hwicap_of_match[] = {
806 { .compatible = "xlnx,opb-hwicap-1.00.b", .data = &buffer_icap_config},
807 { .compatible = "xlnx,xps-hwicap-1.00.a", .data = &fifo_icap_config},
808 {},
809};
810MODULE_DEVICE_TABLE(of, hwicap_of_match);
811
812static struct of_platform_driver hwicap_of_driver = {
813 .owner = THIS_MODULE,
814 .name = DRIVER_NAME,
815 .match_table = hwicap_of_match,
816 .probe = hwicap_of_probe,
817 .remove = __devexit_p(hwicap_of_remove),
818 .driver = {
819 .name = DRIVER_NAME,
820 },
821};
822
823/* Registration helpers to keep the number of #ifdefs to a minimum */
824static inline int __devinit hwicap_of_register(void)
825{
826 pr_debug("hwicap: calling of_register_platform_driver()\n");
827 return of_register_platform_driver(&hwicap_of_driver);
828}
829
830static inline void __devexit hwicap_of_unregister(void)
831{
832 of_unregister_platform_driver(&hwicap_of_driver);
833}
834#else /* CONFIG_OF */
835/* CONFIG_OF not enabled; do nothing helpers */
836static inline int __devinit hwicap_of_register(void) { return 0; }
837static inline void __devexit hwicap_of_unregister(void) { }
838#endif /* CONFIG_OF */
839
840static int __devinit hwicap_module_init(void)
841{
842 dev_t devt;
843 int retval;
844
845 icap_class = class_create(THIS_MODULE, "xilinx_config");
846
847 if (xhwicap_major) {
848 devt = MKDEV(xhwicap_major, xhwicap_minor);
849 retval = register_chrdev_region(
850 devt,
851 HWICAP_DEVICES,
852 DRIVER_NAME);
853 if (retval < 0)
854 return retval;
855 } else {
856 retval = alloc_chrdev_region(&devt,
857 xhwicap_minor,
858 HWICAP_DEVICES,
859 DRIVER_NAME);
860 if (retval < 0)
861 return retval;
862 xhwicap_major = MAJOR(devt);
863 }
864
865 retval = platform_driver_register(&hwicap_platform_driver);
866
867 if (retval)
868 goto failed1;
869
870 retval = hwicap_of_register();
871
872 if (retval)
873 goto failed2;
874
875 return retval;
876
877 failed2:
878 platform_driver_unregister(&hwicap_platform_driver);
879
880 failed1:
881 unregister_chrdev_region(devt, HWICAP_DEVICES);
882
883 return retval;
884}
885
886static void __devexit hwicap_module_cleanup(void)
887{
888 dev_t devt = MKDEV(xhwicap_major, xhwicap_minor);
889
890 class_destroy(icap_class);
891
892 platform_driver_unregister(&hwicap_platform_driver);
893
894 hwicap_of_unregister();
895
896 unregister_chrdev_region(devt, HWICAP_DEVICES);
897}
898
899module_init(hwicap_module_init);
900module_exit(hwicap_module_cleanup);
901
902MODULE_AUTHOR("Xilinx, Inc; Xilinx Research Labs Group");
903MODULE_DESCRIPTION("Xilinx ICAP Port Driver");
904MODULE_LICENSE("GPL");
diff --git a/drivers/char/xilinx_hwicap/xilinx_hwicap.h b/drivers/char/xilinx_hwicap/xilinx_hwicap.h
new file mode 100644
index 000000000000..ae771cac1629
--- /dev/null
+++ b/drivers/char/xilinx_hwicap/xilinx_hwicap.h
@@ -0,0 +1,193 @@
1/*****************************************************************************
2 *
3 * Author: Xilinx, Inc.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 *
10 * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
11 * AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
12 * SOLUTIONS FOR XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE,
13 * OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
14 * APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
15 * THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
16 * AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
17 * FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY
18 * WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
19 * IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
20 * REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
21 * INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22 * FOR A PARTICULAR PURPOSE.
23 *
24 * Xilinx products are not intended for use in life support appliances,
25 * devices, or systems. Use in such applications is expressly prohibited.
26 *
27 * (c) Copyright 2003-2007 Xilinx Inc.
28 * All rights reserved.
29 *
30 * You should have received a copy of the GNU General Public License along
31 * with this program; if not, write to the Free Software Foundation, Inc.,
32 * 675 Mass Ave, Cambridge, MA 02139, USA.
33 *
34 *****************************************************************************/
35
36#ifndef XILINX_HWICAP_H_ /* prevent circular inclusions */
37#define XILINX_HWICAP_H_ /* by using protection macros */
38
39#include <linux/types.h>
40#include <linux/cdev.h>
41#include <linux/version.h>
42#include <linux/platform_device.h>
43
44#include <asm/io.h>
45
46struct hwicap_drvdata {
47 u32 write_buffer_in_use; /* Always in [0,3] */
48 u8 write_buffer[4];
49 u32 read_buffer_in_use; /* Always in [0,3] */
50 u8 read_buffer[4];
51 u32 mem_start; /* phys. address of the control registers */
52 u32 mem_end; /* phys. address of the control registers */
53 u32 mem_size;
54 void __iomem *base_address;/* virt. address of the control registers */
55
56 struct device *dev;
57 struct cdev cdev; /* Char device structure */
58 dev_t devt;
59
60 const struct hwicap_driver_config *config;
61 const struct config_registers *config_regs;
62 void *private_data;
63 bool is_open;
64 struct semaphore sem;
65};
66
67struct hwicap_driver_config {
68 int (*get_configuration)(struct hwicap_drvdata *drvdata, u32 *data,
69 u32 size);
70 int (*set_configuration)(struct hwicap_drvdata *drvdata, u32 *data,
71 u32 size);
72 void (*reset)(struct hwicap_drvdata *drvdata);
73};
74
75/* Number of times to poll the done regsiter */
76#define XHI_MAX_RETRIES 10
77
78/************ Constant Definitions *************/
79
80#define XHI_PAD_FRAMES 0x1
81
82/* Mask for calculating configuration packet headers */
83#define XHI_WORD_COUNT_MASK_TYPE_1 0x7FFUL
84#define XHI_WORD_COUNT_MASK_TYPE_2 0x1FFFFFUL
85#define XHI_TYPE_MASK 0x7
86#define XHI_REGISTER_MASK 0xF
87#define XHI_OP_MASK 0x3
88
89#define XHI_TYPE_SHIFT 29
90#define XHI_REGISTER_SHIFT 13
91#define XHI_OP_SHIFT 27
92
93#define XHI_TYPE_1 1
94#define XHI_TYPE_2 2
95#define XHI_OP_WRITE 2
96#define XHI_OP_READ 1
97
98/* Address Block Types */
99#define XHI_FAR_CLB_BLOCK 0
100#define XHI_FAR_BRAM_BLOCK 1
101#define XHI_FAR_BRAM_INT_BLOCK 2
102
103struct config_registers {
104 u32 CRC;
105 u32 FAR;
106 u32 FDRI;
107 u32 FDRO;
108 u32 CMD;
109 u32 CTL;
110 u32 MASK;
111 u32 STAT;
112 u32 LOUT;
113 u32 COR;
114 u32 MFWR;
115 u32 FLR;
116 u32 KEY;
117 u32 CBC;
118 u32 IDCODE;
119 u32 AXSS;
120 u32 C0R_1;
121 u32 CSOB;
122 u32 WBSTAR;
123 u32 TIMER;
124 u32 BOOTSTS;
125 u32 CTL_1;
126};
127
128/* Configuration Commands */
129#define XHI_CMD_NULL 0
130#define XHI_CMD_WCFG 1
131#define XHI_CMD_MFW 2
132#define XHI_CMD_DGHIGH 3
133#define XHI_CMD_RCFG 4
134#define XHI_CMD_START 5
135#define XHI_CMD_RCAP 6
136#define XHI_CMD_RCRC 7
137#define XHI_CMD_AGHIGH 8
138#define XHI_CMD_SWITCH 9
139#define XHI_CMD_GRESTORE 10
140#define XHI_CMD_SHUTDOWN 11
141#define XHI_CMD_GCAPTURE 12
142#define XHI_CMD_DESYNCH 13
143#define XHI_CMD_IPROG 15 /* Only in Virtex5 */
144#define XHI_CMD_CRCC 16 /* Only in Virtex5 */
145#define XHI_CMD_LTIMER 17 /* Only in Virtex5 */
146
147/* Packet constants */
148#define XHI_SYNC_PACKET 0xAA995566UL
149#define XHI_DUMMY_PACKET 0xFFFFFFFFUL
150#define XHI_NOOP_PACKET (XHI_TYPE_1 << XHI_TYPE_SHIFT)
151#define XHI_TYPE_2_READ ((XHI_TYPE_2 << XHI_TYPE_SHIFT) | \
152 (XHI_OP_READ << XHI_OP_SHIFT))
153
154#define XHI_TYPE_2_WRITE ((XHI_TYPE_2 << XHI_TYPE_SHIFT) | \
155 (XHI_OP_WRITE << XHI_OP_SHIFT))
156
157#define XHI_TYPE2_CNT_MASK 0x07FFFFFF
158
159#define XHI_TYPE_1_PACKET_MAX_WORDS 2047UL
160#define XHI_TYPE_1_HEADER_BYTES 4
161#define XHI_TYPE_2_HEADER_BYTES 8
162
163/* Constant to use for CRC check when CRC has been disabled */
164#define XHI_DISABLED_AUTO_CRC 0x0000DEFCUL
165
166/**
167 * hwicap_type_1_read: Generates a Type 1 read packet header.
168 * @parameter: Register is the address of the register to be read back.
169 *
170 * Generates a Type 1 read packet header, which is used to indirectly
171 * read registers in the configuration logic. This packet must then
172 * be sent through the icap device, and a return packet received with
173 * the information.
174 **/
175static inline u32 hwicap_type_1_read(u32 Register)
176{
177 return (XHI_TYPE_1 << XHI_TYPE_SHIFT) |
178 (Register << XHI_REGISTER_SHIFT) |
179 (XHI_OP_READ << XHI_OP_SHIFT);
180}
181
182/**
183 * hwicap_type_1_write: Generates a Type 1 write packet header
184 * @parameter: Register is the address of the register to be read back.
185 **/
186static inline u32 hwicap_type_1_write(u32 Register)
187{
188 return (XHI_TYPE_1 << XHI_TYPE_SHIFT) |
189 (Register << XHI_REGISTER_SHIFT) |
190 (XHI_OP_WRITE << XHI_OP_SHIFT);
191}
192
193#endif
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 7d170cd381c3..9cc25fd80b60 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -1737,10 +1737,8 @@ config SC92031
1737 1737
1738config CPMAC 1738config CPMAC
1739 tristate "TI AR7 CPMAC Ethernet support (EXPERIMENTAL)" 1739 tristate "TI AR7 CPMAC Ethernet support (EXPERIMENTAL)"
1740 depends on NET_ETHERNET && EXPERIMENTAL && AR7 1740 depends on NET_ETHERNET && EXPERIMENTAL && AR7 && BROKEN
1741 select PHYLIB 1741 select PHYLIB
1742 select FIXED_PHY
1743 select FIXED_MII_100_FDX
1744 help 1742 help
1745 TI AR7 CPMAC Ethernet support 1743 TI AR7 CPMAC Ethernet support
1746 1744
diff --git a/drivers/net/cpmac.c b/drivers/net/cpmac.c
index 6ccebb830ff9..c85194f2cd2d 100644
--- a/drivers/net/cpmac.c
+++ b/drivers/net/cpmac.c
@@ -845,15 +845,6 @@ static void cpmac_adjust_link(struct net_device *dev)
845 spin_unlock(&priv->lock); 845 spin_unlock(&priv->lock);
846} 846}
847 847
848static int cpmac_link_update(struct net_device *dev,
849 struct fixed_phy_status *status)
850{
851 status->link = 1;
852 status->speed = 100;
853 status->duplex = 1;
854 return 0;
855}
856
857static int cpmac_open(struct net_device *dev) 848static int cpmac_open(struct net_device *dev)
858{ 849{
859 int i, size, res; 850 int i, size, res;
@@ -996,11 +987,11 @@ static int external_switch;
996static int __devinit cpmac_probe(struct platform_device *pdev) 987static int __devinit cpmac_probe(struct platform_device *pdev)
997{ 988{
998 int rc, phy_id, i; 989 int rc, phy_id, i;
990 int mdio_bus_id = cpmac_mii.id;
999 struct resource *mem; 991 struct resource *mem;
1000 struct cpmac_priv *priv; 992 struct cpmac_priv *priv;
1001 struct net_device *dev; 993 struct net_device *dev;
1002 struct plat_cpmac_data *pdata; 994 struct plat_cpmac_data *pdata;
1003 struct fixed_info *fixed_phy;
1004 DECLARE_MAC_BUF(mac); 995 DECLARE_MAC_BUF(mac);
1005 996
1006 pdata = pdev->dev.platform_data; 997 pdata = pdev->dev.platform_data;
@@ -1014,9 +1005,23 @@ static int __devinit cpmac_probe(struct platform_device *pdev)
1014 } 1005 }
1015 1006
1016 if (phy_id == PHY_MAX_ADDR) { 1007 if (phy_id == PHY_MAX_ADDR) {
1017 if (external_switch || dumb_switch) 1008 if (external_switch || dumb_switch) {
1009 struct fixed_phy_status status = {};
1010
1011 mdio_bus_id = 0;
1012
1013 /*
1014 * FIXME: this should be in the platform code!
1015 * Since there is not platform code at all (that is,
1016 * no mainline users of that driver), place it here
1017 * for now.
1018 */
1018 phy_id = 0; 1019 phy_id = 0;
1019 else { 1020 status.link = 1;
1021 status.duplex = 1;
1022 status.speed = 100;
1023 fixed_phy_add(PHY_POLL, phy_id, &status);
1024 } else {
1020 printk(KERN_ERR "cpmac: no PHY present\n"); 1025 printk(KERN_ERR "cpmac: no PHY present\n");
1021 return -ENODEV; 1026 return -ENODEV;
1022 } 1027 }
@@ -1060,32 +1065,8 @@ static int __devinit cpmac_probe(struct platform_device *pdev)
1060 priv->msg_enable = netif_msg_init(debug_level, 0xff); 1065 priv->msg_enable = netif_msg_init(debug_level, 0xff);
1061 memcpy(dev->dev_addr, pdata->dev_addr, sizeof(dev->dev_addr)); 1066 memcpy(dev->dev_addr, pdata->dev_addr, sizeof(dev->dev_addr));
1062 1067
1063 if (phy_id == 31) { 1068 snprintf(priv->phy_name, BUS_ID_SIZE, PHY_ID_FMT, mdio_bus_id, phy_id);
1064 snprintf(priv->phy_name, BUS_ID_SIZE, PHY_ID_FMT, cpmac_mii.id,
1065 phy_id);
1066 } else {
1067 /* Let's try to get a free fixed phy... */
1068 for (i = 0; i < MAX_PHY_AMNT; i++) {
1069 fixed_phy = fixed_mdio_get_phydev(i);
1070 if (!fixed_phy)
1071 continue;
1072 if (!fixed_phy->phydev->attached_dev) {
1073 strncpy(priv->phy_name,
1074 fixed_phy->phydev->dev.bus_id,
1075 BUS_ID_SIZE);
1076 fixed_mdio_set_link_update(fixed_phy->phydev,
1077 &cpmac_link_update);
1078 goto phy_found;
1079 }
1080 }
1081 if (netif_msg_drv(priv))
1082 printk(KERN_ERR "%s: Could not find fixed PHY\n",
1083 dev->name);
1084 rc = -ENODEV;
1085 goto fail;
1086 }
1087 1069
1088phy_found:
1089 priv->phy = phy_connect(dev, priv->phy_name, &cpmac_adjust_link, 0, 1070 priv->phy = phy_connect(dev, priv->phy_name, &cpmac_adjust_link, 0,
1090 PHY_INTERFACE_MODE_MII); 1071 PHY_INTERFACE_MODE_MII);
1091 if (IS_ERR(priv->phy)) { 1072 if (IS_ERR(priv->phy)) {
diff --git a/drivers/of/base.c b/drivers/of/base.c
index b306fef1ac41..80c9deca5f35 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -138,6 +138,31 @@ struct device_node *of_get_parent(const struct device_node *node)
138EXPORT_SYMBOL(of_get_parent); 138EXPORT_SYMBOL(of_get_parent);
139 139
140/** 140/**
141 * of_get_next_parent - Iterate to a node's parent
142 * @node: Node to get parent of
143 *
144 * This is like of_get_parent() except that it drops the
145 * refcount on the passed node, making it suitable for iterating
146 * through a node's parents.
147 *
148 * Returns a node pointer with refcount incremented, use
149 * of_node_put() on it when done.
150 */
151struct device_node *of_get_next_parent(struct device_node *node)
152{
153 struct device_node *parent;
154
155 if (!node)
156 return NULL;
157
158 read_lock(&devtree_lock);
159 parent = of_node_get(node->parent);
160 of_node_put(node);
161 read_unlock(&devtree_lock);
162 return parent;
163}
164
165/**
141 * of_get_next_child - Iterate a node childs 166 * of_get_next_child - Iterate a node childs
142 * @node: parent node 167 * @node: parent node
143 * @prev: previous child of the parent node, or NULL to get first 168 * @prev: previous child of the parent node, or NULL to get first
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index b47bb2d7476a..ca09a63a64db 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -85,6 +85,15 @@ static int of_platform_device_resume(struct device * dev)
85 return error; 85 return error;
86} 86}
87 87
88static void of_platform_device_shutdown(struct device *dev)
89{
90 struct of_device *of_dev = to_of_device(dev);
91 struct of_platform_driver *drv = to_of_platform_driver(dev->driver);
92
93 if (dev->driver && drv->shutdown)
94 drv->shutdown(of_dev);
95}
96
88int of_bus_type_init(struct bus_type *bus, const char *name) 97int of_bus_type_init(struct bus_type *bus, const char *name)
89{ 98{
90 bus->name = name; 99 bus->name = name;
@@ -93,6 +102,7 @@ int of_bus_type_init(struct bus_type *bus, const char *name)
93 bus->remove = of_platform_device_remove; 102 bus->remove = of_platform_device_remove;
94 bus->suspend = of_platform_device_suspend; 103 bus->suspend = of_platform_device_suspend;
95 bus->resume = of_platform_device_resume; 104 bus->resume = of_platform_device_resume;
105 bus->shutdown = of_platform_device_shutdown;
96 return bus_register(bus); 106 return bus_register(bus);
97} 107}
98 108
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 50d6e2214ddf..84a054d7e986 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -1142,17 +1142,17 @@ config SERIAL_SGI_L1_CONSOLE
1142 say Y. Otherwise, say N. 1142 say Y. Otherwise, say N.
1143 1143
1144config SERIAL_MPC52xx 1144config SERIAL_MPC52xx
1145 tristate "Freescale MPC52xx family PSC serial support" 1145 tristate "Freescale MPC52xx/MPC512x family PSC serial support"
1146 depends on PPC_MPC52xx 1146 depends on PPC_MPC52xx || PPC_MPC512x
1147 select SERIAL_CORE 1147 select SERIAL_CORE
1148 help 1148 help
1149 This drivers support the MPC52xx PSC serial ports. If you would 1149 This driver supports MPC52xx and MPC512x PSC serial ports. If you would
1150 like to use them, you must answer Y or M to this option. Not that 1150 like to use them, you must answer Y or M to this option. Note that
1151 for use as console, it must be included in kernel and not as a 1151 for use as console, it must be included in kernel and not as a
1152 module. 1152 module.
1153 1153
1154config SERIAL_MPC52xx_CONSOLE 1154config SERIAL_MPC52xx_CONSOLE
1155 bool "Console on a Freescale MPC52xx family PSC serial port" 1155 bool "Console on a Freescale MPC52xx/MPC512x family PSC serial port"
1156 depends on SERIAL_MPC52xx=y 1156 depends on SERIAL_MPC52xx=y
1157 select SERIAL_CORE_CONSOLE 1157 select SERIAL_CORE_CONSOLE
1158 help 1158 help
@@ -1160,7 +1160,7 @@ config SERIAL_MPC52xx_CONSOLE
1160 of the Freescale MPC52xx family as a console. 1160 of the Freescale MPC52xx family as a console.
1161 1161
1162config SERIAL_MPC52xx_CONSOLE_BAUD 1162config SERIAL_MPC52xx_CONSOLE_BAUD
1163 int "Freescale MPC52xx family PSC serial port baud" 1163 int "Freescale MPC52xx/MPC512x family PSC serial port baud"
1164 depends on SERIAL_MPC52xx_CONSOLE=y 1164 depends on SERIAL_MPC52xx_CONSOLE=y
1165 default "9600" 1165 default "9600"
1166 help 1166 help
diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c
index 3c4d29e59b2c..a638f23c6c61 100644
--- a/drivers/serial/mpc52xx_uart.c
+++ b/drivers/serial/mpc52xx_uart.c
@@ -16,6 +16,9 @@
16 * Some of the code has been inspired/copied from the 2.4 code written 16 * Some of the code has been inspired/copied from the 2.4 code written
17 * by Dale Farnsworth <dfarnsworth@mvista.com>. 17 * by Dale Farnsworth <dfarnsworth@mvista.com>.
18 * 18 *
19 * Copyright (C) 2008 Freescale Semiconductor Inc.
20 * John Rigby <jrigby@gmail.com>
21 * Added support for MPC5121
19 * Copyright (C) 2006 Secret Lab Technologies Ltd. 22 * Copyright (C) 2006 Secret Lab Technologies Ltd.
20 * Grant Likely <grant.likely@secretlab.ca> 23 * Grant Likely <grant.likely@secretlab.ca>
21 * Copyright (C) 2004-2006 Sylvain Munaut <tnt@246tNt.com> 24 * Copyright (C) 2004-2006 Sylvain Munaut <tnt@246tNt.com>
@@ -67,7 +70,6 @@
67#include <linux/serial.h> 70#include <linux/serial.h>
68#include <linux/sysrq.h> 71#include <linux/sysrq.h>
69#include <linux/console.h> 72#include <linux/console.h>
70
71#include <linux/delay.h> 73#include <linux/delay.h>
72#include <linux/io.h> 74#include <linux/io.h>
73 75
@@ -79,6 +81,7 @@
79#endif 81#endif
80 82
81#include <asm/mpc52xx.h> 83#include <asm/mpc52xx.h>
84#include <asm/mpc512x.h>
82#include <asm/mpc52xx_psc.h> 85#include <asm/mpc52xx_psc.h>
83 86
84#if defined(CONFIG_SERIAL_MPC52xx_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) 87#if defined(CONFIG_SERIAL_MPC52xx_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
@@ -111,8 +114,8 @@ static struct device_node *mpc52xx_uart_nodes[MPC52xx_PSC_MAXNUM];
111static void mpc52xx_uart_of_enumerate(void); 114static void mpc52xx_uart_of_enumerate(void);
112#endif 115#endif
113 116
117
114#define PSC(port) ((struct mpc52xx_psc __iomem *)((port)->membase)) 118#define PSC(port) ((struct mpc52xx_psc __iomem *)((port)->membase))
115#define FIFO(port) ((struct mpc52xx_psc_fifo __iomem *)(PSC(port)+1))
116 119
117 120
118/* Forward declaration of the interruption handling routine */ 121/* Forward declaration of the interruption handling routine */
@@ -128,15 +131,301 @@ static irqreturn_t mpc52xx_uart_int(int irq, void *dev_id);
128#define uart_console(port) (0) 131#define uart_console(port) (0)
129#endif 132#endif
130 133
134/* ======================================================================== */
135/* PSC fifo operations for isolating differences between 52xx and 512x */
136/* ======================================================================== */
137
138struct psc_ops {
139 void (*fifo_init)(struct uart_port *port);
140 int (*raw_rx_rdy)(struct uart_port *port);
141 int (*raw_tx_rdy)(struct uart_port *port);
142 int (*rx_rdy)(struct uart_port *port);
143 int (*tx_rdy)(struct uart_port *port);
144 int (*tx_empty)(struct uart_port *port);
145 void (*stop_rx)(struct uart_port *port);
146 void (*start_tx)(struct uart_port *port);
147 void (*stop_tx)(struct uart_port *port);
148 void (*rx_clr_irq)(struct uart_port *port);
149 void (*tx_clr_irq)(struct uart_port *port);
150 void (*write_char)(struct uart_port *port, unsigned char c);
151 unsigned char (*read_char)(struct uart_port *port);
152 void (*cw_disable_ints)(struct uart_port *port);
153 void (*cw_restore_ints)(struct uart_port *port);
154 unsigned long (*getuartclk)(void *p);
155};
156
157#ifdef CONFIG_PPC_MPC52xx
158#define FIFO_52xx(port) ((struct mpc52xx_psc_fifo __iomem *)(PSC(port)+1))
159static void mpc52xx_psc_fifo_init(struct uart_port *port)
160{
161 struct mpc52xx_psc __iomem *psc = PSC(port);
162 struct mpc52xx_psc_fifo __iomem *fifo = FIFO_52xx(port);
163
164 /* /32 prescaler */
165 out_be16(&psc->mpc52xx_psc_clock_select, 0xdd00);
166
167 out_8(&fifo->rfcntl, 0x00);
168 out_be16(&fifo->rfalarm, 0x1ff);
169 out_8(&fifo->tfcntl, 0x07);
170 out_be16(&fifo->tfalarm, 0x80);
171
172 port->read_status_mask |= MPC52xx_PSC_IMR_RXRDY | MPC52xx_PSC_IMR_TXRDY;
173 out_be16(&psc->mpc52xx_psc_imr, port->read_status_mask);
174}
175
176static int mpc52xx_psc_raw_rx_rdy(struct uart_port *port)
177{
178 return in_be16(&PSC(port)->mpc52xx_psc_status)
179 & MPC52xx_PSC_SR_RXRDY;
180}
181
182static int mpc52xx_psc_raw_tx_rdy(struct uart_port *port)
183{
184 return in_be16(&PSC(port)->mpc52xx_psc_status)
185 & MPC52xx_PSC_SR_TXRDY;
186}
187
188
189static int mpc52xx_psc_rx_rdy(struct uart_port *port)
190{
191 return in_be16(&PSC(port)->mpc52xx_psc_isr)
192 & port->read_status_mask
193 & MPC52xx_PSC_IMR_RXRDY;
194}
195
196static int mpc52xx_psc_tx_rdy(struct uart_port *port)
197{
198 return in_be16(&PSC(port)->mpc52xx_psc_isr)
199 & port->read_status_mask
200 & MPC52xx_PSC_IMR_TXRDY;
201}
202
203static int mpc52xx_psc_tx_empty(struct uart_port *port)
204{
205 return in_be16(&PSC(port)->mpc52xx_psc_status)
206 & MPC52xx_PSC_SR_TXEMP;
207}
208
209static void mpc52xx_psc_start_tx(struct uart_port *port)
210{
211 port->read_status_mask |= MPC52xx_PSC_IMR_TXRDY;
212 out_be16(&PSC(port)->mpc52xx_psc_imr, port->read_status_mask);
213}
214
215static void mpc52xx_psc_stop_tx(struct uart_port *port)
216{
217 port->read_status_mask &= ~MPC52xx_PSC_IMR_TXRDY;
218 out_be16(&PSC(port)->mpc52xx_psc_imr, port->read_status_mask);
219}
220
221static void mpc52xx_psc_stop_rx(struct uart_port *port)
222{
223 port->read_status_mask &= ~MPC52xx_PSC_IMR_RXRDY;
224 out_be16(&PSC(port)->mpc52xx_psc_imr, port->read_status_mask);
225}
226
227static void mpc52xx_psc_rx_clr_irq(struct uart_port *port)
228{
229}
230
231static void mpc52xx_psc_tx_clr_irq(struct uart_port *port)
232{
233}
234
235static void mpc52xx_psc_write_char(struct uart_port *port, unsigned char c)
236{
237 out_8(&PSC(port)->mpc52xx_psc_buffer_8, c);
238}
239
240static unsigned char mpc52xx_psc_read_char(struct uart_port *port)
241{
242 return in_8(&PSC(port)->mpc52xx_psc_buffer_8);
243}
244
245static void mpc52xx_psc_cw_disable_ints(struct uart_port *port)
246{
247 out_be16(&PSC(port)->mpc52xx_psc_imr, 0);
248}
249
250static void mpc52xx_psc_cw_restore_ints(struct uart_port *port)
251{
252 out_be16(&PSC(port)->mpc52xx_psc_imr, port->read_status_mask);
253}
254
255/* Search for bus-frequency property in this node or a parent */
256static unsigned long mpc52xx_getuartclk(void *p)
257{
131#if defined(CONFIG_PPC_MERGE) 258#if defined(CONFIG_PPC_MERGE)
132static struct of_device_id mpc52xx_uart_of_match[] = { 259 /*
133 { .type = "serial", .compatible = "fsl,mpc5200-psc-uart", }, 260 * 5200 UARTs have a / 32 prescaler
134 { .type = "serial", .compatible = "mpc5200-psc-uart", }, /* lite5200 */ 261 * but the generic serial code assumes 16
135 { .type = "serial", .compatible = "mpc5200-serial", }, /* efika */ 262 * so return ipb freq / 2
136 {}, 263 */
264 return mpc52xx_find_ipb_freq(p) / 2;
265#else
266 pr_debug("unexpected call to mpc52xx_getuartclk with arch/ppc\n");
267 return NULL;
268#endif
269}
270
271static struct psc_ops mpc52xx_psc_ops = {
272 .fifo_init = mpc52xx_psc_fifo_init,
273 .raw_rx_rdy = mpc52xx_psc_raw_rx_rdy,
274 .raw_tx_rdy = mpc52xx_psc_raw_tx_rdy,
275 .rx_rdy = mpc52xx_psc_rx_rdy,
276 .tx_rdy = mpc52xx_psc_tx_rdy,
277 .tx_empty = mpc52xx_psc_tx_empty,
278 .stop_rx = mpc52xx_psc_stop_rx,
279 .start_tx = mpc52xx_psc_start_tx,
280 .stop_tx = mpc52xx_psc_stop_tx,
281 .rx_clr_irq = mpc52xx_psc_rx_clr_irq,
282 .tx_clr_irq = mpc52xx_psc_tx_clr_irq,
283 .write_char = mpc52xx_psc_write_char,
284 .read_char = mpc52xx_psc_read_char,
285 .cw_disable_ints = mpc52xx_psc_cw_disable_ints,
286 .cw_restore_ints = mpc52xx_psc_cw_restore_ints,
287 .getuartclk = mpc52xx_getuartclk,
288};
289
290#endif /* CONFIG_MPC52xx */
291
292#ifdef CONFIG_PPC_MPC512x
293#define FIFO_512x(port) ((struct mpc512x_psc_fifo __iomem *)(PSC(port)+1))
294static void mpc512x_psc_fifo_init(struct uart_port *port)
295{
296 out_be32(&FIFO_512x(port)->txcmd, MPC512x_PSC_FIFO_RESET_SLICE);
297 out_be32(&FIFO_512x(port)->txcmd, MPC512x_PSC_FIFO_ENABLE_SLICE);
298 out_be32(&FIFO_512x(port)->txalarm, 1);
299 out_be32(&FIFO_512x(port)->tximr, 0);
300
301 out_be32(&FIFO_512x(port)->rxcmd, MPC512x_PSC_FIFO_RESET_SLICE);
302 out_be32(&FIFO_512x(port)->rxcmd, MPC512x_PSC_FIFO_ENABLE_SLICE);
303 out_be32(&FIFO_512x(port)->rxalarm, 1);
304 out_be32(&FIFO_512x(port)->rximr, 0);
305
306 out_be32(&FIFO_512x(port)->tximr, MPC512x_PSC_FIFO_ALARM);
307 out_be32(&FIFO_512x(port)->rximr, MPC512x_PSC_FIFO_ALARM);
308}
309
310static int mpc512x_psc_raw_rx_rdy(struct uart_port *port)
311{
312 return !(in_be32(&FIFO_512x(port)->rxsr) & MPC512x_PSC_FIFO_EMPTY);
313}
314
315static int mpc512x_psc_raw_tx_rdy(struct uart_port *port)
316{
317 return !(in_be32(&FIFO_512x(port)->txsr) & MPC512x_PSC_FIFO_FULL);
318}
319
320static int mpc512x_psc_rx_rdy(struct uart_port *port)
321{
322 return in_be32(&FIFO_512x(port)->rxsr)
323 & in_be32(&FIFO_512x(port)->rximr)
324 & MPC512x_PSC_FIFO_ALARM;
325}
326
327static int mpc512x_psc_tx_rdy(struct uart_port *port)
328{
329 return in_be32(&FIFO_512x(port)->txsr)
330 & in_be32(&FIFO_512x(port)->tximr)
331 & MPC512x_PSC_FIFO_ALARM;
332}
333
334static int mpc512x_psc_tx_empty(struct uart_port *port)
335{
336 return in_be32(&FIFO_512x(port)->txsr)
337 & MPC512x_PSC_FIFO_EMPTY;
338}
339
340static void mpc512x_psc_stop_rx(struct uart_port *port)
341{
342 unsigned long rx_fifo_imr;
343
344 rx_fifo_imr = in_be32(&FIFO_512x(port)->rximr);
345 rx_fifo_imr &= ~MPC512x_PSC_FIFO_ALARM;
346 out_be32(&FIFO_512x(port)->rximr, rx_fifo_imr);
347}
348
349static void mpc512x_psc_start_tx(struct uart_port *port)
350{
351 unsigned long tx_fifo_imr;
352
353 tx_fifo_imr = in_be32(&FIFO_512x(port)->tximr);
354 tx_fifo_imr |= MPC512x_PSC_FIFO_ALARM;
355 out_be32(&FIFO_512x(port)->tximr, tx_fifo_imr);
356}
357
358static void mpc512x_psc_stop_tx(struct uart_port *port)
359{
360 unsigned long tx_fifo_imr;
361
362 tx_fifo_imr = in_be32(&FIFO_512x(port)->tximr);
363 tx_fifo_imr &= ~MPC512x_PSC_FIFO_ALARM;
364 out_be32(&FIFO_512x(port)->tximr, tx_fifo_imr);
365}
366
367static void mpc512x_psc_rx_clr_irq(struct uart_port *port)
368{
369 out_be32(&FIFO_512x(port)->rxisr, in_be32(&FIFO_512x(port)->rxisr));
370}
371
372static void mpc512x_psc_tx_clr_irq(struct uart_port *port)
373{
374 out_be32(&FIFO_512x(port)->txisr, in_be32(&FIFO_512x(port)->txisr));
375}
376
377static void mpc512x_psc_write_char(struct uart_port *port, unsigned char c)
378{
379 out_8(&FIFO_512x(port)->txdata_8, c);
380}
381
382static unsigned char mpc512x_psc_read_char(struct uart_port *port)
383{
384 return in_8(&FIFO_512x(port)->rxdata_8);
385}
386
387static void mpc512x_psc_cw_disable_ints(struct uart_port *port)
388{
389 port->read_status_mask =
390 in_be32(&FIFO_512x(port)->tximr) << 16 |
391 in_be32(&FIFO_512x(port)->rximr);
392 out_be32(&FIFO_512x(port)->tximr, 0);
393 out_be32(&FIFO_512x(port)->rximr, 0);
394}
395
396static void mpc512x_psc_cw_restore_ints(struct uart_port *port)
397{
398 out_be32(&FIFO_512x(port)->tximr,
399 (port->read_status_mask >> 16) & 0x7f);
400 out_be32(&FIFO_512x(port)->rximr, port->read_status_mask & 0x7f);
401}
402
403static unsigned long mpc512x_getuartclk(void *p)
404{
405 return mpc512x_find_ips_freq(p);
406}
407
408static struct psc_ops mpc512x_psc_ops = {
409 .fifo_init = mpc512x_psc_fifo_init,
410 .raw_rx_rdy = mpc512x_psc_raw_rx_rdy,
411 .raw_tx_rdy = mpc512x_psc_raw_tx_rdy,
412 .rx_rdy = mpc512x_psc_rx_rdy,
413 .tx_rdy = mpc512x_psc_tx_rdy,
414 .tx_empty = mpc512x_psc_tx_empty,
415 .stop_rx = mpc512x_psc_stop_rx,
416 .start_tx = mpc512x_psc_start_tx,
417 .stop_tx = mpc512x_psc_stop_tx,
418 .rx_clr_irq = mpc512x_psc_rx_clr_irq,
419 .tx_clr_irq = mpc512x_psc_tx_clr_irq,
420 .write_char = mpc512x_psc_write_char,
421 .read_char = mpc512x_psc_read_char,
422 .cw_disable_ints = mpc512x_psc_cw_disable_ints,
423 .cw_restore_ints = mpc512x_psc_cw_restore_ints,
424 .getuartclk = mpc512x_getuartclk,
137}; 425};
138#endif 426#endif
139 427
428static struct psc_ops *psc_ops;
140 429
141/* ======================================================================== */ 430/* ======================================================================== */
142/* UART operations */ 431/* UART operations */
@@ -145,8 +434,7 @@ static struct of_device_id mpc52xx_uart_of_match[] = {
145static unsigned int 434static unsigned int
146mpc52xx_uart_tx_empty(struct uart_port *port) 435mpc52xx_uart_tx_empty(struct uart_port *port)
147{ 436{
148 int status = in_be16(&PSC(port)->mpc52xx_psc_status); 437 return psc_ops->tx_empty(port) ? TIOCSER_TEMT : 0;
149 return (status & MPC52xx_PSC_SR_TXEMP) ? TIOCSER_TEMT : 0;
150} 438}
151 439
152static void 440static void
@@ -166,16 +454,14 @@ static void
166mpc52xx_uart_stop_tx(struct uart_port *port) 454mpc52xx_uart_stop_tx(struct uart_port *port)
167{ 455{
168 /* port->lock taken by caller */ 456 /* port->lock taken by caller */
169 port->read_status_mask &= ~MPC52xx_PSC_IMR_TXRDY; 457 psc_ops->stop_tx(port);
170 out_be16(&PSC(port)->mpc52xx_psc_imr, port->read_status_mask);
171} 458}
172 459
173static void 460static void
174mpc52xx_uart_start_tx(struct uart_port *port) 461mpc52xx_uart_start_tx(struct uart_port *port)
175{ 462{
176 /* port->lock taken by caller */ 463 /* port->lock taken by caller */
177 port->read_status_mask |= MPC52xx_PSC_IMR_TXRDY; 464 psc_ops->start_tx(port);
178 out_be16(&PSC(port)->mpc52xx_psc_imr, port->read_status_mask);
179} 465}
180 466
181static void 467static void
@@ -188,8 +474,7 @@ mpc52xx_uart_send_xchar(struct uart_port *port, char ch)
188 if (ch) { 474 if (ch) {
189 /* Make sure tx interrupts are on */ 475 /* Make sure tx interrupts are on */
190 /* Truly necessary ??? They should be anyway */ 476 /* Truly necessary ??? They should be anyway */
191 port->read_status_mask |= MPC52xx_PSC_IMR_TXRDY; 477 psc_ops->start_tx(port);
192 out_be16(&PSC(port)->mpc52xx_psc_imr, port->read_status_mask);
193 } 478 }
194 479
195 spin_unlock_irqrestore(&port->lock, flags); 480 spin_unlock_irqrestore(&port->lock, flags);
@@ -199,8 +484,7 @@ static void
199mpc52xx_uart_stop_rx(struct uart_port *port) 484mpc52xx_uart_stop_rx(struct uart_port *port)
200{ 485{
201 /* port->lock taken by caller */ 486 /* port->lock taken by caller */
202 port->read_status_mask &= ~MPC52xx_PSC_IMR_RXRDY; 487 psc_ops->stop_rx(port);
203 out_be16(&PSC(port)->mpc52xx_psc_imr, port->read_status_mask);
204} 488}
205 489
206static void 490static void
@@ -227,12 +511,12 @@ static int
227mpc52xx_uart_startup(struct uart_port *port) 511mpc52xx_uart_startup(struct uart_port *port)
228{ 512{
229 struct mpc52xx_psc __iomem *psc = PSC(port); 513 struct mpc52xx_psc __iomem *psc = PSC(port);
230 struct mpc52xx_psc_fifo __iomem *fifo = FIFO(port);
231 int ret; 514 int ret;
232 515
233 /* Request IRQ */ 516 /* Request IRQ */
234 ret = request_irq(port->irq, mpc52xx_uart_int, 517 ret = request_irq(port->irq, mpc52xx_uart_int,
235 IRQF_DISABLED | IRQF_SAMPLE_RANDOM, "mpc52xx_psc_uart", port); 518 IRQF_DISABLED | IRQF_SAMPLE_RANDOM | IRQF_SHARED,
519 "mpc52xx_psc_uart", port);
236 if (ret) 520 if (ret)
237 return ret; 521 return ret;
238 522
@@ -242,15 +526,7 @@ mpc52xx_uart_startup(struct uart_port *port)
242 526
243 out_be32(&psc->sicr, 0); /* UART mode DCD ignored */ 527 out_be32(&psc->sicr, 0); /* UART mode DCD ignored */
244 528
245 out_be16(&psc->mpc52xx_psc_clock_select, 0xdd00); /* /16 prescaler on */ 529 psc_ops->fifo_init(port);
246
247 out_8(&fifo->rfcntl, 0x00);
248 out_be16(&fifo->rfalarm, 0x1ff);
249 out_8(&fifo->tfcntl, 0x07);
250 out_be16(&fifo->tfalarm, 0x80);
251
252 port->read_status_mask |= MPC52xx_PSC_IMR_RXRDY | MPC52xx_PSC_IMR_TXRDY;
253 out_be16(&psc->mpc52xx_psc_imr, port->read_status_mask);
254 530
255 out_8(&psc->command, MPC52xx_PSC_TX_ENABLE); 531 out_8(&psc->command, MPC52xx_PSC_TX_ENABLE);
256 out_8(&psc->command, MPC52xx_PSC_RX_ENABLE); 532 out_8(&psc->command, MPC52xx_PSC_RX_ENABLE);
@@ -333,8 +609,7 @@ mpc52xx_uart_set_termios(struct uart_port *port, struct ktermios *new,
333 * boot for the console, all stuff is not yet ready to receive at that 609 * boot for the console, all stuff is not yet ready to receive at that
334 * time and that just makes the kernel oops */ 610 * time and that just makes the kernel oops */
335 /* while (j-- && mpc52xx_uart_int_rx_chars(port)); */ 611 /* while (j-- && mpc52xx_uart_int_rx_chars(port)); */
336 while (!(in_be16(&psc->mpc52xx_psc_status) & MPC52xx_PSC_SR_TXEMP) && 612 while (!mpc52xx_uart_tx_empty(port) && --j)
337 --j)
338 udelay(1); 613 udelay(1);
339 614
340 if (!j) 615 if (!j)
@@ -462,11 +737,9 @@ mpc52xx_uart_int_rx_chars(struct uart_port *port)
462 unsigned short status; 737 unsigned short status;
463 738
464 /* While we can read, do so ! */ 739 /* While we can read, do so ! */
465 while ((status = in_be16(&PSC(port)->mpc52xx_psc_status)) & 740 while (psc_ops->raw_rx_rdy(port)) {
466 MPC52xx_PSC_SR_RXRDY) {
467
468 /* Get the char */ 741 /* Get the char */
469 ch = in_8(&PSC(port)->mpc52xx_psc_buffer_8); 742 ch = psc_ops->read_char(port);
470 743
471 /* Handle sysreq char */ 744 /* Handle sysreq char */
472#ifdef SUPPORT_SYSRQ 745#ifdef SUPPORT_SYSRQ
@@ -481,6 +754,8 @@ mpc52xx_uart_int_rx_chars(struct uart_port *port)
481 flag = TTY_NORMAL; 754 flag = TTY_NORMAL;
482 port->icount.rx++; 755 port->icount.rx++;
483 756
757 status = in_be16(&PSC(port)->mpc52xx_psc_status);
758
484 if (status & (MPC52xx_PSC_SR_PE | 759 if (status & (MPC52xx_PSC_SR_PE |
485 MPC52xx_PSC_SR_FE | 760 MPC52xx_PSC_SR_FE |
486 MPC52xx_PSC_SR_RB)) { 761 MPC52xx_PSC_SR_RB)) {
@@ -510,7 +785,7 @@ mpc52xx_uart_int_rx_chars(struct uart_port *port)
510 785
511 tty_flip_buffer_push(tty); 786 tty_flip_buffer_push(tty);
512 787
513 return in_be16(&PSC(port)->mpc52xx_psc_status) & MPC52xx_PSC_SR_RXRDY; 788 return psc_ops->raw_rx_rdy(port);
514} 789}
515 790
516static inline int 791static inline int
@@ -520,7 +795,7 @@ mpc52xx_uart_int_tx_chars(struct uart_port *port)
520 795
521 /* Process out of band chars */ 796 /* Process out of band chars */
522 if (port->x_char) { 797 if (port->x_char) {
523 out_8(&PSC(port)->mpc52xx_psc_buffer_8, port->x_char); 798 psc_ops->write_char(port, port->x_char);
524 port->icount.tx++; 799 port->icount.tx++;
525 port->x_char = 0; 800 port->x_char = 0;
526 return 1; 801 return 1;
@@ -533,8 +808,8 @@ mpc52xx_uart_int_tx_chars(struct uart_port *port)
533 } 808 }
534 809
535 /* Send chars */ 810 /* Send chars */
536 while (in_be16(&PSC(port)->mpc52xx_psc_status) & MPC52xx_PSC_SR_TXRDY) { 811 while (psc_ops->raw_tx_rdy(port)) {
537 out_8(&PSC(port)->mpc52xx_psc_buffer_8, xmit->buf[xmit->tail]); 812 psc_ops->write_char(port, xmit->buf[xmit->tail]);
538 xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); 813 xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
539 port->icount.tx++; 814 port->icount.tx++;
540 if (uart_circ_empty(xmit)) 815 if (uart_circ_empty(xmit))
@@ -560,7 +835,6 @@ mpc52xx_uart_int(int irq, void *dev_id)
560 struct uart_port *port = dev_id; 835 struct uart_port *port = dev_id;
561 unsigned long pass = ISR_PASS_LIMIT; 836 unsigned long pass = ISR_PASS_LIMIT;
562 unsigned int keepgoing; 837 unsigned int keepgoing;
563 unsigned short status;
564 838
565 spin_lock(&port->lock); 839 spin_lock(&port->lock);
566 840
@@ -569,18 +843,12 @@ mpc52xx_uart_int(int irq, void *dev_id)
569 /* If we don't find anything to do, we stop */ 843 /* If we don't find anything to do, we stop */
570 keepgoing = 0; 844 keepgoing = 0;
571 845
572 /* Read status */ 846 psc_ops->rx_clr_irq(port);
573 status = in_be16(&PSC(port)->mpc52xx_psc_isr); 847 if (psc_ops->rx_rdy(port))
574 status &= port->read_status_mask;
575
576 /* Do we need to receive chars ? */
577 /* For this RX interrupts must be on and some chars waiting */
578 if (status & MPC52xx_PSC_IMR_RXRDY)
579 keepgoing |= mpc52xx_uart_int_rx_chars(port); 848 keepgoing |= mpc52xx_uart_int_rx_chars(port);
580 849
581 /* Do we need to send chars ? */ 850 psc_ops->tx_clr_irq(port);
582 /* For this, TX must be ready and TX interrupt enabled */ 851 if (psc_ops->tx_rdy(port))
583 if (status & MPC52xx_PSC_IMR_TXRDY)
584 keepgoing |= mpc52xx_uart_int_tx_chars(port); 852 keepgoing |= mpc52xx_uart_int_tx_chars(port);
585 853
586 /* Limit number of iteration */ 854 /* Limit number of iteration */
@@ -647,36 +915,33 @@ static void
647mpc52xx_console_write(struct console *co, const char *s, unsigned int count) 915mpc52xx_console_write(struct console *co, const char *s, unsigned int count)
648{ 916{
649 struct uart_port *port = &mpc52xx_uart_ports[co->index]; 917 struct uart_port *port = &mpc52xx_uart_ports[co->index];
650 struct mpc52xx_psc __iomem *psc = PSC(port);
651 unsigned int i, j; 918 unsigned int i, j;
652 919
653 /* Disable interrupts */ 920 /* Disable interrupts */
654 out_be16(&psc->mpc52xx_psc_imr, 0); 921 psc_ops->cw_disable_ints(port);
655 922
656 /* Wait the TX buffer to be empty */ 923 /* Wait the TX buffer to be empty */
657 j = 5000000; /* Maximum wait */ 924 j = 5000000; /* Maximum wait */
658 while (!(in_be16(&psc->mpc52xx_psc_status) & MPC52xx_PSC_SR_TXEMP) && 925 while (!mpc52xx_uart_tx_empty(port) && --j)
659 --j)
660 udelay(1); 926 udelay(1);
661 927
662 /* Write all the chars */ 928 /* Write all the chars */
663 for (i = 0; i < count; i++, s++) { 929 for (i = 0; i < count; i++, s++) {
664 /* Line return handling */ 930 /* Line return handling */
665 if (*s == '\n') 931 if (*s == '\n')
666 out_8(&psc->mpc52xx_psc_buffer_8, '\r'); 932 psc_ops->write_char(port, '\r');
667 933
668 /* Send the char */ 934 /* Send the char */
669 out_8(&psc->mpc52xx_psc_buffer_8, *s); 935 psc_ops->write_char(port, *s);
670 936
671 /* Wait the TX buffer to be empty */ 937 /* Wait the TX buffer to be empty */
672 j = 20000; /* Maximum wait */ 938 j = 20000; /* Maximum wait */
673 while (!(in_be16(&psc->mpc52xx_psc_status) & 939 while (!mpc52xx_uart_tx_empty(port) && --j)
674 MPC52xx_PSC_SR_TXEMP) && --j)
675 udelay(1); 940 udelay(1);
676 } 941 }
677 942
678 /* Restore interrupt state */ 943 /* Restore interrupt state */
679 out_be16(&psc->mpc52xx_psc_imr, port->read_status_mask); 944 psc_ops->cw_restore_ints(port);
680} 945}
681 946
682#if !defined(CONFIG_PPC_MERGE) 947#if !defined(CONFIG_PPC_MERGE)
@@ -721,7 +986,7 @@ mpc52xx_console_setup(struct console *co, char *options)
721{ 986{
722 struct uart_port *port = &mpc52xx_uart_ports[co->index]; 987 struct uart_port *port = &mpc52xx_uart_ports[co->index];
723 struct device_node *np = mpc52xx_uart_nodes[co->index]; 988 struct device_node *np = mpc52xx_uart_nodes[co->index];
724 unsigned int ipb_freq; 989 unsigned int uartclk;
725 struct resource res; 990 struct resource res;
726 int ret; 991 int ret;
727 992
@@ -753,17 +1018,16 @@ mpc52xx_console_setup(struct console *co, char *options)
753 return ret; 1018 return ret;
754 } 1019 }
755 1020
756 /* Search for bus-frequency property in this node or a parent */ 1021 uartclk = psc_ops->getuartclk(np);
757 ipb_freq = mpc52xx_find_ipb_freq(np); 1022 if (uartclk == 0) {
758 if (ipb_freq == 0) { 1023 pr_debug("Could not find uart clock frequency!\n");
759 pr_debug("Could not find IPB bus frequency!\n");
760 return -EINVAL; 1024 return -EINVAL;
761 } 1025 }
762 1026
763 /* Basic port init. Needed since we use some uart_??? func before 1027 /* Basic port init. Needed since we use some uart_??? func before
764 * real init for early access */ 1028 * real init for early access */
765 spin_lock_init(&port->lock); 1029 spin_lock_init(&port->lock);
766 port->uartclk = ipb_freq / 2; 1030 port->uartclk = uartclk;
767 port->ops = &mpc52xx_uart_ops; 1031 port->ops = &mpc52xx_uart_ops;
768 port->mapbase = res.start; 1032 port->mapbase = res.start;
769 port->membase = ioremap(res.start, sizeof(struct mpc52xx_psc)); 1033 port->membase = ioremap(res.start, sizeof(struct mpc52xx_psc));
@@ -945,11 +1209,25 @@ static struct platform_driver mpc52xx_uart_platform_driver = {
945/* OF Platform Driver */ 1209/* OF Platform Driver */
946/* ======================================================================== */ 1210/* ======================================================================== */
947 1211
1212static struct of_device_id mpc52xx_uart_of_match[] = {
1213#ifdef CONFIG_PPC_MPC52xx
1214 { .compatible = "fsl,mpc5200-psc-uart", .data = &mpc52xx_psc_ops, },
1215 /* binding used by old lite5200 device trees: */
1216 { .compatible = "mpc5200-psc-uart", .data = &mpc52xx_psc_ops, },
1217 /* binding used by efika: */
1218 { .compatible = "mpc5200-serial", .data = &mpc52xx_psc_ops, },
1219#endif
1220#ifdef CONFIG_PPC_MPC512x
1221 { .compatible = "fsl,mpc5121-psc-uart", .data = &mpc512x_psc_ops, },
1222 {},
1223#endif
1224};
1225
948static int __devinit 1226static int __devinit
949mpc52xx_uart_of_probe(struct of_device *op, const struct of_device_id *match) 1227mpc52xx_uart_of_probe(struct of_device *op, const struct of_device_id *match)
950{ 1228{
951 int idx = -1; 1229 int idx = -1;
952 unsigned int ipb_freq; 1230 unsigned int uartclk;
953 struct uart_port *port = NULL; 1231 struct uart_port *port = NULL;
954 struct resource res; 1232 struct resource res;
955 int ret; 1233 int ret;
@@ -965,10 +1243,9 @@ mpc52xx_uart_of_probe(struct of_device *op, const struct of_device_id *match)
965 pr_debug("Found %s assigned to ttyPSC%x\n", 1243 pr_debug("Found %s assigned to ttyPSC%x\n",
966 mpc52xx_uart_nodes[idx]->full_name, idx); 1244 mpc52xx_uart_nodes[idx]->full_name, idx);
967 1245
968 /* Search for bus-frequency property in this node or a parent */ 1246 uartclk = psc_ops->getuartclk(op->node);
969 ipb_freq = mpc52xx_find_ipb_freq(op->node); 1247 if (uartclk == 0) {
970 if (ipb_freq == 0) { 1248 dev_dbg(&op->dev, "Could not find uart clock frequency!\n");
971 dev_dbg(&op->dev, "Could not find IPB bus frequency!\n");
972 return -EINVAL; 1249 return -EINVAL;
973 } 1250 }
974 1251
@@ -976,7 +1253,7 @@ mpc52xx_uart_of_probe(struct of_device *op, const struct of_device_id *match)
976 port = &mpc52xx_uart_ports[idx]; 1253 port = &mpc52xx_uart_ports[idx];
977 1254
978 spin_lock_init(&port->lock); 1255 spin_lock_init(&port->lock);
979 port->uartclk = ipb_freq / 2; 1256 port->uartclk = uartclk;
980 port->fifosize = 512; 1257 port->fifosize = 512;
981 port->iotype = UPIO_MEM; 1258 port->iotype = UPIO_MEM;
982 port->flags = UPF_BOOT_AUTOCONF | 1259 port->flags = UPF_BOOT_AUTOCONF |
@@ -1080,15 +1357,19 @@ mpc52xx_uart_of_enumerate(void)
1080 static int enum_done; 1357 static int enum_done;
1081 struct device_node *np; 1358 struct device_node *np;
1082 const unsigned int *devno; 1359 const unsigned int *devno;
1360 const struct of_device_id *match;
1083 int i; 1361 int i;
1084 1362
1085 if (enum_done) 1363 if (enum_done)
1086 return; 1364 return;
1087 1365
1088 for_each_node_by_type(np, "serial") { 1366 for_each_node_by_type(np, "serial") {
1089 if (!of_match_node(mpc52xx_uart_of_match, np)) 1367 match = of_match_node(mpc52xx_uart_of_match, np);
1368 if (!match)
1090 continue; 1369 continue;
1091 1370
1371 psc_ops = match->data;
1372
1092 /* Is a particular device number requested? */ 1373 /* Is a particular device number requested? */
1093 devno = of_get_property(np, "port-number", NULL); 1374 devno = of_get_property(np, "port-number", NULL);
1094 mpc52xx_uart_of_assign(np, devno ? *devno : -1); 1375 mpc52xx_uart_of_assign(np, devno ? *devno : -1);
@@ -1149,6 +1430,7 @@ mpc52xx_uart_init(void)
1149 return ret; 1430 return ret;
1150 } 1431 }
1151#else 1432#else
1433 psc_ops = &mpc52xx_psc_ops;
1152 ret = platform_driver_register(&mpc52xx_uart_platform_driver); 1434 ret = platform_driver_register(&mpc52xx_uart_platform_driver);
1153 if (ret) { 1435 if (ret) {
1154 printk(KERN_ERR "%s: platform_driver_register failed (%i)\n", 1436 printk(KERN_ERR "%s: platform_driver_register failed (%i)\n",
diff --git a/drivers/serial/uartlite.c b/drivers/serial/uartlite.c
index bacf68dca01a..4e06ab6bcb6e 100644
--- a/drivers/serial/uartlite.c
+++ b/drivers/serial/uartlite.c
@@ -17,10 +17,21 @@
17#include <linux/tty.h> 17#include <linux/tty.h>
18#include <linux/delay.h> 18#include <linux/delay.h>
19#include <linux/interrupt.h> 19#include <linux/interrupt.h>
20#include <linux/init.h>
20#include <asm/io.h> 21#include <asm/io.h>
21#if defined(CONFIG_OF) 22#if defined(CONFIG_OF)
23#include <linux/of.h>
22#include <linux/of_device.h> 24#include <linux/of_device.h>
23#include <linux/of_platform.h> 25#include <linux/of_platform.h>
26
27/* Match table for of_platform binding */
28static struct of_device_id ulite_of_match[] __devinitdata = {
29 { .compatible = "xlnx,opb-uartlite-1.00.b", },
30 { .compatible = "xlnx,xps-uartlite-1.00.a", },
31 {}
32};
33MODULE_DEVICE_TABLE(of, ulite_of_match);
34
24#endif 35#endif
25 36
26#define ULITE_NAME "ttyUL" 37#define ULITE_NAME "ttyUL"
@@ -275,6 +286,9 @@ static void ulite_release_port(struct uart_port *port)
275 286
276static int ulite_request_port(struct uart_port *port) 287static int ulite_request_port(struct uart_port *port)
277{ 288{
289 pr_debug("ulite console: port=%p; port->mapbase=%x\n",
290 port, port->mapbase);
291
278 if (!request_mem_region(port->mapbase, ULITE_REGION, "uartlite")) { 292 if (!request_mem_region(port->mapbase, ULITE_REGION, "uartlite")) {
279 dev_err(port->dev, "Memory region busy\n"); 293 dev_err(port->dev, "Memory region busy\n");
280 return -EBUSY; 294 return -EBUSY;
@@ -375,32 +389,6 @@ static void ulite_console_write(struct console *co, const char *s,
375 spin_unlock_irqrestore(&port->lock, flags); 389 spin_unlock_irqrestore(&port->lock, flags);
376} 390}
377 391
378#if defined(CONFIG_OF)
379static inline void __init ulite_console_of_find_device(int id)
380{
381 struct device_node *np;
382 struct resource res;
383 const unsigned int *of_id;
384 int rc;
385
386 for_each_compatible_node(np, NULL, "xilinx,uartlite") {
387 of_id = of_get_property(np, "port-number", NULL);
388 if ((!of_id) || (*of_id != id))
389 continue;
390
391 rc = of_address_to_resource(np, 0, &res);
392 if (rc)
393 continue;
394
395 ulite_ports[id].mapbase = res.start;
396 of_node_put(np);
397 return;
398 }
399}
400#else /* CONFIG_OF */
401static inline void __init ulite_console_of_find_device(int id) { /* do nothing */ }
402#endif /* CONFIG_OF */
403
404static int __init ulite_console_setup(struct console *co, char *options) 392static int __init ulite_console_setup(struct console *co, char *options)
405{ 393{
406 struct uart_port *port; 394 struct uart_port *port;
@@ -414,11 +402,7 @@ static int __init ulite_console_setup(struct console *co, char *options)
414 402
415 port = &ulite_ports[co->index]; 403 port = &ulite_ports[co->index];
416 404
417 /* Check if it is an OF device */ 405 /* Has the device been initialized yet? */
418 if (!port->mapbase)
419 ulite_console_of_find_device(co->index);
420
421 /* Do we have a device now? */
422 if (!port->mapbase) { 406 if (!port->mapbase) {
423 pr_debug("console on ttyUL%i not present\n", co->index); 407 pr_debug("console on ttyUL%i not present\n", co->index);
424 return -ENODEV; 408 return -ENODEV;
@@ -617,13 +601,6 @@ static int __devexit ulite_of_remove(struct of_device *op)
617 return ulite_release(&op->dev); 601 return ulite_release(&op->dev);
618} 602}
619 603
620/* Match table for of_platform binding */
621static struct of_device_id __devinit ulite_of_match[] = {
622 { .type = "serial", .compatible = "xilinx,uartlite", },
623 {},
624};
625MODULE_DEVICE_TABLE(of, ulite_of_match);
626
627static struct of_platform_driver ulite_of_driver = { 604static struct of_platform_driver ulite_of_driver = {
628 .owner = THIS_MODULE, 605 .owner = THIS_MODULE,
629 .name = "uartlite", 606 .name = "uartlite",
diff --git a/drivers/video/xilinxfb.c b/drivers/video/xilinxfb.c
index e38d3b7c3ad7..7b3a8423f485 100644
--- a/drivers/video/xilinxfb.c
+++ b/drivers/video/xilinxfb.c
@@ -459,8 +459,8 @@ static int __devexit xilinxfb_of_remove(struct of_device *op)
459} 459}
460 460
461/* Match table for of_platform binding */ 461/* Match table for of_platform binding */
462static struct of_device_id __devinit xilinxfb_of_match[] = { 462static struct of_device_id xilinxfb_of_match[] __devinitdata = {
463 { .compatible = "xilinx,ml300-fb", }, 463 { .compatible = "xlnx,plb-tft-cntlr-ref-1.00.a", },
464 {}, 464 {},
465}; 465};
466MODULE_DEVICE_TABLE(of, xilinxfb_of_match); 466MODULE_DEVICE_TABLE(of, xilinxfb_of_match);
diff --git a/include/asm-powerpc/cputable.h b/include/asm-powerpc/cputable.h
index 528ef183c221..1e79673b7316 100644
--- a/include/asm-powerpc/cputable.h
+++ b/include/asm-powerpc/cputable.h
@@ -46,7 +46,7 @@ enum powerpc_oprofile_type {
46 PPC_OPROFILE_RS64 = 1, 46 PPC_OPROFILE_RS64 = 1,
47 PPC_OPROFILE_POWER4 = 2, 47 PPC_OPROFILE_POWER4 = 2,
48 PPC_OPROFILE_G4 = 3, 48 PPC_OPROFILE_G4 = 3,
49 PPC_OPROFILE_BOOKE = 4, 49 PPC_OPROFILE_FSL_EMB = 4,
50 PPC_OPROFILE_CELL = 5, 50 PPC_OPROFILE_CELL = 5,
51 PPC_OPROFILE_PA6T = 6, 51 PPC_OPROFILE_PA6T = 6,
52}; 52};
diff --git a/include/asm-powerpc/dcr-native.h b/include/asm-powerpc/dcr-native.h
index af5fb31af559..be6c879e8760 100644
--- a/include/asm-powerpc/dcr-native.h
+++ b/include/asm-powerpc/dcr-native.h
@@ -59,25 +59,36 @@ do { \
59/* R/W of indirect DCRs make use of standard naming conventions for DCRs */ 59/* R/W of indirect DCRs make use of standard naming conventions for DCRs */
60extern spinlock_t dcr_ind_lock; 60extern spinlock_t dcr_ind_lock;
61 61
62#define mfdcri(base, reg) \ 62static inline unsigned __mfdcri(int base_addr, int base_data, int reg)
63({ \ 63{
64 unsigned long flags; \ 64 unsigned long flags;
65 unsigned int val; \ 65 unsigned int val;
66 spin_lock_irqsave(&dcr_ind_lock, flags); \
67 mtdcr(DCRN_ ## base ## _CONFIG_ADDR, reg); \
68 val = mfdcr(DCRN_ ## base ## _CONFIG_DATA); \
69 spin_unlock_irqrestore(&dcr_ind_lock, flags); \
70 val; \
71})
72 66
73#define mtdcri(base, reg, data) \ 67 spin_lock_irqsave(&dcr_ind_lock, flags);
74do { \ 68 __mtdcr(base_addr, reg);
75 unsigned long flags; \ 69 val = __mfdcr(base_data);
76 spin_lock_irqsave(&dcr_ind_lock, flags); \ 70 spin_unlock_irqrestore(&dcr_ind_lock, flags);
77 mtdcr(DCRN_ ## base ## _CONFIG_ADDR, reg); \ 71 return val;
78 mtdcr(DCRN_ ## base ## _CONFIG_DATA, data); \ 72}
79 spin_unlock_irqrestore(&dcr_ind_lock, flags); \ 73
80} while (0) 74static inline void __mtdcri(int base_addr, int base_data, int reg,
75 unsigned val)
76{
77 unsigned long flags;
78
79 spin_lock_irqsave(&dcr_ind_lock, flags);
80 __mtdcr(base_addr, reg);
81 __mtdcr(base_data, val);
82 spin_unlock_irqrestore(&dcr_ind_lock, flags);
83}
84
85#define mfdcri(base, reg) __mfdcri(DCRN_ ## base ## _CONFIG_ADDR, \
86 DCRN_ ## base ## _CONFIG_DATA, \
87 reg)
88
89#define mtdcri(base, reg, data) __mtdcri(DCRN_ ## base ## _CONFIG_ADDR, \
90 DCRN_ ## base ## _CONFIG_DATA, \
91 reg, data)
81 92
82#endif /* __ASSEMBLY__ */ 93#endif /* __ASSEMBLY__ */
83#endif /* __KERNEL__ */ 94#endif /* __KERNEL__ */
diff --git a/include/asm-powerpc/elf.h b/include/asm-powerpc/elf.h
index 6bd07ef78ac4..9080d85cb9d0 100644
--- a/include/asm-powerpc/elf.h
+++ b/include/asm-powerpc/elf.h
@@ -165,8 +165,10 @@ typedef elf_vrreg_t elf_vrregset_t32[ELF_NVRREG32];
165 * This is used to ensure we don't load something for the wrong architecture. 165 * This is used to ensure we don't load something for the wrong architecture.
166 */ 166 */
167#define elf_check_arch(x) ((x)->e_machine == ELF_ARCH) 167#define elf_check_arch(x) ((x)->e_machine == ELF_ARCH)
168#define compat_elf_check_arch(x) ((x)->e_machine == EM_PPC)
168 169
169#define USE_ELF_CORE_DUMP 170#define USE_ELF_CORE_DUMP
171#define CORE_DUMP_USE_REGSET
170#define ELF_EXEC_PAGESIZE PAGE_SIZE 172#define ELF_EXEC_PAGESIZE PAGE_SIZE
171 173
172/* This is the location that an ET_DYN program is loaded if exec'ed. Typical 174/* This is the location that an ET_DYN program is loaded if exec'ed. Typical
diff --git a/include/asm-powerpc/mpc512x.h b/include/asm-powerpc/mpc512x.h
new file mode 100644
index 000000000000..c48a1658eeac
--- /dev/null
+++ b/include/asm-powerpc/mpc512x.h
@@ -0,0 +1,22 @@
1/*
2 * Copyright (C) 2007 Freescale Semiconductor, Inc. All rights reserved.
3 *
4 * Author: John Rigby, <jrigby@freescale.com>, Friday Apr 13 2007
5 *
6 * Description:
7 * MPC5121 Prototypes and definitions
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#ifndef __ASM_POWERPC_MPC512x_H__
17#define __ASM_POWERPC_MPC512x_H__
18
19extern unsigned long mpc512x_find_ips_freq(struct device_node *node);
20
21#endif /* __ASM_POWERPC_MPC512x_H__ */
22
diff --git a/include/asm-powerpc/mpc52xx_psc.h b/include/asm-powerpc/mpc52xx_psc.h
index bea42b95390f..710c5d36efaa 100644
--- a/include/asm-powerpc/mpc52xx_psc.h
+++ b/include/asm-powerpc/mpc52xx_psc.h
@@ -190,5 +190,53 @@ struct mpc52xx_psc_fifo {
190 u16 tflwfptr; /* PSC + 0x9e */ 190 u16 tflwfptr; /* PSC + 0x9e */
191}; 191};
192 192
193#define MPC512x_PSC_FIFO_RESET_SLICE 0x80
194#define MPC512x_PSC_FIFO_ENABLE_SLICE 0x01
195#define MPC512x_PSC_FIFO_ENABLE_DMA 0x04
196
197#define MPC512x_PSC_FIFO_EMPTY 0x1
198#define MPC512x_PSC_FIFO_FULL 0x2
199#define MPC512x_PSC_FIFO_ALARM 0x4
200#define MPC512x_PSC_FIFO_URERR 0x8
201#define MPC512x_PSC_FIFO_ORERR 0x01
202#define MPC512x_PSC_FIFO_MEMERROR 0x02
203
204struct mpc512x_psc_fifo {
205 u32 reserved1[10];
206 u32 txcmd; /* PSC + 0x80 */
207 u32 txalarm; /* PSC + 0x84 */
208 u32 txsr; /* PSC + 0x88 */
209 u32 txisr; /* PSC + 0x8c */
210 u32 tximr; /* PSC + 0x90 */
211 u32 txcnt; /* PSC + 0x94 */
212 u32 txptr; /* PSC + 0x98 */
213 u32 txsz; /* PSC + 0x9c */
214 u32 reserved2[7];
215 union {
216 u8 txdata_8;
217 u16 txdata_16;
218 u32 txdata_32;
219 } txdata; /* PSC + 0xbc */
220#define txdata_8 txdata.txdata_8
221#define txdata_16 txdata.txdata_16
222#define txdata_32 txdata.txdata_32
223 u32 rxcmd; /* PSC + 0xc0 */
224 u32 rxalarm; /* PSC + 0xc4 */
225 u32 rxsr; /* PSC + 0xc8 */
226 u32 rxisr; /* PSC + 0xcc */
227 u32 rximr; /* PSC + 0xd0 */
228 u32 rxcnt; /* PSC + 0xd4 */
229 u32 rxptr; /* PSC + 0xd8 */
230 u32 rxsz; /* PSC + 0xdc */
231 u32 reserved3[7];
232 union {
233 u8 rxdata_8;
234 u16 rxdata_16;
235 u32 rxdata_32;
236 } rxdata; /* PSC + 0xfc */
237#define rxdata_8 rxdata.rxdata_8
238#define rxdata_16 rxdata.rxdata_16
239#define rxdata_32 rxdata.rxdata_32
240};
193 241
194#endif /* __ASM_MPC52xx_PSC_H__ */ 242#endif /* __ASM_MPC52xx_PSC_H__ */
diff --git a/include/asm-powerpc/oprofile_impl.h b/include/asm-powerpc/oprofile_impl.h
index 938fefb4c4bc..95035c602ba6 100644
--- a/include/asm-powerpc/oprofile_impl.h
+++ b/include/asm-powerpc/oprofile_impl.h
@@ -54,7 +54,7 @@ struct op_powerpc_model {
54 int num_counters; 54 int num_counters;
55}; 55};
56 56
57extern struct op_powerpc_model op_model_fsl_booke; 57extern struct op_powerpc_model op_model_fsl_emb;
58extern struct op_powerpc_model op_model_rs64; 58extern struct op_powerpc_model op_model_rs64;
59extern struct op_powerpc_model op_model_power4; 59extern struct op_powerpc_model op_model_power4;
60extern struct op_powerpc_model op_model_7450; 60extern struct op_powerpc_model op_model_7450;
diff --git a/include/asm-powerpc/ptrace.h b/include/asm-powerpc/ptrace.h
index ffc150f602b8..891d68932f39 100644
--- a/include/asm-powerpc/ptrace.h
+++ b/include/asm-powerpc/ptrace.h
@@ -55,6 +55,8 @@ struct pt_regs {
55 55
56#ifdef __powerpc64__ 56#ifdef __powerpc64__
57 57
58#define __ARCH_WANT_COMPAT_SYS_PTRACE
59
58#define STACK_FRAME_OVERHEAD 112 /* size of minimum stack frame */ 60#define STACK_FRAME_OVERHEAD 112 /* size of minimum stack frame */
59 61
60/* Size of dummy stack frame allocated when calling signal handler. */ 62/* Size of dummy stack frame allocated when calling signal handler. */
diff --git a/include/asm-powerpc/reg.h b/include/asm-powerpc/reg.h
index 2408a29507e5..0d6238987df8 100644
--- a/include/asm-powerpc/reg.h
+++ b/include/asm-powerpc/reg.h
@@ -18,6 +18,10 @@
18#include <asm/reg_booke.h> 18#include <asm/reg_booke.h>
19#endif /* CONFIG_BOOKE || CONFIG_40x */ 19#endif /* CONFIG_BOOKE || CONFIG_40x */
20 20
21#ifdef CONFIG_FSL_EMB_PERFMON
22#include <asm/reg_fsl_emb.h>
23#endif
24
21#ifdef CONFIG_8xx 25#ifdef CONFIG_8xx
22#include <asm/reg_8xx.h> 26#include <asm/reg_8xx.h>
23#endif /* CONFIG_8xx */ 27#endif /* CONFIG_8xx */
diff --git a/include/asm-powerpc/reg_booke.h b/include/asm-powerpc/reg_booke.h
index 0405ef479814..cf54a3f31753 100644
--- a/include/asm-powerpc/reg_booke.h
+++ b/include/asm-powerpc/reg_booke.h
@@ -9,68 +9,6 @@
9#ifndef __ASM_POWERPC_REG_BOOKE_H__ 9#ifndef __ASM_POWERPC_REG_BOOKE_H__
10#define __ASM_POWERPC_REG_BOOKE_H__ 10#define __ASM_POWERPC_REG_BOOKE_H__
11 11
12#ifndef __ASSEMBLY__
13/* Performance Monitor Registers */
14#define mfpmr(rn) ({unsigned int rval; \
15 asm volatile("mfpmr %0," __stringify(rn) \
16 : "=r" (rval)); rval;})
17#define mtpmr(rn, v) asm volatile("mtpmr " __stringify(rn) ",%0" : : "r" (v))
18#endif /* __ASSEMBLY__ */
19
20/* Freescale Book E Performance Monitor APU Registers */
21#define PMRN_PMC0 0x010 /* Performance Monitor Counter 0 */
22#define PMRN_PMC1 0x011 /* Performance Monitor Counter 1 */
23#define PMRN_PMC2 0x012 /* Performance Monitor Counter 1 */
24#define PMRN_PMC3 0x013 /* Performance Monitor Counter 1 */
25#define PMRN_PMLCA0 0x090 /* PM Local Control A0 */
26#define PMRN_PMLCA1 0x091 /* PM Local Control A1 */
27#define PMRN_PMLCA2 0x092 /* PM Local Control A2 */
28#define PMRN_PMLCA3 0x093 /* PM Local Control A3 */
29
30#define PMLCA_FC 0x80000000 /* Freeze Counter */
31#define PMLCA_FCS 0x40000000 /* Freeze in Supervisor */
32#define PMLCA_FCU 0x20000000 /* Freeze in User */
33#define PMLCA_FCM1 0x10000000 /* Freeze when PMM==1 */
34#define PMLCA_FCM0 0x08000000 /* Freeze when PMM==0 */
35#define PMLCA_CE 0x04000000 /* Condition Enable */
36
37#define PMLCA_EVENT_MASK 0x007f0000 /* Event field */
38#define PMLCA_EVENT_SHIFT 16
39
40#define PMRN_PMLCB0 0x110 /* PM Local Control B0 */
41#define PMRN_PMLCB1 0x111 /* PM Local Control B1 */
42#define PMRN_PMLCB2 0x112 /* PM Local Control B2 */
43#define PMRN_PMLCB3 0x113 /* PM Local Control B3 */
44
45#define PMLCB_THRESHMUL_MASK 0x0700 /* Threshhold Multiple Field */
46#define PMLCB_THRESHMUL_SHIFT 8
47
48#define PMLCB_THRESHOLD_MASK 0x003f /* Threshold Field */
49#define PMLCB_THRESHOLD_SHIFT 0
50
51#define PMRN_PMGC0 0x190 /* PM Global Control 0 */
52
53#define PMGC0_FAC 0x80000000 /* Freeze all Counters */
54#define PMGC0_PMIE 0x40000000 /* Interrupt Enable */
55#define PMGC0_FCECE 0x20000000 /* Freeze countes on
56 Enabled Condition or
57 Event */
58
59#define PMRN_UPMC0 0x000 /* User Performance Monitor Counter 0 */
60#define PMRN_UPMC1 0x001 /* User Performance Monitor Counter 1 */
61#define PMRN_UPMC2 0x002 /* User Performance Monitor Counter 1 */
62#define PMRN_UPMC3 0x003 /* User Performance Monitor Counter 1 */
63#define PMRN_UPMLCA0 0x080 /* User PM Local Control A0 */
64#define PMRN_UPMLCA1 0x081 /* User PM Local Control A1 */
65#define PMRN_UPMLCA2 0x082 /* User PM Local Control A2 */
66#define PMRN_UPMLCA3 0x083 /* User PM Local Control A3 */
67#define PMRN_UPMLCB0 0x100 /* User PM Local Control B0 */
68#define PMRN_UPMLCB1 0x101 /* User PM Local Control B1 */
69#define PMRN_UPMLCB2 0x102 /* User PM Local Control B2 */
70#define PMRN_UPMLCB3 0x103 /* User PM Local Control B3 */
71#define PMRN_UPMGC0 0x180 /* User PM Global Control 0 */
72
73
74/* Machine State Register (MSR) Fields */ 12/* Machine State Register (MSR) Fields */
75#define MSR_UCLE (1<<26) /* User-mode cache lock enable */ 13#define MSR_UCLE (1<<26) /* User-mode cache lock enable */
76#define MSR_SPE (1<<25) /* Enable SPE */ 14#define MSR_SPE (1<<25) /* Enable SPE */
diff --git a/include/asm-powerpc/reg_fsl_emb.h b/include/asm-powerpc/reg_fsl_emb.h
new file mode 100644
index 000000000000..1e180a594589
--- /dev/null
+++ b/include/asm-powerpc/reg_fsl_emb.h
@@ -0,0 +1,72 @@
1/*
2 * Contains register definitions for the Freescale Embedded Performance
3 * Monitor.
4 */
5#ifdef __KERNEL__
6#ifndef __ASM_POWERPC_REG_FSL_EMB_H__
7#define __ASM_POWERPC_REG_FSL_EMB_H__
8
9#ifndef __ASSEMBLY__
10/* Performance Monitor Registers */
11#define mfpmr(rn) ({unsigned int rval; \
12 asm volatile("mfpmr %0," __stringify(rn) \
13 : "=r" (rval)); rval;})
14#define mtpmr(rn, v) asm volatile("mtpmr " __stringify(rn) ",%0" : : "r" (v))
15#endif /* __ASSEMBLY__ */
16
17/* Freescale Book E Performance Monitor APU Registers */
18#define PMRN_PMC0 0x010 /* Performance Monitor Counter 0 */
19#define PMRN_PMC1 0x011 /* Performance Monitor Counter 1 */
20#define PMRN_PMC2 0x012 /* Performance Monitor Counter 1 */
21#define PMRN_PMC3 0x013 /* Performance Monitor Counter 1 */
22#define PMRN_PMLCA0 0x090 /* PM Local Control A0 */
23#define PMRN_PMLCA1 0x091 /* PM Local Control A1 */
24#define PMRN_PMLCA2 0x092 /* PM Local Control A2 */
25#define PMRN_PMLCA3 0x093 /* PM Local Control A3 */
26
27#define PMLCA_FC 0x80000000 /* Freeze Counter */
28#define PMLCA_FCS 0x40000000 /* Freeze in Supervisor */
29#define PMLCA_FCU 0x20000000 /* Freeze in User */
30#define PMLCA_FCM1 0x10000000 /* Freeze when PMM==1 */
31#define PMLCA_FCM0 0x08000000 /* Freeze when PMM==0 */
32#define PMLCA_CE 0x04000000 /* Condition Enable */
33
34#define PMLCA_EVENT_MASK 0x007f0000 /* Event field */
35#define PMLCA_EVENT_SHIFT 16
36
37#define PMRN_PMLCB0 0x110 /* PM Local Control B0 */
38#define PMRN_PMLCB1 0x111 /* PM Local Control B1 */
39#define PMRN_PMLCB2 0x112 /* PM Local Control B2 */
40#define PMRN_PMLCB3 0x113 /* PM Local Control B3 */
41
42#define PMLCB_THRESHMUL_MASK 0x0700 /* Threshhold Multiple Field */
43#define PMLCB_THRESHMUL_SHIFT 8
44
45#define PMLCB_THRESHOLD_MASK 0x003f /* Threshold Field */
46#define PMLCB_THRESHOLD_SHIFT 0
47
48#define PMRN_PMGC0 0x190 /* PM Global Control 0 */
49
50#define PMGC0_FAC 0x80000000 /* Freeze all Counters */
51#define PMGC0_PMIE 0x40000000 /* Interrupt Enable */
52#define PMGC0_FCECE 0x20000000 /* Freeze countes on
53 Enabled Condition or
54 Event */
55
56#define PMRN_UPMC0 0x000 /* User Performance Monitor Counter 0 */
57#define PMRN_UPMC1 0x001 /* User Performance Monitor Counter 1 */
58#define PMRN_UPMC2 0x002 /* User Performance Monitor Counter 1 */
59#define PMRN_UPMC3 0x003 /* User Performance Monitor Counter 1 */
60#define PMRN_UPMLCA0 0x080 /* User PM Local Control A0 */
61#define PMRN_UPMLCA1 0x081 /* User PM Local Control A1 */
62#define PMRN_UPMLCA2 0x082 /* User PM Local Control A2 */
63#define PMRN_UPMLCA3 0x083 /* User PM Local Control A3 */
64#define PMRN_UPMLCB0 0x100 /* User PM Local Control B0 */
65#define PMRN_UPMLCB1 0x101 /* User PM Local Control B1 */
66#define PMRN_UPMLCB2 0x102 /* User PM Local Control B2 */
67#define PMRN_UPMLCB3 0x103 /* User PM Local Control B3 */
68#define PMRN_UPMGC0 0x180 /* User PM Global Control 0 */
69
70
71#endif /* __ASM_POWERPC_REG_FSL_EMB_H__ */
72#endif /* __KERNEL__ */
diff --git a/include/asm-powerpc/system.h b/include/asm-powerpc/system.h
index 2a65ae637204..29552ff182aa 100644
--- a/include/asm-powerpc/system.h
+++ b/include/asm-powerpc/system.h
@@ -65,7 +65,7 @@
65struct task_struct; 65struct task_struct;
66struct pt_regs; 66struct pt_regs;
67 67
68#ifdef CONFIG_DEBUGGER 68#if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC)
69 69
70extern int (*__debugger)(struct pt_regs *regs); 70extern int (*__debugger)(struct pt_regs *regs);
71extern int (*__debugger_ipi)(struct pt_regs *regs); 71extern int (*__debugger_ipi)(struct pt_regs *regs);
diff --git a/include/asm-powerpc/vio.h b/include/asm-powerpc/vio.h
index 9204c15839c5..56512a968dab 100644
--- a/include/asm-powerpc/vio.h
+++ b/include/asm-powerpc/vio.h
@@ -66,7 +66,7 @@ extern void __devinit vio_unregister_device(struct vio_dev *dev);
66 66
67struct device_node; 67struct device_node;
68 68
69extern struct vio_dev * __devinit vio_register_device_node( 69extern struct vio_dev *vio_register_device_node(
70 struct device_node *node_vdev); 70 struct device_node *node_vdev);
71extern const void *vio_get_attribute(struct vio_dev *vdev, char *which, 71extern const void *vio_get_attribute(struct vio_dev *vdev, char *which,
72 int *length); 72 int *length);
diff --git a/include/linux/elf.h b/include/linux/elf.h
index ed98c761bae7..bad1b16ec49a 100644
--- a/include/linux/elf.h
+++ b/include/linux/elf.h
@@ -357,6 +357,7 @@ typedef struct elf64_shdr {
357#define NT_AUXV 6 357#define NT_AUXV 6
358#define NT_PRXFPREG 0x46e62b7f /* copied from gdb5.1/include/elf/common.h */ 358#define NT_PRXFPREG 0x46e62b7f /* copied from gdb5.1/include/elf/common.h */
359#define NT_PPC_VMX 0x100 /* PowerPC Altivec/VMX registers */ 359#define NT_PPC_VMX 0x100 /* PowerPC Altivec/VMX registers */
360#define NT_PPC_SPE 0x101 /* PowerPC SPE/EVR registers */
360#define NT_386_TLS 0x200 /* i386 TLS slots (struct user_desc) */ 361#define NT_386_TLS 0x200 /* i386 TLS slots (struct user_desc) */
361 362
362 363
diff --git a/include/linux/of.h b/include/linux/of.h
index b5f33efcb8e2..6981016dcc25 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -50,6 +50,7 @@ extern struct device_node *of_find_matching_node(struct device_node *from,
50extern struct device_node *of_find_node_by_path(const char *path); 50extern struct device_node *of_find_node_by_path(const char *path);
51extern struct device_node *of_find_node_by_phandle(phandle handle); 51extern struct device_node *of_find_node_by_phandle(phandle handle);
52extern struct device_node *of_get_parent(const struct device_node *node); 52extern struct device_node *of_get_parent(const struct device_node *node);
53extern struct device_node *of_get_next_parent(struct device_node *node);
53extern struct device_node *of_get_next_child(const struct device_node *node, 54extern struct device_node *of_get_next_child(const struct device_node *node,
54 struct device_node *prev); 55 struct device_node *prev);
55#define for_each_child_of_node(parent, child) \ 56#define for_each_child_of_node(parent, child) \