aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/Kconfig19
-rw-r--r--arch/arm/Makefile4
-rw-r--r--arch/arm/boot/compressed/head.S3
-rw-r--r--arch/arm/configs/ixdp2401_defconfig4
-rw-r--r--arch/arm/configs/ixdp2801_defconfig2
-rw-r--r--arch/arm/configs/ixp4xx_defconfig2
-rw-r--r--arch/arm/configs/realview_defconfig (renamed from arch/arm/configs/mp1000_defconfig)430
-rw-r--r--arch/arm/kernel/irq.c31
-rw-r--r--arch/arm/kernel/process.c9
-rw-r--r--arch/arm/kernel/smp.c109
-rw-r--r--arch/arm/lib/Makefile22
-rw-r--r--arch/arm/lib/bitops.h2
-rw-r--r--arch/arm/lib/clear_user.S52
-rw-r--r--arch/arm/lib/copy_from_user.S101
-rw-r--r--arch/arm/lib/copy_template.S255
-rw-r--r--arch/arm/lib/copy_to_user.S101
-rw-r--r--arch/arm/lib/memcpy.S410
-rw-r--r--arch/arm/lib/memmove.S206
-rw-r--r--arch/arm/lib/uaccess.S170
-rw-r--r--arch/arm/mach-clps711x/Kconfig11
-rw-r--r--arch/arm/mach-clps711x/Makefile1
-rw-r--r--arch/arm/mach-clps711x/edb7211-mm.c8
-rw-r--r--arch/arm/mach-clps711x/mp1000-mach.c49
-rw-r--r--arch/arm/mach-clps711x/mp1000-mm.c47
-rw-r--r--arch/arm/mach-clps711x/mp1000-seprom.c195
-rw-r--r--arch/arm/mach-ebsa110/core.c26
-rw-r--r--arch/arm/mach-ixp2000/Makefile2
-rw-r--r--arch/arm/mach-ixp2000/core.c79
-rw-r--r--arch/arm/mach-ixp2000/enp2611.c31
-rw-r--r--arch/arm/mach-ixp2000/ixdp2x00.c4
-rw-r--r--arch/arm/mach-ixp2000/ixdp2x01.c9
-rw-r--r--arch/arm/mach-ixp2000/pci.c6
-rw-r--r--arch/arm/mach-ixp2000/uengine.c474
-rw-r--r--arch/arm/mach-pxa/lubbock.c143
-rw-r--r--arch/arm/mach-pxa/mainstone.c90
-rw-r--r--arch/arm/mach-realview/Kconfig11
-rw-r--r--arch/arm/mach-realview/Makefile6
-rw-r--r--arch/arm/mach-realview/Makefile.boot4
-rw-r--r--arch/arm/mach-realview/clock.c145
-rw-r--r--arch/arm/mach-realview/clock.h25
-rw-r--r--arch/arm/mach-realview/core.c605
-rw-r--r--arch/arm/mach-realview/core.h118
-rw-r--r--arch/arm/mach-realview/realview_eb.c172
-rw-r--r--arch/arm/mach-s3c2410/mach-rx3715.c70
-rw-r--r--arch/arm/mm/Kconfig18
-rw-r--r--arch/arm/mm/init.c9
-rw-r--r--arch/arm/mm/mm-armv.c8
-rw-r--r--arch/i386/pci/fixup.c2
-rw-r--r--arch/ia64/Kconfig4
-rw-r--r--arch/ia64/lib/Makefile2
-rw-r--r--arch/ia64/lib/swiotlb.c759
-rw-r--r--arch/m68knommu/defconfig3
-rw-r--r--arch/powerpc/kernel/entry_64.S2
-rw-r--r--arch/um/include/net_kern.h9
-rw-r--r--arch/x86_64/kernel/Makefile2
-rw-r--r--arch/x86_64/lib/bitops.c66
56 files changed, 3189 insertions, 1958 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 682367bd0f65..296bc03d1cf1 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -194,6 +194,13 @@ config ARCH_VERSATILE
194 help 194 help
195 This enables support for ARM Ltd Versatile board. 195 This enables support for ARM Ltd Versatile board.
196 196
197config ARCH_REALVIEW
198 bool "RealView"
199 select ARM_AMBA
200 select ICST307
201 help
202 This enables support for ARM Ltd RealView boards.
203
197config ARCH_IMX 204config ARCH_IMX
198 bool "IMX" 205 bool "IMX"
199 206
@@ -244,6 +251,8 @@ source "arch/arm/mach-versatile/Kconfig"
244 251
245source "arch/arm/mach-aaec2000/Kconfig" 252source "arch/arm/mach-aaec2000/Kconfig"
246 253
254source "arch/arm/mach-realview/Kconfig"
255
247# Definitions to make life easier 256# Definitions to make life easier
248config ARCH_ACORN 257config ARCH_ACORN
249 bool 258 bool
@@ -340,6 +349,13 @@ config NR_CPUS
340 depends on SMP 349 depends on SMP
341 default "4" 350 default "4"
342 351
352config HOTPLUG_CPU
353 bool "Support for hot-pluggable CPUs (EXPERIMENTAL)"
354 depends on SMP && HOTPLUG && EXPERIMENTAL
355 help
356 Say Y here to experiment with turning CPUs off and on. CPUs
357 can be controlled through /sys/devices/system/cpu.
358
343config PREEMPT 359config PREEMPT
344 bool "Preemptible Kernel (EXPERIMENTAL)" 360 bool "Preemptible Kernel (EXPERIMENTAL)"
345 depends on EXPERIMENTAL 361 depends on EXPERIMENTAL
@@ -688,8 +704,7 @@ source "drivers/acorn/block/Kconfig"
688 704
689if PCMCIA || ARCH_CLPS7500 || ARCH_IOP3XX || ARCH_IXP4XX \ 705if PCMCIA || ARCH_CLPS7500 || ARCH_IOP3XX || ARCH_IXP4XX \
690 || ARCH_L7200 || ARCH_LH7A40X || ARCH_PXA || ARCH_RPC \ 706 || ARCH_L7200 || ARCH_LH7A40X || ARCH_PXA || ARCH_RPC \
691 || ARCH_S3C2410 || ARCH_SA1100 || ARCH_SHARK || FOOTBRIDGE \ 707 || ARCH_S3C2410 || ARCH_SA1100 || ARCH_SHARK || FOOTBRIDGE
692 || MACH_MP1000
693source "drivers/ide/Kconfig" 708source "drivers/ide/Kconfig"
694endif 709endif
695 710
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 64cf480b0b02..114cda7f1b73 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -38,6 +38,7 @@ comma = ,
38# macro, but instead defines a whole series of macros which makes 38# macro, but instead defines a whole series of macros which makes
39# testing for a specific architecture or later rather impossible. 39# testing for a specific architecture or later rather impossible.
40arch-$(CONFIG_CPU_32v6) :=-D__LINUX_ARM_ARCH__=6 $(call cc-option,-march=armv6,-march=armv5t -Wa$(comma)-march=armv6) 40arch-$(CONFIG_CPU_32v6) :=-D__LINUX_ARM_ARCH__=6 $(call cc-option,-march=armv6,-march=armv5t -Wa$(comma)-march=armv6)
41arch-$(CONFIG_CPU_32v6K) :=-D__LINUX_ARM_ARCH__=6 $(call cc-option,-march=armv6k,-march=armv5t -Wa$(comma)-march=armv6k)
41arch-$(CONFIG_CPU_32v5) :=-D__LINUX_ARM_ARCH__=5 $(call cc-option,-march=armv5te,-march=armv4) 42arch-$(CONFIG_CPU_32v5) :=-D__LINUX_ARM_ARCH__=5 $(call cc-option,-march=armv5te,-march=armv4)
42arch-$(CONFIG_CPU_32v4) :=-D__LINUX_ARM_ARCH__=4 -march=armv4 43arch-$(CONFIG_CPU_32v4) :=-D__LINUX_ARM_ARCH__=4 -march=armv4
43arch-$(CONFIG_CPU_32v3) :=-D__LINUX_ARM_ARCH__=3 -march=armv3 44arch-$(CONFIG_CPU_32v3) :=-D__LINUX_ARM_ARCH__=3 -march=armv3
@@ -99,6 +100,7 @@ textaddr-$(CONFIG_ARCH_FORTUNET) := 0xc0008000
99 machine-$(CONFIG_ARCH_IMX) := imx 100 machine-$(CONFIG_ARCH_IMX) := imx
100 machine-$(CONFIG_ARCH_H720X) := h720x 101 machine-$(CONFIG_ARCH_H720X) := h720x
101 machine-$(CONFIG_ARCH_AAEC2000) := aaec2000 102 machine-$(CONFIG_ARCH_AAEC2000) := aaec2000
103 machine-$(CONFIG_ARCH_REALVIEW) := realview
102 104
103ifeq ($(CONFIG_ARCH_EBSA110),y) 105ifeq ($(CONFIG_ARCH_EBSA110),y)
104# This is what happens if you forget the IOCS16 line. 106# This is what happens if you forget the IOCS16 line.
@@ -142,7 +144,7 @@ drivers-$(CONFIG_OPROFILE) += arch/arm/oprofile/
142drivers-$(CONFIG_ARCH_CLPS7500) += drivers/acorn/char/ 144drivers-$(CONFIG_ARCH_CLPS7500) += drivers/acorn/char/
143drivers-$(CONFIG_ARCH_L7200) += drivers/acorn/char/ 145drivers-$(CONFIG_ARCH_L7200) += drivers/acorn/char/
144 146
145libs-y += arch/arm/lib/ 147libs-y := arch/arm/lib/ $(libs-y)
146 148
147# Default target when executing plain make 149# Default target when executing plain make
148ifeq ($(CONFIG_XIP_KERNEL),y) 150ifeq ($(CONFIG_XIP_KERNEL),y)
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index a54d2eb64892..7c7f475e213e 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -39,8 +39,7 @@
39 defined(CONFIG_ARCH_IXP4XX) || \ 39 defined(CONFIG_ARCH_IXP4XX) || \
40 defined(CONFIG_ARCH_IXP2000) || \ 40 defined(CONFIG_ARCH_IXP2000) || \
41 defined(CONFIG_ARCH_LH7A40X) || \ 41 defined(CONFIG_ARCH_LH7A40X) || \
42 defined(CONFIG_ARCH_OMAP) || \ 42 defined(CONFIG_ARCH_OMAP)
43 defined(CONFIG_MACH_MP1000)
44 .macro loadsp, rb 43 .macro loadsp, rb
45 addruart \rb 44 addruart \rb
46 .endm 45 .endm
diff --git a/arch/arm/configs/ixdp2401_defconfig b/arch/arm/configs/ixdp2401_defconfig
index 38c9a721d5c9..32bd552e0986 100644
--- a/arch/arm/configs/ixdp2401_defconfig
+++ b/arch/arm/configs/ixdp2401_defconfig
@@ -152,7 +152,7 @@ CONFIG_ALIGNMENT_TRAP=y
152# 152#
153CONFIG_ZBOOT_ROM_TEXT=0x0 153CONFIG_ZBOOT_ROM_TEXT=0x0
154CONFIG_ZBOOT_ROM_BSS=0x0 154CONFIG_ZBOOT_ROM_BSS=0x0
155CONFIG_CMDLINE="console=ttyS0,57600 root=/dev/nfs ip=bootp mem=64M@0x0 pci=firmware" 155CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs ip=bootp mem=64M@0x0 pci=firmware"
156# CONFIG_XIP_KERNEL is not set 156# CONFIG_XIP_KERNEL is not set
157 157
158# 158#
@@ -560,7 +560,7 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
560# 560#
561CONFIG_SERIAL_8250=y 561CONFIG_SERIAL_8250=y
562CONFIG_SERIAL_8250_CONSOLE=y 562CONFIG_SERIAL_8250_CONSOLE=y
563CONFIG_SERIAL_8250_NR_UARTS=2 563CONFIG_SERIAL_8250_NR_UARTS=3
564# CONFIG_SERIAL_8250_EXTENDED is not set 564# CONFIG_SERIAL_8250_EXTENDED is not set
565 565
566# 566#
diff --git a/arch/arm/configs/ixdp2801_defconfig b/arch/arm/configs/ixdp2801_defconfig
index 12ef23d1c016..66ac0885df3e 100644
--- a/arch/arm/configs/ixdp2801_defconfig
+++ b/arch/arm/configs/ixdp2801_defconfig
@@ -560,7 +560,7 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
560# 560#
561CONFIG_SERIAL_8250=y 561CONFIG_SERIAL_8250=y
562CONFIG_SERIAL_8250_CONSOLE=y 562CONFIG_SERIAL_8250_CONSOLE=y
563CONFIG_SERIAL_8250_NR_UARTS=2 563CONFIG_SERIAL_8250_NR_UARTS=3
564# CONFIG_SERIAL_8250_EXTENDED is not set 564# CONFIG_SERIAL_8250_EXTENDED is not set
565 565
566# 566#
diff --git a/arch/arm/configs/ixp4xx_defconfig b/arch/arm/configs/ixp4xx_defconfig
index c279e41ed10e..f74c926beb42 100644
--- a/arch/arm/configs/ixp4xx_defconfig
+++ b/arch/arm/configs/ixp4xx_defconfig
@@ -104,7 +104,7 @@ CONFIG_ARCH_IXCDP1100=y
104CONFIG_ARCH_PRPMC1100=y 104CONFIG_ARCH_PRPMC1100=y
105CONFIG_ARCH_IXDP4XX=y 105CONFIG_ARCH_IXDP4XX=y
106CONFIG_CPU_IXP46X=y 106CONFIG_CPU_IXP46X=y
107CONFIG_MACH_GTWX5715=y 107# CONFIG_MACH_GTWX5715 is not set
108 108
109# 109#
110# IXP4xx Options 110# IXP4xx Options
diff --git a/arch/arm/configs/mp1000_defconfig b/arch/arm/configs/realview_defconfig
index d2cbc6fada1d..0485b2f1cc20 100644
--- a/arch/arm/configs/mp1000_defconfig
+++ b/arch/arm/configs/realview_defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.14-rc1 3# Linux kernel version: 2.6.14-rc2
4# Fri Sep 16 15:48:13 2005 4# Thu Sep 29 14:50:10 2005
5# 5#
6CONFIG_ARM=y 6CONFIG_ARM=y
7CONFIG_MMU=y 7CONFIG_MMU=y
@@ -12,11 +12,9 @@ CONFIG_GENERIC_CALIBRATE_DELAY=y
12# 12#
13# Code maturity level options 13# Code maturity level options
14# 14#
15CONFIG_EXPERIMENTAL=y 15# CONFIG_EXPERIMENTAL is not set
16# CONFIG_CLEAN_COMPILE is not set 16CONFIG_CLEAN_COMPILE=y
17CONFIG_BROKEN=y
18CONFIG_BROKEN_ON_SMP=y 17CONFIG_BROKEN_ON_SMP=y
19CONFIG_LOCK_KERNEL=y
20CONFIG_INIT_ENV_ARG_LIMIT=32 18CONFIG_INIT_ENV_ARG_LIMIT=32
21 19
22# 20#
@@ -24,18 +22,16 @@ CONFIG_INIT_ENV_ARG_LIMIT=32
24# 22#
25CONFIG_LOCALVERSION="" 23CONFIG_LOCALVERSION=""
26CONFIG_LOCALVERSION_AUTO=y 24CONFIG_LOCALVERSION_AUTO=y
27CONFIG_SWAP=y 25# CONFIG_SWAP is not set
28CONFIG_SYSVIPC=y 26CONFIG_SYSVIPC=y
29# CONFIG_POSIX_MQUEUE is not set
30# CONFIG_BSD_PROCESS_ACCT is not set 27# CONFIG_BSD_PROCESS_ACCT is not set
31CONFIG_SYSCTL=y 28CONFIG_SYSCTL=y
32# CONFIG_AUDIT is not set 29# CONFIG_AUDIT is not set
33# CONFIG_HOTPLUG is not set 30CONFIG_HOTPLUG=y
34CONFIG_KOBJECT_UEVENT=y 31CONFIG_KOBJECT_UEVENT=y
35CONFIG_IKCONFIG=y 32# CONFIG_IKCONFIG is not set
36CONFIG_IKCONFIG_PROC=y
37CONFIG_INITRAMFS_SOURCE="" 33CONFIG_INITRAMFS_SOURCE=""
38CONFIG_EMBEDDED=y 34# CONFIG_EMBEDDED is not set
39CONFIG_KALLSYMS=y 35CONFIG_KALLSYMS=y
40# CONFIG_KALLSYMS_ALL is not set 36# CONFIG_KALLSYMS_ALL is not set
41# CONFIG_KALLSYMS_EXTRA_PASS is not set 37# CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -58,17 +54,15 @@ CONFIG_BASE_SMALL=0
58# 54#
59CONFIG_MODULES=y 55CONFIG_MODULES=y
60CONFIG_MODULE_UNLOAD=y 56CONFIG_MODULE_UNLOAD=y
61# CONFIG_MODULE_FORCE_UNLOAD is not set
62CONFIG_OBSOLETE_MODPARM=y 57CONFIG_OBSOLETE_MODPARM=y
63# CONFIG_MODVERSIONS is not set
64# CONFIG_MODULE_SRCVERSION_ALL is not set 58# CONFIG_MODULE_SRCVERSION_ALL is not set
65CONFIG_KMOD=y 59# CONFIG_KMOD is not set
66 60
67# 61#
68# System Type 62# System Type
69# 63#
70# CONFIG_ARCH_CLPS7500 is not set 64# CONFIG_ARCH_CLPS7500 is not set
71CONFIG_ARCH_CLPS711X=y 65# CONFIG_ARCH_CLPS711X is not set
72# CONFIG_ARCH_CO285 is not set 66# CONFIG_ARCH_CO285 is not set
73# CONFIG_ARCH_EBSA110 is not set 67# CONFIG_ARCH_EBSA110 is not set
74# CONFIG_ARCH_CAMELOT is not set 68# CONFIG_ARCH_CAMELOT is not set
@@ -86,43 +80,43 @@ CONFIG_ARCH_CLPS711X=y
86# CONFIG_ARCH_LH7A40X is not set 80# CONFIG_ARCH_LH7A40X is not set
87# CONFIG_ARCH_OMAP is not set 81# CONFIG_ARCH_OMAP is not set
88# CONFIG_ARCH_VERSATILE is not set 82# CONFIG_ARCH_VERSATILE is not set
83CONFIG_ARCH_REALVIEW=y
89# CONFIG_ARCH_IMX is not set 84# CONFIG_ARCH_IMX is not set
90# CONFIG_ARCH_H720X is not set 85# CONFIG_ARCH_H720X is not set
91# CONFIG_ARCH_AAEC2000 is not set 86# CONFIG_ARCH_AAEC2000 is not set
92 87
93# 88#
94# CLPS711X/EP721X Implementations 89# RealView platform type
95# 90#
96# CONFIG_ARCH_AUTCPU12 is not set 91CONFIG_MACH_REALVIEW_EB=y
97# CONFIG_ARCH_CDB89712 is not set
98# CONFIG_ARCH_CEIVA is not set
99# CONFIG_ARCH_CLEP7312 is not set
100# CONFIG_ARCH_EDB7211 is not set
101# CONFIG_ARCH_P720T is not set
102# CONFIG_ARCH_FORTUNET is not set
103CONFIG_MACH_MP1000=y
104CONFIG_MP1000_90MHZ=y
105 92
106# 93#
107# Processor Type 94# Processor Type
108# 95#
109CONFIG_CPU_32=y 96CONFIG_CPU_32=y
110CONFIG_CPU_ARM720T=y 97CONFIG_CPU_ARM926T=y
111CONFIG_CPU_32v4=y 98# CONFIG_CPU_V6 is not set
112CONFIG_CPU_ABRT_LV4T=y 99CONFIG_CPU_32v5=y
113CONFIG_CPU_CACHE_V4=y 100CONFIG_CPU_ABRT_EV5TJ=y
114CONFIG_CPU_CACHE_VIVT=y 101CONFIG_CPU_CACHE_VIVT=y
115CONFIG_CPU_COPY_V4WT=y 102CONFIG_CPU_COPY_V4WB=y
116CONFIG_CPU_TLB_V4WT=y 103CONFIG_CPU_TLB_V4WBI=y
117 104
118# 105#
119# Processor Features 106# Processor Features
120# 107#
121CONFIG_ARM_THUMB=y 108CONFIG_ARM_THUMB=y
109# CONFIG_CPU_ICACHE_DISABLE is not set
110# CONFIG_CPU_DCACHE_DISABLE is not set
111# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
112# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
113CONFIG_ARM_GIC=y
114CONFIG_ICST307=y
122 115
123# 116#
124# Bus support 117# Bus support
125# 118#
119CONFIG_ARM_AMBA=y
126CONFIG_ISA_DMA_API=y 120CONFIG_ISA_DMA_API=y
127 121
128# 122#
@@ -133,14 +127,8 @@ CONFIG_ISA_DMA_API=y
133# 127#
134# Kernel Features 128# Kernel Features
135# 129#
136# CONFIG_SMP is not set
137CONFIG_PREEMPT=y
138# CONFIG_NO_IDLE_HZ is not set 130# CONFIG_NO_IDLE_HZ is not set
139# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set 131# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
140CONFIG_SELECT_MEMORY_MODEL=y
141CONFIG_FLATMEM_MANUAL=y
142# CONFIG_DISCONTIGMEM_MANUAL is not set
143# CONFIG_SPARSEMEM_MANUAL is not set
144CONFIG_FLATMEM=y 132CONFIG_FLATMEM=y
145CONFIG_FLAT_NODE_MEM_MAP=y 133CONFIG_FLAT_NODE_MEM_MAP=y
146# CONFIG_SPARSEMEM_STATIC is not set 134# CONFIG_SPARSEMEM_STATIC is not set
@@ -151,7 +139,7 @@ CONFIG_ALIGNMENT_TRAP=y
151# 139#
152CONFIG_ZBOOT_ROM_TEXT=0x0 140CONFIG_ZBOOT_ROM_TEXT=0x0
153CONFIG_ZBOOT_ROM_BSS=0x0 141CONFIG_ZBOOT_ROM_BSS=0x0
154CONFIG_CMDLINE="console=ttyCL,38400 root=/dev/discs/disc0/part1 ip=any cs89x0_media=rj45" 142CONFIG_CMDLINE="root=/dev/nfs nfsroot=10.1.69.3:/work/nfsroot ip=dhcp console=ttyAMA0 mem=128M"
155# CONFIG_XIP_KERNEL is not set 143# CONFIG_XIP_KERNEL is not set
156 144
157# 145#
@@ -163,14 +151,14 @@ CONFIG_CMDLINE="console=ttyCL,38400 root=/dev/discs/disc0/part1 ip=any cs89x0_me
163# 151#
164CONFIG_FPE_NWFPE=y 152CONFIG_FPE_NWFPE=y
165# CONFIG_FPE_NWFPE_XP is not set 153# CONFIG_FPE_NWFPE_XP is not set
166# CONFIG_FPE_FASTFPE is not set 154# CONFIG_VFP is not set
167 155
168# 156#
169# Userspace binary formats 157# Userspace binary formats
170# 158#
171CONFIG_BINFMT_ELF=y 159CONFIG_BINFMT_ELF=y
172# CONFIG_BINFMT_AOUT is not set 160# CONFIG_BINFMT_AOUT is not set
173CONFIG_BINFMT_MISC=y 161# CONFIG_BINFMT_MISC is not set
174# CONFIG_ARTHUR is not set 162# CONFIG_ARTHUR is not set
175 163
176# 164#
@@ -197,10 +185,9 @@ CONFIG_IP_FIB_HASH=y
197CONFIG_IP_PNP=y 185CONFIG_IP_PNP=y
198CONFIG_IP_PNP_DHCP=y 186CONFIG_IP_PNP_DHCP=y
199CONFIG_IP_PNP_BOOTP=y 187CONFIG_IP_PNP_BOOTP=y
200CONFIG_IP_PNP_RARP=y 188# CONFIG_IP_PNP_RARP is not set
201# CONFIG_NET_IPIP is not set 189# CONFIG_NET_IPIP is not set
202# CONFIG_NET_IPGRE is not set 190# CONFIG_NET_IPGRE is not set
203# CONFIG_ARPD is not set
204# CONFIG_SYN_COOKIES is not set 191# CONFIG_SYN_COOKIES is not set
205# CONFIG_INET_AH is not set 192# CONFIG_INET_AH is not set
206# CONFIG_INET_ESP is not set 193# CONFIG_INET_ESP is not set
@@ -210,36 +197,14 @@ CONFIG_INET_DIAG=y
210CONFIG_INET_TCP_DIAG=y 197CONFIG_INET_TCP_DIAG=y
211# CONFIG_TCP_CONG_ADVANCED is not set 198# CONFIG_TCP_CONG_ADVANCED is not set
212CONFIG_TCP_CONG_BIC=y 199CONFIG_TCP_CONG_BIC=y
213CONFIG_IPV6=y 200# CONFIG_IPV6 is not set
214# CONFIG_IPV6_PRIVACY is not set
215# CONFIG_INET6_AH is not set
216# CONFIG_INET6_ESP is not set
217# CONFIG_INET6_IPCOMP is not set
218# CONFIG_INET6_TUNNEL is not set
219# CONFIG_IPV6_TUNNEL is not set
220# CONFIG_NETFILTER is not set 201# CONFIG_NETFILTER is not set
221
222#
223# DCCP Configuration (EXPERIMENTAL)
224#
225# CONFIG_IP_DCCP is not set
226
227#
228# SCTP Configuration (EXPERIMENTAL)
229#
230# CONFIG_IP_SCTP is not set
231# CONFIG_ATM is not set
232# CONFIG_BRIDGE is not set 202# CONFIG_BRIDGE is not set
233# CONFIG_VLAN_8021Q is not set 203# CONFIG_VLAN_8021Q is not set
234# CONFIG_DECNET is not set 204# CONFIG_DECNET is not set
235# CONFIG_LLC2 is not set 205# CONFIG_LLC2 is not set
236# CONFIG_IPX is not set 206# CONFIG_IPX is not set
237# CONFIG_ATALK is not set 207# CONFIG_ATALK is not set
238# CONFIG_X25 is not set
239# CONFIG_LAPB is not set
240# CONFIG_NET_DIVERT is not set
241# CONFIG_ECONET is not set
242# CONFIG_WAN_ROUTER is not set
243# CONFIG_NET_SCHED is not set 208# CONFIG_NET_SCHED is not set
244# CONFIG_NET_CLS_ROUTE is not set 209# CONFIG_NET_CLS_ROUTE is not set
245 210
@@ -247,7 +212,6 @@ CONFIG_IPV6=y
247# Network testing 212# Network testing
248# 213#
249# CONFIG_NET_PKTGEN is not set 214# CONFIG_NET_PKTGEN is not set
250# CONFIG_NETFILTER_NETLINK is not set
251# CONFIG_HAMRADIO is not set 215# CONFIG_HAMRADIO is not set
252# CONFIG_IRDA is not set 216# CONFIG_IRDA is not set
253# CONFIG_BT is not set 217# CONFIG_BT is not set
@@ -269,14 +233,10 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
269# Memory Technology Devices (MTD) 233# Memory Technology Devices (MTD)
270# 234#
271CONFIG_MTD=y 235CONFIG_MTD=y
272CONFIG_MTD_DEBUG=y 236# CONFIG_MTD_DEBUG is not set
273CONFIG_MTD_DEBUG_VERBOSE=3
274# CONFIG_MTD_CONCAT is not set 237# CONFIG_MTD_CONCAT is not set
275CONFIG_MTD_PARTITIONS=y 238CONFIG_MTD_PARTITIONS=y
276CONFIG_MTD_REDBOOT_PARTS=m 239# CONFIG_MTD_REDBOOT_PARTS is not set
277CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-2
278CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y
279# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set
280CONFIG_MTD_CMDLINE_PARTS=y 240CONFIG_MTD_CMDLINE_PARTS=y
281# CONFIG_MTD_AFS_PARTS is not set 241# CONFIG_MTD_AFS_PARTS is not set
282 242
@@ -292,45 +252,36 @@ CONFIG_MTD_BLOCK=y
292# 252#
293# RAM/ROM/Flash chip drivers 253# RAM/ROM/Flash chip drivers
294# 254#
295CONFIG_MTD_CFI=m 255CONFIG_MTD_CFI=y
296# CONFIG_MTD_JEDECPROBE is not set 256# CONFIG_MTD_JEDECPROBE is not set
297CONFIG_MTD_GEN_PROBE=m 257CONFIG_MTD_GEN_PROBE=y
298CONFIG_MTD_CFI_ADV_OPTIONS=y 258# CONFIG_MTD_CFI_ADV_OPTIONS is not set
299CONFIG_MTD_CFI_NOSWAP=y 259CONFIG_MTD_MAP_BANK_WIDTH_1=y
300# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set 260CONFIG_MTD_MAP_BANK_WIDTH_2=y
301# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
302CONFIG_MTD_CFI_GEOMETRY=y
303# CONFIG_MTD_MAP_BANK_WIDTH_1 is not set
304# CONFIG_MTD_MAP_BANK_WIDTH_2 is not set
305CONFIG_MTD_MAP_BANK_WIDTH_4=y 261CONFIG_MTD_MAP_BANK_WIDTH_4=y
306# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set 262# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
307# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set 263# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
308# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set 264# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
309# CONFIG_MTD_CFI_I1 is not set 265CONFIG_MTD_CFI_I1=y
310CONFIG_MTD_CFI_I2=y 266CONFIG_MTD_CFI_I2=y
311# CONFIG_MTD_CFI_I4 is not set 267# CONFIG_MTD_CFI_I4 is not set
312# CONFIG_MTD_CFI_I8 is not set 268# CONFIG_MTD_CFI_I8 is not set
313# CONFIG_MTD_OTP is not set 269CONFIG_MTD_CFI_INTELEXT=y
314CONFIG_MTD_CFI_INTELEXT=m 270CONFIG_MTD_CFI_AMDSTD=y
315# CONFIG_MTD_CFI_AMDSTD is not set 271CONFIG_MTD_CFI_AMDSTD_RETRY=0
316# CONFIG_MTD_CFI_STAA is not set 272# CONFIG_MTD_CFI_STAA is not set
317CONFIG_MTD_CFI_UTIL=m 273CONFIG_MTD_CFI_UTIL=y
318# CONFIG_MTD_RAM is not set 274# CONFIG_MTD_RAM is not set
319# CONFIG_MTD_ROM is not set 275# CONFIG_MTD_ROM is not set
320# CONFIG_MTD_ABSENT is not set 276# CONFIG_MTD_ABSENT is not set
321# CONFIG_MTD_OBSOLETE_CHIPS is not set
322# CONFIG_MTD_XIP is not set
323 277
324# 278#
325# Mapping drivers for chip access 279# Mapping drivers for chip access
326# 280#
327# CONFIG_MTD_COMPLEX_MAPPINGS is not set 281# CONFIG_MTD_COMPLEX_MAPPINGS is not set
328CONFIG_MTD_PHYSMAP=m 282# CONFIG_MTD_PHYSMAP is not set
329CONFIG_MTD_PHYSMAP_START=0x0000000 283CONFIG_MTD_ARM_INTEGRATOR=y
330CONFIG_MTD_PHYSMAP_LEN=0x4000000 284# CONFIG_MTD_EDB7312 is not set
331CONFIG_MTD_PHYSMAP_BANKWIDTH=2
332# CONFIG_MTD_ARM_INTEGRATOR is not set
333CONFIG_MTD_EDB7312=m
334# CONFIG_MTD_PLATRAM is not set 285# CONFIG_MTD_PLATRAM is not set
335 286
336# 287#
@@ -340,7 +291,6 @@ CONFIG_MTD_EDB7312=m
340# CONFIG_MTD_PHRAM is not set 291# CONFIG_MTD_PHRAM is not set
341# CONFIG_MTD_MTDRAM is not set 292# CONFIG_MTD_MTDRAM is not set
342# CONFIG_MTD_BLKMTD is not set 293# CONFIG_MTD_BLKMTD is not set
343# CONFIG_MTD_BLOCK2MTD is not set
344 294
345# 295#
346# Disk-On-Chip Device Drivers 296# Disk-On-Chip Device Drivers
@@ -352,12 +302,7 @@ CONFIG_MTD_EDB7312=m
352# 302#
353# NAND Flash Device Drivers 303# NAND Flash Device Drivers
354# 304#
355CONFIG_MTD_NAND=y 305# CONFIG_MTD_NAND is not set
356# CONFIG_MTD_NAND_VERIFY_WRITE is not set
357CONFIG_MTD_NAND_MP1000=y
358CONFIG_MTD_NAND_IDS=y
359# CONFIG_MTD_NAND_DISKONCHIP is not set
360# CONFIG_MTD_NAND_NANDSIM is not set
361 306
362# 307#
363# Parallel port support 308# Parallel port support
@@ -372,53 +317,22 @@ CONFIG_MTD_NAND_IDS=y
372# Block devices 317# Block devices
373# 318#
374# CONFIG_BLK_DEV_COW_COMMON is not set 319# CONFIG_BLK_DEV_COW_COMMON is not set
375CONFIG_BLK_DEV_LOOP=m 320# CONFIG_BLK_DEV_LOOP is not set
376# CONFIG_BLK_DEV_CRYPTOLOOP is not set
377# CONFIG_BLK_DEV_NBD is not set 321# CONFIG_BLK_DEV_NBD is not set
378CONFIG_BLK_DEV_RAM=y 322# CONFIG_BLK_DEV_RAM is not set
379CONFIG_BLK_DEV_RAM_COUNT=2 323CONFIG_BLK_DEV_RAM_COUNT=16
380CONFIG_BLK_DEV_RAM_SIZE=16384
381CONFIG_BLK_DEV_INITRD=y
382# CONFIG_CDROM_PKTCDVD is not set 324# CONFIG_CDROM_PKTCDVD is not set
383 325
384# 326#
385# IO Schedulers 327# IO Schedulers
386# 328#
387CONFIG_IOSCHED_NOOP=y 329CONFIG_IOSCHED_NOOP=y
388CONFIG_IOSCHED_AS=y 330# CONFIG_IOSCHED_AS is not set
389CONFIG_IOSCHED_DEADLINE=y 331CONFIG_IOSCHED_DEADLINE=y
390CONFIG_IOSCHED_CFQ=y 332# CONFIG_IOSCHED_CFQ is not set
391# CONFIG_ATA_OVER_ETH is not set 333# CONFIG_ATA_OVER_ETH is not set
392 334
393# 335#
394# ATA/ATAPI/MFM/RLL support
395#
396CONFIG_IDE=y
397CONFIG_BLK_DEV_IDE=y
398
399#
400# Please see Documentation/ide.txt for help/info on IDE drives
401#
402# CONFIG_BLK_DEV_IDE_SATA is not set
403# CONFIG_BLK_DEV_HD_IDE is not set
404CONFIG_BLK_DEV_IDEDISK=y
405# CONFIG_IDEDISK_MULTI_MODE is not set
406# CONFIG_BLK_DEV_IDECD is not set
407# CONFIG_BLK_DEV_IDETAPE is not set
408# CONFIG_BLK_DEV_IDEFLOPPY is not set
409# CONFIG_IDE_TASK_IOCTL is not set
410
411#
412# IDE chipset support/bugfixes
413#
414# CONFIG_IDE_GENERIC is not set
415CONFIG_IDE_ARM=y
416CONFIG_BLK_DEV_IDE_MP1000=y
417# CONFIG_BLK_DEV_IDEDMA is not set
418# CONFIG_IDEDMA_AUTO is not set
419# CONFIG_BLK_DEV_HD is not set
420
421#
422# SCSI device support 336# SCSI device support
423# 337#
424# CONFIG_RAID_ATTRS is not set 338# CONFIG_RAID_ATTRS is not set
@@ -427,14 +341,7 @@ CONFIG_BLK_DEV_IDE_MP1000=y
427# 341#
428# Multi-device support (RAID and LVM) 342# Multi-device support (RAID and LVM)
429# 343#
430CONFIG_MD=y 344# CONFIG_MD is not set
431# CONFIG_BLK_DEV_MD is not set
432CONFIG_BLK_DEV_DM=y
433# CONFIG_DM_CRYPT is not set
434# CONFIG_DM_SNAPSHOT is not set
435# CONFIG_DM_MIRROR is not set
436# CONFIG_DM_ZERO is not set
437# CONFIG_DM_MULTIPATH is not set
438 345
439# 346#
440# Fusion MPT device support 347# Fusion MPT device support
@@ -444,7 +351,6 @@ CONFIG_BLK_DEV_DM=y
444# 351#
445# IEEE 1394 (FireWire) support 352# IEEE 1394 (FireWire) support
446# 353#
447# CONFIG_IEEE1394 is not set
448 354
449# 355#
450# I2O device support 356# I2O device support
@@ -468,10 +374,9 @@ CONFIG_NETDEVICES=y
468# Ethernet (10 or 100Mbit) 374# Ethernet (10 or 100Mbit)
469# 375#
470CONFIG_NET_ETHERNET=y 376CONFIG_NET_ETHERNET=y
471# CONFIG_MII is not set 377CONFIG_MII=y
472# CONFIG_SMC91X is not set 378CONFIG_SMC91X=y
473# CONFIG_DM9000 is not set 379# CONFIG_DM9000 is not set
474CONFIG_CS89x0=y
475 380
476# 381#
477# Ethernet (1000 Mbit) 382# Ethernet (1000 Mbit)
@@ -496,8 +401,6 @@ CONFIG_CS89x0=y
496# CONFIG_WAN is not set 401# CONFIG_WAN is not set
497# CONFIG_PPP is not set 402# CONFIG_PPP is not set
498# CONFIG_SLIP is not set 403# CONFIG_SLIP is not set
499# CONFIG_SHAPER is not set
500# CONFIG_NETCONSOLE is not set
501# CONFIG_NETPOLL is not set 404# CONFIG_NETPOLL is not set
502# CONFIG_NET_POLL_CONTROLLER is not set 405# CONFIG_NET_POLL_CONTROLLER is not set
503 406
@@ -514,17 +417,28 @@ CONFIG_INPUT=y
514# 417#
515# Userland interfaces 418# Userland interfaces
516# 419#
517# CONFIG_INPUT_MOUSEDEV is not set 420CONFIG_INPUT_MOUSEDEV=y
421CONFIG_INPUT_MOUSEDEV_PSAUX=y
422CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
423CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
518# CONFIG_INPUT_JOYDEV is not set 424# CONFIG_INPUT_JOYDEV is not set
519# CONFIG_INPUT_TSDEV is not set 425# CONFIG_INPUT_TSDEV is not set
520# CONFIG_INPUT_EVDEV is not set 426# CONFIG_INPUT_EVDEV is not set
521CONFIG_INPUT_EVBUG=y 427# CONFIG_INPUT_EVBUG is not set
522 428
523# 429#
524# Input Device Drivers 430# Input Device Drivers
525# 431#
526# CONFIG_INPUT_KEYBOARD is not set 432CONFIG_INPUT_KEYBOARD=y
527# CONFIG_INPUT_MOUSE is not set 433CONFIG_KEYBOARD_ATKBD=y
434# CONFIG_KEYBOARD_SUNKBD is not set
435# CONFIG_KEYBOARD_LKKBD is not set
436# CONFIG_KEYBOARD_XTKBD is not set
437# CONFIG_KEYBOARD_NEWTON is not set
438CONFIG_INPUT_MOUSE=y
439CONFIG_MOUSE_PS2=y
440# CONFIG_MOUSE_SERIAL is not set
441# CONFIG_MOUSE_VSXXXAA is not set
528# CONFIG_INPUT_JOYSTICK is not set 442# CONFIG_INPUT_JOYSTICK is not set
529# CONFIG_INPUT_TOUCHSCREEN is not set 443# CONFIG_INPUT_TOUCHSCREEN is not set
530# CONFIG_INPUT_MISC is not set 444# CONFIG_INPUT_MISC is not set
@@ -533,8 +447,9 @@ CONFIG_INPUT_EVBUG=y
533# Hardware I/O ports 447# Hardware I/O ports
534# 448#
535CONFIG_SERIO=y 449CONFIG_SERIO=y
536CONFIG_SERIO_SERPORT=y 450# CONFIG_SERIO_SERPORT is not set
537# CONFIG_SERIO_LIBPS2 is not set 451CONFIG_SERIO_AMBAKMI=y
452CONFIG_SERIO_LIBPS2=y
538# CONFIG_SERIO_RAW is not set 453# CONFIG_SERIO_RAW is not set
539# CONFIG_GAMEPORT is not set 454# CONFIG_GAMEPORT is not set
540 455
@@ -549,21 +464,19 @@ CONFIG_HW_CONSOLE=y
549# 464#
550# Serial drivers 465# Serial drivers
551# 466#
552CONFIG_SERIAL_8250=y 467# CONFIG_SERIAL_8250 is not set
553CONFIG_SERIAL_8250_CONSOLE=y
554CONFIG_SERIAL_8250_NR_UARTS=2
555# CONFIG_SERIAL_8250_EXTENDED is not set
556 468
557# 469#
558# Non-8250 serial port support 470# Non-8250 serial port support
559# 471#
560CONFIG_SERIAL_CLPS711X=y 472# CONFIG_SERIAL_AMBA_PL010 is not set
561CONFIG_SERIAL_CLPS711X_CONSOLE=y 473CONFIG_SERIAL_AMBA_PL011=y
474CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
562CONFIG_SERIAL_CORE=y 475CONFIG_SERIAL_CORE=y
563CONFIG_SERIAL_CORE_CONSOLE=y 476CONFIG_SERIAL_CORE_CONSOLE=y
564CONFIG_UNIX98_PTYS=y 477CONFIG_UNIX98_PTYS=y
565CONFIG_LEGACY_PTYS=y 478CONFIG_LEGACY_PTYS=y
566CONFIG_LEGACY_PTY_COUNT=256 479CONFIG_LEGACY_PTY_COUNT=16
567 480
568# 481#
569# IPMI 482# IPMI
@@ -574,8 +487,8 @@ CONFIG_LEGACY_PTY_COUNT=256
574# Watchdog Cards 487# Watchdog Cards
575# 488#
576# CONFIG_WATCHDOG is not set 489# CONFIG_WATCHDOG is not set
577CONFIG_NVRAM=y 490# CONFIG_NVRAM is not set
578CONFIG_RTC=y 491# CONFIG_RTC is not set
579# CONFIG_DTLK is not set 492# CONFIG_DTLK is not set
580# CONFIG_R3964 is not set 493# CONFIG_R3964 is not set
581 494
@@ -596,9 +509,8 @@ CONFIG_RTC=y
596# 509#
597# Hardware Monitoring support 510# Hardware Monitoring support
598# 511#
599CONFIG_HWMON=y 512# CONFIG_HWMON is not set
600# CONFIG_HWMON_VID is not set 513# CONFIG_HWMON_VID is not set
601# CONFIG_HWMON_DEBUG_CHIP is not set
602 514
603# 515#
604# Misc devices 516# Misc devices
@@ -621,18 +533,72 @@ CONFIG_HWMON=y
621# 533#
622# Graphics support 534# Graphics support
623# 535#
624# CONFIG_FB is not set 536CONFIG_FB=y
537CONFIG_FB_CFB_FILLRECT=y
538CONFIG_FB_CFB_COPYAREA=y
539CONFIG_FB_CFB_IMAGEBLIT=y
540CONFIG_FB_SOFT_CURSOR=y
541# CONFIG_FB_MACMODES is not set
542# CONFIG_FB_MODE_HELPERS is not set
543# CONFIG_FB_TILEBLITTING is not set
544CONFIG_FB_ARMCLCD=y
545# CONFIG_FB_S1D13XXX is not set
546# CONFIG_FB_VIRTUAL is not set
625 547
626# 548#
627# Console display driver support 549# Console display driver support
628# 550#
629# CONFIG_VGA_CONSOLE is not set 551# CONFIG_VGA_CONSOLE is not set
630CONFIG_DUMMY_CONSOLE=y 552CONFIG_DUMMY_CONSOLE=y
553CONFIG_FRAMEBUFFER_CONSOLE=y
554# CONFIG_FONTS is not set
555CONFIG_FONT_8x8=y
556CONFIG_FONT_8x16=y
557
558#
559# Logo configuration
560#
561CONFIG_LOGO=y
562# CONFIG_LOGO_LINUX_MONO is not set
563# CONFIG_LOGO_LINUX_VGA16 is not set
564CONFIG_LOGO_LINUX_CLUT224=y
565# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
631 566
632# 567#
633# Sound 568# Sound
634# 569#
635# CONFIG_SOUND is not set 570CONFIG_SOUND=y
571
572#
573# Advanced Linux Sound Architecture
574#
575CONFIG_SND=y
576CONFIG_SND_TIMER=y
577CONFIG_SND_PCM=y
578# CONFIG_SND_SEQUENCER is not set
579CONFIG_SND_OSSEMUL=y
580CONFIG_SND_MIXER_OSS=y
581CONFIG_SND_PCM_OSS=y
582# CONFIG_SND_VERBOSE_PRINTK is not set
583# CONFIG_SND_DEBUG is not set
584
585#
586# Generic devices
587#
588# CONFIG_SND_DUMMY is not set
589# CONFIG_SND_MTPAV is not set
590# CONFIG_SND_SERIAL_U16550 is not set
591# CONFIG_SND_MPU401 is not set
592
593#
594# ALSA ARM devices
595#
596# CONFIG_SND_ARMAACI is not set
597
598#
599# Open Sound System
600#
601# CONFIG_SOUND_PRIME is not set
636 602
637# 603#
638# USB support 604# USB support
@@ -654,32 +620,17 @@ CONFIG_USB_ARCH_HAS_HCD=y
654# 620#
655# File systems 621# File systems
656# 622#
657CONFIG_EXT2_FS=y 623# CONFIG_EXT2_FS is not set
658CONFIG_EXT2_FS_XATTR=y 624# CONFIG_EXT3_FS is not set
659# CONFIG_EXT2_FS_POSIX_ACL is not set 625# CONFIG_JBD is not set
660# CONFIG_EXT2_FS_SECURITY is not set 626# CONFIG_REISERFS_FS is not set
661# CONFIG_EXT2_FS_XIP is not set
662CONFIG_EXT3_FS=y
663CONFIG_EXT3_FS_XATTR=y
664# CONFIG_EXT3_FS_POSIX_ACL is not set
665# CONFIG_EXT3_FS_SECURITY is not set
666CONFIG_JBD=y
667# CONFIG_JBD_DEBUG is not set
668CONFIG_FS_MBCACHE=y
669CONFIG_REISERFS_FS=m
670# CONFIG_REISERFS_CHECK is not set
671# CONFIG_REISERFS_PROC_INFO is not set
672# CONFIG_REISERFS_FS_XATTR is not set
673# CONFIG_JFS_FS is not set 627# CONFIG_JFS_FS is not set
674CONFIG_FS_POSIX_ACL=y 628# CONFIG_FS_POSIX_ACL is not set
675# CONFIG_XFS_FS is not set 629# CONFIG_XFS_FS is not set
676# CONFIG_MINIX_FS is not set 630# CONFIG_MINIX_FS is not set
677# CONFIG_ROMFS_FS is not set 631# CONFIG_ROMFS_FS is not set
678CONFIG_INOTIFY=y 632CONFIG_INOTIFY=y
679CONFIG_QUOTA=y 633# CONFIG_QUOTA is not set
680# CONFIG_QFMT_V1 is not set
681# CONFIG_QFMT_V2 is not set
682CONFIG_QUOTACTL=y
683CONFIG_DNOTIFY=y 634CONFIG_DNOTIFY=y
684# CONFIG_AUTOFS_FS is not set 635# CONFIG_AUTOFS_FS is not set
685# CONFIG_AUTOFS4_FS is not set 636# CONFIG_AUTOFS4_FS is not set
@@ -694,8 +645,11 @@ CONFIG_DNOTIFY=y
694# 645#
695# DOS/FAT/NT Filesystems 646# DOS/FAT/NT Filesystems
696# 647#
648CONFIG_FAT_FS=y
697# CONFIG_MSDOS_FS is not set 649# CONFIG_MSDOS_FS is not set
698# CONFIG_VFAT_FS is not set 650CONFIG_VFAT_FS=y
651CONFIG_FAT_DEFAULT_CODEPAGE=437
652CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
699# CONFIG_NTFS_FS is not set 653# CONFIG_NTFS_FS is not set
700 654
701# 655#
@@ -704,7 +658,6 @@ CONFIG_DNOTIFY=y
704CONFIG_PROC_FS=y 658CONFIG_PROC_FS=y
705CONFIG_SYSFS=y 659CONFIG_SYSFS=y
706CONFIG_TMPFS=y 660CONFIG_TMPFS=y
707# CONFIG_HUGETLBFS is not set
708# CONFIG_HUGETLB_PAGE is not set 661# CONFIG_HUGETLB_PAGE is not set
709CONFIG_RAMFS=y 662CONFIG_RAMFS=y
710# CONFIG_RELAYFS_FS is not set 663# CONFIG_RELAYFS_FS is not set
@@ -712,22 +665,10 @@ CONFIG_RAMFS=y
712# 665#
713# Miscellaneous filesystems 666# Miscellaneous filesystems
714# 667#
715# CONFIG_ADFS_FS is not set
716# CONFIG_AFFS_FS is not set
717# CONFIG_HFS_FS is not set
718# CONFIG_HFSPLUS_FS is not set 668# CONFIG_HFSPLUS_FS is not set
719# CONFIG_BEFS_FS is not set
720# CONFIG_BFS_FS is not set
721# CONFIG_EFS_FS is not set
722# CONFIG_JFFS_FS is not set 669# CONFIG_JFFS_FS is not set
723CONFIG_JFFS2_FS=m 670# CONFIG_JFFS2_FS is not set
724CONFIG_JFFS2_FS_DEBUG=0 671CONFIG_CRAMFS=y
725CONFIG_JFFS2_FS_WRITEBUFFER=y
726# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
727CONFIG_JFFS2_ZLIB=y
728CONFIG_JFFS2_RTIME=y
729# CONFIG_JFFS2_RUBIN is not set
730CONFIG_CRAMFS=m
731# CONFIG_VXFS_FS is not set 672# CONFIG_VXFS_FS is not set
732# CONFIG_HPFS_FS is not set 673# CONFIG_HPFS_FS is not set
733# CONFIG_QNX4FS_FS is not set 674# CONFIG_QNX4FS_FS is not set
@@ -740,32 +681,16 @@ CONFIG_CRAMFS=m
740CONFIG_NFS_FS=y 681CONFIG_NFS_FS=y
741CONFIG_NFS_V3=y 682CONFIG_NFS_V3=y
742# CONFIG_NFS_V3_ACL is not set 683# CONFIG_NFS_V3_ACL is not set
743CONFIG_NFS_V4=y 684# CONFIG_NFSD is not set
744# CONFIG_NFS_DIRECTIO is not set
745CONFIG_NFSD=y
746CONFIG_NFSD_V3=y
747# CONFIG_NFSD_V3_ACL is not set
748CONFIG_NFSD_V4=y
749CONFIG_NFSD_TCP=y
750CONFIG_ROOT_NFS=y 685CONFIG_ROOT_NFS=y
751CONFIG_LOCKD=y 686CONFIG_LOCKD=y
752CONFIG_LOCKD_V4=y 687CONFIG_LOCKD_V4=y
753CONFIG_EXPORTFS=y
754CONFIG_NFS_COMMON=y 688CONFIG_NFS_COMMON=y
755CONFIG_SUNRPC=y 689CONFIG_SUNRPC=y
756CONFIG_SUNRPC_GSS=y 690# CONFIG_SMB_FS is not set
757CONFIG_RPCSEC_GSS_KRB5=y 691# CONFIG_CIFS is not set
758# CONFIG_RPCSEC_GSS_SPKM3 is not set
759CONFIG_SMB_FS=m
760# CONFIG_SMB_NLS_DEFAULT is not set
761CONFIG_CIFS=m
762# CONFIG_CIFS_STATS is not set
763# CONFIG_CIFS_XATTR is not set
764# CONFIG_CIFS_EXPERIMENTAL is not set
765# CONFIG_NCP_FS is not set 692# CONFIG_NCP_FS is not set
766# CONFIG_CODA_FS is not set 693# CONFIG_CODA_FS is not set
767# CONFIG_AFS_FS is not set
768# CONFIG_9P_FS is not set
769 694
770# 695#
771# Partition Types 696# Partition Types
@@ -802,7 +727,7 @@ CONFIG_NLS_CODEPAGE_437=y
802# CONFIG_NLS_CODEPAGE_1250 is not set 727# CONFIG_NLS_CODEPAGE_1250 is not set
803# CONFIG_NLS_CODEPAGE_1251 is not set 728# CONFIG_NLS_CODEPAGE_1251 is not set
804# CONFIG_NLS_ASCII is not set 729# CONFIG_NLS_ASCII is not set
805# CONFIG_NLS_ISO8859_1 is not set 730CONFIG_NLS_ISO8859_1=y
806# CONFIG_NLS_ISO8859_2 is not set 731# CONFIG_NLS_ISO8859_2 is not set
807# CONFIG_NLS_ISO8859_3 is not set 732# CONFIG_NLS_ISO8859_3 is not set
808# CONFIG_NLS_ISO8859_4 is not set 733# CONFIG_NLS_ISO8859_4 is not set
@@ -818,34 +743,26 @@ CONFIG_NLS_CODEPAGE_437=y
818# CONFIG_NLS_UTF8 is not set 743# CONFIG_NLS_UTF8 is not set
819 744
820# 745#
821# Profiling support
822#
823# CONFIG_PROFILING is not set
824
825#
826# Kernel hacking 746# Kernel hacking
827# 747#
828CONFIG_PRINTK_TIME=y 748# CONFIG_PRINTK_TIME is not set
829CONFIG_DEBUG_KERNEL=y 749CONFIG_DEBUG_KERNEL=y
830# CONFIG_MAGIC_SYSRQ is not set 750CONFIG_MAGIC_SYSRQ=y
831CONFIG_LOG_BUF_SHIFT=14 751CONFIG_LOG_BUF_SHIFT=14
832CONFIG_DETECT_SOFTLOCKUP=y 752CONFIG_DETECT_SOFTLOCKUP=y
833# CONFIG_SCHEDSTATS is not set 753# CONFIG_SCHEDSTATS is not set
834# CONFIG_DEBUG_SLAB is not set 754# CONFIG_DEBUG_SLAB is not set
835CONFIG_DEBUG_PREEMPT=y
836# CONFIG_DEBUG_SPINLOCK is not set 755# CONFIG_DEBUG_SPINLOCK is not set
837# CONFIG_DEBUG_SPINLOCK_SLEEP is not set 756# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
838# CONFIG_DEBUG_KOBJECT is not set 757# CONFIG_DEBUG_KOBJECT is not set
839# CONFIG_DEBUG_BUGVERBOSE is not set 758CONFIG_DEBUG_BUGVERBOSE=y
840CONFIG_DEBUG_INFO=y 759# CONFIG_DEBUG_INFO is not set
841# CONFIG_DEBUG_FS is not set 760# CONFIG_DEBUG_FS is not set
842CONFIG_FRAME_POINTER=y 761CONFIG_FRAME_POINTER=y
843CONFIG_DEBUG_USER=y 762CONFIG_DEBUG_USER=y
844CONFIG_DEBUG_WAITQ=y 763# CONFIG_DEBUG_WAITQ is not set
845CONFIG_DEBUG_ERRORS=y 764CONFIG_DEBUG_ERRORS=y
846CONFIG_DEBUG_LL=y 765# CONFIG_DEBUG_LL is not set
847# CONFIG_DEBUG_ICEDCC is not set
848# CONFIG_DEBUG_CLPS711X_UART2 is not set
849 766
850# 767#
851# Security options 768# Security options
@@ -856,31 +773,7 @@ CONFIG_DEBUG_LL=y
856# 773#
857# Cryptographic options 774# Cryptographic options
858# 775#
859CONFIG_CRYPTO=y 776# CONFIG_CRYPTO is not set
860# CONFIG_CRYPTO_HMAC is not set
861# CONFIG_CRYPTO_NULL is not set
862# CONFIG_CRYPTO_MD4 is not set
863CONFIG_CRYPTO_MD5=y
864# CONFIG_CRYPTO_SHA1 is not set
865# CONFIG_CRYPTO_SHA256 is not set
866# CONFIG_CRYPTO_SHA512 is not set
867# CONFIG_CRYPTO_WP512 is not set
868# CONFIG_CRYPTO_TGR192 is not set
869CONFIG_CRYPTO_DES=y
870# CONFIG_CRYPTO_BLOWFISH is not set
871# CONFIG_CRYPTO_TWOFISH is not set
872# CONFIG_CRYPTO_SERPENT is not set
873# CONFIG_CRYPTO_AES is not set
874# CONFIG_CRYPTO_CAST5 is not set
875# CONFIG_CRYPTO_CAST6 is not set
876# CONFIG_CRYPTO_TEA is not set
877# CONFIG_CRYPTO_ARC4 is not set
878# CONFIG_CRYPTO_KHAZAD is not set
879# CONFIG_CRYPTO_ANUBIS is not set
880# CONFIG_CRYPTO_DEFLATE is not set
881# CONFIG_CRYPTO_MICHAEL_MIC is not set
882# CONFIG_CRYPTO_CRC32C is not set
883# CONFIG_CRYPTO_TEST is not set
884 777
885# 778#
886# Hardware crypto devices 779# Hardware crypto devices
@@ -893,5 +786,4 @@ CONFIG_CRYPTO_DES=y
893# CONFIG_CRC16 is not set 786# CONFIG_CRC16 is not set
894CONFIG_CRC32=y 787CONFIG_CRC32=y
895# CONFIG_LIBCRC32C is not set 788# CONFIG_LIBCRC32C is not set
896CONFIG_ZLIB_INFLATE=m 789CONFIG_ZLIB_INFLATE=y
897CONFIG_ZLIB_DEFLATE=m
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index 3284118f356b..9def4404e1f2 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -1050,3 +1050,34 @@ static int __init noirqdebug_setup(char *str)
1050} 1050}
1051 1051
1052__setup("noirqdebug", noirqdebug_setup); 1052__setup("noirqdebug", noirqdebug_setup);
1053
1054#ifdef CONFIG_HOTPLUG_CPU
1055/*
1056 * The CPU has been marked offline. Migrate IRQs off this CPU. If
1057 * the affinity settings do not allow other CPUs, force them onto any
1058 * available CPU.
1059 */
1060void migrate_irqs(void)
1061{
1062 unsigned int i, cpu = smp_processor_id();
1063
1064 for (i = 0; i < NR_IRQS; i++) {
1065 struct irqdesc *desc = irq_desc + i;
1066
1067 if (desc->cpu == cpu) {
1068 unsigned int newcpu = any_online_cpu(desc->affinity);
1069
1070 if (newcpu == NR_CPUS) {
1071 if (printk_ratelimit())
1072 printk(KERN_INFO "IRQ%u no longer affine to CPU%u\n",
1073 i, cpu);
1074
1075 cpus_setall(desc->affinity);
1076 newcpu = any_online_cpu(desc->affinity);
1077 }
1078
1079 route_irq(desc, i, newcpu);
1080 }
1081 }
1082}
1083#endif /* CONFIG_HOTPLUG_CPU */
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 409db6d5ec99..ba298277becd 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -26,6 +26,7 @@
26#include <linux/interrupt.h> 26#include <linux/interrupt.h>
27#include <linux/kallsyms.h> 27#include <linux/kallsyms.h>
28#include <linux/init.h> 28#include <linux/init.h>
29#include <linux/cpu.h>
29 30
30#include <asm/system.h> 31#include <asm/system.h>
31#include <asm/io.h> 32#include <asm/io.h>
@@ -105,6 +106,14 @@ void cpu_idle(void)
105 /* endless idle loop with no priority at all */ 106 /* endless idle loop with no priority at all */
106 while (1) { 107 while (1) {
107 void (*idle)(void) = pm_idle; 108 void (*idle)(void) = pm_idle;
109
110#ifdef CONFIG_HOTPLUG_CPU
111 if (cpu_is_offline(smp_processor_id())) {
112 leds_event(led_idle_start);
113 cpu_die();
114 }
115#endif
116
108 if (!idle) 117 if (!idle)
109 idle = default_idle; 118 idle = default_idle;
110 preempt_disable(); 119 preempt_disable();
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 826164945747..edb5a406922f 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -80,19 +80,23 @@ static DEFINE_SPINLOCK(smp_call_function_lock);
80 80
81int __cpuinit __cpu_up(unsigned int cpu) 81int __cpuinit __cpu_up(unsigned int cpu)
82{ 82{
83 struct task_struct *idle; 83 struct cpuinfo_arm *ci = &per_cpu(cpu_data, cpu);
84 struct task_struct *idle = ci->idle;
84 pgd_t *pgd; 85 pgd_t *pgd;
85 pmd_t *pmd; 86 pmd_t *pmd;
86 int ret; 87 int ret;
87 88
88 /* 89 /*
89 * Spawn a new process manually. Grab a pointer to 90 * Spawn a new process manually, if not already done.
90 * its task struct so we can mess with it 91 * Grab a pointer to its task struct so we can mess with it
91 */ 92 */
92 idle = fork_idle(cpu); 93 if (!idle) {
93 if (IS_ERR(idle)) { 94 idle = fork_idle(cpu);
94 printk(KERN_ERR "CPU%u: fork() failed\n", cpu); 95 if (IS_ERR(idle)) {
95 return PTR_ERR(idle); 96 printk(KERN_ERR "CPU%u: fork() failed\n", cpu);
97 return PTR_ERR(idle);
98 }
99 ci->idle = idle;
96 } 100 }
97 101
98 /* 102 /*
@@ -155,6 +159,91 @@ int __cpuinit __cpu_up(unsigned int cpu)
155 return ret; 159 return ret;
156} 160}
157 161
162#ifdef CONFIG_HOTPLUG_CPU
163/*
164 * __cpu_disable runs on the processor to be shutdown.
165 */
166int __cpuexit __cpu_disable(void)
167{
168 unsigned int cpu = smp_processor_id();
169 struct task_struct *p;
170 int ret;
171
172 ret = mach_cpu_disable(cpu);
173 if (ret)
174 return ret;
175
176 /*
177 * Take this CPU offline. Once we clear this, we can't return,
178 * and we must not schedule until we're ready to give up the cpu.
179 */
180 cpu_clear(cpu, cpu_online_map);
181
182 /*
183 * OK - migrate IRQs away from this CPU
184 */
185 migrate_irqs();
186
187 /*
188 * Flush user cache and TLB mappings, and then remove this CPU
189 * from the vm mask set of all processes.
190 */
191 flush_cache_all();
192 local_flush_tlb_all();
193
194 read_lock(&tasklist_lock);
195 for_each_process(p) {
196 if (p->mm)
197 cpu_clear(cpu, p->mm->cpu_vm_mask);
198 }
199 read_unlock(&tasklist_lock);
200
201 return 0;
202}
203
204/*
205 * called on the thread which is asking for a CPU to be shutdown -
206 * waits until shutdown has completed, or it is timed out.
207 */
208void __cpuexit __cpu_die(unsigned int cpu)
209{
210 if (!platform_cpu_kill(cpu))
211 printk("CPU%u: unable to kill\n", cpu);
212}
213
214/*
215 * Called from the idle thread for the CPU which has been shutdown.
216 *
217 * Note that we disable IRQs here, but do not re-enable them
218 * before returning to the caller. This is also the behaviour
219 * of the other hotplug-cpu capable cores, so presumably coming
220 * out of idle fixes this.
221 */
222void __cpuexit cpu_die(void)
223{
224 unsigned int cpu = smp_processor_id();
225
226 local_irq_disable();
227 idle_task_exit();
228
229 /*
230 * actual CPU shutdown procedure is at least platform (if not
231 * CPU) specific
232 */
233 platform_cpu_die(cpu);
234
235 /*
236 * Do not return to the idle loop - jump back to the secondary
237 * cpu initialisation. There's some initialisation which needs
238 * to be repeated to undo the effects of taking the CPU offline.
239 */
240 __asm__("mov sp, %0\n"
241 " b secondary_start_kernel"
242 :
243 : "r" ((void *)current->thread_info + THREAD_SIZE - 8));
244}
245#endif /* CONFIG_HOTPLUG_CPU */
246
158/* 247/*
159 * This is the secondary CPU boot entry. We're using this CPUs 248 * This is the secondary CPU boot entry. We're using this CPUs
160 * idle thread stack, but a set of temporary page tables. 249 * idle thread stack, but a set of temporary page tables.
@@ -236,6 +325,8 @@ void __init smp_prepare_boot_cpu(void)
236{ 325{
237 unsigned int cpu = smp_processor_id(); 326 unsigned int cpu = smp_processor_id();
238 327
328 per_cpu(cpu_data, cpu).idle = current;
329
239 cpu_set(cpu, cpu_possible_map); 330 cpu_set(cpu, cpu_possible_map);
240 cpu_set(cpu, cpu_present_map); 331 cpu_set(cpu, cpu_present_map);
241 cpu_set(cpu, cpu_online_map); 332 cpu_set(cpu, cpu_online_map);
@@ -309,8 +400,8 @@ int smp_call_function_on_cpu(void (*func)(void *info), void *info, int retry,
309 printk(KERN_CRIT 400 printk(KERN_CRIT
310 "CPU%u: smp_call_function timeout for %p(%p)\n" 401 "CPU%u: smp_call_function timeout for %p(%p)\n"
311 " callmap %lx pending %lx, %swait\n", 402 " callmap %lx pending %lx, %swait\n",
312 smp_processor_id(), func, info, callmap, data.pending, 403 smp_processor_id(), func, info, *cpus_addr(callmap),
313 wait ? "" : "no "); 404 *cpus_addr(data.pending), wait ? "" : "no ");
314 405
315 /* 406 /*
316 * TRACE 407 * TRACE
diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile
index 71e5b99e519e..391f3ab3ff32 100644
--- a/arch/arm/lib/Makefile
+++ b/arch/arm/lib/Makefile
@@ -7,13 +7,27 @@
7lib-y := backtrace.o changebit.o csumipv6.o csumpartial.o \ 7lib-y := backtrace.o changebit.o csumipv6.o csumpartial.o \
8 csumpartialcopy.o csumpartialcopyuser.o clearbit.o \ 8 csumpartialcopy.o csumpartialcopyuser.o clearbit.o \
9 copy_page.o delay.o findbit.o memchr.o memcpy.o \ 9 copy_page.o delay.o findbit.o memchr.o memcpy.o \
10 memset.o memzero.o setbit.o strncpy_from_user.o \ 10 memmove.o memset.o memzero.o setbit.o \
11 strnlen_user.o strchr.o strrchr.o testchangebit.o \ 11 strncpy_from_user.o strnlen_user.o \
12 testclearbit.o testsetbit.o uaccess.o getuser.o \ 12 strchr.o strrchr.o \
13 putuser.o ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \ 13 testchangebit.o testclearbit.o testsetbit.o \
14 getuser.o putuser.o clear_user.o \
15 ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \
14 ucmpdi2.o lib1funcs.o div64.o sha1.o \ 16 ucmpdi2.o lib1funcs.o div64.o sha1.o \
15 io-readsb.o io-writesb.o io-readsl.o io-writesl.o 17 io-readsb.o io-writesb.o io-readsl.o io-writesl.o
16 18
19# the code in uaccess.S is not preemption safe and
20# probably faster on ARMv3 only
21ifeq ($CONFIG_PREEMPT,y)
22 lib-y += copy_from_user.o copy_to_user.o
23else
24ifneq ($(CONFIG_CPU_32v3),y)
25 lib-y += copy_from_user.o copy_to_user.o
26else
27 lib-y += uaccess.o
28endif
29endif
30
17ifeq ($(CONFIG_CPU_32v3),y) 31ifeq ($(CONFIG_CPU_32v3),y)
18 lib-y += io-readsw-armv3.o io-writesw-armv3.o 32 lib-y += io-readsw-armv3.o io-writesw-armv3.o
19else 33else
diff --git a/arch/arm/lib/bitops.h b/arch/arm/lib/bitops.h
index 64a988c1ad44..f35d91fbe117 100644
--- a/arch/arm/lib/bitops.h
+++ b/arch/arm/lib/bitops.h
@@ -1,6 +1,6 @@
1#include <linux/config.h> 1#include <linux/config.h>
2 2
3#if __LINUX_ARM_ARCH__ >= 6 && defined(CONFIG_CPU_MPCORE) 3#if __LINUX_ARM_ARCH__ >= 6 && defined(CONFIG_CPU_32v6K)
4 .macro bitop, instr 4 .macro bitop, instr
5 mov r2, #1 5 mov r2, #1
6 and r3, r0, #7 @ Get bit offset 6 and r3, r0, #7 @ Get bit offset
diff --git a/arch/arm/lib/clear_user.S b/arch/arm/lib/clear_user.S
new file mode 100644
index 000000000000..7ff9f831b3f9
--- /dev/null
+++ b/arch/arm/lib/clear_user.S
@@ -0,0 +1,52 @@
1/*
2 * linux/arch/arm/lib/clear_user.S
3 *
4 * Copyright (C) 1995, 1996,1997,1998 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#include <linux/linkage.h>
11#include <asm/assembler.h>
12
13 .text
14
15/* Prototype: int __arch_clear_user(void *addr, size_t sz)
16 * Purpose : clear some user memory
17 * Params : addr - user memory address to clear
18 * : sz - number of bytes to clear
19 * Returns : number of bytes NOT cleared
20 */
21ENTRY(__arch_clear_user)
22 stmfd sp!, {r1, lr}
23 mov r2, #0
24 cmp r1, #4
25 blt 2f
26 ands ip, r0, #3
27 beq 1f
28 cmp ip, #2
29USER( strbt r2, [r0], #1)
30USER( strlebt r2, [r0], #1)
31USER( strltbt r2, [r0], #1)
32 rsb ip, ip, #4
33 sub r1, r1, ip @ 7 6 5 4 3 2 1
341: subs r1, r1, #8 @ -1 -2 -3 -4 -5 -6 -7
35USER( strplt r2, [r0], #4)
36USER( strplt r2, [r0], #4)
37 bpl 1b
38 adds r1, r1, #4 @ 3 2 1 0 -1 -2 -3
39USER( strplt r2, [r0], #4)
402: tst r1, #2 @ 1x 1x 0x 0x 1x 1x 0x
41USER( strnebt r2, [r0], #1)
42USER( strnebt r2, [r0], #1)
43 tst r1, #1 @ x1 x0 x1 x0 x1 x0 x1
44USER( strnebt r2, [r0], #1)
45 mov r0, #0
46 LOADREGS(fd,sp!, {r1, pc})
47
48 .section .fixup,"ax"
49 .align 0
509001: LOADREGS(fd,sp!, {r0, pc})
51 .previous
52
diff --git a/arch/arm/lib/copy_from_user.S b/arch/arm/lib/copy_from_user.S
new file mode 100644
index 000000000000..7497393a0e81
--- /dev/null
+++ b/arch/arm/lib/copy_from_user.S
@@ -0,0 +1,101 @@
1/*
2 * linux/arch/arm/lib/copy_from_user.S
3 *
4 * Author: Nicolas Pitre
5 * Created: Sep 29, 2005
6 * Copyright: MontaVista Software, Inc.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/linkage.h>
14#include <asm/assembler.h>
15
16/*
17 * Prototype:
18 *
19 * size_t __arch_copy_from_user(void *to, const void *from, size_t n)
20 *
21 * Purpose:
22 *
23 * copy a block to kernel memory from user memory
24 *
25 * Params:
26 *
27 * to = kernel memory
28 * from = user memory
29 * n = number of bytes to copy
30 *
31 * Return value:
32 *
33 * Number of bytes NOT copied.
34 */
35
36 .macro ldr1w ptr reg abort
37100: ldrt \reg, [\ptr], #4
38 .section __ex_table, "a"
39 .long 100b, \abort
40 .previous
41 .endm
42
43 .macro ldr4w ptr reg1 reg2 reg3 reg4 abort
44 ldr1w \ptr, \reg1, \abort
45 ldr1w \ptr, \reg2, \abort
46 ldr1w \ptr, \reg3, \abort
47 ldr1w \ptr, \reg4, \abort
48 .endm
49
50 .macro ldr8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
51 ldr4w \ptr, \reg1, \reg2, \reg3, \reg4, \abort
52 ldr4w \ptr, \reg5, \reg6, \reg7, \reg8, \abort
53 .endm
54
55 .macro ldr1b ptr reg cond=al abort
56100: ldr\cond\()bt \reg, [\ptr], #1
57 .section __ex_table, "a"
58 .long 100b, \abort
59 .previous
60 .endm
61
62 .macro str1w ptr reg abort
63 str \reg, [\ptr], #4
64 .endm
65
66 .macro str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
67 stmia \ptr!, {\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8}
68 .endm
69
70 .macro str1b ptr reg cond=al abort
71 str\cond\()b \reg, [\ptr], #1
72 .endm
73
74 .macro enter reg1 reg2
75 mov r3, #0
76 stmdb sp!, {r0, r2, r3, \reg1, \reg2}
77 .endm
78
79 .macro exit reg1 reg2
80 add sp, sp, #8
81 ldmfd sp!, {r0, \reg1, \reg2}
82 .endm
83
84 .text
85
86ENTRY(__arch_copy_from_user)
87
88#include "copy_template.S"
89
90 .section .fixup,"ax"
91 .align 0
92 copy_abort_preamble
93 ldmfd sp!, {r1, r2}
94 sub r3, r0, r1
95 rsb r1, r3, r2
96 str r1, [sp]
97 bl __memzero
98 ldr r0, [sp], #4
99 copy_abort_end
100 .previous
101
diff --git a/arch/arm/lib/copy_template.S b/arch/arm/lib/copy_template.S
new file mode 100644
index 000000000000..838e435e4922
--- /dev/null
+++ b/arch/arm/lib/copy_template.S
@@ -0,0 +1,255 @@
1/*
2 * linux/arch/arm/lib/copy_template.s
3 *
4 * Code template for optimized memory copy functions
5 *
6 * Author: Nicolas Pitre
7 * Created: Sep 28, 2005
8 * Copyright: MontaVista Software, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15/*
16 * This can be used to enable code to cacheline align the source pointer.
17 * Experiments on tested architectures (StrongARM and XScale) didn't show
18 * this a worthwhile thing to do. That might be different in the future.
19 */
20//#define CALGN(code...) code
21#define CALGN(code...)
22
23/*
24 * Theory of operation
25 * -------------------
26 *
27 * This file provides the core code for a forward memory copy used in
28 * the implementation of memcopy(), copy_to_user() and copy_from_user().
29 *
30 * The including file must define the following accessor macros
31 * according to the need of the given function:
32 *
33 * ldr1w ptr reg abort
34 *
35 * This loads one word from 'ptr', stores it in 'reg' and increments
36 * 'ptr' to the next word. The 'abort' argument is used for fixup tables.
37 *
38 * ldr4w ptr reg1 reg2 reg3 reg4 abort
39 * ldr8w ptr, reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
40 *
41 * This loads four or eight words starting from 'ptr', stores them
42 * in provided registers and increments 'ptr' past those words.
43 * The'abort' argument is used for fixup tables.
44 *
45 * ldr1b ptr reg cond abort
46 *
47 * Similar to ldr1w, but it loads a byte and increments 'ptr' one byte.
48 * It also must apply the condition code if provided, otherwise the
49 * "al" condition is assumed by default.
50 *
51 * str1w ptr reg abort
52 * str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
53 * str1b ptr reg cond abort
54 *
55 * Same as their ldr* counterparts, but data is stored to 'ptr' location
56 * rather than being loaded.
57 *
58 * enter reg1 reg2
59 *
60 * Preserve the provided registers on the stack plus any additional
61 * data as needed by the implementation including this code. Called
62 * upon code entry.
63 *
64 * exit reg1 reg2
65 *
66 * Restore registers with the values previously saved with the
67 * 'preserv' macro. Called upon code termination.
68 */
69
70
71 enter r4, lr
72
73 subs r2, r2, #4
74 blt 8f
75 ands ip, r0, #3
76 PLD( pld [r1, #0] )
77 bne 9f
78 ands ip, r1, #3
79 bne 10f
80
811: subs r2, r2, #(28)
82 stmfd sp!, {r5 - r8}
83 blt 5f
84
85 CALGN( ands ip, r1, #31 )
86 CALGN( rsb r3, ip, #32 )
87 CALGN( sbcnes r4, r3, r2 ) @ C is always set here
88 CALGN( bcs 2f )
89 CALGN( adr r4, 6f )
90 CALGN( subs r2, r2, r3 ) @ C gets set
91 CALGN( add pc, r4, ip )
92
93 PLD( pld [r1, #0] )
942: PLD( subs r2, r2, #96 )
95 PLD( pld [r1, #28] )
96 PLD( blt 4f )
97 PLD( pld [r1, #60] )
98 PLD( pld [r1, #92] )
99
1003: PLD( pld [r1, #124] )
1014: ldr8w r1, r3, r4, r5, r6, r7, r8, ip, lr, abort=20f
102 subs r2, r2, #32
103 str8w r0, r3, r4, r5, r6, r7, r8, ip, lr, abort=20f
104 bge 3b
105 PLD( cmn r2, #96 )
106 PLD( bge 4b )
107
1085: ands ip, r2, #28
109 rsb ip, ip, #32
110 addne pc, pc, ip @ C is always clear here
111 b 7f
1126: nop
113 ldr1w r1, r3, abort=20f
114 ldr1w r1, r4, abort=20f
115 ldr1w r1, r5, abort=20f
116 ldr1w r1, r6, abort=20f
117 ldr1w r1, r7, abort=20f
118 ldr1w r1, r8, abort=20f
119 ldr1w r1, lr, abort=20f
120
121 add pc, pc, ip
122 nop
123 nop
124 str1w r0, r3, abort=20f
125 str1w r0, r4, abort=20f
126 str1w r0, r5, abort=20f
127 str1w r0, r6, abort=20f
128 str1w r0, r7, abort=20f
129 str1w r0, r8, abort=20f
130 str1w r0, lr, abort=20f
131
132 CALGN( bcs 2b )
133
1347: ldmfd sp!, {r5 - r8}
135
1368: movs r2, r2, lsl #31
137 ldr1b r1, r3, ne, abort=21f
138 ldr1b r1, r4, cs, abort=21f
139 ldr1b r1, ip, cs, abort=21f
140 str1b r0, r3, ne, abort=21f
141 str1b r0, r4, cs, abort=21f
142 str1b r0, ip, cs, abort=21f
143
144 exit r4, pc
145
1469: rsb ip, ip, #4
147 cmp ip, #2
148 ldr1b r1, r3, gt, abort=21f
149 ldr1b r1, r4, ge, abort=21f
150 ldr1b r1, lr, abort=21f
151 str1b r0, r3, gt, abort=21f
152 str1b r0, r4, ge, abort=21f
153 subs r2, r2, ip
154 str1b r0, lr, abort=21f
155 blt 8b
156 ands ip, r1, #3
157 beq 1b
158
15910: bic r1, r1, #3
160 cmp ip, #2
161 ldr1w r1, lr, abort=21f
162 beq 17f
163 bgt 18f
164
165
166 .macro forward_copy_shift pull push
167
168 subs r2, r2, #28
169 blt 14f
170
171 CALGN( ands ip, r1, #31 )
172 CALGN( rsb ip, ip, #32 )
173 CALGN( sbcnes r4, ip, r2 ) @ C is always set here
174 CALGN( subcc r2, r2, ip )
175 CALGN( bcc 15f )
176
17711: stmfd sp!, {r5 - r9}
178
179 PLD( pld [r1, #0] )
180 PLD( subs r2, r2, #96 )
181 PLD( pld [r1, #28] )
182 PLD( blt 13f )
183 PLD( pld [r1, #60] )
184 PLD( pld [r1, #92] )
185
18612: PLD( pld [r1, #124] )
18713: ldr4w r1, r4, r5, r6, r7, abort=19f
188 mov r3, lr, pull #\pull
189 subs r2, r2, #32
190 ldr4w r1, r8, r9, ip, lr, abort=19f
191 orr r3, r3, r4, push #\push
192 mov r4, r4, pull #\pull
193 orr r4, r4, r5, push #\push
194 mov r5, r5, pull #\pull
195 orr r5, r5, r6, push #\push
196 mov r6, r6, pull #\pull
197 orr r6, r6, r7, push #\push
198 mov r7, r7, pull #\pull
199 orr r7, r7, r8, push #\push
200 mov r8, r8, pull #\pull
201 orr r8, r8, r9, push #\push
202 mov r9, r9, pull #\pull
203 orr r9, r9, ip, push #\push
204 mov ip, ip, pull #\pull
205 orr ip, ip, lr, push #\push
206 str8w r0, r3, r4, r5, r6, r7, r8, r9, ip, , abort=19f
207 bge 12b
208 PLD( cmn r2, #96 )
209 PLD( bge 13b )
210
211 ldmfd sp!, {r5 - r9}
212
21314: ands ip, r2, #28
214 beq 16f
215
21615: mov r3, lr, pull #\pull
217 ldr1w r1, lr, abort=21f
218 subs ip, ip, #4
219 orr r3, r3, lr, push #\push
220 str1w r0, r3, abort=21f
221 bgt 15b
222 CALGN( cmp r2, #0 )
223 CALGN( bge 11b )
224
22516: sub r1, r1, #(\push / 8)
226 b 8b
227
228 .endm
229
230
231 forward_copy_shift pull=8 push=24
232
23317: forward_copy_shift pull=16 push=16
234
23518: forward_copy_shift pull=24 push=8
236
237
238/*
239 * Abort preanble and completion macros.
240 * If a fixup handler is required then those macros must surround it.
241 * It is assumed that the fixup code will handle the private part of
242 * the exit macro.
243 */
244
245 .macro copy_abort_preamble
24619: ldmfd sp!, {r5 - r9}
247 b 21f
24820: ldmfd sp!, {r5 - r8}
24921:
250 .endm
251
252 .macro copy_abort_end
253 ldmfd sp!, {r4, pc}
254 .endm
255
diff --git a/arch/arm/lib/copy_to_user.S b/arch/arm/lib/copy_to_user.S
new file mode 100644
index 000000000000..4a6d8ea14022
--- /dev/null
+++ b/arch/arm/lib/copy_to_user.S
@@ -0,0 +1,101 @@
1/*
2 * linux/arch/arm/lib/copy_to_user.S
3 *
4 * Author: Nicolas Pitre
5 * Created: Sep 29, 2005
6 * Copyright: MontaVista Software, Inc.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/linkage.h>
14#include <asm/assembler.h>
15
16/*
17 * Prototype:
18 *
19 * size_t __arch_copy_to_user(void *to, const void *from, size_t n)
20 *
21 * Purpose:
22 *
23 * copy a block to user memory from kernel memory
24 *
25 * Params:
26 *
27 * to = user memory
28 * from = kernel memory
29 * n = number of bytes to copy
30 *
31 * Return value:
32 *
33 * Number of bytes NOT copied.
34 */
35
36 .macro ldr1w ptr reg abort
37 ldr \reg, [\ptr], #4
38 .endm
39
40 .macro ldr4w ptr reg1 reg2 reg3 reg4 abort
41 ldmia \ptr!, {\reg1, \reg2, \reg3, \reg4}
42 .endm
43
44 .macro ldr8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
45 ldmia \ptr!, {\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8}
46 .endm
47
48 .macro ldr1b ptr reg cond=al abort
49 ldr\cond\()b \reg, [\ptr], #1
50 .endm
51
52 .macro str1w ptr reg abort
53100: strt \reg, [\ptr], #4
54 .section __ex_table, "a"
55 .long 100b, \abort
56 .previous
57 .endm
58
59 .macro str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
60 str1w \ptr, \reg1, \abort
61 str1w \ptr, \reg2, \abort
62 str1w \ptr, \reg3, \abort
63 str1w \ptr, \reg4, \abort
64 str1w \ptr, \reg5, \abort
65 str1w \ptr, \reg6, \abort
66 str1w \ptr, \reg7, \abort
67 str1w \ptr, \reg8, \abort
68 .endm
69
70 .macro str1b ptr reg cond=al abort
71100: str\cond\()bt \reg, [\ptr], #1
72 .section __ex_table, "a"
73 .long 100b, \abort
74 .previous
75 .endm
76
77 .macro enter reg1 reg2
78 mov r3, #0
79 stmdb sp!, {r0, r2, r3, \reg1, \reg2}
80 .endm
81
82 .macro exit reg1 reg2
83 add sp, sp, #8
84 ldmfd sp!, {r0, \reg1, \reg2}
85 .endm
86
87 .text
88
89ENTRY(__arch_copy_to_user)
90
91#include "copy_template.S"
92
93 .section .fixup,"ax"
94 .align 0
95 copy_abort_preamble
96 ldmfd sp!, {r1, r2, r3}
97 sub r0, r0, r1
98 rsb r0, r0, r2
99 copy_abort_end
100 .previous
101
diff --git a/arch/arm/lib/memcpy.S b/arch/arm/lib/memcpy.S
index f5a593ceb8cc..7e71d6708a8d 100644
--- a/arch/arm/lib/memcpy.S
+++ b/arch/arm/lib/memcpy.S
@@ -1,393 +1,59 @@
1/* 1/*
2 * linux/arch/arm/lib/memcpy.S 2 * linux/arch/arm/lib/memcpy.S
3 * 3 *
4 * Copyright (C) 1995-1999 Russell King 4 * Author: Nicolas Pitre
5 * Created: Sep 28, 2005
6 * Copyright: MontaVista Software, Inc.
5 * 7 *
6 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as 9 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation. 10 * published by the Free Software Foundation.
9 *
10 * ASM optimised string functions
11 */ 11 */
12
12#include <linux/linkage.h> 13#include <linux/linkage.h>
13#include <asm/assembler.h> 14#include <asm/assembler.h>
14 15
15 .text 16 .macro ldr1w ptr reg abort
16 17 ldr \reg, [\ptr], #4
17#define ENTER \ 18 .endm
18 mov ip,sp ;\
19 stmfd sp!,{r0,r4-r9,fp,ip,lr,pc} ;\
20 sub fp,ip,#4
21
22#define EXIT \
23 LOADREGS(ea, fp, {r0, r4 - r9, fp, sp, pc})
24
25#define EXITEQ \
26 LOADREGS(eqea, fp, {r0, r4 - r9, fp, sp, pc})
27
28/*
29 * Prototype: void memcpy(void *to,const void *from,unsigned long n);
30 */
31ENTRY(memcpy)
32ENTRY(memmove)
33 ENTER
34 cmp r1, r0
35 bcc 23f
36 subs r2, r2, #4
37 blt 6f
38 PLD( pld [r1, #0] )
39 ands ip, r0, #3
40 bne 7f
41 ands ip, r1, #3
42 bne 8f
43 19
441: subs r2, r2, #8 20 .macro ldr4w ptr reg1 reg2 reg3 reg4 abort
45 blt 5f 21 ldmia \ptr!, {\reg1, \reg2, \reg3, \reg4}
46 subs r2, r2, #20 22 .endm
47 blt 4f
48 PLD( pld [r1, #28] )
49 PLD( subs r2, r2, #64 )
50 PLD( blt 3f )
512: PLD( pld [r1, #60] )
52 PLD( pld [r1, #92] )
53 ldmia r1!, {r3 - r9, ip}
54 subs r2, r2, #32
55 stmgeia r0!, {r3 - r9, ip}
56 ldmgeia r1!, {r3 - r9, ip}
57 subges r2, r2, #32
58 stmia r0!, {r3 - r9, ip}
59 bge 2b
603: PLD( ldmia r1!, {r3 - r9, ip} )
61 PLD( adds r2, r2, #32 )
62 PLD( stmgeia r0!, {r3 - r9, ip} )
63 PLD( ldmgeia r1!, {r3 - r9, ip} )
64 PLD( subges r2, r2, #32 )
65 PLD( stmia r0!, {r3 - r9, ip} )
664: cmn r2, #16
67 ldmgeia r1!, {r3 - r6}
68 subge r2, r2, #16
69 stmgeia r0!, {r3 - r6}
70 adds r2, r2, #20
71 ldmgeia r1!, {r3 - r5}
72 subge r2, r2, #12
73 stmgeia r0!, {r3 - r5}
745: adds r2, r2, #8
75 blt 6f
76 subs r2, r2, #4
77 ldrlt r3, [r1], #4
78 ldmgeia r1!, {r4, r5}
79 subge r2, r2, #4
80 strlt r3, [r0], #4
81 stmgeia r0!, {r4, r5}
82 23
836: adds r2, r2, #4 24 .macro ldr8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
84 EXITEQ 25 ldmia \ptr!, {\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8}
85 cmp r2, #2 26 .endm
86 ldrb r3, [r1], #1
87 ldrgeb r4, [r1], #1
88 ldrgtb r5, [r1], #1
89 strb r3, [r0], #1
90 strgeb r4, [r0], #1
91 strgtb r5, [r0], #1
92 EXIT
93 27
947: rsb ip, ip, #4 28 .macro ldr1b ptr reg cond=al abort
95 cmp ip, #2 29 ldr\cond\()b \reg, [\ptr], #1
96 ldrb r3, [r1], #1 30 .endm
97 ldrgeb r4, [r1], #1
98 ldrgtb r5, [r1], #1
99 strb r3, [r0], #1
100 strgeb r4, [r0], #1
101 strgtb r5, [r0], #1
102 subs r2, r2, ip
103 blt 6b
104 ands ip, r1, #3
105 beq 1b
106 31
1078: bic r1, r1, #3 32 .macro str1w ptr reg abort
108 ldr r7, [r1], #4 33 str \reg, [\ptr], #4
109 cmp ip, #2 34 .endm
110 bgt 18f
111 beq 13f
112 cmp r2, #12
113 blt 11f
114 PLD( pld [r1, #12] )
115 sub r2, r2, #12
116 PLD( subs r2, r2, #32 )
117 PLD( blt 10f )
118 PLD( pld [r1, #28] )
1199: PLD( pld [r1, #44] )
12010: mov r3, r7, pull #8
121 ldmia r1!, {r4 - r7}
122 subs r2, r2, #16
123 orr r3, r3, r4, push #24
124 mov r4, r4, pull #8
125 orr r4, r4, r5, push #24
126 mov r5, r5, pull #8
127 orr r5, r5, r6, push #24
128 mov r6, r6, pull #8
129 orr r6, r6, r7, push #24
130 stmia r0!, {r3 - r6}
131 bge 9b
132 PLD( cmn r2, #32 )
133 PLD( bge 10b )
134 PLD( add r2, r2, #32 )
135 adds r2, r2, #12
136 blt 12f
13711: mov r3, r7, pull #8
138 ldr r7, [r1], #4
139 subs r2, r2, #4
140 orr r3, r3, r7, push #24
141 str r3, [r0], #4
142 bge 11b
14312: sub r1, r1, #3
144 b 6b
145 35
14613: cmp r2, #12 36 .macro str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
147 blt 16f 37 stmia \ptr!, {\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8}
148 PLD( pld [r1, #12] ) 38 .endm
149 sub r2, r2, #12
150 PLD( subs r2, r2, #32 )
151 PLD( blt 15f )
152 PLD( pld [r1, #28] )
15314: PLD( pld [r1, #44] )
15415: mov r3, r7, pull #16
155 ldmia r1!, {r4 - r7}
156 subs r2, r2, #16
157 orr r3, r3, r4, push #16
158 mov r4, r4, pull #16
159 orr r4, r4, r5, push #16
160 mov r5, r5, pull #16
161 orr r5, r5, r6, push #16
162 mov r6, r6, pull #16
163 orr r6, r6, r7, push #16
164 stmia r0!, {r3 - r6}
165 bge 14b
166 PLD( cmn r2, #32 )
167 PLD( bge 15b )
168 PLD( add r2, r2, #32 )
169 adds r2, r2, #12
170 blt 17f
17116: mov r3, r7, pull #16
172 ldr r7, [r1], #4
173 subs r2, r2, #4
174 orr r3, r3, r7, push #16
175 str r3, [r0], #4
176 bge 16b
17717: sub r1, r1, #2
178 b 6b
179 39
18018: cmp r2, #12 40 .macro str1b ptr reg cond=al abort
181 blt 21f 41 str\cond\()b \reg, [\ptr], #1
182 PLD( pld [r1, #12] ) 42 .endm
183 sub r2, r2, #12
184 PLD( subs r2, r2, #32 )
185 PLD( blt 20f )
186 PLD( pld [r1, #28] )
18719: PLD( pld [r1, #44] )
18820: mov r3, r7, pull #24
189 ldmia r1!, {r4 - r7}
190 subs r2, r2, #16
191 orr r3, r3, r4, push #8
192 mov r4, r4, pull #24
193 orr r4, r4, r5, push #8
194 mov r5, r5, pull #24
195 orr r5, r5, r6, push #8
196 mov r6, r6, pull #24
197 orr r6, r6, r7, push #8
198 stmia r0!, {r3 - r6}
199 bge 19b
200 PLD( cmn r2, #32 )
201 PLD( bge 20b )
202 PLD( add r2, r2, #32 )
203 adds r2, r2, #12
204 blt 22f
20521: mov r3, r7, pull #24
206 ldr r7, [r1], #4
207 subs r2, r2, #4
208 orr r3, r3, r7, push #8
209 str r3, [r0], #4
210 bge 21b
21122: sub r1, r1, #1
212 b 6b
213 43
44 .macro enter reg1 reg2
45 stmdb sp!, {r0, \reg1, \reg2}
46 .endm
214 47
21523: add r1, r1, r2 48 .macro exit reg1 reg2
216 add r0, r0, r2 49 ldmfd sp!, {r0, \reg1, \reg2}
217 subs r2, r2, #4 50 .endm
218 blt 29f
219 PLD( pld [r1, #-4] )
220 ands ip, r0, #3
221 bne 30f
222 ands ip, r1, #3
223 bne 31f
224 51
22524: subs r2, r2, #8 52 .text
226 blt 28f
227 subs r2, r2, #20
228 blt 27f
229 PLD( pld [r1, #-32] )
230 PLD( subs r2, r2, #64 )
231 PLD( blt 26f )
23225: PLD( pld [r1, #-64] )
233 PLD( pld [r1, #-96] )
234 ldmdb r1!, {r3 - r9, ip}
235 subs r2, r2, #32
236 stmgedb r0!, {r3 - r9, ip}
237 ldmgedb r1!, {r3 - r9, ip}
238 subges r2, r2, #32
239 stmdb r0!, {r3 - r9, ip}
240 bge 25b
24126: PLD( ldmdb r1!, {r3 - r9, ip} )
242 PLD( adds r2, r2, #32 )
243 PLD( stmgedb r0!, {r3 - r9, ip} )
244 PLD( ldmgedb r1!, {r3 - r9, ip} )
245 PLD( subges r2, r2, #32 )
246 PLD( stmdb r0!, {r3 - r9, ip} )
24727: cmn r2, #16
248 ldmgedb r1!, {r3 - r6}
249 subge r2, r2, #16
250 stmgedb r0!, {r3 - r6}
251 adds r2, r2, #20
252 ldmgedb r1!, {r3 - r5}
253 subge r2, r2, #12
254 stmgedb r0!, {r3 - r5}
25528: adds r2, r2, #8
256 blt 29f
257 subs r2, r2, #4
258 ldrlt r3, [r1, #-4]!
259 ldmgedb r1!, {r4, r5}
260 subge r2, r2, #4
261 strlt r3, [r0, #-4]!
262 stmgedb r0!, {r4, r5}
263 53
26429: adds r2, r2, #4 54/* Prototype: void *memcpy(void *dest, const void *src, size_t n); */
265 EXITEQ
266 cmp r2, #2
267 ldrb r3, [r1, #-1]!
268 ldrgeb r4, [r1, #-1]!
269 ldrgtb r5, [r1, #-1]!
270 strb r3, [r0, #-1]!
271 strgeb r4, [r0, #-1]!
272 strgtb r5, [r0, #-1]!
273 EXIT
274 55
27530: cmp ip, #2 56ENTRY(memcpy)
276 ldrb r3, [r1, #-1]!
277 ldrgeb r4, [r1, #-1]!
278 ldrgtb r5, [r1, #-1]!
279 strb r3, [r0, #-1]!
280 strgeb r4, [r0, #-1]!
281 strgtb r5, [r0, #-1]!
282 subs r2, r2, ip
283 blt 29b
284 ands ip, r1, #3
285 beq 24b
286
28731: bic r1, r1, #3
288 ldr r3, [r1], #0
289 cmp ip, #2
290 blt 41f
291 beq 36f
292 cmp r2, #12
293 blt 34f
294 PLD( pld [r1, #-16] )
295 sub r2, r2, #12
296 PLD( subs r2, r2, #32 )
297 PLD( blt 33f )
298 PLD( pld [r1, #-32] )
29932: PLD( pld [r1, #-48] )
30033: mov r7, r3, push #8
301 ldmdb r1!, {r3, r4, r5, r6}
302 subs r2, r2, #16
303 orr r7, r7, r6, pull #24
304 mov r6, r6, push #8
305 orr r6, r6, r5, pull #24
306 mov r5, r5, push #8
307 orr r5, r5, r4, pull #24
308 mov r4, r4, push #8
309 orr r4, r4, r3, pull #24
310 stmdb r0!, {r4, r5, r6, r7}
311 bge 32b
312 PLD( cmn r2, #32 )
313 PLD( bge 33b )
314 PLD( add r2, r2, #32 )
315 adds r2, r2, #12
316 blt 35f
31734: mov ip, r3, push #8
318 ldr r3, [r1, #-4]!
319 subs r2, r2, #4
320 orr ip, ip, r3, pull #24
321 str ip, [r0, #-4]!
322 bge 34b
32335: add r1, r1, #3
324 b 29b
325
32636: cmp r2, #12
327 blt 39f
328 PLD( pld [r1, #-16] )
329 sub r2, r2, #12
330 PLD( subs r2, r2, #32 )
331 PLD( blt 38f )
332 PLD( pld [r1, #-32] )
33337: PLD( pld [r1, #-48] )
33438: mov r7, r3, push #16
335 ldmdb r1!, {r3, r4, r5, r6}
336 subs r2, r2, #16
337 orr r7, r7, r6, pull #16
338 mov r6, r6, push #16
339 orr r6, r6, r5, pull #16
340 mov r5, r5, push #16
341 orr r5, r5, r4, pull #16
342 mov r4, r4, push #16
343 orr r4, r4, r3, pull #16
344 stmdb r0!, {r4, r5, r6, r7}
345 bge 37b
346 PLD( cmn r2, #32 )
347 PLD( bge 38b )
348 PLD( add r2, r2, #32 )
349 adds r2, r2, #12
350 blt 40f
35139: mov ip, r3, push #16
352 ldr r3, [r1, #-4]!
353 subs r2, r2, #4
354 orr ip, ip, r3, pull #16
355 str ip, [r0, #-4]!
356 bge 39b
35740: add r1, r1, #2
358 b 29b
359 57
36041: cmp r2, #12 58#include "copy_template.S"
361 blt 44f
362 PLD( pld [r1, #-16] )
363 sub r2, r2, #12
364 PLD( subs r2, r2, #32 )
365 PLD( blt 43f )
366 PLD( pld [r1, #-32] )
36742: PLD( pld [r1, #-48] )
36843: mov r7, r3, push #24
369 ldmdb r1!, {r3, r4, r5, r6}
370 subs r2, r2, #16
371 orr r7, r7, r6, pull #8
372 mov r6, r6, push #24
373 orr r6, r6, r5, pull #8
374 mov r5, r5, push #24
375 orr r5, r5, r4, pull #8
376 mov r4, r4, push #24
377 orr r4, r4, r3, pull #8
378 stmdb r0!, {r4, r5, r6, r7}
379 bge 42b
380 PLD( cmn r2, #32 )
381 PLD( bge 43b )
382 PLD( add r2, r2, #32 )
383 adds r2, r2, #12
384 blt 45f
38544: mov ip, r3, push #24
386 ldr r3, [r1, #-4]!
387 subs r2, r2, #4
388 orr ip, ip, r3, pull #8
389 str ip, [r0, #-4]!
390 bge 44b
39145: add r1, r1, #1
392 b 29b
393 59
diff --git a/arch/arm/lib/memmove.S b/arch/arm/lib/memmove.S
new file mode 100644
index 000000000000..ef7fddc14ac9
--- /dev/null
+++ b/arch/arm/lib/memmove.S
@@ -0,0 +1,206 @@
1/*
2 * linux/arch/arm/lib/memmove.S
3 *
4 * Author: Nicolas Pitre
5 * Created: Sep 28, 2005
6 * Copyright: (C) MontaVista Software Inc.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/linkage.h>
14#include <asm/assembler.h>
15
16/*
17 * This can be used to enable code to cacheline align the source pointer.
18 * Experiments on tested architectures (StrongARM and XScale) didn't show
19 * this a worthwhile thing to do. That might be different in the future.
20 */
21//#define CALGN(code...) code
22#define CALGN(code...)
23
24 .text
25
26/*
27 * Prototype: void *memmove(void *dest, const void *src, size_t n);
28 *
29 * Note:
30 *
31 * If the memory regions don't overlap, we simply branch to memcpy which is
32 * normally a bit faster. Otherwise the copy is done going downwards. This
33 * is a transposition of the code from copy_template.S but with the copy
34 * occurring in the opposite direction.
35 */
36
37ENTRY(memmove)
38
39 subs ip, r0, r1
40 cmphi r2, ip
41 bls memcpy
42
43 stmfd sp!, {r0, r4, lr}
44 add r1, r1, r2
45 add r0, r0, r2
46 subs r2, r2, #4
47 blt 8f
48 ands ip, r0, #3
49 PLD( pld [r1, #-4] )
50 bne 9f
51 ands ip, r1, #3
52 bne 10f
53
541: subs r2, r2, #(28)
55 stmfd sp!, {r5 - r8}
56 blt 5f
57
58 CALGN( ands ip, r1, #31 )
59 CALGN( sbcnes r4, ip, r2 ) @ C is always set here
60 CALGN( bcs 2f )
61 CALGN( adr r4, 6f )
62 CALGN( subs r2, r2, ip ) @ C is set here
63 CALGN( add pc, r4, ip )
64
65 PLD( pld [r1, #-4] )
662: PLD( subs r2, r2, #96 )
67 PLD( pld [r1, #-32] )
68 PLD( blt 4f )
69 PLD( pld [r1, #-64] )
70 PLD( pld [r1, #-96] )
71
723: PLD( pld [r1, #-128] )
734: ldmdb r1!, {r3, r4, r5, r6, r7, r8, ip, lr}
74 subs r2, r2, #32
75 stmdb r0!, {r3, r4, r5, r6, r7, r8, ip, lr}
76 bge 3b
77 PLD( cmn r2, #96 )
78 PLD( bge 4b )
79
805: ands ip, r2, #28
81 rsb ip, ip, #32
82 addne pc, pc, ip @ C is always clear here
83 b 7f
846: nop
85 ldr r3, [r1, #-4]!
86 ldr r4, [r1, #-4]!
87 ldr r5, [r1, #-4]!
88 ldr r6, [r1, #-4]!
89 ldr r7, [r1, #-4]!
90 ldr r8, [r1, #-4]!
91 ldr lr, [r1, #-4]!
92
93 add pc, pc, ip
94 nop
95 nop
96 str r3, [r0, #-4]!
97 str r4, [r0, #-4]!
98 str r5, [r0, #-4]!
99 str r6, [r0, #-4]!
100 str r7, [r0, #-4]!
101 str r8, [r0, #-4]!
102 str lr, [r0, #-4]!
103
104 CALGN( bcs 2b )
105
1067: ldmfd sp!, {r5 - r8}
107
1088: movs r2, r2, lsl #31
109 ldrneb r3, [r1, #-1]!
110 ldrcsb r4, [r1, #-1]!
111 ldrcsb ip, [r1, #-1]
112 strneb r3, [r0, #-1]!
113 strcsb r4, [r0, #-1]!
114 strcsb ip, [r0, #-1]
115 ldmfd sp!, {r0, r4, pc}
116
1179: cmp ip, #2
118 ldrgtb r3, [r1, #-1]!
119 ldrgeb r4, [r1, #-1]!
120 ldrb lr, [r1, #-1]!
121 strgtb r3, [r0, #-1]!
122 strgeb r4, [r0, #-1]!
123 subs r2, r2, ip
124 strb lr, [r0, #-1]!
125 blt 8b
126 ands ip, r1, #3
127 beq 1b
128
12910: bic r1, r1, #3
130 cmp ip, #2
131 ldr r3, [r1, #0]
132 beq 17f
133 blt 18f
134
135
136 .macro backward_copy_shift push pull
137
138 subs r2, r2, #28
139 blt 14f
140
141 CALGN( ands ip, r1, #31 )
142 CALGN( rsb ip, ip, #32 )
143 CALGN( sbcnes r4, ip, r2 ) @ C is always set here
144 CALGN( subcc r2, r2, ip )
145 CALGN( bcc 15f )
146
14711: stmfd sp!, {r5 - r9}
148
149 PLD( pld [r1, #-4] )
150 PLD( subs r2, r2, #96 )
151 PLD( pld [r1, #-32] )
152 PLD( blt 13f )
153 PLD( pld [r1, #-64] )
154 PLD( pld [r1, #-96] )
155
15612: PLD( pld [r1, #-128] )
15713: ldmdb r1!, {r7, r8, r9, ip}
158 mov lr, r3, push #\push
159 subs r2, r2, #32
160 ldmdb r1!, {r3, r4, r5, r6}
161 orr lr, lr, ip, pull #\pull
162 mov ip, ip, push #\push
163 orr ip, ip, r9, pull #\pull
164 mov r9, r9, push #\push
165 orr r9, r9, r8, pull #\pull
166 mov r8, r8, push #\push
167 orr r8, r8, r7, pull #\pull
168 mov r7, r7, push #\push
169 orr r7, r7, r6, pull #\pull
170 mov r6, r6, push #\push
171 orr r6, r6, r5, pull #\pull
172 mov r5, r5, push #\push
173 orr r5, r5, r4, pull #\pull
174 mov r4, r4, push #\push
175 orr r4, r4, r3, pull #\pull
176 stmdb r0!, {r4 - r9, ip, lr}
177 bge 12b
178 PLD( cmn r2, #96 )
179 PLD( bge 13b )
180
181 ldmfd sp!, {r5 - r9}
182
18314: ands ip, r2, #28
184 beq 16f
185
18615: mov lr, r3, push #\push
187 ldr r3, [r1, #-4]!
188 subs ip, ip, #4
189 orr lr, lr, r3, pull #\pull
190 str lr, [r0, #-4]!
191 bgt 15b
192 CALGN( cmp r2, #0 )
193 CALGN( bge 11b )
194
19516: add r1, r1, #(\pull / 8)
196 b 8b
197
198 .endm
199
200
201 backward_copy_shift push=8 pull=24
202
20317: backward_copy_shift push=16 pull=16
204
20518: backward_copy_shift push=24 pull=8
206
diff --git a/arch/arm/lib/uaccess.S b/arch/arm/lib/uaccess.S
index d3ed0636c008..6f1b5b49fe4c 100644
--- a/arch/arm/lib/uaccess.S
+++ b/arch/arm/lib/uaccess.S
@@ -43,8 +43,6 @@ ENTRY(__arch_copy_to_user)
43 stmfd sp!, {r2, r4 - r7, lr} 43 stmfd sp!, {r2, r4 - r7, lr}
44 cmp r2, #4 44 cmp r2, #4
45 blt .c2u_not_enough 45 blt .c2u_not_enough
46 PLD( pld [r1, #0] )
47 PLD( pld [r0, #0] )
48 ands ip, r0, #3 46 ands ip, r0, #3
49 bne .c2u_dest_not_aligned 47 bne .c2u_dest_not_aligned
50.c2u_dest_aligned: 48.c2u_dest_aligned:
@@ -73,25 +71,13 @@ USER( strt r3, [r0], #4) @ May fault
73 sub r2, r2, ip 71 sub r2, r2, ip
74 subs ip, ip, #32 72 subs ip, ip, #32
75 blt .c2u_0rem8lp 73 blt .c2u_0rem8lp
76 PLD( pld [r1, #28] ) 74
77 PLD( pld [r0, #28] ) 75.c2u_0cpy8lp: ldmia r1!, {r3 - r6}
78 PLD( subs ip, ip, #64 )
79 PLD( blt .c2u_0cpynopld )
80 PLD( pld [r1, #60] )
81 PLD( pld [r0, #60] )
82
83.c2u_0cpy8lp:
84 PLD( pld [r1, #92] )
85 PLD( pld [r0, #92] )
86.c2u_0cpynopld: ldmia r1!, {r3 - r6}
87 stmia r0!, {r3 - r6} @ Shouldnt fault 76 stmia r0!, {r3 - r6} @ Shouldnt fault
88 ldmia r1!, {r3 - r6} 77 ldmia r1!, {r3 - r6}
89 subs ip, ip, #32 78 subs ip, ip, #32
90 stmia r0!, {r3 - r6} @ Shouldnt fault 79 stmia r0!, {r3 - r6} @ Shouldnt fault
91 bpl .c2u_0cpy8lp 80 bpl .c2u_0cpy8lp
92 PLD( cmn ip, #64 )
93 PLD( bge .c2u_0cpynopld )
94 PLD( add ip, ip, #64 )
95 81
96.c2u_0rem8lp: cmn ip, #16 82.c2u_0rem8lp: cmn ip, #16
97 ldmgeia r1!, {r3 - r6} 83 ldmgeia r1!, {r3 - r6}
@@ -143,17 +129,8 @@ USER( strt r3, [r0], #4) @ May fault
143 sub r2, r2, ip 129 sub r2, r2, ip
144 subs ip, ip, #16 130 subs ip, ip, #16
145 blt .c2u_1rem8lp 131 blt .c2u_1rem8lp
146 PLD( pld [r1, #12] ) 132
147 PLD( pld [r0, #12] ) 133.c2u_1cpy8lp: mov r3, r7, pull #8
148 PLD( subs ip, ip, #32 )
149 PLD( blt .c2u_1cpynopld )
150 PLD( pld [r1, #28] )
151 PLD( pld [r0, #28] )
152
153.c2u_1cpy8lp:
154 PLD( pld [r1, #44] )
155 PLD( pld [r0, #44] )
156.c2u_1cpynopld: mov r3, r7, pull #8
157 ldmia r1!, {r4 - r7} 134 ldmia r1!, {r4 - r7}
158 subs ip, ip, #16 135 subs ip, ip, #16
159 orr r3, r3, r4, push #24 136 orr r3, r3, r4, push #24
@@ -165,9 +142,6 @@ USER( strt r3, [r0], #4) @ May fault
165 orr r6, r6, r7, push #24 142 orr r6, r6, r7, push #24
166 stmia r0!, {r3 - r6} @ Shouldnt fault 143 stmia r0!, {r3 - r6} @ Shouldnt fault
167 bpl .c2u_1cpy8lp 144 bpl .c2u_1cpy8lp
168 PLD( cmn ip, #32 )
169 PLD( bge .c2u_1cpynopld )
170 PLD( add ip, ip, #32 )
171 145
172.c2u_1rem8lp: tst ip, #8 146.c2u_1rem8lp: tst ip, #8
173 movne r3, r7, pull #8 147 movne r3, r7, pull #8
@@ -210,17 +184,8 @@ USER( strt r3, [r0], #4) @ May fault
210 sub r2, r2, ip 184 sub r2, r2, ip
211 subs ip, ip, #16 185 subs ip, ip, #16
212 blt .c2u_2rem8lp 186 blt .c2u_2rem8lp
213 PLD( pld [r1, #12] ) 187
214 PLD( pld [r0, #12] ) 188.c2u_2cpy8lp: mov r3, r7, pull #16
215 PLD( subs ip, ip, #32 )
216 PLD( blt .c2u_2cpynopld )
217 PLD( pld [r1, #28] )
218 PLD( pld [r0, #28] )
219
220.c2u_2cpy8lp:
221 PLD( pld [r1, #44] )
222 PLD( pld [r0, #44] )
223.c2u_2cpynopld: mov r3, r7, pull #16
224 ldmia r1!, {r4 - r7} 189 ldmia r1!, {r4 - r7}
225 subs ip, ip, #16 190 subs ip, ip, #16
226 orr r3, r3, r4, push #16 191 orr r3, r3, r4, push #16
@@ -232,9 +197,6 @@ USER( strt r3, [r0], #4) @ May fault
232 orr r6, r6, r7, push #16 197 orr r6, r6, r7, push #16
233 stmia r0!, {r3 - r6} @ Shouldnt fault 198 stmia r0!, {r3 - r6} @ Shouldnt fault
234 bpl .c2u_2cpy8lp 199 bpl .c2u_2cpy8lp
235 PLD( cmn ip, #32 )
236 PLD( bge .c2u_2cpynopld )
237 PLD( add ip, ip, #32 )
238 200
239.c2u_2rem8lp: tst ip, #8 201.c2u_2rem8lp: tst ip, #8
240 movne r3, r7, pull #16 202 movne r3, r7, pull #16
@@ -277,17 +239,8 @@ USER( strt r3, [r0], #4) @ May fault
277 sub r2, r2, ip 239 sub r2, r2, ip
278 subs ip, ip, #16 240 subs ip, ip, #16
279 blt .c2u_3rem8lp 241 blt .c2u_3rem8lp
280 PLD( pld [r1, #12] ) 242
281 PLD( pld [r0, #12] ) 243.c2u_3cpy8lp: mov r3, r7, pull #24
282 PLD( subs ip, ip, #32 )
283 PLD( blt .c2u_3cpynopld )
284 PLD( pld [r1, #28] )
285 PLD( pld [r0, #28] )
286
287.c2u_3cpy8lp:
288 PLD( pld [r1, #44] )
289 PLD( pld [r0, #44] )
290.c2u_3cpynopld: mov r3, r7, pull #24
291 ldmia r1!, {r4 - r7} 244 ldmia r1!, {r4 - r7}
292 subs ip, ip, #16 245 subs ip, ip, #16
293 orr r3, r3, r4, push #8 246 orr r3, r3, r4, push #8
@@ -299,9 +252,6 @@ USER( strt r3, [r0], #4) @ May fault
299 orr r6, r6, r7, push #8 252 orr r6, r6, r7, push #8
300 stmia r0!, {r3 - r6} @ Shouldnt fault 253 stmia r0!, {r3 - r6} @ Shouldnt fault
301 bpl .c2u_3cpy8lp 254 bpl .c2u_3cpy8lp
302 PLD( cmn ip, #32 )
303 PLD( bge .c2u_3cpynopld )
304 PLD( add ip, ip, #32 )
305 255
306.c2u_3rem8lp: tst ip, #8 256.c2u_3rem8lp: tst ip, #8
307 movne r3, r7, pull #24 257 movne r3, r7, pull #24
@@ -356,8 +306,6 @@ ENTRY(__arch_copy_from_user)
356 stmfd sp!, {r0, r2, r4 - r7, lr} 306 stmfd sp!, {r0, r2, r4 - r7, lr}
357 cmp r2, #4 307 cmp r2, #4
358 blt .cfu_not_enough 308 blt .cfu_not_enough
359 PLD( pld [r1, #0] )
360 PLD( pld [r0, #0] )
361 ands ip, r0, #3 309 ands ip, r0, #3
362 bne .cfu_dest_not_aligned 310 bne .cfu_dest_not_aligned
363.cfu_dest_aligned: 311.cfu_dest_aligned:
@@ -385,25 +333,13 @@ USER( ldrt r3, [r1], #4)
385 sub r2, r2, ip 333 sub r2, r2, ip
386 subs ip, ip, #32 334 subs ip, ip, #32
387 blt .cfu_0rem8lp 335 blt .cfu_0rem8lp
388 PLD( pld [r1, #28] ) 336
389 PLD( pld [r0, #28] ) 337.cfu_0cpy8lp: ldmia r1!, {r3 - r6} @ Shouldnt fault
390 PLD( subs ip, ip, #64 )
391 PLD( blt .cfu_0cpynopld )
392 PLD( pld [r1, #60] )
393 PLD( pld [r0, #60] )
394
395.cfu_0cpy8lp:
396 PLD( pld [r1, #92] )
397 PLD( pld [r0, #92] )
398.cfu_0cpynopld: ldmia r1!, {r3 - r6} @ Shouldnt fault
399 stmia r0!, {r3 - r6} 338 stmia r0!, {r3 - r6}
400 ldmia r1!, {r3 - r6} @ Shouldnt fault 339 ldmia r1!, {r3 - r6} @ Shouldnt fault
401 subs ip, ip, #32 340 subs ip, ip, #32
402 stmia r0!, {r3 - r6} 341 stmia r0!, {r3 - r6}
403 bpl .cfu_0cpy8lp 342 bpl .cfu_0cpy8lp
404 PLD( cmn ip, #64 )
405 PLD( bge .cfu_0cpynopld )
406 PLD( add ip, ip, #64 )
407 343
408.cfu_0rem8lp: cmn ip, #16 344.cfu_0rem8lp: cmn ip, #16
409 ldmgeia r1!, {r3 - r6} @ Shouldnt fault 345 ldmgeia r1!, {r3 - r6} @ Shouldnt fault
@@ -456,17 +392,8 @@ USER( ldrt r7, [r1], #4) @ May fault
456 sub r2, r2, ip 392 sub r2, r2, ip
457 subs ip, ip, #16 393 subs ip, ip, #16
458 blt .cfu_1rem8lp 394 blt .cfu_1rem8lp
459 PLD( pld [r1, #12] ) 395
460 PLD( pld [r0, #12] ) 396.cfu_1cpy8lp: mov r3, r7, pull #8
461 PLD( subs ip, ip, #32 )
462 PLD( blt .cfu_1cpynopld )
463 PLD( pld [r1, #28] )
464 PLD( pld [r0, #28] )
465
466.cfu_1cpy8lp:
467 PLD( pld [r1, #44] )
468 PLD( pld [r0, #44] )
469.cfu_1cpynopld: mov r3, r7, pull #8
470 ldmia r1!, {r4 - r7} @ Shouldnt fault 397 ldmia r1!, {r4 - r7} @ Shouldnt fault
471 subs ip, ip, #16 398 subs ip, ip, #16
472 orr r3, r3, r4, push #24 399 orr r3, r3, r4, push #24
@@ -478,9 +405,6 @@ USER( ldrt r7, [r1], #4) @ May fault
478 orr r6, r6, r7, push #24 405 orr r6, r6, r7, push #24
479 stmia r0!, {r3 - r6} 406 stmia r0!, {r3 - r6}
480 bpl .cfu_1cpy8lp 407 bpl .cfu_1cpy8lp
481 PLD( cmn ip, #32 )
482 PLD( bge .cfu_1cpynopld )
483 PLD( add ip, ip, #32 )
484 408
485.cfu_1rem8lp: tst ip, #8 409.cfu_1rem8lp: tst ip, #8
486 movne r3, r7, pull #8 410 movne r3, r7, pull #8
@@ -523,17 +447,8 @@ USER( ldrt r7, [r1], #4) @ May fault
523 sub r2, r2, ip 447 sub r2, r2, ip
524 subs ip, ip, #16 448 subs ip, ip, #16
525 blt .cfu_2rem8lp 449 blt .cfu_2rem8lp
526 PLD( pld [r1, #12] ) 450
527 PLD( pld [r0, #12] ) 451.cfu_2cpy8lp: mov r3, r7, pull #16
528 PLD( subs ip, ip, #32 )
529 PLD( blt .cfu_2cpynopld )
530 PLD( pld [r1, #28] )
531 PLD( pld [r0, #28] )
532
533.cfu_2cpy8lp:
534 PLD( pld [r1, #44] )
535 PLD( pld [r0, #44] )
536.cfu_2cpynopld: mov r3, r7, pull #16
537 ldmia r1!, {r4 - r7} @ Shouldnt fault 452 ldmia r1!, {r4 - r7} @ Shouldnt fault
538 subs ip, ip, #16 453 subs ip, ip, #16
539 orr r3, r3, r4, push #16 454 orr r3, r3, r4, push #16
@@ -545,9 +460,6 @@ USER( ldrt r7, [r1], #4) @ May fault
545 orr r6, r6, r7, push #16 460 orr r6, r6, r7, push #16
546 stmia r0!, {r3 - r6} 461 stmia r0!, {r3 - r6}
547 bpl .cfu_2cpy8lp 462 bpl .cfu_2cpy8lp
548 PLD( cmn ip, #32 )
549 PLD( bge .cfu_2cpynopld )
550 PLD( add ip, ip, #32 )
551 463
552.cfu_2rem8lp: tst ip, #8 464.cfu_2rem8lp: tst ip, #8
553 movne r3, r7, pull #16 465 movne r3, r7, pull #16
@@ -590,17 +502,8 @@ USER( ldrt r7, [r1], #4) @ May fault
590 sub r2, r2, ip 502 sub r2, r2, ip
591 subs ip, ip, #16 503 subs ip, ip, #16
592 blt .cfu_3rem8lp 504 blt .cfu_3rem8lp
593 PLD( pld [r1, #12] ) 505
594 PLD( pld [r0, #12] ) 506.cfu_3cpy8lp: mov r3, r7, pull #24
595 PLD( subs ip, ip, #32 )
596 PLD( blt .cfu_3cpynopld )
597 PLD( pld [r1, #28] )
598 PLD( pld [r0, #28] )
599
600.cfu_3cpy8lp:
601 PLD( pld [r1, #44] )
602 PLD( pld [r0, #44] )
603.cfu_3cpynopld: mov r3, r7, pull #24
604 ldmia r1!, {r4 - r7} @ Shouldnt fault 507 ldmia r1!, {r4 - r7} @ Shouldnt fault
605 orr r3, r3, r4, push #8 508 orr r3, r3, r4, push #8
606 mov r4, r4, pull #24 509 mov r4, r4, pull #24
@@ -612,9 +515,6 @@ USER( ldrt r7, [r1], #4) @ May fault
612 stmia r0!, {r3 - r6} 515 stmia r0!, {r3 - r6}
613 subs ip, ip, #16 516 subs ip, ip, #16
614 bpl .cfu_3cpy8lp 517 bpl .cfu_3cpy8lp
615 PLD( cmn ip, #32 )
616 PLD( bge .cfu_3cpynopld )
617 PLD( add ip, ip, #32 )
618 518
619.cfu_3rem8lp: tst ip, #8 519.cfu_3rem8lp: tst ip, #8
620 movne r3, r7, pull #24 520 movne r3, r7, pull #24
@@ -657,41 +557,3 @@ USER( ldrgtbt r3, [r1], #1) @ May fault
657 LOADREGS(fd,sp!, {r4 - r7, pc}) 557 LOADREGS(fd,sp!, {r4 - r7, pc})
658 .previous 558 .previous
659 559
660/* Prototype: int __arch_clear_user(void *addr, size_t sz)
661 * Purpose : clear some user memory
662 * Params : addr - user memory address to clear
663 * : sz - number of bytes to clear
664 * Returns : number of bytes NOT cleared
665 */
666ENTRY(__arch_clear_user)
667 stmfd sp!, {r1, lr}
668 mov r2, #0
669 cmp r1, #4
670 blt 2f
671 ands ip, r0, #3
672 beq 1f
673 cmp ip, #2
674USER( strbt r2, [r0], #1)
675USER( strlebt r2, [r0], #1)
676USER( strltbt r2, [r0], #1)
677 rsb ip, ip, #4
678 sub r1, r1, ip @ 7 6 5 4 3 2 1
6791: subs r1, r1, #8 @ -1 -2 -3 -4 -5 -6 -7
680USER( strplt r2, [r0], #4)
681USER( strplt r2, [r0], #4)
682 bpl 1b
683 adds r1, r1, #4 @ 3 2 1 0 -1 -2 -3
684USER( strplt r2, [r0], #4)
6852: tst r1, #2 @ 1x 1x 0x 0x 1x 1x 0x
686USER( strnebt r2, [r0], #1)
687USER( strnebt r2, [r0], #1)
688 tst r1, #1 @ x1 x0 x1 x0 x1 x0 x1
689USER( strnebt r2, [r0], #1)
690 mov r0, #0
691 LOADREGS(fd,sp!, {r1, pc})
692
693 .section .fixup,"ax"
694 .align 0
6959001: LOADREGS(fd,sp!, {r0, pc})
696 .previous
697
diff --git a/arch/arm/mach-clps711x/Kconfig b/arch/arm/mach-clps711x/Kconfig
index d5c155045762..0793dcf54f2e 100644
--- a/arch/arm/mach-clps711x/Kconfig
+++ b/arch/arm/mach-clps711x/Kconfig
@@ -69,17 +69,6 @@ config EP72XX_ROM_BOOT
69 69
70 You almost surely want to say N here. 70 You almost surely want to say N here.
71 71
72config MACH_MP1000
73 bool "MACH_MP1000"
74 help
75 Say Y if you intend to run the kernel on the Comdial MP1000 platform.
76
77config MP1000_90MHZ
78 bool "MP1000_90MHZ"
79 depends on MACH_MP1000
80 help
81 Say Y if you have the MP1000 configured to be set at 90MHZ rather than 74MHZ
82
83endmenu 72endmenu
84 73
85endif 74endif
diff --git a/arch/arm/mach-clps711x/Makefile b/arch/arm/mach-clps711x/Makefile
index 8a6dc1ccf8fe..4a197315f0cf 100644
--- a/arch/arm/mach-clps711x/Makefile
+++ b/arch/arm/mach-clps711x/Makefile
@@ -15,7 +15,6 @@ obj-$(CONFIG_ARCH_CDB89712) += cdb89712.o
15obj-$(CONFIG_ARCH_CLEP7312) += clep7312.o 15obj-$(CONFIG_ARCH_CLEP7312) += clep7312.o
16obj-$(CONFIG_ARCH_EDB7211) += edb7211-arch.o edb7211-mm.o 16obj-$(CONFIG_ARCH_EDB7211) += edb7211-arch.o edb7211-mm.o
17obj-$(CONFIG_ARCH_FORTUNET) += fortunet.o 17obj-$(CONFIG_ARCH_FORTUNET) += fortunet.o
18obj-$(CONFIG_MACH_MP1000) += mp1000-mach.o mp1000-mm.o mp1000-seprom.o
19obj-$(CONFIG_ARCH_P720T) += p720t.o 18obj-$(CONFIG_ARCH_P720T) += p720t.o
20leds-$(CONFIG_ARCH_P720T) += p720t-leds.o 19leds-$(CONFIG_ARCH_P720T) += p720t-leds.o
21obj-$(CONFIG_LEDS) += $(leds-y) 20obj-$(CONFIG_LEDS) += $(leds-y)
diff --git a/arch/arm/mach-clps711x/edb7211-mm.c b/arch/arm/mach-clps711x/edb7211-mm.c
index 72f8bb05d55e..0d52e0851251 100644
--- a/arch/arm/mach-clps711x/edb7211-mm.c
+++ b/arch/arm/mach-clps711x/edb7211-mm.c
@@ -55,22 +55,22 @@ static struct map_desc edb7211_io_desc[] __initdata = {
55 .virtual = EP7211_VIRT_EXTKBD, 55 .virtual = EP7211_VIRT_EXTKBD,
56 .pfn = __phys_to_pfn(EP7211_PHYS_EXTKBD), 56 .pfn = __phys_to_pfn(EP7211_PHYS_EXTKBD),
57 .length = SZ_1M, 57 .length = SZ_1M,
58 .type - MT_DEVICE 58 .type = MT_DEVICE,
59 }, { /* and CS8900A Ethernet chip */ 59 }, { /* and CS8900A Ethernet chip */
60 .virtual = EP7211_VIRT_CS8900A, 60 .virtual = EP7211_VIRT_CS8900A,
61 .pfn = __phys_to_pfn(EP7211_PHYS_CS8900A), 61 .pfn = __phys_to_pfn(EP7211_PHYS_CS8900A),
62 .length = SZ_1M, 62 .length = SZ_1M,
63 .type = MT_DEVICE 63 .type = MT_DEVICE,
64 }, { /* flash banks */ 64 }, { /* flash banks */
65 .virtual = EP7211_VIRT_FLASH1, 65 .virtual = EP7211_VIRT_FLASH1,
66 .pfn = __phys_to_pfn(EP7211_PHYS_FLASH1), 66 .pfn = __phys_to_pfn(EP7211_PHYS_FLASH1),
67 .length = SZ_8M, 67 .length = SZ_8M,
68 .type = MT_DEVICE 68 .type = MT_DEVICE,
69 }, { 69 }, {
70 .virtual = EP7211_VIRT_FLASH2, 70 .virtual = EP7211_VIRT_FLASH2,
71 .pfn = __phys_to_pfn(EP7211_PHYS_FLASH2), 71 .pfn = __phys_to_pfn(EP7211_PHYS_FLASH2),
72 .length = SZ_8M, 72 .length = SZ_8M,
73 .type = MT_DEVICE 73 .type = MT_DEVICE,
74 } 74 }
75}; 75};
76 76
diff --git a/arch/arm/mach-clps711x/mp1000-mach.c b/arch/arm/mach-clps711x/mp1000-mach.c
deleted file mode 100644
index c2816bcde5e7..000000000000
--- a/arch/arm/mach-clps711x/mp1000-mach.c
+++ /dev/null
@@ -1,49 +0,0 @@
1/*
2 * linux/arch/arm/mach-mp1000/mp1000.c
3 *
4 * Copyright (C) 2005 Comdial Corporation
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20#include <linux/init.h>
21#include <linux/types.h>
22#include <linux/string.h>
23
24#include <asm/setup.h>
25#include <asm/mach-types.h>
26#include <asm/mach/arch.h>
27#include <asm/arch/mp1000-seprom.h>
28
29#include "common.h"
30
31extern void mp1000_map_io(void);
32
33static void __init mp1000_init(void)
34{
35 seprom_init();
36}
37
38MACHINE_START(MP1000, "Comdial MP1000")
39 /* Maintainer: Jon Ringle */
40 .phys_ram = 0xc0000000,
41 .phys_io = 0x80000000,
42 .io_pg_offst = ((0xff000000) >> 18) & 0xfffc,
43 .boot_params = 0xc0015100,
44 .map_io = mp1000_map_io,
45 .init_irq = clps711x_init_irq,
46 .init_machine = mp1000_init,
47 .timer = &clps711x_timer,
48MACHINE_END
49
diff --git a/arch/arm/mach-clps711x/mp1000-mm.c b/arch/arm/mach-clps711x/mp1000-mm.c
deleted file mode 100644
index 20e810b0ec0c..000000000000
--- a/arch/arm/mach-clps711x/mp1000-mm.c
+++ /dev/null
@@ -1,47 +0,0 @@
1/*
2 * linux/arch/arm/mach-mp1000/mm.c
3 *
4 * Extra MM routines for the MP1000
5 *
6 * Copyright (C) 2005 Comdial Corporation
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22#include <linux/kernel.h>
23#include <linux/init.h>
24
25#include <asm/hardware.h>
26#include <asm/page.h>
27#include <asm/pgtable.h>
28#include <asm/sizes.h>
29
30#include <asm/mach/map.h>
31
32extern void clps711x_map_io(void);
33
34static struct map_desc mp1000_io_desc[] __initdata = {
35 { MP1000_EIO_BASE, MP1000_EIO_START, MP1000_EIO_SIZE, MT_DEVICE },
36 { MP1000_FIO_BASE, MP1000_FIO_START, MP1000_FIO_SIZE, MT_DEVICE },
37 { MP1000_LIO_BASE, MP1000_LIO_START, MP1000_LIO_SIZE, MT_DEVICE },
38 { MP1000_NIO_BASE, MP1000_NIO_START, MP1000_NIO_SIZE, MT_DEVICE },
39 { MP1000_IDE_BASE, MP1000_IDE_START, MP1000_IDE_SIZE, MT_DEVICE },
40 { MP1000_DSP_BASE, MP1000_DSP_START, MP1000_DSP_SIZE, MT_DEVICE }
41};
42
43void __init mp1000_map_io(void)
44{
45 clps711x_map_io();
46 iotable_init(mp1000_io_desc, ARRAY_SIZE(mp1000_io_desc));
47}
diff --git a/arch/arm/mach-clps711x/mp1000-seprom.c b/arch/arm/mach-clps711x/mp1000-seprom.c
deleted file mode 100644
index b22d0bebb851..000000000000
--- a/arch/arm/mach-clps711x/mp1000-seprom.c
+++ /dev/null
@@ -1,195 +0,0 @@
1/*`
2 * mp1000-seprom.c
3 *
4 * This file contains the Serial EEPROM code for the MP1000 board
5 *
6 * Copyright (C) 2005 Comdial Corporation
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
22 */
23
24#include <linux/kernel.h>
25#include <linux/init.h>
26#include <asm/hardware.h>
27#include <asm/hardware/clps7111.h>
28#include <asm/arch/mp1000-seprom.h>
29
30/* If SepromInit() can initialize and checksum the seprom successfully, */
31/* then it will point seprom_data_ptr at the shadow copy. */
32
33static eeprom_struct seprom_data; /* shadow copy of seprom content */
34
35eeprom_struct *seprom_data_ptr = 0; /* 0 => not initialized */
36
37/*
38 * Port D Bit 5 is Chip Select for EEPROM
39 * Port E Bit 0 is Input, Data out from EEPROM
40 * Port E Bit 1 is Output, Data in to EEPROM
41 * Port E Bit 2 is Output, CLK to EEPROM
42 */
43
44static char *port_d_ptr = (char *)(CLPS7111_VIRT_BASE + PDDR);
45static char *port_e_ptr = (char *)(CLPS7111_VIRT_BASE + PEDR);
46
47#define NO_OF_SHORTS 64 // Device is 64 x 16 bits
48#define ENABLE_RW 0
49#define DISABLE_RW 1
50
51static inline void toggle_seprom_clock(void)
52{
53 *port_e_ptr |= HwPortESepromCLK;
54 *port_e_ptr &= ~(HwPortESepromCLK);
55}
56
57static inline void select_eeprom(void)
58{
59 *port_d_ptr |= HwPortDEECS;
60 *port_e_ptr &= ~(HwPortESepromCLK);
61}
62
63static inline void deselect_eeprom(void)
64{
65 *port_d_ptr &= ~(HwPortDEECS);
66 *port_e_ptr &= ~(HwPortESepromDIn);
67}
68
69/*
70 * GetSepromDataPtr - returns pointer to shadow (RAM) copy of seprom
71 * and returns 0 if seprom is not initialized or
72 * has a checksum error.
73 */
74
75eeprom_struct* get_seprom_ptr(void)
76{
77 return seprom_data_ptr;
78}
79
80unsigned char* get_eeprom_mac_address(void)
81{
82 return seprom_data_ptr->variant.eprom_struct.mac_Address;
83}
84
85/*
86 * ReadSProm, Physically reads data from the Serial PROM
87 */
88static void read_sprom(short address, int length, eeprom_struct *buffer)
89{
90 short data = COMMAND_READ | (address & 0x3F);
91 short bit;
92 int i;
93
94 select_eeprom();
95
96 // Clock in 9 bits of the command
97 for (i = 0, bit = 0x100; i < 9; i++, bit >>= 1) {
98 if (data & bit)
99 *port_e_ptr |= HwPortESepromDIn;
100 else
101 *port_e_ptr &= ~(HwPortESepromDIn);
102
103 toggle_seprom_clock();
104 }
105
106 //
107 // Now read one or more shorts of data from the Seprom
108 //
109 while (length-- > 0) {
110 data = 0;
111
112 // Read 16 bits at a time
113 for (i = 0; i < 16; i++) {
114 data <<= 1;
115 toggle_seprom_clock();
116 data |= *port_e_ptr & HwPortESepromDOut;
117
118 }
119
120 buffer->variant.eprom_short_data[address++] = data;
121 }
122
123 deselect_eeprom();
124
125 return;
126}
127
128
129
130/*
131 * ReadSerialPROM
132 *
133 * Input: Pointer to array of 64 x 16 Bits
134 *
135 * Output: if no problem reading data is filled in
136 */
137static void read_serial_prom(eeprom_struct *data)
138{
139 read_sprom(0, 64, data);
140}
141
142
143//
144// Compute Serial EEPROM checksum
145//
146// Input: Pointer to struct with Eprom data
147//
148// Output: The computed Eprom checksum
149//
150static short compute_seprom_checksum(eeprom_struct *data)
151{
152 short checksum = 0;
153 int i;
154
155 for (i = 0; i < 126; i++) {
156 checksum += (short)data->variant.eprom_byte_data[i];
157 }
158
159 return((short)(0x5555 - (checksum & 0xFFFF)));
160}
161
162//
163// Make sure the data port bits for the SEPROM are correctly initialised
164//
165
166void __init seprom_init(void)
167{
168 short checksum;
169
170 // Init Port D
171 *(char *)(CLPS7111_VIRT_BASE + PDDDR) = 0x0;
172 *(char *)(CLPS7111_VIRT_BASE + PDDR) = 0x15;
173
174 // Init Port E
175 *(int *)(CLPS7111_VIRT_BASE + PEDDR) = 0x06;
176 *(int *)(CLPS7111_VIRT_BASE + PEDR) = 0x04;
177
178 //
179 // Make sure that EEPROM struct size never exceeds 128 bytes
180 //
181 if (sizeof(eeprom_struct) > 128) {
182 panic("Serial PROM struct size > 128, aborting read\n");
183 }
184
185 read_serial_prom(&seprom_data);
186
187 checksum = compute_seprom_checksum(&seprom_data);
188
189 if (checksum != seprom_data.variant.eprom_short_data[63]) {
190 panic("Serial EEPROM checksum failed\n");
191 }
192
193 seprom_data_ptr = &seprom_data;
194}
195
diff --git a/arch/arm/mach-ebsa110/core.c b/arch/arm/mach-ebsa110/core.c
index 15261646dcdd..ed4614983adb 100644
--- a/arch/arm/mach-ebsa110/core.c
+++ b/arch/arm/mach-ebsa110/core.c
@@ -251,9 +251,33 @@ static struct platform_device serial_device = {
251 }, 251 },
252}; 252};
253 253
254static struct resource am79c961_resources[] = {
255 {
256 .start = 0x220,
257 .end = 0x238,
258 .flags = IORESOURCE_IO,
259 }, {
260 .start = IRQ_EBSA110_ETHERNET,
261 .end = IRQ_EBSA110_ETHERNET,
262 .flags = IORESOURCE_IRQ,
263 },
264};
265
266static struct platform_device am79c961_device = {
267 .name = "am79c961",
268 .id = -1,
269 .num_resources = ARRAY_SIZE(am79c961_resources),
270 .resource = am79c961_resources,
271};
272
273static struct platform_device *ebsa110_devices[] = {
274 &serial_device,
275 &am79c961_device,
276};
277
254static int __init ebsa110_init(void) 278static int __init ebsa110_init(void)
255{ 279{
256 return platform_device_register(&serial_device); 280 return platform_add_devices(ebsa110_devices, ARRAY_SIZE(ebsa110_devices));
257} 281}
258 282
259arch_initcall(ebsa110_init); 283arch_initcall(ebsa110_init);
diff --git a/arch/arm/mach-ixp2000/Makefile b/arch/arm/mach-ixp2000/Makefile
index 1e6139d42a92..9621aeb61f46 100644
--- a/arch/arm/mach-ixp2000/Makefile
+++ b/arch/arm/mach-ixp2000/Makefile
@@ -1,7 +1,7 @@
1# 1#
2# Makefile for the linux kernel. 2# Makefile for the linux kernel.
3# 3#
4obj-y := core.o pci.o 4obj-y := core.o pci.o uengine.o
5obj-m := 5obj-m :=
6obj-n := 6obj-n :=
7obj- := 7obj- :=
diff --git a/arch/arm/mach-ixp2000/core.c b/arch/arm/mach-ixp2000/core.c
index 01c393c504d0..df140962bb0f 100644
--- a/arch/arm/mach-ixp2000/core.c
+++ b/arch/arm/mach-ixp2000/core.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * arch/arm/mach-ixp2000/common.c 2 * arch/arm/mach-ixp2000/core.c
3 * 3 *
4 * Common routines used by all IXP2400/2800 based platforms. 4 * Common routines used by all IXP2400/2800 based platforms.
5 * 5 *
@@ -49,7 +49,6 @@ static unsigned long ixp2000_slowport_irq_flags;
49 *************************************************************************/ 49 *************************************************************************/
50void ixp2000_acquire_slowport(struct slowport_cfg *new_cfg, struct slowport_cfg *old_cfg) 50void ixp2000_acquire_slowport(struct slowport_cfg *new_cfg, struct slowport_cfg *old_cfg)
51{ 51{
52
53 spin_lock_irqsave(&ixp2000_slowport_lock, ixp2000_slowport_irq_flags); 52 spin_lock_irqsave(&ixp2000_slowport_lock, ixp2000_slowport_irq_flags);
54 53
55 old_cfg->CCR = *IXP2000_SLOWPORT_CCR; 54 old_cfg->CCR = *IXP2000_SLOWPORT_CCR;
@@ -62,7 +61,7 @@ void ixp2000_acquire_slowport(struct slowport_cfg *new_cfg, struct slowport_cfg
62 ixp2000_reg_write(IXP2000_SLOWPORT_WTC2, new_cfg->WTC); 61 ixp2000_reg_write(IXP2000_SLOWPORT_WTC2, new_cfg->WTC);
63 ixp2000_reg_write(IXP2000_SLOWPORT_RTC2, new_cfg->RTC); 62 ixp2000_reg_write(IXP2000_SLOWPORT_RTC2, new_cfg->RTC);
64 ixp2000_reg_write(IXP2000_SLOWPORT_PCR, new_cfg->PCR); 63 ixp2000_reg_write(IXP2000_SLOWPORT_PCR, new_cfg->PCR);
65 ixp2000_reg_write(IXP2000_SLOWPORT_ADC, new_cfg->ADC); 64 ixp2000_reg_wrb(IXP2000_SLOWPORT_ADC, new_cfg->ADC);
66} 65}
67 66
68void ixp2000_release_slowport(struct slowport_cfg *old_cfg) 67void ixp2000_release_slowport(struct slowport_cfg *old_cfg)
@@ -71,7 +70,7 @@ void ixp2000_release_slowport(struct slowport_cfg *old_cfg)
71 ixp2000_reg_write(IXP2000_SLOWPORT_WTC2, old_cfg->WTC); 70 ixp2000_reg_write(IXP2000_SLOWPORT_WTC2, old_cfg->WTC);
72 ixp2000_reg_write(IXP2000_SLOWPORT_RTC2, old_cfg->RTC); 71 ixp2000_reg_write(IXP2000_SLOWPORT_RTC2, old_cfg->RTC);
73 ixp2000_reg_write(IXP2000_SLOWPORT_PCR, old_cfg->PCR); 72 ixp2000_reg_write(IXP2000_SLOWPORT_PCR, old_cfg->PCR);
74 ixp2000_reg_write(IXP2000_SLOWPORT_ADC, old_cfg->ADC); 73 ixp2000_reg_wrb(IXP2000_SLOWPORT_ADC, old_cfg->ADC);
75 74
76 spin_unlock_irqrestore(&ixp2000_slowport_lock, 75 spin_unlock_irqrestore(&ixp2000_slowport_lock,
77 ixp2000_slowport_irq_flags); 76 ixp2000_slowport_irq_flags);
@@ -145,7 +144,7 @@ void __init ixp2000_map_io(void)
145 iotable_init(ixp2000_io_desc, ARRAY_SIZE(ixp2000_io_desc)); 144 iotable_init(ixp2000_io_desc, ARRAY_SIZE(ixp2000_io_desc));
146 145
147 /* Set slowport to 8-bit mode. */ 146 /* Set slowport to 8-bit mode. */
148 ixp2000_reg_write(IXP2000_SLOWPORT_FRM, 1); 147 ixp2000_reg_wrb(IXP2000_SLOWPORT_FRM, 1);
149} 148}
150 149
151 150
@@ -209,7 +208,7 @@ static int ixp2000_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
209 write_seqlock(&xtime_lock); 208 write_seqlock(&xtime_lock);
210 209
211 /* clear timer 1 */ 210 /* clear timer 1 */
212 ixp2000_reg_write(IXP2000_T1_CLR, 1); 211 ixp2000_reg_wrb(IXP2000_T1_CLR, 1);
213 212
214 while ((next_jiffy_time - *missing_jiffy_timer_csr) > ticks_per_jiffy) { 213 while ((next_jiffy_time - *missing_jiffy_timer_csr) > ticks_per_jiffy) {
215 timer_tick(regs); 214 timer_tick(regs);
@@ -252,12 +251,12 @@ void __init ixp2000_init_time(unsigned long tick_rate)
252 251
253 ixp2000_reg_write(IXP2000_T4_CLR, 0); 252 ixp2000_reg_write(IXP2000_T4_CLR, 0);
254 ixp2000_reg_write(IXP2000_T4_CLD, -1); 253 ixp2000_reg_write(IXP2000_T4_CLD, -1);
255 ixp2000_reg_write(IXP2000_T4_CTL, (1 << 7)); 254 ixp2000_reg_wrb(IXP2000_T4_CTL, (1 << 7));
256 missing_jiffy_timer_csr = IXP2000_T4_CSR; 255 missing_jiffy_timer_csr = IXP2000_T4_CSR;
257 } else { 256 } else {
258 ixp2000_reg_write(IXP2000_T2_CLR, 0); 257 ixp2000_reg_write(IXP2000_T2_CLR, 0);
259 ixp2000_reg_write(IXP2000_T2_CLD, -1); 258 ixp2000_reg_write(IXP2000_T2_CLD, -1);
260 ixp2000_reg_write(IXP2000_T2_CTL, (1 << 7)); 259 ixp2000_reg_wrb(IXP2000_T2_CTL, (1 << 7));
261 missing_jiffy_timer_csr = IXP2000_T2_CSR; 260 missing_jiffy_timer_csr = IXP2000_T2_CSR;
262 } 261 }
263 next_jiffy_time = 0xffffffff; 262 next_jiffy_time = 0xffffffff;
@@ -279,7 +278,7 @@ static void update_gpio_int_csrs(void)
279 ixp2000_reg_write(IXP2000_GPIO_FEDR, GPIO_IRQ_falling_edge); 278 ixp2000_reg_write(IXP2000_GPIO_FEDR, GPIO_IRQ_falling_edge);
280 ixp2000_reg_write(IXP2000_GPIO_REDR, GPIO_IRQ_rising_edge); 279 ixp2000_reg_write(IXP2000_GPIO_REDR, GPIO_IRQ_rising_edge);
281 ixp2000_reg_write(IXP2000_GPIO_LSLR, GPIO_IRQ_level_low); 280 ixp2000_reg_write(IXP2000_GPIO_LSLR, GPIO_IRQ_level_low);
282 ixp2000_reg_write(IXP2000_GPIO_LSHR, GPIO_IRQ_level_high); 281 ixp2000_reg_wrb(IXP2000_GPIO_LSHR, GPIO_IRQ_level_high);
283} 282}
284 283
285void gpio_line_config(int line, int direction) 284void gpio_line_config(int line, int direction)
@@ -297,9 +296,9 @@ void gpio_line_config(int line, int direction)
297 GPIO_IRQ_level_high &= ~(1 << line); 296 GPIO_IRQ_level_high &= ~(1 << line);
298 update_gpio_int_csrs(); 297 update_gpio_int_csrs();
299 298
300 ixp2000_reg_write(IXP2000_GPIO_PDSR, 1 << line); 299 ixp2000_reg_wrb(IXP2000_GPIO_PDSR, 1 << line);
301 } else if (direction == GPIO_IN) { 300 } else if (direction == GPIO_IN) {
302 ixp2000_reg_write(IXP2000_GPIO_PDCR, 1 << line); 301 ixp2000_reg_wrb(IXP2000_GPIO_PDCR, 1 << line);
303 } 302 }
304 local_irq_restore(flags); 303 local_irq_restore(flags);
305} 304}
@@ -365,12 +364,12 @@ static void ixp2000_GPIO_irq_mask_ack(unsigned int irq)
365 364
366 ixp2000_reg_write(IXP2000_GPIO_EDSR, (1 << (irq - IRQ_IXP2000_GPIO0))); 365 ixp2000_reg_write(IXP2000_GPIO_EDSR, (1 << (irq - IRQ_IXP2000_GPIO0)));
367 ixp2000_reg_write(IXP2000_GPIO_LDSR, (1 << (irq - IRQ_IXP2000_GPIO0))); 366 ixp2000_reg_write(IXP2000_GPIO_LDSR, (1 << (irq - IRQ_IXP2000_GPIO0)));
368 ixp2000_reg_write(IXP2000_GPIO_INST, (1 << (irq - IRQ_IXP2000_GPIO0))); 367 ixp2000_reg_wrb(IXP2000_GPIO_INST, (1 << (irq - IRQ_IXP2000_GPIO0)));
369} 368}
370 369
371static void ixp2000_GPIO_irq_mask(unsigned int irq) 370static void ixp2000_GPIO_irq_mask(unsigned int irq)
372{ 371{
373 ixp2000_reg_write(IXP2000_GPIO_INCR, (1 << (irq - IRQ_IXP2000_GPIO0))); 372 ixp2000_reg_wrb(IXP2000_GPIO_INCR, (1 << (irq - IRQ_IXP2000_GPIO0)));
374} 373}
375 374
376static void ixp2000_GPIO_irq_unmask(unsigned int irq) 375static void ixp2000_GPIO_irq_unmask(unsigned int irq)
@@ -389,9 +388,9 @@ static void ixp2000_pci_irq_mask(unsigned int irq)
389{ 388{
390 unsigned long temp = *IXP2000_PCI_XSCALE_INT_ENABLE; 389 unsigned long temp = *IXP2000_PCI_XSCALE_INT_ENABLE;
391 if (irq == IRQ_IXP2000_PCIA) 390 if (irq == IRQ_IXP2000_PCIA)
392 ixp2000_reg_write(IXP2000_PCI_XSCALE_INT_ENABLE, (temp & ~(1 << 26))); 391 ixp2000_reg_wrb(IXP2000_PCI_XSCALE_INT_ENABLE, (temp & ~(1 << 26)));
393 else if (irq == IRQ_IXP2000_PCIB) 392 else if (irq == IRQ_IXP2000_PCIB)
394 ixp2000_reg_write(IXP2000_PCI_XSCALE_INT_ENABLE, (temp & ~(1 << 27))); 393 ixp2000_reg_wrb(IXP2000_PCI_XSCALE_INT_ENABLE, (temp & ~(1 << 27)));
395} 394}
396 395
397static void ixp2000_pci_irq_unmask(unsigned int irq) 396static void ixp2000_pci_irq_unmask(unsigned int irq)
@@ -403,6 +402,40 @@ static void ixp2000_pci_irq_unmask(unsigned int irq)
403 ixp2000_reg_write(IXP2000_PCI_XSCALE_INT_ENABLE, (temp | (1 << 27))); 402 ixp2000_reg_write(IXP2000_PCI_XSCALE_INT_ENABLE, (temp | (1 << 27)));
404} 403}
405 404
405/*
406 * Error interrupts. These are used extensively by the microengine drivers
407 */
408static void ixp2000_err_irq_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
409{
410 int i;
411 unsigned long status = *IXP2000_IRQ_ERR_STATUS;
412
413 for(i = 31; i >= 0; i--) {
414 if(status & (1 << i)) {
415 desc = irq_desc + IRQ_IXP2000_DRAM0_MIN_ERR + i;
416 desc->handle(IRQ_IXP2000_DRAM0_MIN_ERR + i, desc, regs);
417 }
418 }
419}
420
421static void ixp2000_err_irq_mask(unsigned int irq)
422{
423 ixp2000_reg_write(IXP2000_IRQ_ERR_ENABLE_CLR,
424 (1 << (irq - IRQ_IXP2000_DRAM0_MIN_ERR)));
425}
426
427static void ixp2000_err_irq_unmask(unsigned int irq)
428{
429 ixp2000_reg_write(IXP2000_IRQ_ERR_ENABLE_SET,
430 (1 << (irq - IRQ_IXP2000_DRAM0_MIN_ERR)));
431}
432
433static struct irqchip ixp2000_err_irq_chip = {
434 .ack = ixp2000_err_irq_mask,
435 .mask = ixp2000_err_irq_mask,
436 .unmask = ixp2000_err_irq_unmask
437};
438
406static struct irqchip ixp2000_pci_irq_chip = { 439static struct irqchip ixp2000_pci_irq_chip = {
407 .ack = ixp2000_pci_irq_mask, 440 .ack = ixp2000_pci_irq_mask,
408 .mask = ixp2000_pci_irq_mask, 441 .mask = ixp2000_pci_irq_mask,
@@ -411,7 +444,7 @@ static struct irqchip ixp2000_pci_irq_chip = {
411 444
412static void ixp2000_irq_mask(unsigned int irq) 445static void ixp2000_irq_mask(unsigned int irq)
413{ 446{
414 ixp2000_reg_write(IXP2000_IRQ_ENABLE_CLR, (1 << irq)); 447 ixp2000_reg_wrb(IXP2000_IRQ_ENABLE_CLR, (1 << irq));
415} 448}
416 449
417static void ixp2000_irq_unmask(unsigned int irq) 450static void ixp2000_irq_unmask(unsigned int irq)
@@ -443,7 +476,7 @@ void __init ixp2000_init_irq(void)
443 ixp2000_reg_write(IXP2000_GPIO_INCR, -1); 476 ixp2000_reg_write(IXP2000_GPIO_INCR, -1);
444 477
445 /* clear PCI interrupt sources */ 478 /* clear PCI interrupt sources */
446 ixp2000_reg_write(IXP2000_PCI_XSCALE_INT_ENABLE, 0); 479 ixp2000_reg_wrb(IXP2000_PCI_XSCALE_INT_ENABLE, 0);
447 480
448 /* 481 /*
449 * Certain bits in the IRQ status register of the 482 * Certain bits in the IRQ status register of the
@@ -460,6 +493,18 @@ void __init ixp2000_init_irq(void)
460 } else set_irq_flags(irq, 0); 493 } else set_irq_flags(irq, 0);
461 } 494 }
462 495
496 for (irq = IRQ_IXP2000_DRAM0_MIN_ERR; irq <= IRQ_IXP2000_SP_INT; irq++) {
497 if((1 << (irq - IRQ_IXP2000_DRAM0_MIN_ERR)) &
498 IXP2000_VALID_ERR_IRQ_MASK) {
499 set_irq_chip(irq, &ixp2000_err_irq_chip);
500 set_irq_handler(irq, do_level_IRQ);
501 set_irq_flags(irq, IRQF_VALID);
502 }
503 else
504 set_irq_flags(irq, 0);
505 }
506 set_irq_chained_handler(IRQ_IXP2000_ERRSUM, ixp2000_err_irq_handler);
507
463 /* 508 /*
464 * GPIO IRQs are invalid until someone sets the interrupt mode 509 * GPIO IRQs are invalid until someone sets the interrupt mode
465 * by calling set_irq_type(). 510 * by calling set_irq_type().
diff --git a/arch/arm/mach-ixp2000/enp2611.c b/arch/arm/mach-ixp2000/enp2611.c
index 643f5e1c3d93..61f6006241bd 100644
--- a/arch/arm/mach-ixp2000/enp2611.c
+++ b/arch/arm/mach-ixp2000/enp2611.c
@@ -64,6 +64,35 @@ static struct sys_timer enp2611_timer = {
64 64
65 65
66/************************************************************************* 66/*************************************************************************
67 * ENP-2611 I/O
68 *************************************************************************/
69static struct map_desc enp2611_io_desc[] __initdata = {
70 {
71 .virtual = ENP2611_CALEB_VIRT_BASE,
72 .pfn = __phys_to_pfn(ENP2611_CALEB_PHYS_BASE),
73 .length = ENP2611_CALEB_SIZE,
74 .type = MT_IXP2000_DEVICE,
75 }, {
76 .virtual = ENP2611_PM3386_0_VIRT_BASE,
77 .pfn = __phys_to_pfn(ENP2611_PM3386_0_PHYS_BASE),
78 .length = ENP2611_PM3386_0_SIZE,
79 .type = MT_IXP2000_DEVICE,
80 }, {
81 .virtual = ENP2611_PM3386_1_VIRT_BASE,
82 .pfn = __phys_to_pfn(ENP2611_PM3386_1_PHYS_BASE),
83 .length = ENP2611_PM3386_1_SIZE,
84 .type = MT_IXP2000_DEVICE,
85 }
86};
87
88void __init enp2611_map_io(void)
89{
90 ixp2000_map_io();
91 iotable_init(enp2611_io_desc, ARRAY_SIZE(enp2611_io_desc));
92}
93
94
95/*************************************************************************
67 * ENP-2611 PCI 96 * ENP-2611 PCI
68 *************************************************************************/ 97 *************************************************************************/
69static int enp2611_pci_setup(int nr, struct pci_sys_data *sys) 98static int enp2611_pci_setup(int nr, struct pci_sys_data *sys)
@@ -229,7 +258,7 @@ MACHINE_START(ENP2611, "Radisys ENP-2611 PCI network processor board")
229 .phys_io = IXP2000_UART_PHYS_BASE, 258 .phys_io = IXP2000_UART_PHYS_BASE,
230 .io_pg_offst = ((IXP2000_UART_VIRT_BASE) >> 18) & 0xfffc, 259 .io_pg_offst = ((IXP2000_UART_VIRT_BASE) >> 18) & 0xfffc,
231 .boot_params = 0x00000100, 260 .boot_params = 0x00000100,
232 .map_io = ixp2000_map_io, 261 .map_io = enp2611_map_io,
233 .init_irq = ixp2000_init_irq, 262 .init_irq = ixp2000_init_irq,
234 .timer = &enp2611_timer, 263 .timer = &enp2611_timer,
235 .init_machine = enp2611_init_machine, 264 .init_machine = enp2611_init_machine,
diff --git a/arch/arm/mach-ixp2000/ixdp2x00.c b/arch/arm/mach-ixp2000/ixdp2x00.c
index 05dfcb48c2b6..d628da56b4bc 100644
--- a/arch/arm/mach-ixp2000/ixdp2x00.c
+++ b/arch/arm/mach-ixp2000/ixdp2x00.c
@@ -81,7 +81,7 @@ static void ixdp2x00_irq_mask(unsigned int irq)
81 81
82 dummy = *board_irq_mask; 82 dummy = *board_irq_mask;
83 dummy |= IXP2000_BOARD_IRQ_MASK(irq); 83 dummy |= IXP2000_BOARD_IRQ_MASK(irq);
84 ixp2000_reg_write(board_irq_mask, dummy); 84 ixp2000_reg_wrb(board_irq_mask, dummy);
85 85
86#ifdef CONFIG_ARCH_IXDP2400 86#ifdef CONFIG_ARCH_IXDP2400
87 if (machine_is_ixdp2400()) 87 if (machine_is_ixdp2400())
@@ -101,7 +101,7 @@ static void ixdp2x00_irq_unmask(unsigned int irq)
101 101
102 dummy = *board_irq_mask; 102 dummy = *board_irq_mask;
103 dummy &= ~IXP2000_BOARD_IRQ_MASK(irq); 103 dummy &= ~IXP2000_BOARD_IRQ_MASK(irq);
104 ixp2000_reg_write(board_irq_mask, dummy); 104 ixp2000_reg_wrb(board_irq_mask, dummy);
105 105
106 if (machine_is_ixdp2400()) 106 if (machine_is_ixdp2400())
107 ixp2000_release_slowport(&old_cfg); 107 ixp2000_release_slowport(&old_cfg);
diff --git a/arch/arm/mach-ixp2000/ixdp2x01.c b/arch/arm/mach-ixp2000/ixdp2x01.c
index b21249908ae4..e6a882f35da2 100644
--- a/arch/arm/mach-ixp2000/ixdp2x01.c
+++ b/arch/arm/mach-ixp2000/ixdp2x01.c
@@ -51,7 +51,7 @@
51 *************************************************************************/ 51 *************************************************************************/
52static void ixdp2x01_irq_mask(unsigned int irq) 52static void ixdp2x01_irq_mask(unsigned int irq)
53{ 53{
54 ixp2000_reg_write(IXDP2X01_INT_MASK_SET_REG, 54 ixp2000_reg_wrb(IXDP2X01_INT_MASK_SET_REG,
55 IXP2000_BOARD_IRQ_MASK(irq)); 55 IXP2000_BOARD_IRQ_MASK(irq));
56} 56}
57 57
@@ -114,7 +114,7 @@ void __init ixdp2x01_init_irq(void)
114 114
115 /* Mask all interrupts from CPLD, disable simulation */ 115 /* Mask all interrupts from CPLD, disable simulation */
116 ixp2000_reg_write(IXDP2X01_INT_MASK_SET_REG, 0xffffffff); 116 ixp2000_reg_write(IXDP2X01_INT_MASK_SET_REG, 0xffffffff);
117 ixp2000_reg_write(IXDP2X01_INT_SIM_REG, 0); 117 ixp2000_reg_wrb(IXDP2X01_INT_SIM_REG, 0);
118 118
119 for (irq = NR_IXP2000_IRQS; irq < NR_IXDP2X01_IRQS; irq++) { 119 for (irq = NR_IXP2000_IRQS; irq < NR_IXDP2X01_IRQS; irq++) {
120 if (irq & valid_irq_mask) { 120 if (irq & valid_irq_mask) {
@@ -299,7 +299,6 @@ struct hw_pci ixdp2x01_pci __initdata = {
299 299
300int __init ixdp2x01_pci_init(void) 300int __init ixdp2x01_pci_init(void)
301{ 301{
302
303 pci_common_init(&ixdp2x01_pci); 302 pci_common_init(&ixdp2x01_pci);
304 return 0; 303 return 0;
305} 304}
@@ -316,7 +315,7 @@ static struct flash_platform_data ixdp2x01_flash_platform_data = {
316 315
317static unsigned long ixdp2x01_flash_bank_setup(unsigned long ofs) 316static unsigned long ixdp2x01_flash_bank_setup(unsigned long ofs)
318{ 317{
319 ixp2000_reg_write(IXDP2X01_CPLD_FLASH_REG, 318 ixp2000_reg_wrb(IXDP2X01_CPLD_FLASH_REG,
320 ((ofs >> IXDP2X01_FLASH_WINDOW_BITS) | IXDP2X01_CPLD_FLASH_INTERN)); 319 ((ofs >> IXDP2X01_FLASH_WINDOW_BITS) | IXDP2X01_CPLD_FLASH_INTERN));
321 return (ofs & IXDP2X01_FLASH_WINDOW_MASK); 320 return (ofs & IXDP2X01_FLASH_WINDOW_MASK);
322} 321}
@@ -363,7 +362,7 @@ static struct platform_device *ixdp2x01_devices[] __initdata = {
363 362
364static void __init ixdp2x01_init_machine(void) 363static void __init ixdp2x01_init_machine(void)
365{ 364{
366 ixp2000_reg_write(IXDP2X01_CPLD_FLASH_REG, 365 ixp2000_reg_wrb(IXDP2X01_CPLD_FLASH_REG,
367 (IXDP2X01_CPLD_FLASH_BANK_MASK | IXDP2X01_CPLD_FLASH_INTERN)); 366 (IXDP2X01_CPLD_FLASH_BANK_MASK | IXDP2X01_CPLD_FLASH_INTERN));
368 367
369 ixdp2x01_flash_data.nr_banks = 368 ixdp2x01_flash_data.nr_banks =
diff --git a/arch/arm/mach-ixp2000/pci.c b/arch/arm/mach-ixp2000/pci.c
index 522205acb316..d4bf1e1c0031 100644
--- a/arch/arm/mach-ixp2000/pci.c
+++ b/arch/arm/mach-ixp2000/pci.c
@@ -148,7 +148,7 @@ int ixp2000_pci_abort_handler(unsigned long addr, unsigned int fsr, struct pt_re
148 local_irq_save(flags); 148 local_irq_save(flags);
149 temp = *(IXP2000_PCI_CONTROL); 149 temp = *(IXP2000_PCI_CONTROL);
150 if (temp & ((1 << 8) | (1 << 5))) { 150 if (temp & ((1 << 8) | (1 << 5))) {
151 ixp2000_reg_write(IXP2000_PCI_CONTROL, temp); 151 ixp2000_reg_wrb(IXP2000_PCI_CONTROL, temp);
152 } 152 }
153 153
154 temp = *(IXP2000_PCI_CMDSTAT); 154 temp = *(IXP2000_PCI_CMDSTAT);
@@ -178,8 +178,8 @@ clear_master_aborts(void)
178 178
179 local_irq_save(flags); 179 local_irq_save(flags);
180 temp = *(IXP2000_PCI_CONTROL); 180 temp = *(IXP2000_PCI_CONTROL);
181 if (temp & ((1 << 8) | (1 << 5))) { 181 if (temp & ((1 << 8) | (1 << 5))) {
182 ixp2000_reg_write(IXP2000_PCI_CONTROL, temp); 182 ixp2000_reg_wrb(IXP2000_PCI_CONTROL, temp);
183 } 183 }
184 184
185 temp = *(IXP2000_PCI_CMDSTAT); 185 temp = *(IXP2000_PCI_CMDSTAT);
diff --git a/arch/arm/mach-ixp2000/uengine.c b/arch/arm/mach-ixp2000/uengine.c
new file mode 100644
index 000000000000..43e234349d4a
--- /dev/null
+++ b/arch/arm/mach-ixp2000/uengine.c
@@ -0,0 +1,474 @@
1/*
2 * Generic library functions for the microengines found on the Intel
3 * IXP2000 series of network processors.
4 *
5 * Copyright (C) 2004, 2005 Lennert Buytenhek <buytenh@wantstofly.org>
6 * Dedicated to Marija Kulikova.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU Lesser General Public License as
10 * published by the Free Software Foundation; either version 2.1 of the
11 * License, or (at your option) any later version.
12 */
13
14#include <linux/config.h>
15#include <linux/kernel.h>
16#include <linux/init.h>
17#include <linux/slab.h>
18#include <linux/module.h>
19#include <linux/string.h>
20#include <asm/hardware.h>
21#include <asm/arch/ixp2000-regs.h>
22#include <asm/arch/uengine.h>
23#include <asm/io.h>
24
25#define USTORE_ADDRESS 0x000
26#define USTORE_DATA_LOWER 0x004
27#define USTORE_DATA_UPPER 0x008
28#define CTX_ENABLES 0x018
29#define CC_ENABLE 0x01c
30#define CSR_CTX_POINTER 0x020
31#define INDIRECT_CTX_STS 0x040
32#define ACTIVE_CTX_STS 0x044
33#define INDIRECT_CTX_SIG_EVENTS 0x048
34#define INDIRECT_CTX_WAKEUP_EVENTS 0x050
35#define NN_PUT 0x080
36#define NN_GET 0x084
37#define TIMESTAMP_LOW 0x0c0
38#define TIMESTAMP_HIGH 0x0c4
39#define T_INDEX_BYTE_INDEX 0x0f4
40#define LOCAL_CSR_STATUS 0x180
41
42u32 ixp2000_uengine_mask;
43
44static void *ixp2000_uengine_csr_area(int uengine)
45{
46 return ((void *)IXP2000_UENGINE_CSR_VIRT_BASE) + (uengine << 10);
47}
48
49/*
50 * LOCAL_CSR_STATUS=1 after a read or write to a microengine's CSR
51 * space means that the microengine we tried to access was also trying
52 * to access its own CSR space on the same clock cycle as we did. When
53 * this happens, we lose the arbitration process by default, and the
54 * read or write we tried to do was not actually performed, so we try
55 * again until it succeeds.
56 */
57u32 ixp2000_uengine_csr_read(int uengine, int offset)
58{
59 void *uebase;
60 u32 *local_csr_status;
61 u32 *reg;
62 u32 value;
63
64 uebase = ixp2000_uengine_csr_area(uengine);
65
66 local_csr_status = (u32 *)(uebase + LOCAL_CSR_STATUS);
67 reg = (u32 *)(uebase + offset);
68 do {
69 value = ixp2000_reg_read(reg);
70 } while (ixp2000_reg_read(local_csr_status) & 1);
71
72 return value;
73}
74EXPORT_SYMBOL(ixp2000_uengine_csr_read);
75
76void ixp2000_uengine_csr_write(int uengine, int offset, u32 value)
77{
78 void *uebase;
79 u32 *local_csr_status;
80 u32 *reg;
81
82 uebase = ixp2000_uengine_csr_area(uengine);
83
84 local_csr_status = (u32 *)(uebase + LOCAL_CSR_STATUS);
85 reg = (u32 *)(uebase + offset);
86 do {
87 ixp2000_reg_write(reg, value);
88 } while (ixp2000_reg_read(local_csr_status) & 1);
89}
90EXPORT_SYMBOL(ixp2000_uengine_csr_write);
91
92void ixp2000_uengine_reset(u32 uengine_mask)
93{
94 ixp2000_reg_write(IXP2000_RESET1, uengine_mask & ixp2000_uengine_mask);
95 ixp2000_reg_write(IXP2000_RESET1, 0);
96}
97EXPORT_SYMBOL(ixp2000_uengine_reset);
98
99void ixp2000_uengine_set_mode(int uengine, u32 mode)
100{
101 /*
102 * CTL_STR_PAR_EN: unconditionally enable parity checking on
103 * control store.
104 */
105 mode |= 0x10000000;
106 ixp2000_uengine_csr_write(uengine, CTX_ENABLES, mode);
107
108 /*
109 * Enable updating of condition codes.
110 */
111 ixp2000_uengine_csr_write(uengine, CC_ENABLE, 0x00002000);
112
113 /*
114 * Initialise other per-microengine registers.
115 */
116 ixp2000_uengine_csr_write(uengine, NN_PUT, 0x00);
117 ixp2000_uengine_csr_write(uengine, NN_GET, 0x00);
118 ixp2000_uengine_csr_write(uengine, T_INDEX_BYTE_INDEX, 0);
119}
120EXPORT_SYMBOL(ixp2000_uengine_set_mode);
121
122static int make_even_parity(u32 x)
123{
124 return hweight32(x) & 1;
125}
126
127static void ustore_write(int uengine, u64 insn)
128{
129 /*
130 * Generate even parity for top and bottom 20 bits.
131 */
132 insn |= (u64)make_even_parity((insn >> 20) & 0x000fffff) << 41;
133 insn |= (u64)make_even_parity(insn & 0x000fffff) << 40;
134
135 /*
136 * Write to microstore. The second write auto-increments
137 * the USTORE_ADDRESS index register.
138 */
139 ixp2000_uengine_csr_write(uengine, USTORE_DATA_LOWER, (u32)insn);
140 ixp2000_uengine_csr_write(uengine, USTORE_DATA_UPPER, (u32)(insn >> 32));
141}
142
143void ixp2000_uengine_load_microcode(int uengine, u8 *ucode, int insns)
144{
145 int i;
146
147 /*
148 * Start writing to microstore at address 0.
149 */
150 ixp2000_uengine_csr_write(uengine, USTORE_ADDRESS, 0x80000000);
151 for (i = 0; i < insns; i++) {
152 u64 insn;
153
154 insn = (((u64)ucode[0]) << 32) |
155 (((u64)ucode[1]) << 24) |
156 (((u64)ucode[2]) << 16) |
157 (((u64)ucode[3]) << 8) |
158 ((u64)ucode[4]);
159 ucode += 5;
160
161 ustore_write(uengine, insn);
162 }
163
164 /*
165 * Pad with a few NOPs at the end (to avoid the microengine
166 * aborting as it prefetches beyond the last instruction), unless
167 * we run off the end of the instruction store first, at which
168 * point the address register will wrap back to zero.
169 */
170 for (i = 0; i < 4; i++) {
171 u32 addr;
172
173 addr = ixp2000_uengine_csr_read(uengine, USTORE_ADDRESS);
174 if (addr == 0x80000000)
175 break;
176 ustore_write(uengine, 0xf0000c0300ULL);
177 }
178
179 /*
180 * End programming.
181 */
182 ixp2000_uengine_csr_write(uengine, USTORE_ADDRESS, 0x00000000);
183}
184EXPORT_SYMBOL(ixp2000_uengine_load_microcode);
185
186void ixp2000_uengine_init_context(int uengine, int context, int pc)
187{
188 /*
189 * Select the right context for indirect access.
190 */
191 ixp2000_uengine_csr_write(uengine, CSR_CTX_POINTER, context);
192
193 /*
194 * Initialise signal masks to immediately go to Ready state.
195 */
196 ixp2000_uengine_csr_write(uengine, INDIRECT_CTX_SIG_EVENTS, 1);
197 ixp2000_uengine_csr_write(uengine, INDIRECT_CTX_WAKEUP_EVENTS, 1);
198
199 /*
200 * Set program counter.
201 */
202 ixp2000_uengine_csr_write(uengine, INDIRECT_CTX_STS, pc);
203}
204EXPORT_SYMBOL(ixp2000_uengine_init_context);
205
206void ixp2000_uengine_start_contexts(int uengine, u8 ctx_mask)
207{
208 u32 mask;
209
210 /*
211 * Enable the specified context to go to Executing state.
212 */
213 mask = ixp2000_uengine_csr_read(uengine, CTX_ENABLES);
214 mask |= ctx_mask << 8;
215 ixp2000_uengine_csr_write(uengine, CTX_ENABLES, mask);
216}
217EXPORT_SYMBOL(ixp2000_uengine_start_contexts);
218
219void ixp2000_uengine_stop_contexts(int uengine, u8 ctx_mask)
220{
221 u32 mask;
222
223 /*
224 * Disable the Ready->Executing transition. Note that this
225 * does not stop the context until it voluntarily yields.
226 */
227 mask = ixp2000_uengine_csr_read(uengine, CTX_ENABLES);
228 mask &= ~(ctx_mask << 8);
229 ixp2000_uengine_csr_write(uengine, CTX_ENABLES, mask);
230}
231EXPORT_SYMBOL(ixp2000_uengine_stop_contexts);
232
233static int check_ixp_type(struct ixp2000_uengine_code *c)
234{
235 u32 product_id;
236 u32 rev;
237
238 product_id = ixp2000_reg_read(IXP2000_PRODUCT_ID);
239 if (((product_id >> 16) & 0x1f) != 0)
240 return 0;
241
242 switch ((product_id >> 8) & 0xff) {
243 case 0: /* IXP2800 */
244 if (!(c->cpu_model_bitmask & 4))
245 return 0;
246 break;
247
248 case 1: /* IXP2850 */
249 if (!(c->cpu_model_bitmask & 8))
250 return 0;
251 break;
252
253 case 2: /* IXP2400 */
254 if (!(c->cpu_model_bitmask & 2))
255 return 0;
256 break;
257
258 default:
259 return 0;
260 }
261
262 rev = product_id & 0xff;
263 if (rev < c->cpu_min_revision || rev > c->cpu_max_revision)
264 return 0;
265
266 return 1;
267}
268
269static void generate_ucode(u8 *ucode, u32 *gpr_a, u32 *gpr_b)
270{
271 int offset;
272 int i;
273
274 offset = 0;
275
276 for (i = 0; i < 128; i++) {
277 u8 b3;
278 u8 b2;
279 u8 b1;
280 u8 b0;
281
282 b3 = (gpr_a[i] >> 24) & 0xff;
283 b2 = (gpr_a[i] >> 16) & 0xff;
284 b1 = (gpr_a[i] >> 8) & 0xff;
285 b0 = gpr_a[i] & 0xff;
286
287 // immed[@ai, (b1 << 8) | b0]
288 // 11110000 0000VVVV VVVV11VV VVVVVV00 1IIIIIII
289 ucode[offset++] = 0xf0;
290 ucode[offset++] = (b1 >> 4);
291 ucode[offset++] = (b1 << 4) | 0x0c | (b0 >> 6);
292 ucode[offset++] = (b0 << 2);
293 ucode[offset++] = 0x80 | i;
294
295 // immed_w1[@ai, (b3 << 8) | b2]
296 // 11110100 0100VVVV VVVV11VV VVVVVV00 1IIIIIII
297 ucode[offset++] = 0xf4;
298 ucode[offset++] = 0x40 | (b3 >> 4);
299 ucode[offset++] = (b3 << 4) | 0x0c | (b2 >> 6);
300 ucode[offset++] = (b2 << 2);
301 ucode[offset++] = 0x80 | i;
302 }
303
304 for (i = 0; i < 128; i++) {
305 u8 b3;
306 u8 b2;
307 u8 b1;
308 u8 b0;
309
310 b3 = (gpr_b[i] >> 24) & 0xff;
311 b2 = (gpr_b[i] >> 16) & 0xff;
312 b1 = (gpr_b[i] >> 8) & 0xff;
313 b0 = gpr_b[i] & 0xff;
314
315 // immed[@bi, (b1 << 8) | b0]
316 // 11110000 0000VVVV VVVV001I IIIIII11 VVVVVVVV
317 ucode[offset++] = 0xf0;
318 ucode[offset++] = (b1 >> 4);
319 ucode[offset++] = (b1 << 4) | 0x02 | (i >> 6);
320 ucode[offset++] = (i << 2) | 0x03;
321 ucode[offset++] = b0;
322
323 // immed_w1[@bi, (b3 << 8) | b2]
324 // 11110100 0100VVVV VVVV001I IIIIII11 VVVVVVVV
325 ucode[offset++] = 0xf4;
326 ucode[offset++] = 0x40 | (b3 >> 4);
327 ucode[offset++] = (b3 << 4) | 0x02 | (i >> 6);
328 ucode[offset++] = (i << 2) | 0x03;
329 ucode[offset++] = b2;
330 }
331
332 // ctx_arb[kill]
333 ucode[offset++] = 0xe0;
334 ucode[offset++] = 0x00;
335 ucode[offset++] = 0x01;
336 ucode[offset++] = 0x00;
337 ucode[offset++] = 0x00;
338}
339
340static int set_initial_registers(int uengine, struct ixp2000_uengine_code *c)
341{
342 int per_ctx_regs;
343 u32 *gpr_a;
344 u32 *gpr_b;
345 u8 *ucode;
346 int i;
347
348 gpr_a = kmalloc(128 * sizeof(u32), GFP_KERNEL);
349 gpr_b = kmalloc(128 * sizeof(u32), GFP_KERNEL);
350 ucode = kmalloc(513 * 5, GFP_KERNEL);
351 if (gpr_a == NULL || gpr_b == NULL || ucode == NULL) {
352 kfree(ucode);
353 kfree(gpr_b);
354 kfree(gpr_a);
355 return 1;
356 }
357
358 per_ctx_regs = 16;
359 if (c->uengine_parameters & IXP2000_UENGINE_4_CONTEXTS)
360 per_ctx_regs = 32;
361
362 memset(gpr_a, 0, sizeof(gpr_a));
363 memset(gpr_b, 0, sizeof(gpr_b));
364 for (i = 0; i < 256; i++) {
365 struct ixp2000_reg_value *r = c->initial_reg_values + i;
366 u32 *bank;
367 int inc;
368 int j;
369
370 if (r->reg == -1)
371 break;
372
373 bank = (r->reg & 0x400) ? gpr_b : gpr_a;
374 inc = (r->reg & 0x80) ? 128 : per_ctx_regs;
375
376 j = r->reg & 0x7f;
377 while (j < 128) {
378 bank[j] = r->value;
379 j += inc;
380 }
381 }
382
383 generate_ucode(ucode, gpr_a, gpr_b);
384 ixp2000_uengine_load_microcode(uengine, ucode, 513);
385 ixp2000_uengine_init_context(uengine, 0, 0);
386 ixp2000_uengine_start_contexts(uengine, 0x01);
387 for (i = 0; i < 100; i++) {
388 u32 status;
389
390 status = ixp2000_uengine_csr_read(uengine, ACTIVE_CTX_STS);
391 if (!(status & 0x80000000))
392 break;
393 }
394 ixp2000_uengine_stop_contexts(uengine, 0x01);
395
396 kfree(ucode);
397 kfree(gpr_b);
398 kfree(gpr_a);
399
400 return !!(i == 100);
401}
402
403int ixp2000_uengine_load(int uengine, struct ixp2000_uengine_code *c)
404{
405 int ctx;
406
407 if (!check_ixp_type(c))
408 return 1;
409
410 if (!(ixp2000_uengine_mask & (1 << uengine)))
411 return 1;
412
413 ixp2000_uengine_reset(1 << uengine);
414 ixp2000_uengine_set_mode(uengine, c->uengine_parameters);
415 if (set_initial_registers(uengine, c))
416 return 1;
417 ixp2000_uengine_load_microcode(uengine, c->insns, c->num_insns);
418
419 for (ctx = 0; ctx < 8; ctx++)
420 ixp2000_uengine_init_context(uengine, ctx, 0);
421
422 return 0;
423}
424EXPORT_SYMBOL(ixp2000_uengine_load);
425
426
427static int __init ixp2000_uengine_init(void)
428{
429 int uengine;
430 u32 value;
431
432 /*
433 * Determine number of microengines present.
434 */
435 switch ((ixp2000_reg_read(IXP2000_PRODUCT_ID) >> 8) & 0x1fff) {
436 case 0: /* IXP2800 */
437 case 1: /* IXP2850 */
438 ixp2000_uengine_mask = 0x00ff00ff;
439 break;
440
441 case 2: /* IXP2400 */
442 ixp2000_uengine_mask = 0x000f000f;
443 break;
444
445 default:
446 printk(KERN_INFO "Detected unknown IXP2000 model (%.8x)\n",
447 (unsigned int)ixp2000_reg_read(IXP2000_PRODUCT_ID));
448 ixp2000_uengine_mask = 0x00000000;
449 break;
450 }
451
452 /*
453 * Reset microengines.
454 */
455 ixp2000_reg_write(IXP2000_RESET1, ixp2000_uengine_mask);
456 ixp2000_reg_write(IXP2000_RESET1, 0);
457
458 /*
459 * Synchronise timestamp counters across all microengines.
460 */
461 value = ixp2000_reg_read(IXP2000_MISC_CONTROL);
462 ixp2000_reg_write(IXP2000_MISC_CONTROL, value & ~0x80);
463 for (uengine = 0; uengine < 32; uengine++) {
464 if (ixp2000_uengine_mask & (1 << uengine)) {
465 ixp2000_uengine_csr_write(uengine, TIMESTAMP_LOW, 0);
466 ixp2000_uengine_csr_write(uengine, TIMESTAMP_HIGH, 0);
467 }
468 }
469 ixp2000_reg_write(IXP2000_MISC_CONTROL, value | 0x80);
470
471 return 0;
472}
473
474subsys_initcall(ixp2000_uengine_init);
diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c
index 1f6857d7747d..b464bc88ff93 100644
--- a/arch/arm/mach-pxa/lubbock.c
+++ b/arch/arm/mach-pxa/lubbock.c
@@ -19,16 +19,20 @@
19#include <linux/major.h> 19#include <linux/major.h>
20#include <linux/fb.h> 20#include <linux/fb.h>
21#include <linux/interrupt.h> 21#include <linux/interrupt.h>
22#include <linux/mtd/mtd.h>
23#include <linux/mtd/partitions.h>
22 24
23#include <asm/setup.h> 25#include <asm/setup.h>
24#include <asm/memory.h> 26#include <asm/memory.h>
25#include <asm/mach-types.h> 27#include <asm/mach-types.h>
26#include <asm/hardware.h> 28#include <asm/hardware.h>
27#include <asm/irq.h> 29#include <asm/irq.h>
30#include <asm/sizes.h>
28 31
29#include <asm/mach/arch.h> 32#include <asm/mach/arch.h>
30#include <asm/mach/map.h> 33#include <asm/mach/map.h>
31#include <asm/mach/irq.h> 34#include <asm/mach/irq.h>
35#include <asm/mach/flash.h>
32 36
33#include <asm/hardware/sa1111.h> 37#include <asm/hardware/sa1111.h>
34 38
@@ -175,7 +179,7 @@ static struct platform_device sa1111_device = {
175static struct resource smc91x_resources[] = { 179static struct resource smc91x_resources[] = {
176 [0] = { 180 [0] = {
177 .name = "smc91x-regs", 181 .name = "smc91x-regs",
178 .start = 0x0c000000, 182 .start = 0x0c000c00,
179 .end = 0x0c0fffff, 183 .end = 0x0c0fffff,
180 .flags = IORESOURCE_MEM, 184 .flags = IORESOURCE_MEM,
181 }, 185 },
@@ -199,10 +203,75 @@ static struct platform_device smc91x_device = {
199 .resource = smc91x_resources, 203 .resource = smc91x_resources,
200}; 204};
201 205
206static struct resource flash_resources[] = {
207 [0] = {
208 .start = 0x00000000,
209 .end = SZ_64M - 1,
210 .flags = IORESOURCE_MEM,
211 },
212 [1] = {
213 .start = 0x04000000,
214 .end = 0x04000000 + SZ_64M - 1,
215 .flags = IORESOURCE_MEM,
216 },
217};
218
219static struct mtd_partition lubbock_partitions[] = {
220 {
221 .name = "Bootloader",
222 .size = 0x00040000,
223 .offset = 0,
224 .mask_flags = MTD_WRITEABLE /* force read-only */
225 },{
226 .name = "Kernel",
227 .size = 0x00100000,
228 .offset = 0x00040000,
229 },{
230 .name = "Filesystem",
231 .size = MTDPART_SIZ_FULL,
232 .offset = 0x00140000
233 }
234};
235
236static struct flash_platform_data lubbock_flash_data[2] = {
237 {
238 .map_name = "cfi_probe",
239 .parts = lubbock_partitions,
240 .nr_parts = ARRAY_SIZE(lubbock_partitions),
241 }, {
242 .map_name = "cfi_probe",
243 .parts = NULL,
244 .nr_parts = 0,
245 }
246};
247
248static struct platform_device lubbock_flash_device[2] = {
249 {
250 .name = "pxa2xx-flash",
251 .id = 0,
252 .dev = {
253 .platform_data = &lubbock_flash_data[0],
254 },
255 .resource = &flash_resources[0],
256 .num_resources = 1,
257 },
258 {
259 .name = "pxa2xx-flash",
260 .id = 1,
261 .dev = {
262 .platform_data = &lubbock_flash_data[1],
263 },
264 .resource = &flash_resources[1],
265 .num_resources = 1,
266 },
267};
268
202static struct platform_device *devices[] __initdata = { 269static struct platform_device *devices[] __initdata = {
203 &sa1111_device, 270 &sa1111_device,
204 &lub_audio_device, 271 &lub_audio_device,
205 &smc91x_device, 272 &smc91x_device,
273 &lubbock_flash_device[0],
274 &lubbock_flash_device[1],
206}; 275};
207 276
208static struct pxafb_mach_info sharp_lm8v31 __initdata = { 277static struct pxafb_mach_info sharp_lm8v31 __initdata = {
@@ -224,18 +293,75 @@ static struct pxafb_mach_info sharp_lm8v31 __initdata = {
224 .lccr3 = LCCR3_PCP | LCCR3_Acb(255), 293 .lccr3 = LCCR3_PCP | LCCR3_Acb(255),
225}; 294};
226 295
227static int lubbock_mci_init(struct device *dev, irqreturn_t (*lubbock_detect_int)(int, void *, struct pt_regs *), void *data) 296#define MMC_POLL_RATE msecs_to_jiffies(1000)
297
298static void lubbock_mmc_poll(unsigned long);
299static irqreturn_t (*mmc_detect_int)(int, void *, struct pt_regs *);
300
301static struct timer_list mmc_timer = {
302 .function = lubbock_mmc_poll,
303};
304
305static void lubbock_mmc_poll(unsigned long data)
306{
307 unsigned long flags;
308
309 /* clear any previous irq state, then ... */
310 local_irq_save(flags);
311 LUB_IRQ_SET_CLR &= ~(1 << 0);
312 local_irq_restore(flags);
313
314 /* poll until mmc/sd card is removed */
315 if (LUB_IRQ_SET_CLR & (1 << 0))
316 mod_timer(&mmc_timer, jiffies + MMC_POLL_RATE);
317 else {
318 (void) mmc_detect_int(LUBBOCK_SD_IRQ, (void *)data, NULL);
319 enable_irq(LUBBOCK_SD_IRQ);
320 }
321}
322
323static irqreturn_t lubbock_detect_int(int irq, void *data, struct pt_regs *regs)
324{
325 /* IRQ is level triggered; disable, and poll for removal */
326 disable_irq(irq);
327 mod_timer(&mmc_timer, jiffies + MMC_POLL_RATE);
328
329 return mmc_detect_int(irq, data, regs);
330}
331
332static int lubbock_mci_init(struct device *dev,
333 irqreturn_t (*detect_int)(int, void *, struct pt_regs *),
334 void *data)
228{ 335{
229 /* setup GPIO for PXA25x MMC controller */ 336 /* setup GPIO for PXA25x MMC controller */
230 pxa_gpio_mode(GPIO6_MMCCLK_MD); 337 pxa_gpio_mode(GPIO6_MMCCLK_MD);
231 pxa_gpio_mode(GPIO8_MMCCS0_MD); 338 pxa_gpio_mode(GPIO8_MMCCS0_MD);
232 339
233 return 0; 340 /* detect card insert/eject */
341 mmc_detect_int = detect_int;
342 init_timer(&mmc_timer);
343 mmc_timer.data = (unsigned long) data;
344 return request_irq(LUBBOCK_SD_IRQ, lubbock_detect_int,
345 SA_SAMPLE_RANDOM, "lubbock-sd-detect", data);
346}
347
348static int lubbock_mci_get_ro(struct device *dev)
349{
350 return (LUB_MISC_RD & (1 << 2)) != 0;
351}
352
353static void lubbock_mci_exit(struct device *dev, void *data)
354{
355 free_irq(LUBBOCK_SD_IRQ, data);
356 del_timer_sync(&mmc_timer);
234} 357}
235 358
236static struct pxamci_platform_data lubbock_mci_platform_data = { 359static struct pxamci_platform_data lubbock_mci_platform_data = {
237 .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, 360 .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
361 .detect_delay = 1,
238 .init = lubbock_mci_init, 362 .init = lubbock_mci_init,
363 .get_ro = lubbock_mci_get_ro,
364 .exit = lubbock_mci_exit,
239}; 365};
240 366
241static void lubbock_irda_transceiver_mode(struct device *dev, int mode) 367static void lubbock_irda_transceiver_mode(struct device *dev, int mode)
@@ -258,10 +384,21 @@ static struct pxaficp_platform_data lubbock_ficp_platform_data = {
258 384
259static void __init lubbock_init(void) 385static void __init lubbock_init(void)
260{ 386{
387 int flashboot = (LUB_CONF_SWITCHES & 1);
388
261 pxa_set_udc_info(&udc_info); 389 pxa_set_udc_info(&udc_info);
262 set_pxa_fb_info(&sharp_lm8v31); 390 set_pxa_fb_info(&sharp_lm8v31);
263 pxa_set_mci_info(&lubbock_mci_platform_data); 391 pxa_set_mci_info(&lubbock_mci_platform_data);
264 pxa_set_ficp_info(&lubbock_ficp_platform_data); 392 pxa_set_ficp_info(&lubbock_ficp_platform_data);
393
394 lubbock_flash_data[0].width = lubbock_flash_data[1].width =
395 (BOOT_DEF & 1) ? 2 : 4;
396 /* Compensate for the nROMBT switch which swaps the flash banks */
397 printk(KERN_NOTICE "Lubbock configured to boot from %s (bank %d)\n",
398 flashboot?"Flash":"ROM", flashboot);
399
400 lubbock_flash_data[flashboot^1].name = "application-flash";
401 lubbock_flash_data[flashboot].name = "boot-rom";
265 (void) platform_add_devices(devices, ARRAY_SIZE(devices)); 402 (void) platform_add_devices(devices, ARRAY_SIZE(devices));
266} 403}
267 404
diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c
index 887a8cb7b721..07892f4012d8 100644
--- a/arch/arm/mach-pxa/mainstone.c
+++ b/arch/arm/mach-pxa/mainstone.c
@@ -20,6 +20,9 @@
20#include <linux/sched.h> 20#include <linux/sched.h>
21#include <linux/bitops.h> 21#include <linux/bitops.h>
22#include <linux/fb.h> 22#include <linux/fb.h>
23#include <linux/ioport.h>
24#include <linux/mtd/mtd.h>
25#include <linux/mtd/partitions.h>
23 26
24#include <asm/types.h> 27#include <asm/types.h>
25#include <asm/setup.h> 28#include <asm/setup.h>
@@ -27,10 +30,12 @@
27#include <asm/mach-types.h> 30#include <asm/mach-types.h>
28#include <asm/hardware.h> 31#include <asm/hardware.h>
29#include <asm/irq.h> 32#include <asm/irq.h>
33#include <asm/sizes.h>
30 34
31#include <asm/mach/arch.h> 35#include <asm/mach/arch.h>
32#include <asm/mach/map.h> 36#include <asm/mach/map.h>
33#include <asm/mach/irq.h> 37#include <asm/mach/irq.h>
38#include <asm/mach/flash.h>
34 39
35#include <asm/arch/pxa-regs.h> 40#include <asm/arch/pxa-regs.h>
36#include <asm/arch/mainstone.h> 41#include <asm/arch/mainstone.h>
@@ -190,6 +195,69 @@ static struct platform_device mst_audio_device = {
190 .dev = { .platform_data = &mst_audio_ops }, 195 .dev = { .platform_data = &mst_audio_ops },
191}; 196};
192 197
198static struct resource flash_resources[] = {
199 [0] = {
200 .start = PXA_CS0_PHYS,
201 .end = PXA_CS0_PHYS + SZ_64M - 1,
202 .flags = IORESOURCE_MEM,
203 },
204 [1] = {
205 .start = PXA_CS1_PHYS,
206 .end = PXA_CS1_PHYS + SZ_64M - 1,
207 .flags = IORESOURCE_MEM,
208 },
209};
210
211static struct mtd_partition mainstoneflash0_partitions[] = {
212 {
213 .name = "Bootloader",
214 .size = 0x00040000,
215 .offset = 0,
216 .mask_flags = MTD_WRITEABLE /* force read-only */
217 },{
218 .name = "Kernel",
219 .size = 0x00400000,
220 .offset = 0x00040000,
221 },{
222 .name = "Filesystem",
223 .size = MTDPART_SIZ_FULL,
224 .offset = 0x00440000
225 }
226};
227
228static struct flash_platform_data mst_flash_data[2] = {
229 {
230 .map_name = "cfi_probe",
231 .parts = mainstoneflash0_partitions,
232 .nr_parts = ARRAY_SIZE(mainstoneflash0_partitions),
233 }, {
234 .map_name = "cfi_probe",
235 .parts = NULL,
236 .nr_parts = 0,
237 }
238};
239
240static struct platform_device mst_flash_device[2] = {
241 {
242 .name = "pxa2xx-flash",
243 .id = 0,
244 .dev = {
245 .platform_data = &mst_flash_data[0],
246 },
247 .resource = &flash_resources[0],
248 .num_resources = 1,
249 },
250 {
251 .name = "pxa2xx-flash",
252 .id = 1,
253 .dev = {
254 .platform_data = &mst_flash_data[1],
255 },
256 .resource = &flash_resources[1],
257 .num_resources = 1,
258 },
259};
260
193static void mainstone_backlight_power(int on) 261static void mainstone_backlight_power(int on)
194{ 262{
195 if (on) { 263 if (on) {
@@ -318,16 +386,34 @@ static struct pxaficp_platform_data mainstone_ficp_platform_data = {
318 .transceiver_mode = mainstone_irda_transceiver_mode, 386 .transceiver_mode = mainstone_irda_transceiver_mode,
319}; 387};
320 388
389static struct platform_device *platform_devices[] __initdata = {
390 &smc91x_device,
391 &mst_audio_device,
392 &mst_flash_device[0],
393 &mst_flash_device[1],
394};
395
321static void __init mainstone_init(void) 396static void __init mainstone_init(void)
322{ 397{
398 int SW7 = 0; /* FIXME: get from SCR (Mst doc section 3.2.1.1) */
399
400 mst_flash_data[0].width = (BOOT_DEF & 1) ? 2 : 4;
401 mst_flash_data[1].width = 4;
402
403 /* Compensate for SW7 which swaps the flash banks */
404 mst_flash_data[SW7].name = "processor-flash";
405 mst_flash_data[SW7 ^ 1].name = "mainboard-flash";
406
407 printk(KERN_NOTICE "Mainstone configured to boot from %s\n",
408 mst_flash_data[0].name);
409
323 /* 410 /*
324 * On Mainstone, we route AC97_SYSCLK via GPIO45 to 411 * On Mainstone, we route AC97_SYSCLK via GPIO45 to
325 * the audio daughter card 412 * the audio daughter card
326 */ 413 */
327 pxa_gpio_mode(GPIO45_SYSCLK_AC97_MD); 414 pxa_gpio_mode(GPIO45_SYSCLK_AC97_MD);
328 415
329 platform_device_register(&smc91x_device); 416 platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
330 platform_device_register(&mst_audio_device);
331 417
332 /* reading Mainstone's "Virtual Configuration Register" 418 /* reading Mainstone's "Virtual Configuration Register"
333 might be handy to select LCD type here */ 419 might be handy to select LCD type here */
diff --git a/arch/arm/mach-realview/Kconfig b/arch/arm/mach-realview/Kconfig
new file mode 100644
index 000000000000..4b63dc9eabfe
--- /dev/null
+++ b/arch/arm/mach-realview/Kconfig
@@ -0,0 +1,11 @@
1menu "RealView platform type"
2 depends on ARCH_REALVIEW
3
4config MACH_REALVIEW_EB
5 bool "Support RealView/EB platform"
6 default n
7 select ARM_GIC
8 help
9 Include support for the ARM(R) RealView Emulation Baseboard platform.
10
11endmenu
diff --git a/arch/arm/mach-realview/Makefile b/arch/arm/mach-realview/Makefile
new file mode 100644
index 000000000000..8d37ea1605fd
--- /dev/null
+++ b/arch/arm/mach-realview/Makefile
@@ -0,0 +1,6 @@
1#
2# Makefile for the linux kernel.
3#
4
5obj-y := core.o clock.o
6obj-$(CONFIG_MACH_REALVIEW_EB) += realview_eb.o
diff --git a/arch/arm/mach-realview/Makefile.boot b/arch/arm/mach-realview/Makefile.boot
new file mode 100644
index 000000000000..c7e75acfe6c9
--- /dev/null
+++ b/arch/arm/mach-realview/Makefile.boot
@@ -0,0 +1,4 @@
1 zreladdr-y := 0x00008000
2params_phys-y := 0x00000100
3initrd_phys-y := 0x00800000
4
diff --git a/arch/arm/mach-realview/clock.c b/arch/arm/mach-realview/clock.c
new file mode 100644
index 000000000000..002635c97bb6
--- /dev/null
+++ b/arch/arm/mach-realview/clock.c
@@ -0,0 +1,145 @@
1/*
2 * linux/arch/arm/mach-realview/clock.c
3 *
4 * Copyright (C) 2004 ARM Limited.
5 * Written by Deep Blue Solutions Limited.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#include <linux/module.h>
12#include <linux/kernel.h>
13#include <linux/list.h>
14#include <linux/errno.h>
15#include <linux/err.h>
16
17#include <asm/semaphore.h>
18#include <asm/hardware/clock.h>
19#include <asm/hardware/icst307.h>
20
21#include "clock.h"
22
23static LIST_HEAD(clocks);
24static DECLARE_MUTEX(clocks_sem);
25
26struct clk *clk_get(struct device *dev, const char *id)
27{
28 struct clk *p, *clk = ERR_PTR(-ENOENT);
29
30 down(&clocks_sem);
31 list_for_each_entry(p, &clocks, node) {
32 if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
33 clk = p;
34 break;
35 }
36 }
37 up(&clocks_sem);
38
39 return clk;
40}
41EXPORT_SYMBOL(clk_get);
42
43void clk_put(struct clk *clk)
44{
45 module_put(clk->owner);
46}
47EXPORT_SYMBOL(clk_put);
48
49int clk_enable(struct clk *clk)
50{
51 return 0;
52}
53EXPORT_SYMBOL(clk_enable);
54
55void clk_disable(struct clk *clk)
56{
57}
58EXPORT_SYMBOL(clk_disable);
59
60int clk_use(struct clk *clk)
61{
62 return 0;
63}
64EXPORT_SYMBOL(clk_use);
65
66void clk_unuse(struct clk *clk)
67{
68}
69EXPORT_SYMBOL(clk_unuse);
70
71unsigned long clk_get_rate(struct clk *clk)
72{
73 return clk->rate;
74}
75EXPORT_SYMBOL(clk_get_rate);
76
77long clk_round_rate(struct clk *clk, unsigned long rate)
78{
79 return rate;
80}
81EXPORT_SYMBOL(clk_round_rate);
82
83int clk_set_rate(struct clk *clk, unsigned long rate)
84{
85 int ret = -EIO;
86
87 if (clk->setvco) {
88 struct icst307_vco vco;
89
90 vco = icst307_khz_to_vco(clk->params, rate / 1000);
91 clk->rate = icst307_khz(clk->params, vco) * 1000;
92
93 printk("Clock %s: setting VCO reg params: S=%d R=%d V=%d\n",
94 clk->name, vco.s, vco.r, vco.v);
95
96 clk->setvco(clk, vco);
97 ret = 0;
98 }
99 return ret;
100}
101EXPORT_SYMBOL(clk_set_rate);
102
103/*
104 * These are fixed clocks.
105 */
106static struct clk kmi_clk = {
107 .name = "KMIREFCLK",
108 .rate = 24000000,
109};
110
111static struct clk uart_clk = {
112 .name = "UARTCLK",
113 .rate = 24000000,
114};
115
116static struct clk mmci_clk = {
117 .name = "MCLK",
118 .rate = 33000000,
119};
120
121int clk_register(struct clk *clk)
122{
123 down(&clocks_sem);
124 list_add(&clk->node, &clocks);
125 up(&clocks_sem);
126 return 0;
127}
128EXPORT_SYMBOL(clk_register);
129
130void clk_unregister(struct clk *clk)
131{
132 down(&clocks_sem);
133 list_del(&clk->node);
134 up(&clocks_sem);
135}
136EXPORT_SYMBOL(clk_unregister);
137
138static int __init clk_init(void)
139{
140 clk_register(&kmi_clk);
141 clk_register(&uart_clk);
142 clk_register(&mmci_clk);
143 return 0;
144}
145arch_initcall(clk_init);
diff --git a/arch/arm/mach-realview/clock.h b/arch/arm/mach-realview/clock.h
new file mode 100644
index 000000000000..dadba695e181
--- /dev/null
+++ b/arch/arm/mach-realview/clock.h
@@ -0,0 +1,25 @@
1/*
2 * linux/arch/arm/mach-realview/clock.h
3 *
4 * Copyright (C) 2004 ARM Limited.
5 * Written by Deep Blue Solutions Limited.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11struct module;
12struct icst307_params;
13
14struct clk {
15 struct list_head node;
16 unsigned long rate;
17 struct module *owner;
18 const char *name;
19 const struct icst307_params *params;
20 void *data;
21 void (*setvco)(struct clk *, struct icst307_vco vco);
22};
23
24int clk_register(struct clk *clk);
25void clk_unregister(struct clk *clk);
diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c
new file mode 100644
index 000000000000..482eb512ebe8
--- /dev/null
+++ b/arch/arm/mach-realview/core.c
@@ -0,0 +1,605 @@
1/*
2 * linux/arch/arm/mach-realview/core.c
3 *
4 * Copyright (C) 1999 - 2003 ARM Limited
5 * Copyright (C) 2000 Deep Blue Solutions Ltd
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21#include <linux/config.h>
22#include <linux/init.h>
23#include <linux/platform_device.h>
24#include <linux/dma-mapping.h>
25#include <linux/sysdev.h>
26#include <linux/interrupt.h>
27
28#include <asm/system.h>
29#include <asm/hardware.h>
30#include <asm/io.h>
31#include <asm/irq.h>
32#include <asm/leds.h>
33#include <asm/mach-types.h>
34#include <asm/hardware/amba.h>
35#include <asm/hardware/amba_clcd.h>
36#include <asm/hardware/arm_timer.h>
37#include <asm/hardware/icst307.h>
38
39#include <asm/mach/arch.h>
40#include <asm/mach/flash.h>
41#include <asm/mach/irq.h>
42#include <asm/mach/time.h>
43#include <asm/mach/map.h>
44#include <asm/mach/mmc.h>
45
46#include <asm/hardware/gic.h>
47
48#include "core.h"
49#include "clock.h"
50
51#define REALVIEW_REFCOUNTER (__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_24MHz_OFFSET)
52
53/*
54 * This is the RealView sched_clock implementation. This has
55 * a resolution of 41.7ns, and a maximum value of about 179s.
56 */
57unsigned long long sched_clock(void)
58{
59 unsigned long long v;
60
61 v = (unsigned long long)readl(REALVIEW_REFCOUNTER) * 125;
62 do_div(v, 3);
63
64 return v;
65}
66
67
68#define REALVIEW_FLASHCTRL (__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_FLASH_OFFSET)
69
70static int realview_flash_init(void)
71{
72 u32 val;
73
74 val = __raw_readl(REALVIEW_FLASHCTRL);
75 val &= ~REALVIEW_FLASHPROG_FLVPPEN;
76 __raw_writel(val, REALVIEW_FLASHCTRL);
77
78 return 0;
79}
80
81static void realview_flash_exit(void)
82{
83 u32 val;
84
85 val = __raw_readl(REALVIEW_FLASHCTRL);
86 val &= ~REALVIEW_FLASHPROG_FLVPPEN;
87 __raw_writel(val, REALVIEW_FLASHCTRL);
88}
89
90static void realview_flash_set_vpp(int on)
91{
92 u32 val;
93
94 val = __raw_readl(REALVIEW_FLASHCTRL);
95 if (on)
96 val |= REALVIEW_FLASHPROG_FLVPPEN;
97 else
98 val &= ~REALVIEW_FLASHPROG_FLVPPEN;
99 __raw_writel(val, REALVIEW_FLASHCTRL);
100}
101
102static struct flash_platform_data realview_flash_data = {
103 .map_name = "cfi_probe",
104 .width = 4,
105 .init = realview_flash_init,
106 .exit = realview_flash_exit,
107 .set_vpp = realview_flash_set_vpp,
108};
109
110static struct resource realview_flash_resource = {
111 .start = REALVIEW_FLASH_BASE,
112 .end = REALVIEW_FLASH_BASE + REALVIEW_FLASH_SIZE,
113 .flags = IORESOURCE_MEM,
114};
115
116struct platform_device realview_flash_device = {
117 .name = "armflash",
118 .id = 0,
119 .dev = {
120 .platform_data = &realview_flash_data,
121 },
122 .num_resources = 1,
123 .resource = &realview_flash_resource,
124};
125
126static struct resource realview_smc91x_resources[] = {
127 [0] = {
128 .start = REALVIEW_ETH_BASE,
129 .end = REALVIEW_ETH_BASE + SZ_64K - 1,
130 .flags = IORESOURCE_MEM,
131 },
132 [1] = {
133 .start = IRQ_ETH,
134 .end = IRQ_ETH,
135 .flags = IORESOURCE_IRQ,
136 },
137};
138
139struct platform_device realview_smc91x_device = {
140 .name = "smc91x",
141 .id = 0,
142 .num_resources = ARRAY_SIZE(realview_smc91x_resources),
143 .resource = realview_smc91x_resources,
144};
145
146#define REALVIEW_SYSMCI (__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_MCI_OFFSET)
147
148static unsigned int realview_mmc_status(struct device *dev)
149{
150 struct amba_device *adev = container_of(dev, struct amba_device, dev);
151 u32 mask;
152
153 if (adev->res.start == REALVIEW_MMCI0_BASE)
154 mask = 1;
155 else
156 mask = 2;
157
158 return readl(REALVIEW_SYSMCI) & mask;
159}
160
161struct mmc_platform_data realview_mmc0_plat_data = {
162 .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
163 .status = realview_mmc_status,
164};
165
166struct mmc_platform_data realview_mmc1_plat_data = {
167 .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
168 .status = realview_mmc_status,
169};
170
171/*
172 * Clock handling
173 */
174static const struct icst307_params realview_oscvco_params = {
175 .ref = 24000,
176 .vco_max = 200000,
177 .vd_min = 4 + 8,
178 .vd_max = 511 + 8,
179 .rd_min = 1 + 2,
180 .rd_max = 127 + 2,
181};
182
183static void realview_oscvco_set(struct clk *clk, struct icst307_vco vco)
184{
185 void __iomem *sys_lock = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_LOCK_OFFSET;
186 void __iomem *sys_osc = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_OSC1_OFFSET;
187 u32 val;
188
189 val = readl(sys_osc) & ~0x7ffff;
190 val |= vco.v | (vco.r << 9) | (vco.s << 16);
191
192 writel(0xa05f, sys_lock);
193 writel(val, sys_osc);
194 writel(0, sys_lock);
195}
196
197struct clk realview_clcd_clk = {
198 .name = "CLCDCLK",
199 .params = &realview_oscvco_params,
200 .setvco = realview_oscvco_set,
201};
202
203/*
204 * CLCD support.
205 */
206#define SYS_CLCD_MODE_MASK (3 << 0)
207#define SYS_CLCD_MODE_888 (0 << 0)
208#define SYS_CLCD_MODE_5551 (1 << 0)
209#define SYS_CLCD_MODE_565_RLSB (2 << 0)
210#define SYS_CLCD_MODE_565_BLSB (3 << 0)
211#define SYS_CLCD_NLCDIOON (1 << 2)
212#define SYS_CLCD_VDDPOSSWITCH (1 << 3)
213#define SYS_CLCD_PWR3V5SWITCH (1 << 4)
214#define SYS_CLCD_ID_MASK (0x1f << 8)
215#define SYS_CLCD_ID_SANYO_3_8 (0x00 << 8)
216#define SYS_CLCD_ID_UNKNOWN_8_4 (0x01 << 8)
217#define SYS_CLCD_ID_EPSON_2_2 (0x02 << 8)
218#define SYS_CLCD_ID_SANYO_2_5 (0x07 << 8)
219#define SYS_CLCD_ID_VGA (0x1f << 8)
220
221static struct clcd_panel vga = {
222 .mode = {
223 .name = "VGA",
224 .refresh = 60,
225 .xres = 640,
226 .yres = 480,
227 .pixclock = 39721,
228 .left_margin = 40,
229 .right_margin = 24,
230 .upper_margin = 32,
231 .lower_margin = 11,
232 .hsync_len = 96,
233 .vsync_len = 2,
234 .sync = 0,
235 .vmode = FB_VMODE_NONINTERLACED,
236 },
237 .width = -1,
238 .height = -1,
239 .tim2 = TIM2_BCD | TIM2_IPC,
240 .cntl = CNTL_LCDTFT | CNTL_LCDVCOMP(1),
241 .bpp = 16,
242};
243
244static struct clcd_panel sanyo_3_8_in = {
245 .mode = {
246 .name = "Sanyo QVGA",
247 .refresh = 116,
248 .xres = 320,
249 .yres = 240,
250 .pixclock = 100000,
251 .left_margin = 6,
252 .right_margin = 6,
253 .upper_margin = 5,
254 .lower_margin = 5,
255 .hsync_len = 6,
256 .vsync_len = 6,
257 .sync = 0,
258 .vmode = FB_VMODE_NONINTERLACED,
259 },
260 .width = -1,
261 .height = -1,
262 .tim2 = TIM2_BCD,
263 .cntl = CNTL_LCDTFT | CNTL_LCDVCOMP(1),
264 .bpp = 16,
265};
266
267static struct clcd_panel sanyo_2_5_in = {
268 .mode = {
269 .name = "Sanyo QVGA Portrait",
270 .refresh = 116,
271 .xres = 240,
272 .yres = 320,
273 .pixclock = 100000,
274 .left_margin = 20,
275 .right_margin = 10,
276 .upper_margin = 2,
277 .lower_margin = 2,
278 .hsync_len = 10,
279 .vsync_len = 2,
280 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
281 .vmode = FB_VMODE_NONINTERLACED,
282 },
283 .width = -1,
284 .height = -1,
285 .tim2 = TIM2_IVS | TIM2_IHS | TIM2_IPC,
286 .cntl = CNTL_LCDTFT | CNTL_LCDVCOMP(1),
287 .bpp = 16,
288};
289
290static struct clcd_panel epson_2_2_in = {
291 .mode = {
292 .name = "Epson QCIF",
293 .refresh = 390,
294 .xres = 176,
295 .yres = 220,
296 .pixclock = 62500,
297 .left_margin = 3,
298 .right_margin = 2,
299 .upper_margin = 1,
300 .lower_margin = 0,
301 .hsync_len = 3,
302 .vsync_len = 2,
303 .sync = 0,
304 .vmode = FB_VMODE_NONINTERLACED,
305 },
306 .width = -1,
307 .height = -1,
308 .tim2 = TIM2_BCD | TIM2_IPC,
309 .cntl = CNTL_LCDTFT | CNTL_LCDVCOMP(1),
310 .bpp = 16,
311};
312
313/*
314 * Detect which LCD panel is connected, and return the appropriate
315 * clcd_panel structure. Note: we do not have any information on
316 * the required timings for the 8.4in panel, so we presently assume
317 * VGA timings.
318 */
319static struct clcd_panel *realview_clcd_panel(void)
320{
321 void __iomem *sys_clcd = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_CLCD_OFFSET;
322 struct clcd_panel *panel = &vga;
323 u32 val;
324
325 val = readl(sys_clcd) & SYS_CLCD_ID_MASK;
326 if (val == SYS_CLCD_ID_SANYO_3_8)
327 panel = &sanyo_3_8_in;
328 else if (val == SYS_CLCD_ID_SANYO_2_5)
329 panel = &sanyo_2_5_in;
330 else if (val == SYS_CLCD_ID_EPSON_2_2)
331 panel = &epson_2_2_in;
332 else if (val == SYS_CLCD_ID_VGA)
333 panel = &vga;
334 else {
335 printk(KERN_ERR "CLCD: unknown LCD panel ID 0x%08x, using VGA\n",
336 val);
337 panel = &vga;
338 }
339
340 return panel;
341}
342
343/*
344 * Disable all display connectors on the interface module.
345 */
346static void realview_clcd_disable(struct clcd_fb *fb)
347{
348 void __iomem *sys_clcd = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_CLCD_OFFSET;
349 u32 val;
350
351 val = readl(sys_clcd);
352 val &= ~SYS_CLCD_NLCDIOON | SYS_CLCD_PWR3V5SWITCH;
353 writel(val, sys_clcd);
354}
355
356/*
357 * Enable the relevant connector on the interface module.
358 */
359static void realview_clcd_enable(struct clcd_fb *fb)
360{
361 void __iomem *sys_clcd = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_CLCD_OFFSET;
362 u32 val;
363
364 val = readl(sys_clcd);
365 val &= ~SYS_CLCD_MODE_MASK;
366
367 switch (fb->fb.var.green.length) {
368 case 5:
369 val |= SYS_CLCD_MODE_5551;
370 break;
371 case 6:
372 val |= SYS_CLCD_MODE_565_RLSB;
373 break;
374 case 8:
375 val |= SYS_CLCD_MODE_888;
376 break;
377 }
378
379 /*
380 * Set the MUX
381 */
382 writel(val, sys_clcd);
383
384 /*
385 * And now enable the PSUs
386 */
387 val |= SYS_CLCD_NLCDIOON | SYS_CLCD_PWR3V5SWITCH;
388 writel(val, sys_clcd);
389}
390
391static unsigned long framesize = SZ_1M;
392
393static int realview_clcd_setup(struct clcd_fb *fb)
394{
395 dma_addr_t dma;
396
397 fb->panel = realview_clcd_panel();
398
399 fb->fb.screen_base = dma_alloc_writecombine(&fb->dev->dev, framesize,
400 &dma, GFP_KERNEL);
401 if (!fb->fb.screen_base) {
402 printk(KERN_ERR "CLCD: unable to map framebuffer\n");
403 return -ENOMEM;
404 }
405
406 fb->fb.fix.smem_start = dma;
407 fb->fb.fix.smem_len = framesize;
408
409 return 0;
410}
411
412static int realview_clcd_mmap(struct clcd_fb *fb, struct vm_area_struct *vma)
413{
414 return dma_mmap_writecombine(&fb->dev->dev, vma,
415 fb->fb.screen_base,
416 fb->fb.fix.smem_start,
417 fb->fb.fix.smem_len);
418}
419
420static void realview_clcd_remove(struct clcd_fb *fb)
421{
422 dma_free_writecombine(&fb->dev->dev, fb->fb.fix.smem_len,
423 fb->fb.screen_base, fb->fb.fix.smem_start);
424}
425
426struct clcd_board clcd_plat_data = {
427 .name = "RealView",
428 .check = clcdfb_check,
429 .decode = clcdfb_decode,
430 .disable = realview_clcd_disable,
431 .enable = realview_clcd_enable,
432 .setup = realview_clcd_setup,
433 .mmap = realview_clcd_mmap,
434 .remove = realview_clcd_remove,
435};
436
437#ifdef CONFIG_LEDS
438#define VA_LEDS_BASE (__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_LED_OFFSET)
439
440void realview_leds_event(led_event_t ledevt)
441{
442 unsigned long flags;
443 u32 val;
444
445 local_irq_save(flags);
446 val = readl(VA_LEDS_BASE);
447
448 switch (ledevt) {
449 case led_idle_start:
450 val = val & ~REALVIEW_SYS_LED0;
451 break;
452
453 case led_idle_end:
454 val = val | REALVIEW_SYS_LED0;
455 break;
456
457 case led_timer:
458 val = val ^ REALVIEW_SYS_LED1;
459 break;
460
461 case led_halted:
462 val = 0;
463 break;
464
465 default:
466 break;
467 }
468
469 writel(val, VA_LEDS_BASE);
470 local_irq_restore(flags);
471}
472#endif /* CONFIG_LEDS */
473
474/*
475 * Where is the timer (VA)?
476 */
477#define TIMER0_VA_BASE __io_address(REALVIEW_TIMER0_1_BASE)
478#define TIMER1_VA_BASE (__io_address(REALVIEW_TIMER0_1_BASE) + 0x20)
479#define TIMER2_VA_BASE __io_address(REALVIEW_TIMER2_3_BASE)
480#define TIMER3_VA_BASE (__io_address(REALVIEW_TIMER2_3_BASE) + 0x20)
481
482/*
483 * How long is the timer interval?
484 */
485#define TIMER_INTERVAL (TICKS_PER_uSEC * mSEC_10)
486#if TIMER_INTERVAL >= 0x100000
487#define TIMER_RELOAD (TIMER_INTERVAL >> 8)
488#define TIMER_DIVISOR (TIMER_CTRL_DIV256)
489#define TICKS2USECS(x) (256 * (x) / TICKS_PER_uSEC)
490#elif TIMER_INTERVAL >= 0x10000
491#define TIMER_RELOAD (TIMER_INTERVAL >> 4) /* Divide by 16 */
492#define TIMER_DIVISOR (TIMER_CTRL_DIV16)
493#define TICKS2USECS(x) (16 * (x) / TICKS_PER_uSEC)
494#else
495#define TIMER_RELOAD (TIMER_INTERVAL)
496#define TIMER_DIVISOR (TIMER_CTRL_DIV1)
497#define TICKS2USECS(x) ((x) / TICKS_PER_uSEC)
498#endif
499
500/*
501 * Returns number of ms since last clock interrupt. Note that interrupts
502 * will have been disabled by do_gettimeoffset()
503 */
504static unsigned long realview_gettimeoffset(void)
505{
506 unsigned long ticks1, ticks2, status;
507
508 /*
509 * Get the current number of ticks. Note that there is a race
510 * condition between us reading the timer and checking for
511 * an interrupt. We get around this by ensuring that the
512 * counter has not reloaded between our two reads.
513 */
514 ticks2 = readl(TIMER0_VA_BASE + TIMER_VALUE) & 0xffff;
515 do {
516 ticks1 = ticks2;
517 status = __raw_readl(__io_address(REALVIEW_GIC_DIST_BASE + GIC_DIST_PENDING_SET)
518 + ((IRQ_TIMERINT0_1 >> 5) << 2));
519 ticks2 = readl(TIMER0_VA_BASE + TIMER_VALUE) & 0xffff;
520 } while (ticks2 > ticks1);
521
522 /*
523 * Number of ticks since last interrupt.
524 */
525 ticks1 = TIMER_RELOAD - ticks2;
526
527 /*
528 * Interrupt pending? If so, we've reloaded once already.
529 *
530 * FIXME: Need to check this is effectively timer 0 that expires
531 */
532 if (status & IRQMASK_TIMERINT0_1)
533 ticks1 += TIMER_RELOAD;
534
535 /*
536 * Convert the ticks to usecs
537 */
538 return TICKS2USECS(ticks1);
539}
540
541/*
542 * IRQ handler for the timer
543 */
544static irqreturn_t realview_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
545{
546 write_seqlock(&xtime_lock);
547
548 // ...clear the interrupt
549 writel(1, TIMER0_VA_BASE + TIMER_INTCLR);
550
551 timer_tick(regs);
552
553 write_sequnlock(&xtime_lock);
554
555 return IRQ_HANDLED;
556}
557
558static struct irqaction realview_timer_irq = {
559 .name = "RealView Timer Tick",
560 .flags = SA_INTERRUPT | SA_TIMER,
561 .handler = realview_timer_interrupt,
562};
563
564/*
565 * Set up timer interrupt, and return the current time in seconds.
566 */
567static void __init realview_timer_init(void)
568{
569 u32 val;
570
571 /*
572 * set clock frequency:
573 * REALVIEW_REFCLK is 32KHz
574 * REALVIEW_TIMCLK is 1MHz
575 */
576 val = readl(__io_address(REALVIEW_SCTL_BASE));
577 writel((REALVIEW_TIMCLK << REALVIEW_TIMER1_EnSel) |
578 (REALVIEW_TIMCLK << REALVIEW_TIMER2_EnSel) |
579 (REALVIEW_TIMCLK << REALVIEW_TIMER3_EnSel) |
580 (REALVIEW_TIMCLK << REALVIEW_TIMER4_EnSel) | val,
581 __io_address(REALVIEW_SCTL_BASE));
582
583 /*
584 * Initialise to a known state (all timers off)
585 */
586 writel(0, TIMER0_VA_BASE + TIMER_CTRL);
587 writel(0, TIMER1_VA_BASE + TIMER_CTRL);
588 writel(0, TIMER2_VA_BASE + TIMER_CTRL);
589 writel(0, TIMER3_VA_BASE + TIMER_CTRL);
590
591 writel(TIMER_RELOAD, TIMER0_VA_BASE + TIMER_LOAD);
592 writel(TIMER_RELOAD, TIMER0_VA_BASE + TIMER_VALUE);
593 writel(TIMER_DIVISOR | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC |
594 TIMER_CTRL_IE, TIMER0_VA_BASE + TIMER_CTRL);
595
596 /*
597 * Make irqs happen for the system timer
598 */
599 setup_irq(IRQ_TIMERINT0_1, &realview_timer_irq);
600}
601
602struct sys_timer realview_timer = {
603 .init = realview_timer_init,
604 .offset = realview_gettimeoffset,
605};
diff --git a/arch/arm/mach-realview/core.h b/arch/arm/mach-realview/core.h
new file mode 100644
index 000000000000..575599db74db
--- /dev/null
+++ b/arch/arm/mach-realview/core.h
@@ -0,0 +1,118 @@
1/*
2 * linux/arch/arm/mach-realview/core.h
3 *
4 * Copyright (C) 2004 ARM Limited
5 * Copyright (C) 2000 Deep Blue Solutions Ltd
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22#ifndef __ASM_ARCH_REALVIEW_H
23#define __ASM_ARCH_REALVIEW_H
24
25#include <asm/hardware/amba.h>
26#include <asm/io.h>
27
28#define __io_address(n) __io(IO_ADDRESS(n))
29
30extern struct sys_timer realview_timer;
31
32#define AMBA_DEVICE(name,busid,base,plat) \
33static struct amba_device name##_device = { \
34 .dev = { \
35 .coherent_dma_mask = ~0, \
36 .bus_id = busid, \
37 .platform_data = plat, \
38 }, \
39 .res = { \
40 .start = REALVIEW_##base##_BASE, \
41 .end = (REALVIEW_##base##_BASE) + SZ_4K - 1,\
42 .flags = IORESOURCE_MEM, \
43 }, \
44 .dma_mask = ~0, \
45 .irq = base##_IRQ, \
46 /* .dma = base##_DMA,*/ \
47}
48
49/*
50 * These devices are connected via the core APB bridge
51 */
52#define GPIO2_IRQ { IRQ_GPIOINT2, NO_IRQ }
53#define GPIO2_DMA { 0, 0 }
54#define GPIO3_IRQ { IRQ_GPIOINT3, NO_IRQ }
55#define GPIO3_DMA { 0, 0 }
56
57#define AACI_IRQ { IRQ_AACI, NO_IRQ }
58#define AACI_DMA { 0x80, 0x81 }
59#define MMCI0_IRQ { IRQ_MMCI0A,IRQ_MMCI0B }
60#define MMCI0_DMA { 0x84, 0 }
61#define KMI0_IRQ { IRQ_KMI0, NO_IRQ }
62#define KMI0_DMA { 0, 0 }
63#define KMI1_IRQ { IRQ_KMI1, NO_IRQ }
64#define KMI1_DMA { 0, 0 }
65
66/*
67 * These devices are connected directly to the multi-layer AHB switch
68 */
69#define SMC_IRQ { NO_IRQ, NO_IRQ }
70#define SMC_DMA { 0, 0 }
71#define MPMC_IRQ { NO_IRQ, NO_IRQ }
72#define MPMC_DMA { 0, 0 }
73#define CLCD_IRQ { IRQ_CLCDINT, NO_IRQ }
74#define CLCD_DMA { 0, 0 }
75#define DMAC_IRQ { IRQ_DMAINT, NO_IRQ }
76#define DMAC_DMA { 0, 0 }
77
78/*
79 * These devices are connected via the core APB bridge
80 */
81#define SCTL_IRQ { NO_IRQ, NO_IRQ }
82#define SCTL_DMA { 0, 0 }
83#define WATCHDOG_IRQ { IRQ_WDOGINT, NO_IRQ }
84#define WATCHDOG_DMA { 0, 0 }
85#define GPIO0_IRQ { IRQ_GPIOINT0, NO_IRQ }
86#define GPIO0_DMA { 0, 0 }
87#define GPIO1_IRQ { IRQ_GPIOINT1, NO_IRQ }
88#define GPIO1_DMA { 0, 0 }
89#define RTC_IRQ { IRQ_RTCINT, NO_IRQ }
90#define RTC_DMA { 0, 0 }
91
92/*
93 * These devices are connected via the DMA APB bridge
94 */
95#define SCI_IRQ { IRQ_SCIINT, NO_IRQ }
96#define SCI_DMA { 7, 6 }
97#define UART0_IRQ { IRQ_UARTINT0, NO_IRQ }
98#define UART0_DMA { 15, 14 }
99#define UART1_IRQ { IRQ_UARTINT1, NO_IRQ }
100#define UART1_DMA { 13, 12 }
101#define UART2_IRQ { IRQ_UARTINT2, NO_IRQ }
102#define UART2_DMA { 11, 10 }
103#define UART3_IRQ { IRQ_UART3, NO_IRQ }
104#define UART3_DMA { 0x86, 0x87 }
105#define SSP_IRQ { IRQ_SSPINT, NO_IRQ }
106#define SSP_DMA { 9, 8 }
107
108
109extern struct platform_device realview_flash_device;
110extern struct platform_device realview_smc91x_device;
111extern struct mmc_platform_data realview_mmc0_plat_data;
112extern struct mmc_platform_data realview_mmc1_plat_data;
113extern struct clk realview_clcd_clk;
114extern struct clcd_board clcd_plat_data;
115
116extern void realview_leds_event(led_event_t ledevt);
117
118#endif
diff --git a/arch/arm/mach-realview/realview_eb.c b/arch/arm/mach-realview/realview_eb.c
new file mode 100644
index 000000000000..267bb07e39b7
--- /dev/null
+++ b/arch/arm/mach-realview/realview_eb.c
@@ -0,0 +1,172 @@
1/*
2 * linux/arch/arm/mach-realview/realview_eb.c
3 *
4 * Copyright (C) 2004 ARM Limited
5 * Copyright (C) 2000 Deep Blue Solutions Ltd
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22#include <linux/config.h>
23#include <linux/init.h>
24#include <linux/platform_device.h>
25#include <linux/sysdev.h>
26
27#include <asm/hardware.h>
28#include <asm/io.h>
29#include <asm/irq.h>
30#include <asm/leds.h>
31#include <asm/mach-types.h>
32#include <asm/hardware/gic.h>
33#include <asm/hardware/amba.h>
34#include <asm/hardware/icst307.h>
35
36#include <asm/mach/arch.h>
37#include <asm/mach/map.h>
38#include <asm/mach/mmc.h>
39
40#include <asm/arch/irqs.h>
41
42#include "core.h"
43#include "clock.h"
44
45static struct map_desc realview_eb_io_desc[] __initdata = {
46 {
47 .virtual = IO_ADDRESS(REALVIEW_SYS_BASE),
48 .pfn = __phys_to_pfn(REALVIEW_SYS_BASE),
49 .length = SZ_4K,
50 .type = MT_DEVICE,
51 }, {
52 .virtual = IO_ADDRESS(REALVIEW_GIC_CPU_BASE),
53 .pfn = __phys_to_pfn(REALVIEW_GIC_CPU_BASE),
54 .length = SZ_4K,
55 .type = MT_DEVICE,
56 }, {
57 .virtual = IO_ADDRESS(REALVIEW_GIC_DIST_BASE),
58 .pfn = __phys_to_pfn(REALVIEW_GIC_DIST_BASE),
59 .length = SZ_4K,
60 .type = MT_DEVICE,
61 }, {
62 .virtual = IO_ADDRESS(REALVIEW_SCTL_BASE),
63 .pfn = __phys_to_pfn(REALVIEW_SCTL_BASE),
64 .length = SZ_4K,
65 .type = MT_DEVICE,
66 }, {
67 .virtual = IO_ADDRESS(REALVIEW_TIMER0_1_BASE),
68 .pfn = __phys_to_pfn(REALVIEW_TIMER0_1_BASE),
69 .length = SZ_4K,
70 .type = MT_DEVICE,
71 }, {
72 .virtual = IO_ADDRESS(REALVIEW_TIMER2_3_BASE),
73 .pfn = __phys_to_pfn(REALVIEW_TIMER2_3_BASE),
74 .length = SZ_4K,
75 .type = MT_DEVICE,
76 },
77#ifdef CONFIG_DEBUG_LL
78 {
79 .virtual = IO_ADDRESS(REALVIEW_UART0_BASE),
80 .pfn = __phys_to_pfn(REALVIEW_UART0_BASE),
81 .length = SZ_4K,
82 .type = MT_DEVICE,
83 }
84#endif
85};
86
87static void __init realview_eb_map_io(void)
88{
89 iotable_init(realview_eb_io_desc, ARRAY_SIZE(realview_eb_io_desc));
90}
91
92/* FPGA Primecells */
93AMBA_DEVICE(aaci, "fpga:04", AACI, NULL);
94AMBA_DEVICE(mmc0, "fpga:05", MMCI0, &realview_mmc0_plat_data);
95AMBA_DEVICE(kmi0, "fpga:06", KMI0, NULL);
96AMBA_DEVICE(kmi1, "fpga:07", KMI1, NULL);
97AMBA_DEVICE(uart3, "fpga:09", UART3, NULL);
98
99/* DevChip Primecells */
100AMBA_DEVICE(smc, "dev:00", SMC, NULL);
101AMBA_DEVICE(clcd, "dev:20", CLCD, &clcd_plat_data);
102AMBA_DEVICE(dmac, "dev:30", DMAC, NULL);
103AMBA_DEVICE(sctl, "dev:e0", SCTL, NULL);
104AMBA_DEVICE(wdog, "dev:e1", WATCHDOG, NULL);
105AMBA_DEVICE(gpio0, "dev:e4", GPIO0, NULL);
106AMBA_DEVICE(gpio1, "dev:e5", GPIO1, NULL);
107AMBA_DEVICE(gpio2, "dev:e6", GPIO2, NULL);
108AMBA_DEVICE(rtc, "dev:e8", RTC, NULL);
109AMBA_DEVICE(sci0, "dev:f0", SCI, NULL);
110AMBA_DEVICE(uart0, "dev:f1", UART0, NULL);
111AMBA_DEVICE(uart1, "dev:f2", UART1, NULL);
112AMBA_DEVICE(uart2, "dev:f3", UART2, NULL);
113AMBA_DEVICE(ssp0, "dev:f4", SSP, NULL);
114
115static struct amba_device *amba_devs[] __initdata = {
116 &dmac_device,
117 &uart0_device,
118 &uart1_device,
119 &uart2_device,
120 &uart3_device,
121 &smc_device,
122 &clcd_device,
123 &sctl_device,
124 &wdog_device,
125 &gpio0_device,
126 &gpio1_device,
127 &gpio2_device,
128 &rtc_device,
129 &sci0_device,
130 &ssp0_device,
131 &aaci_device,
132 &mmc0_device,
133 &kmi0_device,
134 &kmi1_device,
135};
136
137static void __init gic_init_irq(void)
138{
139 gic_dist_init(__io_address(REALVIEW_GIC_DIST_BASE));
140 gic_cpu_init(__io_address(REALVIEW_GIC_CPU_BASE));
141}
142
143static void __init realview_eb_init(void)
144{
145 int i;
146
147 clk_register(&realview_clcd_clk);
148
149 platform_device_register(&realview_flash_device);
150 platform_device_register(&realview_smc91x_device);
151
152 for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
153 struct amba_device *d = amba_devs[i];
154 amba_device_register(d, &iomem_resource);
155 }
156
157#ifdef CONFIG_LEDS
158 leds_event = realview_leds_event;
159#endif
160}
161
162MACHINE_START(REALVIEW_EB, "ARM-RealView EB")
163 /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
164 .phys_ram = 0x00000000,
165 .phys_io = REALVIEW_UART0_BASE,
166 .io_pg_offst = (IO_ADDRESS(REALVIEW_UART0_BASE) >> 18) & 0xfffc,
167 .boot_params = 0x00000100,
168 .map_io = realview_eb_map_io,
169 .init_irq = gic_init_irq,
170 .timer = &realview_timer,
171 .init_machine = realview_eb_init,
172MACHINE_END
diff --git a/arch/arm/mach-s3c2410/mach-rx3715.c b/arch/arm/mach-s3c2410/mach-rx3715.c
index 8f2a90bf940b..24d69019a843 100644
--- a/arch/arm/mach-s3c2410/mach-rx3715.c
+++ b/arch/arm/mach-s3c2410/mach-rx3715.c
@@ -17,6 +17,7 @@
17 * 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA 17 * 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA
18 * 14-Mar-2005 BJD Fixed __iomem warnings 18 * 14-Mar-2005 BJD Fixed __iomem warnings
19 * 20-Sep-2005 BJD Added static to non-exported items 19 * 20-Sep-2005 BJD Added static to non-exported items
20 * 31-Oct-2005 BJD Added LCD setup for framebuffer
20*/ 21*/
21 22
22#include <linux/kernel.h> 23#include <linux/kernel.h>
@@ -43,6 +44,9 @@
43 44
44#include <asm/arch/regs-serial.h> 45#include <asm/arch/regs-serial.h>
45#include <asm/arch/regs-gpio.h> 46#include <asm/arch/regs-gpio.h>
47#include <asm/arch/regs-lcd.h>
48
49#include <asm/arch/fb.h>
46 50
47#include "clock.h" 51#include "clock.h"
48#include "devs.h" 52#include "devs.h"
@@ -97,6 +101,66 @@ static struct s3c2410_uartcfg rx3715_uartcfgs[] = {
97 } 101 }
98}; 102};
99 103
104/* framebuffer lcd controller information */
105
106static struct s3c2410fb_mach_info rx3715_lcdcfg __initdata = {
107 .regs = {
108 .lcdcon1 = S3C2410_LCDCON1_TFT16BPP | \
109 S3C2410_LCDCON1_TFT | \
110 S3C2410_LCDCON1_CLKVAL(0x0C),
111
112 .lcdcon2 = S3C2410_LCDCON2_VBPD(5) | \
113 S3C2410_LCDCON2_LINEVAL(319) | \
114 S3C2410_LCDCON2_VFPD(6) | \
115 S3C2410_LCDCON2_VSPW(2),
116
117 .lcdcon3 = S3C2410_LCDCON3_HBPD(35) | \
118 S3C2410_LCDCON3_HOZVAL(239) | \
119 S3C2410_LCDCON3_HFPD(35),
120
121 .lcdcon4 = S3C2410_LCDCON4_MVAL(0) | \
122 S3C2410_LCDCON4_HSPW(7),
123
124 .lcdcon5 = S3C2410_LCDCON5_INVVLINE |
125 S3C2410_LCDCON5_FRM565 |
126 S3C2410_LCDCON5_HWSWP,
127 },
128
129 .lpcsel = 0xf82,
130
131 .gpccon = 0xaa955699,
132 .gpccon_mask = 0xffc003cc,
133 .gpcup = 0x0000ffff,
134 .gpcup_mask = 0xffffffff,
135
136 .gpdcon = 0xaa95aaa1,
137 .gpdcon_mask = 0xffc0fff0,
138 .gpdup = 0x0000faff,
139 .gpdup_mask = 0xffffffff,
140
141 .fixed_syncs = 1,
142 .width = 240,
143 .height = 320,
144
145 .xres = {
146 .min = 240,
147 .max = 240,
148 .defval = 240,
149 },
150
151 .yres = {
152 .max = 320,
153 .min = 320,
154 .defval = 320,
155 },
156
157 .bpp = {
158 .min = 16,
159 .max = 16,
160 .defval = 16,
161 },
162};
163
100static struct platform_device *rx3715_devices[] __initdata = { 164static struct platform_device *rx3715_devices[] __initdata = {
101 &s3c_device_usb, 165 &s3c_device_usb,
102 &s3c_device_lcd, 166 &s3c_device_lcd,
@@ -123,14 +187,12 @@ static void __init rx3715_init_irq(void)
123 s3c24xx_init_irq(); 187 s3c24xx_init_irq();
124} 188}
125 189
126#ifdef CONFIG_PM
127static void __init rx3715_init_machine(void) 190static void __init rx3715_init_machine(void)
128{ 191{
129 s3c2410_pm_init(); 192 s3c2410_pm_init();
193 s3c24xx_fb_set_platdata(&rx3715_lcdcfg);
130} 194}
131#else 195
132#define rx3715_init_machine NULL
133#endif
134 196
135MACHINE_START(RX3715, "IPAQ-RX3715") 197MACHINE_START(RX3715, "IPAQ-RX3715")
136 /* Maintainer: Ben Dooks <ben@fluff.org> */ 198 /* Maintainer: Ben Dooks <ben@fluff.org> */
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index c54e04c995ee..e3c14d6b4328 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -120,8 +120,8 @@ config CPU_ARM925T
120 120
121# ARM926T 121# ARM926T
122config CPU_ARM926T 122config CPU_ARM926T
123 bool "Support ARM926T processor" if ARCH_INTEGRATOR 123 bool "Support ARM926T processor"
124 depends on ARCH_INTEGRATOR || ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX 124 depends on ARCH_INTEGRATOR || ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || MACH_REALVIEW_EB
125 default y if ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX 125 default y if ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX
126 select CPU_32v5 126 select CPU_32v5
127 select CPU_ABRT_EV5TJ 127 select CPU_ABRT_EV5TJ
@@ -242,7 +242,7 @@ config CPU_XSCALE
242# ARMv6 242# ARMv6
243config CPU_V6 243config CPU_V6
244 bool "Support ARM V6 processor" 244 bool "Support ARM V6 processor"
245 depends on ARCH_INTEGRATOR 245 depends on ARCH_INTEGRATOR || MACH_REALVIEW_EB
246 select CPU_32v6 246 select CPU_32v6
247 select CPU_ABRT_EV6 247 select CPU_ABRT_EV6
248 select CPU_CACHE_V6 248 select CPU_CACHE_V6
@@ -250,6 +250,18 @@ config CPU_V6
250 select CPU_COPY_V6 250 select CPU_COPY_V6
251 select CPU_TLB_V6 251 select CPU_TLB_V6
252 252
253# ARMv6k
254config CPU_32v6K
255 bool "Support ARM V6K processor extensions" if !SMP
256 depends on CPU_V6
257 default y if SMP
258 help
259 Say Y here if your ARMv6 processor supports the 'K' extension.
260 This enables the kernel to use some instructions not present
261 on previous processors, and as such a kernel build with this
262 enabled will not boot on processors with do not support these
263 instructions.
264
253# Figure out what processor architecture version we should be using. 265# Figure out what processor architecture version we should be using.
254# This defines the compiler instruction set which depends on the machine type. 266# This defines the compiler instruction set which depends on the machine type.
255config CPU_32v3 267config CPU_32v3
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index fd079ff1fc53..c168f322ef8c 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -486,10 +486,17 @@ static void __init devicemaps_init(struct machine_desc *mdesc)
486 486
487 /* 487 /*
488 * Ask the machine support to map in the statically mapped devices. 488 * Ask the machine support to map in the statically mapped devices.
489 * After this point, we can start to touch devices again.
490 */ 489 */
491 if (mdesc->map_io) 490 if (mdesc->map_io)
492 mdesc->map_io(); 491 mdesc->map_io();
492
493 /*
494 * Finally flush the tlb again - this ensures that we're in a
495 * consistent state wrt the writebuffer if the writebuffer needs
496 * draining. After this point, we can start to touch devices
497 * again.
498 */
499 local_flush_tlb_all();
493} 500}
494 501
495/* 502/*
diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c
index 1221fdde1769..fb5b40289de2 100644
--- a/arch/arm/mm/mm-armv.c
+++ b/arch/arm/mm/mm-armv.c
@@ -469,14 +469,14 @@ void __init create_mapping(struct map_desc *md)
469 469
470 if (md->virtual != vectors_base() && md->virtual < TASK_SIZE) { 470 if (md->virtual != vectors_base() && md->virtual < TASK_SIZE) {
471 printk(KERN_WARNING "BUG: not creating mapping for " 471 printk(KERN_WARNING "BUG: not creating mapping for "
472 "0x%016llx at 0x%08lx in user region\n", 472 "0x%08llx at 0x%08lx in user region\n",
473 __pfn_to_phys((u64)md->pfn), md->virtual); 473 __pfn_to_phys((u64)md->pfn), md->virtual);
474 return; 474 return;
475 } 475 }
476 476
477 if ((md->type == MT_DEVICE || md->type == MT_ROM) && 477 if ((md->type == MT_DEVICE || md->type == MT_ROM) &&
478 md->virtual >= PAGE_OFFSET && md->virtual < VMALLOC_END) { 478 md->virtual >= PAGE_OFFSET && md->virtual < VMALLOC_END) {
479 printk(KERN_WARNING "BUG: mapping for 0x%016llx at 0x%08lx " 479 printk(KERN_WARNING "BUG: mapping for 0x%08llx at 0x%08lx "
480 "overlaps vmalloc space\n", 480 "overlaps vmalloc space\n",
481 __pfn_to_phys((u64)md->pfn), md->virtual); 481 __pfn_to_phys((u64)md->pfn), md->virtual);
482 } 482 }
@@ -492,14 +492,14 @@ void __init create_mapping(struct map_desc *md)
492 if(md->pfn >= 0x100000) { 492 if(md->pfn >= 0x100000) {
493 if(domain) { 493 if(domain) {
494 printk(KERN_ERR "MM: invalid domain in supersection " 494 printk(KERN_ERR "MM: invalid domain in supersection "
495 "mapping for 0x%016llx at 0x%08lx\n", 495 "mapping for 0x%08llx at 0x%08lx\n",
496 __pfn_to_phys((u64)md->pfn), md->virtual); 496 __pfn_to_phys((u64)md->pfn), md->virtual);
497 return; 497 return;
498 } 498 }
499 if((md->virtual | md->length | __pfn_to_phys(md->pfn)) 499 if((md->virtual | md->length | __pfn_to_phys(md->pfn))
500 & ~SUPERSECTION_MASK) { 500 & ~SUPERSECTION_MASK) {
501 printk(KERN_ERR "MM: cannot create mapping for " 501 printk(KERN_ERR "MM: cannot create mapping for "
502 "0x%016llx at 0x%08lx invalid alignment\n", 502 "0x%08llx at 0x%08lx invalid alignment\n",
503 __pfn_to_phys((u64)md->pfn), md->virtual); 503 __pfn_to_phys((u64)md->pfn), md->virtual);
504 return; 504 return;
505 } 505 }
diff --git a/arch/i386/pci/fixup.c b/arch/i386/pci/fixup.c
index 330fd2b68075..3984226a8b98 100644
--- a/arch/i386/pci/fixup.c
+++ b/arch/i386/pci/fixup.c
@@ -398,7 +398,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_video);
398 */ 398 */
399static u16 toshiba_line_size; 399static u16 toshiba_line_size;
400 400
401static struct dmi_system_id __devinit toshiba_ohci1394_dmi_table[] = { 401static struct dmi_system_id __devinitdata toshiba_ohci1394_dmi_table[] = {
402 { 402 {
403 .ident = "Toshiba PS5 based laptop", 403 .ident = "Toshiba PS5 based laptop",
404 .matches = { 404 .matches = {
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
index 1642375fb14e..3b4248cff9a7 100644
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -26,6 +26,10 @@ config MMU
26 bool 26 bool
27 default y 27 default y
28 28
29config SWIOTLB
30 bool
31 default y
32
29config RWSEM_XCHGADD_ALGORITHM 33config RWSEM_XCHGADD_ALGORITHM
30 bool 34 bool
31 default y 35 default y
diff --git a/arch/ia64/lib/Makefile b/arch/ia64/lib/Makefile
index cb1af597370b..ac64664a1807 100644
--- a/arch/ia64/lib/Makefile
+++ b/arch/ia64/lib/Makefile
@@ -9,7 +9,7 @@ lib-y := __divsi3.o __udivsi3.o __modsi3.o __umodsi3.o \
9 bitop.o checksum.o clear_page.o csum_partial_copy.o \ 9 bitop.o checksum.o clear_page.o csum_partial_copy.o \
10 clear_user.o strncpy_from_user.o strlen_user.o strnlen_user.o \ 10 clear_user.o strncpy_from_user.o strlen_user.o strnlen_user.o \
11 flush.o ip_fast_csum.o do_csum.o \ 11 flush.o ip_fast_csum.o do_csum.o \
12 memset.o strlen.o swiotlb.o 12 memset.o strlen.o
13 13
14lib-$(CONFIG_ITANIUM) += copy_page.o copy_user.o memcpy.o 14lib-$(CONFIG_ITANIUM) += copy_page.o copy_user.o memcpy.o
15lib-$(CONFIG_MCKINLEY) += copy_page_mck.o memcpy_mck.o 15lib-$(CONFIG_MCKINLEY) += copy_page_mck.o memcpy_mck.o
diff --git a/arch/ia64/lib/swiotlb.c b/arch/ia64/lib/swiotlb.c
deleted file mode 100644
index 96edcc0fdcd9..000000000000
--- a/arch/ia64/lib/swiotlb.c
+++ /dev/null
@@ -1,759 +0,0 @@
1/*
2 * Dynamic DMA mapping support.
3 *
4 * This implementation is for IA-64 platforms that do not support
5 * I/O TLBs (aka DMA address translation hardware).
6 * Copyright (C) 2000 Asit Mallick <Asit.K.Mallick@intel.com>
7 * Copyright (C) 2000 Goutham Rao <goutham.rao@intel.com>
8 * Copyright (C) 2000, 2003 Hewlett-Packard Co
9 * David Mosberger-Tang <davidm@hpl.hp.com>
10 *
11 * 03/05/07 davidm Switch from PCI-DMA to generic device DMA API.
12 * 00/12/13 davidm Rename to swiotlb.c and add mark_clean() to avoid
13 * unnecessary i-cache flushing.
14 * 04/07/.. ak Better overflow handling. Assorted fixes.
15 */
16
17#include <linux/cache.h>
18#include <linux/mm.h>
19#include <linux/module.h>
20#include <linux/pci.h>
21#include <linux/spinlock.h>
22#include <linux/string.h>
23#include <linux/types.h>
24#include <linux/ctype.h>
25
26#include <asm/io.h>
27#include <asm/pci.h>
28#include <asm/dma.h>
29
30#include <linux/init.h>
31#include <linux/bootmem.h>
32
33#define OFFSET(val,align) ((unsigned long) \
34 ( (val) & ( (align) - 1)))
35
36#define SG_ENT_VIRT_ADDRESS(sg) (page_address((sg)->page) + (sg)->offset)
37#define SG_ENT_PHYS_ADDRESS(SG) virt_to_phys(SG_ENT_VIRT_ADDRESS(SG))
38
39/*
40 * Maximum allowable number of contiguous slabs to map,
41 * must be a power of 2. What is the appropriate value ?
42 * The complexity of {map,unmap}_single is linearly dependent on this value.
43 */
44#define IO_TLB_SEGSIZE 128
45
46/*
47 * log of the size of each IO TLB slab. The number of slabs is command line
48 * controllable.
49 */
50#define IO_TLB_SHIFT 11
51
52#define SLABS_PER_PAGE (1 << (PAGE_SHIFT - IO_TLB_SHIFT))
53
54/*
55 * Minimum IO TLB size to bother booting with. Systems with mainly
56 * 64bit capable cards will only lightly use the swiotlb. If we can't
57 * allocate a contiguous 1MB, we're probably in trouble anyway.
58 */
59#define IO_TLB_MIN_SLABS ((1<<20) >> IO_TLB_SHIFT)
60
61int swiotlb_force;
62
63/*
64 * Used to do a quick range check in swiotlb_unmap_single and
65 * swiotlb_sync_single_*, to see if the memory was in fact allocated by this
66 * API.
67 */
68static char *io_tlb_start, *io_tlb_end;
69
70/*
71 * The number of IO TLB blocks (in groups of 64) betweeen io_tlb_start and
72 * io_tlb_end. This is command line adjustable via setup_io_tlb_npages.
73 */
74static unsigned long io_tlb_nslabs;
75
76/*
77 * When the IOMMU overflows we return a fallback buffer. This sets the size.
78 */
79static unsigned long io_tlb_overflow = 32*1024;
80
81void *io_tlb_overflow_buffer;
82
83/*
84 * This is a free list describing the number of free entries available from
85 * each index
86 */
87static unsigned int *io_tlb_list;
88static unsigned int io_tlb_index;
89
90/*
91 * We need to save away the original address corresponding to a mapped entry
92 * for the sync operations.
93 */
94static unsigned char **io_tlb_orig_addr;
95
96/*
97 * Protect the above data structures in the map and unmap calls
98 */
99static DEFINE_SPINLOCK(io_tlb_lock);
100
101static int __init
102setup_io_tlb_npages(char *str)
103{
104 if (isdigit(*str)) {
105 io_tlb_nslabs = simple_strtoul(str, &str, 0);
106 /* avoid tail segment of size < IO_TLB_SEGSIZE */
107 io_tlb_nslabs = ALIGN(io_tlb_nslabs, IO_TLB_SEGSIZE);
108 }
109 if (*str == ',')
110 ++str;
111 if (!strcmp(str, "force"))
112 swiotlb_force = 1;
113 return 1;
114}
115__setup("swiotlb=", setup_io_tlb_npages);
116/* make io_tlb_overflow tunable too? */
117
118/*
119 * Statically reserve bounce buffer space and initialize bounce buffer data
120 * structures for the software IO TLB used to implement the PCI DMA API.
121 */
122void
123swiotlb_init_with_default_size (size_t default_size)
124{
125 unsigned long i;
126
127 if (!io_tlb_nslabs) {
128 io_tlb_nslabs = (default_size >> IO_TLB_SHIFT);
129 io_tlb_nslabs = ALIGN(io_tlb_nslabs, IO_TLB_SEGSIZE);
130 }
131
132 /*
133 * Get IO TLB memory from the low pages
134 */
135 io_tlb_start = alloc_bootmem_low_pages_limit(io_tlb_nslabs *
136 (1 << IO_TLB_SHIFT), 0x100000000);
137 if (!io_tlb_start)
138 panic("Cannot allocate SWIOTLB buffer");
139 io_tlb_end = io_tlb_start + io_tlb_nslabs * (1 << IO_TLB_SHIFT);
140
141 /*
142 * Allocate and initialize the free list array. This array is used
143 * to find contiguous free memory regions of size up to IO_TLB_SEGSIZE
144 * between io_tlb_start and io_tlb_end.
145 */
146 io_tlb_list = alloc_bootmem(io_tlb_nslabs * sizeof(int));
147 for (i = 0; i < io_tlb_nslabs; i++)
148 io_tlb_list[i] = IO_TLB_SEGSIZE - OFFSET(i, IO_TLB_SEGSIZE);
149 io_tlb_index = 0;
150 io_tlb_orig_addr = alloc_bootmem(io_tlb_nslabs * sizeof(char *));
151
152 /*
153 * Get the overflow emergency buffer
154 */
155 io_tlb_overflow_buffer = alloc_bootmem_low(io_tlb_overflow);
156 printk(KERN_INFO "Placing software IO TLB between 0x%lx - 0x%lx\n",
157 virt_to_phys(io_tlb_start), virt_to_phys(io_tlb_end));
158}
159
160void
161swiotlb_init (void)
162{
163 swiotlb_init_with_default_size(64 * (1<<20)); /* default to 64MB */
164}
165
166/*
167 * Systems with larger DMA zones (those that don't support ISA) can
168 * initialize the swiotlb later using the slab allocator if needed.
169 * This should be just like above, but with some error catching.
170 */
171int
172swiotlb_late_init_with_default_size (size_t default_size)
173{
174 unsigned long i, req_nslabs = io_tlb_nslabs;
175 unsigned int order;
176
177 if (!io_tlb_nslabs) {
178 io_tlb_nslabs = (default_size >> IO_TLB_SHIFT);
179 io_tlb_nslabs = ALIGN(io_tlb_nslabs, IO_TLB_SEGSIZE);
180 }
181
182 /*
183 * Get IO TLB memory from the low pages
184 */
185 order = get_order(io_tlb_nslabs * (1 << IO_TLB_SHIFT));
186 io_tlb_nslabs = SLABS_PER_PAGE << order;
187
188 while ((SLABS_PER_PAGE << order) > IO_TLB_MIN_SLABS) {
189 io_tlb_start = (char *)__get_free_pages(GFP_DMA | __GFP_NOWARN,
190 order);
191 if (io_tlb_start)
192 break;
193 order--;
194 }
195
196 if (!io_tlb_start)
197 goto cleanup1;
198
199 if (order != get_order(io_tlb_nslabs * (1 << IO_TLB_SHIFT))) {
200 printk(KERN_WARNING "Warning: only able to allocate %ld MB "
201 "for software IO TLB\n", (PAGE_SIZE << order) >> 20);
202 io_tlb_nslabs = SLABS_PER_PAGE << order;
203 }
204 io_tlb_end = io_tlb_start + io_tlb_nslabs * (1 << IO_TLB_SHIFT);
205 memset(io_tlb_start, 0, io_tlb_nslabs * (1 << IO_TLB_SHIFT));
206
207 /*
208 * Allocate and initialize the free list array. This array is used
209 * to find contiguous free memory regions of size up to IO_TLB_SEGSIZE
210 * between io_tlb_start and io_tlb_end.
211 */
212 io_tlb_list = (unsigned int *)__get_free_pages(GFP_KERNEL,
213 get_order(io_tlb_nslabs * sizeof(int)));
214 if (!io_tlb_list)
215 goto cleanup2;
216
217 for (i = 0; i < io_tlb_nslabs; i++)
218 io_tlb_list[i] = IO_TLB_SEGSIZE - OFFSET(i, IO_TLB_SEGSIZE);
219 io_tlb_index = 0;
220
221 io_tlb_orig_addr = (unsigned char **)__get_free_pages(GFP_KERNEL,
222 get_order(io_tlb_nslabs * sizeof(char *)));
223 if (!io_tlb_orig_addr)
224 goto cleanup3;
225
226 memset(io_tlb_orig_addr, 0, io_tlb_nslabs * sizeof(char *));
227
228 /*
229 * Get the overflow emergency buffer
230 */
231 io_tlb_overflow_buffer = (void *)__get_free_pages(GFP_DMA,
232 get_order(io_tlb_overflow));
233 if (!io_tlb_overflow_buffer)
234 goto cleanup4;
235
236 printk(KERN_INFO "Placing %ldMB software IO TLB between 0x%lx - "
237 "0x%lx\n", (io_tlb_nslabs * (1 << IO_TLB_SHIFT)) >> 20,
238 virt_to_phys(io_tlb_start), virt_to_phys(io_tlb_end));
239
240 return 0;
241
242cleanup4:
243 free_pages((unsigned long)io_tlb_orig_addr, get_order(io_tlb_nslabs *
244 sizeof(char *)));
245 io_tlb_orig_addr = NULL;
246cleanup3:
247 free_pages((unsigned long)io_tlb_list, get_order(io_tlb_nslabs *
248 sizeof(int)));
249 io_tlb_list = NULL;
250 io_tlb_end = NULL;
251cleanup2:
252 free_pages((unsigned long)io_tlb_start, order);
253 io_tlb_start = NULL;
254cleanup1:
255 io_tlb_nslabs = req_nslabs;
256 return -ENOMEM;
257}
258
259static inline int
260address_needs_mapping(struct device *hwdev, dma_addr_t addr)
261{
262 dma_addr_t mask = 0xffffffff;
263 /* If the device has a mask, use it, otherwise default to 32 bits */
264 if (hwdev && hwdev->dma_mask)
265 mask = *hwdev->dma_mask;
266 return (addr & ~mask) != 0;
267}
268
269/*
270 * Allocates bounce buffer and returns its kernel virtual address.
271 */
272static void *
273map_single(struct device *hwdev, char *buffer, size_t size, int dir)
274{
275 unsigned long flags;
276 char *dma_addr;
277 unsigned int nslots, stride, index, wrap;
278 int i;
279
280 /*
281 * For mappings greater than a page, we limit the stride (and
282 * hence alignment) to a page size.
283 */
284 nslots = ALIGN(size, 1 << IO_TLB_SHIFT) >> IO_TLB_SHIFT;
285 if (size > PAGE_SIZE)
286 stride = (1 << (PAGE_SHIFT - IO_TLB_SHIFT));
287 else
288 stride = 1;
289
290 if (!nslots)
291 BUG();
292
293 /*
294 * Find suitable number of IO TLB entries size that will fit this
295 * request and allocate a buffer from that IO TLB pool.
296 */
297 spin_lock_irqsave(&io_tlb_lock, flags);
298 {
299 wrap = index = ALIGN(io_tlb_index, stride);
300
301 if (index >= io_tlb_nslabs)
302 wrap = index = 0;
303
304 do {
305 /*
306 * If we find a slot that indicates we have 'nslots'
307 * number of contiguous buffers, we allocate the
308 * buffers from that slot and mark the entries as '0'
309 * indicating unavailable.
310 */
311 if (io_tlb_list[index] >= nslots) {
312 int count = 0;
313
314 for (i = index; i < (int) (index + nslots); i++)
315 io_tlb_list[i] = 0;
316 for (i = index - 1; (OFFSET(i, IO_TLB_SEGSIZE) != IO_TLB_SEGSIZE -1) && io_tlb_list[i]; i--)
317 io_tlb_list[i] = ++count;
318 dma_addr = io_tlb_start + (index << IO_TLB_SHIFT);
319
320 /*
321 * Update the indices to avoid searching in
322 * the next round.
323 */
324 io_tlb_index = ((index + nslots) < io_tlb_nslabs
325 ? (index + nslots) : 0);
326
327 goto found;
328 }
329 index += stride;
330 if (index >= io_tlb_nslabs)
331 index = 0;
332 } while (index != wrap);
333
334 spin_unlock_irqrestore(&io_tlb_lock, flags);
335 return NULL;
336 }
337 found:
338 spin_unlock_irqrestore(&io_tlb_lock, flags);
339
340 /*
341 * Save away the mapping from the original address to the DMA address.
342 * This is needed when we sync the memory. Then we sync the buffer if
343 * needed.
344 */
345 io_tlb_orig_addr[index] = buffer;
346 if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL)
347 memcpy(dma_addr, buffer, size);
348
349 return dma_addr;
350}
351
352/*
353 * dma_addr is the kernel virtual address of the bounce buffer to unmap.
354 */
355static void
356unmap_single(struct device *hwdev, char *dma_addr, size_t size, int dir)
357{
358 unsigned long flags;
359 int i, count, nslots = ALIGN(size, 1 << IO_TLB_SHIFT) >> IO_TLB_SHIFT;
360 int index = (dma_addr - io_tlb_start) >> IO_TLB_SHIFT;
361 char *buffer = io_tlb_orig_addr[index];
362
363 /*
364 * First, sync the memory before unmapping the entry
365 */
366 if (buffer && ((dir == DMA_FROM_DEVICE) || (dir == DMA_BIDIRECTIONAL)))
367 /*
368 * bounce... copy the data back into the original buffer * and
369 * delete the bounce buffer.
370 */
371 memcpy(buffer, dma_addr, size);
372
373 /*
374 * Return the buffer to the free list by setting the corresponding
375 * entries to indicate the number of contigous entries available.
376 * While returning the entries to the free list, we merge the entries
377 * with slots below and above the pool being returned.
378 */
379 spin_lock_irqsave(&io_tlb_lock, flags);
380 {
381 count = ((index + nslots) < ALIGN(index + 1, IO_TLB_SEGSIZE) ?
382 io_tlb_list[index + nslots] : 0);
383 /*
384 * Step 1: return the slots to the free list, merging the
385 * slots with superceeding slots
386 */
387 for (i = index + nslots - 1; i >= index; i--)
388 io_tlb_list[i] = ++count;
389 /*
390 * Step 2: merge the returned slots with the preceding slots,
391 * if available (non zero)
392 */
393 for (i = index - 1; (OFFSET(i, IO_TLB_SEGSIZE) != IO_TLB_SEGSIZE -1) && io_tlb_list[i]; i--)
394 io_tlb_list[i] = ++count;
395 }
396 spin_unlock_irqrestore(&io_tlb_lock, flags);
397}
398
399static void
400sync_single(struct device *hwdev, char *dma_addr, size_t size, int dir)
401{
402 int index = (dma_addr - io_tlb_start) >> IO_TLB_SHIFT;
403 char *buffer = io_tlb_orig_addr[index];
404
405 /*
406 * bounce... copy the data back into/from the original buffer
407 * XXX How do you handle DMA_BIDIRECTIONAL here ?
408 */
409 if (dir == DMA_FROM_DEVICE)
410 memcpy(buffer, dma_addr, size);
411 else if (dir == DMA_TO_DEVICE)
412 memcpy(dma_addr, buffer, size);
413 else
414 BUG();
415}
416
417void *
418swiotlb_alloc_coherent(struct device *hwdev, size_t size,
419 dma_addr_t *dma_handle, gfp_t flags)
420{
421 unsigned long dev_addr;
422 void *ret;
423 int order = get_order(size);
424
425 /*
426 * XXX fix me: the DMA API should pass us an explicit DMA mask
427 * instead, or use ZONE_DMA32 (ia64 overloads ZONE_DMA to be a ~32
428 * bit range instead of a 16MB one).
429 */
430 flags |= GFP_DMA;
431
432 ret = (void *)__get_free_pages(flags, order);
433 if (ret && address_needs_mapping(hwdev, virt_to_phys(ret))) {
434 /*
435 * The allocated memory isn't reachable by the device.
436 * Fall back on swiotlb_map_single().
437 */
438 free_pages((unsigned long) ret, order);
439 ret = NULL;
440 }
441 if (!ret) {
442 /*
443 * We are either out of memory or the device can't DMA
444 * to GFP_DMA memory; fall back on
445 * swiotlb_map_single(), which will grab memory from
446 * the lowest available address range.
447 */
448 dma_addr_t handle;
449 handle = swiotlb_map_single(NULL, NULL, size, DMA_FROM_DEVICE);
450 if (dma_mapping_error(handle))
451 return NULL;
452
453 ret = phys_to_virt(handle);
454 }
455
456 memset(ret, 0, size);
457 dev_addr = virt_to_phys(ret);
458
459 /* Confirm address can be DMA'd by device */
460 if (address_needs_mapping(hwdev, dev_addr)) {
461 printk("hwdev DMA mask = 0x%016Lx, dev_addr = 0x%016lx\n",
462 (unsigned long long)*hwdev->dma_mask, dev_addr);
463 panic("swiotlb_alloc_coherent: allocated memory is out of "
464 "range for device");
465 }
466 *dma_handle = dev_addr;
467 return ret;
468}
469
470void
471swiotlb_free_coherent(struct device *hwdev, size_t size, void *vaddr,
472 dma_addr_t dma_handle)
473{
474 if (!(vaddr >= (void *)io_tlb_start
475 && vaddr < (void *)io_tlb_end))
476 free_pages((unsigned long) vaddr, get_order(size));
477 else
478 /* DMA_TO_DEVICE to avoid memcpy in unmap_single */
479 swiotlb_unmap_single (hwdev, dma_handle, size, DMA_TO_DEVICE);
480}
481
482static void
483swiotlb_full(struct device *dev, size_t size, int dir, int do_panic)
484{
485 /*
486 * Ran out of IOMMU space for this operation. This is very bad.
487 * Unfortunately the drivers cannot handle this operation properly.
488 * unless they check for pci_dma_mapping_error (most don't)
489 * When the mapping is small enough return a static buffer to limit
490 * the damage, or panic when the transfer is too big.
491 */
492 printk(KERN_ERR "PCI-DMA: Out of SW-IOMMU space for %lu bytes at "
493 "device %s\n", size, dev ? dev->bus_id : "?");
494
495 if (size > io_tlb_overflow && do_panic) {
496 if (dir == PCI_DMA_FROMDEVICE || dir == PCI_DMA_BIDIRECTIONAL)
497 panic("PCI-DMA: Memory would be corrupted\n");
498 if (dir == PCI_DMA_TODEVICE || dir == PCI_DMA_BIDIRECTIONAL)
499 panic("PCI-DMA: Random memory would be DMAed\n");
500 }
501}
502
503/*
504 * Map a single buffer of the indicated size for DMA in streaming mode. The
505 * PCI address to use is returned.
506 *
507 * Once the device is given the dma address, the device owns this memory until
508 * either swiotlb_unmap_single or swiotlb_dma_sync_single is performed.
509 */
510dma_addr_t
511swiotlb_map_single(struct device *hwdev, void *ptr, size_t size, int dir)
512{
513 unsigned long dev_addr = virt_to_phys(ptr);
514 void *map;
515
516 if (dir == DMA_NONE)
517 BUG();
518 /*
519 * If the pointer passed in happens to be in the device's DMA window,
520 * we can safely return the device addr and not worry about bounce
521 * buffering it.
522 */
523 if (!address_needs_mapping(hwdev, dev_addr) && !swiotlb_force)
524 return dev_addr;
525
526 /*
527 * Oh well, have to allocate and map a bounce buffer.
528 */
529 map = map_single(hwdev, ptr, size, dir);
530 if (!map) {
531 swiotlb_full(hwdev, size, dir, 1);
532 map = io_tlb_overflow_buffer;
533 }
534
535 dev_addr = virt_to_phys(map);
536
537 /*
538 * Ensure that the address returned is DMA'ble
539 */
540 if (address_needs_mapping(hwdev, dev_addr))
541 panic("map_single: bounce buffer is not DMA'ble");
542
543 return dev_addr;
544}
545
546/*
547 * Since DMA is i-cache coherent, any (complete) pages that were written via
548 * DMA can be marked as "clean" so that lazy_mmu_prot_update() doesn't have to
549 * flush them when they get mapped into an executable vm-area.
550 */
551static void
552mark_clean(void *addr, size_t size)
553{
554 unsigned long pg_addr, end;
555
556 pg_addr = PAGE_ALIGN((unsigned long) addr);
557 end = (unsigned long) addr + size;
558 while (pg_addr + PAGE_SIZE <= end) {
559 struct page *page = virt_to_page(pg_addr);
560 set_bit(PG_arch_1, &page->flags);
561 pg_addr += PAGE_SIZE;
562 }
563}
564
565/*
566 * Unmap a single streaming mode DMA translation. The dma_addr and size must
567 * match what was provided for in a previous swiotlb_map_single call. All
568 * other usages are undefined.
569 *
570 * After this call, reads by the cpu to the buffer are guaranteed to see
571 * whatever the device wrote there.
572 */
573void
574swiotlb_unmap_single(struct device *hwdev, dma_addr_t dev_addr, size_t size,
575 int dir)
576{
577 char *dma_addr = phys_to_virt(dev_addr);
578
579 if (dir == DMA_NONE)
580 BUG();
581 if (dma_addr >= io_tlb_start && dma_addr < io_tlb_end)
582 unmap_single(hwdev, dma_addr, size, dir);
583 else if (dir == DMA_FROM_DEVICE)
584 mark_clean(dma_addr, size);
585}
586
587/*
588 * Make physical memory consistent for a single streaming mode DMA translation
589 * after a transfer.
590 *
591 * If you perform a swiotlb_map_single() but wish to interrogate the buffer
592 * using the cpu, yet do not wish to teardown the PCI dma mapping, you must
593 * call this function before doing so. At the next point you give the PCI dma
594 * address back to the card, you must first perform a
595 * swiotlb_dma_sync_for_device, and then the device again owns the buffer
596 */
597void
598swiotlb_sync_single_for_cpu(struct device *hwdev, dma_addr_t dev_addr,
599 size_t size, int dir)
600{
601 char *dma_addr = phys_to_virt(dev_addr);
602
603 if (dir == DMA_NONE)
604 BUG();
605 if (dma_addr >= io_tlb_start && dma_addr < io_tlb_end)
606 sync_single(hwdev, dma_addr, size, dir);
607 else if (dir == DMA_FROM_DEVICE)
608 mark_clean(dma_addr, size);
609}
610
611void
612swiotlb_sync_single_for_device(struct device *hwdev, dma_addr_t dev_addr,
613 size_t size, int dir)
614{
615 char *dma_addr = phys_to_virt(dev_addr);
616
617 if (dir == DMA_NONE)
618 BUG();
619 if (dma_addr >= io_tlb_start && dma_addr < io_tlb_end)
620 sync_single(hwdev, dma_addr, size, dir);
621 else if (dir == DMA_FROM_DEVICE)
622 mark_clean(dma_addr, size);
623}
624
625/*
626 * Map a set of buffers described by scatterlist in streaming mode for DMA.
627 * This is the scatter-gather version of the above swiotlb_map_single
628 * interface. Here the scatter gather list elements are each tagged with the
629 * appropriate dma address and length. They are obtained via
630 * sg_dma_{address,length}(SG).
631 *
632 * NOTE: An implementation may be able to use a smaller number of
633 * DMA address/length pairs than there are SG table elements.
634 * (for example via virtual mapping capabilities)
635 * The routine returns the number of addr/length pairs actually
636 * used, at most nents.
637 *
638 * Device ownership issues as mentioned above for swiotlb_map_single are the
639 * same here.
640 */
641int
642swiotlb_map_sg(struct device *hwdev, struct scatterlist *sg, int nelems,
643 int dir)
644{
645 void *addr;
646 unsigned long dev_addr;
647 int i;
648
649 if (dir == DMA_NONE)
650 BUG();
651
652 for (i = 0; i < nelems; i++, sg++) {
653 addr = SG_ENT_VIRT_ADDRESS(sg);
654 dev_addr = virt_to_phys(addr);
655 if (swiotlb_force || address_needs_mapping(hwdev, dev_addr)) {
656 sg->dma_address = (dma_addr_t) virt_to_phys(map_single(hwdev, addr, sg->length, dir));
657 if (!sg->dma_address) {
658 /* Don't panic here, we expect map_sg users
659 to do proper error handling. */
660 swiotlb_full(hwdev, sg->length, dir, 0);
661 swiotlb_unmap_sg(hwdev, sg - i, i, dir);
662 sg[0].dma_length = 0;
663 return 0;
664 }
665 } else
666 sg->dma_address = dev_addr;
667 sg->dma_length = sg->length;
668 }
669 return nelems;
670}
671
672/*
673 * Unmap a set of streaming mode DMA translations. Again, cpu read rules
674 * concerning calls here are the same as for swiotlb_unmap_single() above.
675 */
676void
677swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nelems,
678 int dir)
679{
680 int i;
681
682 if (dir == DMA_NONE)
683 BUG();
684
685 for (i = 0; i < nelems; i++, sg++)
686 if (sg->dma_address != SG_ENT_PHYS_ADDRESS(sg))
687 unmap_single(hwdev, (void *) phys_to_virt(sg->dma_address), sg->dma_length, dir);
688 else if (dir == DMA_FROM_DEVICE)
689 mark_clean(SG_ENT_VIRT_ADDRESS(sg), sg->dma_length);
690}
691
692/*
693 * Make physical memory consistent for a set of streaming mode DMA translations
694 * after a transfer.
695 *
696 * The same as swiotlb_sync_single_* but for a scatter-gather list, same rules
697 * and usage.
698 */
699void
700swiotlb_sync_sg_for_cpu(struct device *hwdev, struct scatterlist *sg,
701 int nelems, int dir)
702{
703 int i;
704
705 if (dir == DMA_NONE)
706 BUG();
707
708 for (i = 0; i < nelems; i++, sg++)
709 if (sg->dma_address != SG_ENT_PHYS_ADDRESS(sg))
710 sync_single(hwdev, (void *) sg->dma_address,
711 sg->dma_length, dir);
712}
713
714void
715swiotlb_sync_sg_for_device(struct device *hwdev, struct scatterlist *sg,
716 int nelems, int dir)
717{
718 int i;
719
720 if (dir == DMA_NONE)
721 BUG();
722
723 for (i = 0; i < nelems; i++, sg++)
724 if (sg->dma_address != SG_ENT_PHYS_ADDRESS(sg))
725 sync_single(hwdev, (void *) sg->dma_address,
726 sg->dma_length, dir);
727}
728
729int
730swiotlb_dma_mapping_error(dma_addr_t dma_addr)
731{
732 return (dma_addr == virt_to_phys(io_tlb_overflow_buffer));
733}
734
735/*
736 * Return whether the given PCI device DMA address mask can be supported
737 * properly. For example, if your device can only drive the low 24-bits
738 * during PCI bus mastering, then you would pass 0x00ffffff as the mask to
739 * this function.
740 */
741int
742swiotlb_dma_supported (struct device *hwdev, u64 mask)
743{
744 return (virt_to_phys (io_tlb_end) - 1) <= mask;
745}
746
747EXPORT_SYMBOL(swiotlb_init);
748EXPORT_SYMBOL(swiotlb_map_single);
749EXPORT_SYMBOL(swiotlb_unmap_single);
750EXPORT_SYMBOL(swiotlb_map_sg);
751EXPORT_SYMBOL(swiotlb_unmap_sg);
752EXPORT_SYMBOL(swiotlb_sync_single_for_cpu);
753EXPORT_SYMBOL(swiotlb_sync_single_for_device);
754EXPORT_SYMBOL(swiotlb_sync_sg_for_cpu);
755EXPORT_SYMBOL(swiotlb_sync_sg_for_device);
756EXPORT_SYMBOL(swiotlb_dma_mapping_error);
757EXPORT_SYMBOL(swiotlb_alloc_coherent);
758EXPORT_SYMBOL(swiotlb_free_coherent);
759EXPORT_SYMBOL(swiotlb_dma_supported);
diff --git a/arch/m68knommu/defconfig b/arch/m68knommu/defconfig
index 87f2d6587c56..2d59ba1a79ba 100644
--- a/arch/m68knommu/defconfig
+++ b/arch/m68knommu/defconfig
@@ -99,7 +99,7 @@ CONFIG_M5272C3=y
99# CONFIG_NETtel is not set 99# CONFIG_NETtel is not set
100# CONFIG_CPU16B is not set 100# CONFIG_CPU16B is not set
101# CONFIG_MOD5272 is not set 101# CONFIG_MOD5272 is not set
102CONFIG_MOTOROLA=y 102CONFIG_FREESCALE=y
103# CONFIG_LARGE_ALLOCS is not set 103# CONFIG_LARGE_ALLOCS is not set
104CONFIG_4KSTACKS=y 104CONFIG_4KSTACKS=y
105CONFIG_RAMAUTO=y 105CONFIG_RAMAUTO=y
@@ -554,7 +554,6 @@ CONFIG_EXT2_FS=y
554# CONFIG_XFS_FS is not set 554# CONFIG_XFS_FS is not set
555# CONFIG_MINIX_FS is not set 555# CONFIG_MINIX_FS is not set
556CONFIG_ROMFS_FS=y 556CONFIG_ROMFS_FS=y
557CONFIG_MAGIC_ROM_PTR=y
558# CONFIG_INOTIFY is not set 557# CONFIG_INOTIFY is not set
559# CONFIG_QUOTA is not set 558# CONFIG_QUOTA is not set
560# CONFIG_DNOTIFY is not set 559# CONFIG_DNOTIFY is not set
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index 984a10630714..2d22bf03484e 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -279,7 +279,7 @@ _GLOBAL(ppc32_rt_sigsuspend)
279 bne syscall_exit 279 bne syscall_exit
280 /* If sigsuspend() returns zero, we are going into a signal handler. We 280 /* If sigsuspend() returns zero, we are going into a signal handler. We
281 may need to call audit_syscall_exit() to mark the exit from sigsuspend() */ 281 may need to call audit_syscall_exit() to mark the exit from sigsuspend() */
282#ifdef CONFIG_AUDIT 282#ifdef CONFIG_AUDITSYSCALL
283 ld r3,PACACURRENT(r13) 283 ld r3,PACACURRENT(r13)
284 ld r4,AUDITCONTEXT(r3) 284 ld r4,AUDITCONTEXT(r3)
285 cmpdi 0,r4,0 285 cmpdi 0,r4,0
diff --git a/arch/um/include/net_kern.h b/arch/um/include/net_kern.h
index 1c07949a13d6..f7de6df60dd7 100644
--- a/arch/um/include/net_kern.h
+++ b/arch/um/include/net_kern.h
@@ -6,10 +6,11 @@
6#ifndef __UM_NET_KERN_H 6#ifndef __UM_NET_KERN_H
7#define __UM_NET_KERN_H 7#define __UM_NET_KERN_H
8 8
9#include "linux/netdevice.h" 9#include <linux/netdevice.h>
10#include "linux/skbuff.h" 10#include <linux/platform_device.h>
11#include "linux/socket.h" 11#include <linux/skbuff.h>
12#include "linux/list.h" 12#include <linux/socket.h>
13#include <linux/list.h>
13 14
14struct uml_net { 15struct uml_net {
15 struct list_head list; 16 struct list_head list;
diff --git a/arch/x86_64/kernel/Makefile b/arch/x86_64/kernel/Makefile
index bcdd0a805fe7..14328cab5d3a 100644
--- a/arch/x86_64/kernel/Makefile
+++ b/arch/x86_64/kernel/Makefile
@@ -27,7 +27,6 @@ obj-$(CONFIG_CPU_FREQ) += cpufreq/
27obj-$(CONFIG_EARLY_PRINTK) += early_printk.o 27obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
28obj-$(CONFIG_GART_IOMMU) += pci-gart.o aperture.o 28obj-$(CONFIG_GART_IOMMU) += pci-gart.o aperture.o
29obj-$(CONFIG_DUMMY_IOMMU) += pci-nommu.o pci-dma.o 29obj-$(CONFIG_DUMMY_IOMMU) += pci-nommu.o pci-dma.o
30obj-$(CONFIG_SWIOTLB) += swiotlb.o
31obj-$(CONFIG_KPROBES) += kprobes.o 30obj-$(CONFIG_KPROBES) += kprobes.o
32obj-$(CONFIG_X86_PM_TIMER) += pmtimer.o 31obj-$(CONFIG_X86_PM_TIMER) += pmtimer.o
33 32
@@ -41,7 +40,6 @@ CFLAGS_vsyscall.o := $(PROFILING) -g0
41bootflag-y += ../../i386/kernel/bootflag.o 40bootflag-y += ../../i386/kernel/bootflag.o
42cpuid-$(subst m,y,$(CONFIG_X86_CPUID)) += ../../i386/kernel/cpuid.o 41cpuid-$(subst m,y,$(CONFIG_X86_CPUID)) += ../../i386/kernel/cpuid.o
43topology-y += ../../i386/mach-default/topology.o 42topology-y += ../../i386/mach-default/topology.o
44swiotlb-$(CONFIG_SWIOTLB) += ../../ia64/lib/swiotlb.o
45microcode-$(subst m,y,$(CONFIG_MICROCODE)) += ../../i386/kernel/microcode.o 43microcode-$(subst m,y,$(CONFIG_MICROCODE)) += ../../i386/kernel/microcode.o
46intel_cacheinfo-y += ../../i386/kernel/cpu/intel_cacheinfo.o 44intel_cacheinfo-y += ../../i386/kernel/cpu/intel_cacheinfo.o
47quirks-y += ../../i386/kernel/quirks.o 45quirks-y += ../../i386/kernel/quirks.o
diff --git a/arch/x86_64/lib/bitops.c b/arch/x86_64/lib/bitops.c
index a29fb75b33ac..95b6d9639fba 100644
--- a/arch/x86_64/lib/bitops.c
+++ b/arch/x86_64/lib/bitops.c
@@ -5,19 +5,23 @@
5#undef find_first_bit 5#undef find_first_bit
6#undef find_next_bit 6#undef find_next_bit
7 7
8/** 8static inline long
9 * find_first_zero_bit - find the first zero bit in a memory region 9__find_first_zero_bit(const unsigned long * addr, unsigned long size)
10 * @addr: The address to start the search at
11 * @size: The maximum size to search
12 *
13 * Returns the bit-number of the first zero bit, not the number of the byte
14 * containing a bit.
15 */
16inline long find_first_zero_bit(const unsigned long * addr, unsigned long size)
17{ 10{
18 long d0, d1, d2; 11 long d0, d1, d2;
19 long res; 12 long res;
20 13
14 /*
15 * We must test the size in words, not in bits, because
16 * otherwise incoming sizes in the range -63..-1 will not run
17 * any scasq instructions, and then the flags used by the je
18 * instruction will have whatever random value was in place
19 * before. Nobody should call us like that, but
20 * find_next_zero_bit() does when offset and size are at the
21 * same word and it fails to find a zero itself.
22 */
23 size += 63;
24 size >>= 6;
21 if (!size) 25 if (!size)
22 return 0; 26 return 0;
23 asm volatile( 27 asm volatile(
@@ -30,12 +34,30 @@ inline long find_first_zero_bit(const unsigned long * addr, unsigned long size)
30 " shlq $3,%%rdi\n" 34 " shlq $3,%%rdi\n"
31 " addq %%rdi,%%rdx" 35 " addq %%rdi,%%rdx"
32 :"=d" (res), "=&c" (d0), "=&D" (d1), "=&a" (d2) 36 :"=d" (res), "=&c" (d0), "=&D" (d1), "=&a" (d2)
33 :"0" (0ULL), "1" ((size + 63) >> 6), "2" (addr), "3" (-1ULL), 37 :"0" (0ULL), "1" (size), "2" (addr), "3" (-1ULL),
34 [addr] "r" (addr) : "memory"); 38 [addr] "S" (addr) : "memory");
39 /*
40 * Any register would do for [addr] above, but GCC tends to
41 * prefer rbx over rsi, even though rsi is readily available
42 * and doesn't have to be saved.
43 */
35 return res; 44 return res;
36} 45}
37 46
38/** 47/**
48 * find_first_zero_bit - find the first zero bit in a memory region
49 * @addr: The address to start the search at
50 * @size: The maximum size to search
51 *
52 * Returns the bit-number of the first zero bit, not the number of the byte
53 * containing a bit.
54 */
55long find_first_zero_bit(const unsigned long * addr, unsigned long size)
56{
57 return __find_first_zero_bit (addr, size);
58}
59
60/**
39 * find_next_zero_bit - find the first zero bit in a memory region 61 * find_next_zero_bit - find the first zero bit in a memory region
40 * @addr: The address to base the search on 62 * @addr: The address to base the search on
41 * @offset: The bitnumber to start searching at 63 * @offset: The bitnumber to start searching at
@@ -43,7 +65,7 @@ inline long find_first_zero_bit(const unsigned long * addr, unsigned long size)
43 */ 65 */
44long find_next_zero_bit (const unsigned long * addr, long size, long offset) 66long find_next_zero_bit (const unsigned long * addr, long size, long offset)
45{ 67{
46 unsigned long * p = ((unsigned long *) addr) + (offset >> 6); 68 const unsigned long * p = addr + (offset >> 6);
47 unsigned long set = 0; 69 unsigned long set = 0;
48 unsigned long res, bit = offset&63; 70 unsigned long res, bit = offset&63;
49 71
@@ -63,8 +85,8 @@ long find_next_zero_bit (const unsigned long * addr, long size, long offset)
63 /* 85 /*
64 * No zero yet, search remaining full words for a zero 86 * No zero yet, search remaining full words for a zero
65 */ 87 */
66 res = find_first_zero_bit ((const unsigned long *)p, 88 res = __find_first_zero_bit (p, size - 64 * (p - addr));
67 size - 64 * (p - (unsigned long *) addr)); 89
68 return (offset + set + res); 90 return (offset + set + res);
69} 91}
70 92
@@ -74,6 +96,19 @@ __find_first_bit(const unsigned long * addr, unsigned long size)
74 long d0, d1; 96 long d0, d1;
75 long res; 97 long res;
76 98
99 /*
100 * We must test the size in words, not in bits, because
101 * otherwise incoming sizes in the range -63..-1 will not run
102 * any scasq instructions, and then the flags used by the jz
103 * instruction will have whatever random value was in place
104 * before. Nobody should call us like that, but
105 * find_next_bit() does when offset and size are at the same
106 * word and it fails to find a one itself.
107 */
108 size += 63;
109 size >>= 6;
110 if (!size)
111 return 0;
77 asm volatile( 112 asm volatile(
78 " repe; scasq\n" 113 " repe; scasq\n"
79 " jz 1f\n" 114 " jz 1f\n"
@@ -83,8 +118,7 @@ __find_first_bit(const unsigned long * addr, unsigned long size)
83 " shlq $3,%%rdi\n" 118 " shlq $3,%%rdi\n"
84 " addq %%rdi,%%rax" 119 " addq %%rdi,%%rax"
85 :"=a" (res), "=&c" (d0), "=&D" (d1) 120 :"=a" (res), "=&c" (d0), "=&D" (d1)
86 :"0" (0ULL), 121 :"0" (0ULL), "1" (size), "2" (addr),
87 "1" ((size + 63) >> 6), "2" (addr),
88 [addr] "r" (addr) : "memory"); 122 [addr] "r" (addr) : "memory");
89 return res; 123 return res;
90} 124}