aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2004-08-21 22:32:28 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2004-08-21 22:32:28 -0700
commit94c4cad90f76ee3d6427baf22c3ec8361c930aa5 (patch)
tree2fb3d274891d6be75fb3cfea36ca6fec01ae092a /arch
parent7fd9f7569bc89388c6f68aafd3971d08c0cee2f6 (diff)
parent6e6798994dc49b9f20ee25ec9e6c92b04727ec3e (diff)
downloadhistory-94c4cad90f76ee3d6427baf22c3ec8361c930aa5.tar.gz
Merge bk://bk.arm.linux.org.uk/linux-2.6-rmk
into ppc970.osdl.org:/home/torvalds/v2.6/linux
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/Kconfig15
-rw-r--r--arch/arm/Makefile1
-rw-r--r--arch/arm/boot/Makefile1
-rw-r--r--arch/arm/boot/compressed/head-xscale.S20
-rw-r--r--arch/arm/configs/iq80321_defconfig297
-rw-r--r--arch/arm/configs/mx1ads_defconfig (renamed from arch/arm/configs/iq80310_defconfig)546
-rw-r--r--arch/arm/configs/s3c2410_defconfig8
-rw-r--r--arch/arm/kernel/Makefile3
-rw-r--r--arch/arm/kernel/asm-offsets.c16
-rw-r--r--arch/arm/kernel/debug.S28
-rw-r--r--arch/arm/kernel/entry-armv.S82
-rw-r--r--arch/arm/kernel/iwmmxt.S320
-rw-r--r--arch/arm/kernel/process.c6
-rw-r--r--arch/arm/kernel/setup.c2
-rw-r--r--arch/arm/kernel/signal.c119
-rw-r--r--arch/arm/lib/getuser.S57
-rw-r--r--arch/arm/lib/putuser.S59
-rw-r--r--arch/arm/mach-imx/Kconfig10
-rw-r--r--arch/arm/mach-imx/Makefile19
-rw-r--r--arch/arm/mach-imx/dma.c203
-rw-r--r--arch/arm/mach-imx/generic.c274
-rw-r--r--arch/arm/mach-imx/generic.h14
-rw-r--r--arch/arm/mach-imx/irq.c252
-rw-r--r--arch/arm/mach-imx/leds-mx1ads.c54
-rw-r--r--arch/arm/mach-imx/leds.c31
-rw-r--r--arch/arm/mach-imx/leds.h9
-rw-r--r--arch/arm/mach-imx/mx1ads.c88
-rw-r--r--arch/arm/mach-imx/time.c95
-rw-r--r--arch/arm/mach-integrator/cpu.c8
-rw-r--r--arch/arm/mach-iop3xx/Kconfig22
-rw-r--r--arch/arm/mach-iop3xx/Makefile12
-rw-r--r--arch/arm/mach-iop3xx/arch.c34
-rw-r--r--arch/arm/mach-iop3xx/iop310-irq.c111
-rw-r--r--arch/arm/mach-iop3xx/iop310-pci.c434
-rw-r--r--arch/arm/mach-iop3xx/iop321-pci.c1
-rw-r--r--arch/arm/mach-iop3xx/iop321-time.c2
-rw-r--r--arch/arm/mach-iop3xx/iq80310-irq.c139
-rw-r--r--arch/arm/mach-iop3xx/iq80310-pci.c164
-rw-r--r--arch/arm/mach-iop3xx/iq80310-time.c124
-rw-r--r--arch/arm/mach-iop3xx/mm.c69
-rw-r--r--arch/arm/mach-iop3xx/xs80200-irq.c63
-rw-r--r--arch/arm/mach-ixp4xx/common.c2
-rw-r--r--arch/arm/mach-omap/Makefile10
-rw-r--r--arch/arm/mach-omap/board-generic.c56
-rw-r--r--arch/arm/mach-omap/board-h2.c115
-rw-r--r--arch/arm/mach-omap/board-h3.c90
-rw-r--r--arch/arm/mach-omap/board-innovator.c58
-rw-r--r--arch/arm/mach-omap/board-osk.c4
-rw-r--r--arch/arm/mach-omap/board-perseus2.c15
-rw-r--r--arch/arm/mach-omap/bus.c246
-rw-r--r--arch/arm/mach-omap/clocks.c11
-rw-r--r--arch/arm/mach-omap/common.c53
-rw-r--r--arch/arm/mach-omap/common.h1
-rw-r--r--arch/arm/mach-omap/dma.c156
-rw-r--r--arch/arm/mach-omap/fpga.c30
-rw-r--r--arch/arm/mach-omap/gpio.c28
-rw-r--r--arch/arm/mach-omap/irq.c20
-rw-r--r--arch/arm/mach-omap/leds-h2p2-debug.c (renamed from arch/arm/mach-omap/leds-perseus2.c)32
-rw-r--r--arch/arm/mach-omap/leds.c9
-rw-r--r--arch/arm/mach-omap/leds.h2
-rw-r--r--arch/arm/mach-omap/mcbsp.c669
-rw-r--r--arch/arm/mach-omap/ocpi.c4
-rw-r--r--arch/arm/mach-omap/usb.c541
-rw-r--r--arch/arm/mach-pxa/Kconfig7
-rw-r--r--arch/arm/mach-s3c2410/Kconfig22
-rw-r--r--arch/arm/mach-s3c2410/Makefile4
-rw-r--r--arch/arm/mach-s3c2410/clock.c304
-rw-r--r--arch/arm/mach-s3c2410/clock.h20
-rw-r--r--arch/arm/mach-s3c2410/devs.c341
-rw-r--r--arch/arm/mach-s3c2410/devs.h31
-rw-r--r--arch/arm/mach-s3c2410/dma.c1085
-rw-r--r--arch/arm/mach-s3c2410/irq.c143
-rw-r--r--arch/arm/mach-s3c2410/s3c2410.h16
-rw-r--r--arch/arm/mm/Kconfig2
-rw-r--r--arch/arm/mm/init.c8
-rw-r--r--arch/arm/mm/proc-xscale.S7
-rw-r--r--arch/arm/tools/mach-types29
77 files changed, 5709 insertions, 2274 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 43adecf6ac3432..ac644beed72071 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -158,6 +158,9 @@ config ARCH_VERSATILE_PB
help
This enables support for ARM Ltd Versatile PB board.
+config ARCH_IMX
+ bool "IMX"
+
endchoice
source "arch/arm/mach-clps711x/Kconfig"
@@ -182,6 +185,8 @@ source "arch/arm/mach-s3c2410/Kconfig"
source "arch/arm/mach-lh7a40x/Kconfig"
+source "arch/arm/mach-imx/Kconfig"
+
# Definitions to make life easier
config ARCH_ACORN
bool
@@ -294,7 +299,7 @@ config ARM_AMBA
config ISA
bool
- depends on FOOTBRIDGE_HOST || ARCH_SHARK || ARCH_CLPS7500 || ARCH_EBSA110 || ARCH_CDB89712 || ARCH_EDB7211 || ARCH_SA1100
+ depends on FOOTBRIDGE_HOST || ARCH_SHARK || ARCH_CLPS7500 || ARCH_EBSA110 || ARCH_CDB89712 || ARCH_EDB7211 || ARCH_SA1100 || ARCH_MX1ADS
default y
help
Find out whether you have ISA slots on your motherboard. ISA is the
@@ -552,7 +557,7 @@ config CMDLINE
config LEDS
bool "Timer and CPU usage LEDs"
- depends on ARCH_NETWINDER || ARCH_EBSA110 || ARCH_EBSA285 || ARCH_SHARK || ARCH_CO285 || ARCH_SA1100 || ARCH_LUBBOCK || MACH_MAINSTONE || ARCH_PXA_IDP || ARCH_INTEGRATOR || ARCH_CDB89712 || ARCH_P720T || ARCH_OMAP || ARCH_VERSATILE_PB
+ depends on ARCH_NETWINDER || ARCH_EBSA110 || ARCH_EBSA285 || ARCH_SHARK || ARCH_CO285 || ARCH_SA1100 || ARCH_LUBBOCK || MACH_MAINSTONE || ARCH_PXA_IDP || ARCH_INTEGRATOR || ARCH_CDB89712 || ARCH_P720T || ARCH_OMAP || ARCH_VERSATILE_PB || ARCH_IMX
help
If you say Y here, the LEDs on your machine will be used
to provide useful information about your current system status.
@@ -565,8 +570,8 @@ config LEDS
system, but the driver will do nothing.
config LEDS_TIMER
- bool "Timer LED" if LEDS && (ARCH_NETWINDER || ARCH_EBSA285 || ARCH_SHARK || MACH_MAINSTONE || ARCH_CO285 || ARCH_SA1100 || ARCH_LUBBOCK || ARCH_PXA_IDP || ARCH_INTEGRATOR || ARCH_P720T || ARCH_VERSATILE_PB)
- depends on ARCH_NETWINDER || ARCH_EBSA110 || ARCH_EBSA285 || ARCH_SHARK || ARCH_CO285 || ARCH_SA1100 || ARCH_LUBBOCK || MACH_MAINSTONE || ARCH_PXA_IDP || ARCH_INTEGRATOR || ARCH_CDB89712 || ARCH_P720T || ARCH_OMAP || ARCH_VERSATILE_PB
+ bool "Timer LED" if LEDS && (ARCH_NETWINDER || ARCH_EBSA285 || ARCH_SHARK || MACH_MAINSTONE || ARCH_CO285 || ARCH_SA1100 || ARCH_LUBBOCK || ARCH_PXA_IDP || ARCH_INTEGRATOR || ARCH_P720T || ARCH_VERSATILE_PB || ARCH_IMX)
+ depends on ARCH_NETWINDER || ARCH_EBSA110 || ARCH_EBSA285 || ARCH_SHARK || ARCH_CO285 || ARCH_SA1100 || ARCH_LUBBOCK || MACH_MAINSTONE || ARCH_PXA_IDP || ARCH_INTEGRATOR || ARCH_CDB89712 || ARCH_P720T || ARCH_OMAP || ARCH_VERSATILE_PB || ARCH_IMX
default y if ARCH_EBSA110
help
If you say Y here, one of the system LEDs (the green one on the
@@ -581,7 +586,7 @@ config LEDS_TIMER
config LEDS_CPU
bool "CPU usage LED"
- depends on LEDS && (ARCH_NETWINDER || ARCH_EBSA285 || ARCH_SHARK || ARCH_CO285 || ARCH_SA1100 || ARCH_LUBBOCK || MACH_MAINSTONE || ARCH_PXA_IDP || ARCH_INTEGRATOR || ARCH_P720T || ARCH_VERSATILE_PB)
+ depends on LEDS && (ARCH_NETWINDER || ARCH_EBSA285 || ARCH_SHARK || ARCH_CO285 || ARCH_SA1100 || ARCH_LUBBOCK || MACH_MAINSTONE || ARCH_PXA_IDP || ARCH_INTEGRATOR || ARCH_P720T || ARCH_VERSATILE_PB || ARCH_IMX)
help
If you say Y here, the red LED will be used to give a good real
time indication of CPU usage, by lighting whenever the idle task
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 8b34b0d8aedde3..ca201efcfb1550 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -94,6 +94,7 @@ textaddr-$(CONFIG_ARCH_FORTUNET) := 0xc0008000
machine-$(CONFIG_ARCH_S3C2410) := s3c2410
machine-$(CONFIG_ARCH_LH7A40X) := lh7a40x
machine-$(CONFIG_ARCH_VERSATILE_PB) := versatile
+ machine-$(CONFIG_ARCH_IMX) := imx
ifeq ($(CONFIG_ARCH_EBSA110),y)
# This is what happens if you forget the IOCS16 line.
diff --git a/arch/arm/boot/Makefile b/arch/arm/boot/Makefile
index c247afdd79e492..570f76e90a111c 100644
--- a/arch/arm/boot/Makefile
+++ b/arch/arm/boot/Makefile
@@ -47,6 +47,7 @@ endif
params_phys-$(CONFIG_ARCH_SA1100) := 0xc0000100
initrd_phys-$(CONFIG_ARCH_SA1100) := 0xc0800000
zreladdr-$(CONFIG_ARCH_PXA) := 0xa0008000
+ zreladdr-$(CONFIG_ARCH_MX1ADS) := 0x08008000
zreladdr-$(CONFIG_ARCH_IOP3XX) := 0xa0008000
params_phys-$(CONFIG_ARCH_IOP3XX) := 0xa0000100
zreladdr-$(CONFIG_ARCH_IXP4XX) := 0x00008000
diff --git a/arch/arm/boot/compressed/head-xscale.S b/arch/arm/boot/compressed/head-xscale.S
index f9194499e8630e..05ca50b3fcb40c 100644
--- a/arch/arm/boot/compressed/head-xscale.S
+++ b/arch/arm/boot/compressed/head-xscale.S
@@ -47,23 +47,3 @@ __XScale_start:
#ifdef CONFIG_ARCH_COTULLA_IDP
mov r7, #MACH_TYPE_COTULLA_IDP
#endif
-
-#ifdef CONFIG_ARCH_IQ80310
- /*
- * Crank the CPU up to 733MHz
- */
- mov r1, #9
- mcr p14, 0, r1, c6, c0, 0
-
- /*
- * Disable ECC error notification
- * At some point, we should add an ECC handler to Linux
- */
- mov r1, #0x1500
- mov r0, #0x4
- str r0, [r1, #0x34]
-
- mov r7, #MACH_TYPE_IQ80310
-#endif
-
-
diff --git a/arch/arm/configs/iq80321_defconfig b/arch/arm/configs/iq80321_defconfig
index c9afe2458b9534..c7acf4c3838f25 100644
--- a/arch/arm/configs/iq80321_defconfig
+++ b/arch/arm/configs/iq80321_defconfig
@@ -10,21 +10,33 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y
# Code maturity level options
#
CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_STANDALONE=y
+CONFIG_BROKEN_ON_SMP=y
#
# General setup
#
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_HOTPLUG is not set
+# CONFIG_IKCONFIG is not set
# CONFIG_EMBEDDED is not set
CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
CONFIG_FUTEX=y
CONFIG_EPOLL=y
+CONFIG_IOSCHED_NOOP=y
CONFIG_IOSCHED_AS=y
CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
#
# Loadable module support
@@ -38,32 +50,24 @@ CONFIG_KMOD=y
#
# System Type
#
-# CONFIG_ARCH_ADIFCC is not set
# CONFIG_ARCH_CLPS7500 is not set
# CONFIG_ARCH_CLPS711X is not set
# CONFIG_ARCH_CO285 is not set
-# CONFIG_ARCH_PXA is not set
# CONFIG_ARCH_EBSA110 is not set
# CONFIG_ARCH_CAMELOT is not set
# CONFIG_ARCH_FOOTBRIDGE is not set
# CONFIG_ARCH_INTEGRATOR is not set
CONFIG_ARCH_IOP3XX=y
+# CONFIG_ARCH_IXP4XX is not set
# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_PXA is not set
# CONFIG_ARCH_RPC is not set
# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
# CONFIG_ARCH_SHARK is not set
-
-#
-# CLPS711X/EP721X Implementations
-#
-
-#
-# Epxa10db
-#
-
-#
-# Footbridge Implementations
-#
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_VERSATILE_PB is not set
#
# IOP3xx Implementation Options
@@ -82,27 +86,14 @@ CONFIG_ARCH_IOP321=y
# CONFIG_IOP3XX_PMON is not set
#
-# ADIFCC Implementation Options
-#
-
-#
-# ADI Board Types
-#
-
-#
-# Intel PXA250/210 Implementations
-#
-
-#
-# SA11x0 Implementations
-#
-
-#
# Processor Type
#
CONFIG_CPU_32=y
CONFIG_CPU_XSCALE=y
CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5T=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_MINICACHE=y
#
# Processor Features
@@ -119,12 +110,6 @@ CONFIG_ZBOOT_ROM_TEXT=0x0
CONFIG_ZBOOT_ROM_BSS=0x0
# CONFIG_PCI_LEGACY_PROC is not set
CONFIG_PCI_NAMES=y
-# CONFIG_HOTPLUG is not set
-
-#
-# MMC/SD Card support
-#
-# CONFIG_MMC is not set
#
# At least one math emulation must be selected
@@ -132,11 +117,16 @@ CONFIG_PCI_NAMES=y
CONFIG_FPE_NWFPE=y
# CONFIG_FPE_NWFPE_XP is not set
# CONFIG_FPE_FASTFPE is not set
-CONFIG_KCORE_ELF=y
-# CONFIG_KCORE_AOUT is not set
-CONFIG_BINFMT_AOUT=y
+# CONFIG_VFP is not set
CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_AOUT=y
# CONFIG_BINFMT_MISC is not set
+
+#
+# Generic Driver Options
+#
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_DEBUG_DRIVER is not set
# CONFIG_PM is not set
# CONFIG_PREEMPT is not set
# CONFIG_ARTHUR is not set
@@ -214,7 +204,6 @@ CONFIG_MTD_CFI_INTELEXT=y
#
# Plug and Play support
#
-# CONFIG_PNP is not set
#
# Block devices
@@ -226,6 +215,7 @@ CONFIG_MTD_CFI_INTELEXT=y
# CONFIG_BLK_DEV_UMEM is not set
# CONFIG_BLK_DEV_LOOP is not set
# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_SIZE=8192
# CONFIG_BLK_DEV_INITRD is not set
@@ -245,8 +235,6 @@ CONFIG_NET=y
#
# CONFIG_PACKET is not set
# CONFIG_NETLINK_DEV is not set
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
CONFIG_UNIX=y
# CONFIG_NET_KEY is not set
CONFIG_INET=y
@@ -259,13 +247,20 @@ CONFIG_IP_PNP_BOOTP=y
# CONFIG_NET_IPIP is not set
# CONFIG_NET_IPGRE is not set
# CONFIG_ARPD is not set
-# CONFIG_INET_ECN is not set
# CONFIG_SYN_COOKIES is not set
# CONFIG_INET_AH is not set
# CONFIG_INET_ESP is not set
# CONFIG_INET_IPCOMP is not set
#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+# CONFIG_IPV6 is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+
+#
# IP: Netfilter Configuration
#
# CONFIG_IP_NF_CONNTRACK is not set
@@ -276,22 +271,16 @@ CONFIG_IP_PNP_BOOTP=y
# CONFIG_IP_NF_COMPAT_IPFWADM is not set
#
-# IP: Virtual Server Configuration
-#
-# CONFIG_IP_VS is not set
-# CONFIG_IPV6 is not set
-# CONFIG_XFRM_USER is not set
-
-#
# SCTP Configuration (EXPERIMENTAL)
#
-CONFIG_IPV6_SCTP__=y
# CONFIG_IP_SCTP is not set
# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
# CONFIG_VLAN_8021Q is not set
-# CONFIG_LLC is not set
# CONFIG_DECNET is not set
-# CONFIG_BRIDGE is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
# CONFIG_X25 is not set
# CONFIG_LAPB is not set
# CONFIG_NET_DIVERT is not set
@@ -303,32 +292,37 @@ CONFIG_IPV6_SCTP__=y
# QoS and/or fair queueing
#
# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
#
# Network testing
#
# CONFIG_NET_PKTGEN is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
#
# ARCnet devices
#
# CONFIG_ARCNET is not set
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
-# CONFIG_MII is not set
-# CONFIG_SMC91X is not set
+CONFIG_MII=y
# CONFIG_HAPPYMEAL is not set
# CONFIG_SUNGEM is not set
# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_SMC91X is not set
#
# Tulip family network device support
@@ -340,6 +334,7 @@ CONFIG_NET_PCI=y
# CONFIG_AMD8111_ETH is not set
# CONFIG_ADAPTEC_STARFIRE is not set
# CONFIG_B44 is not set
+# CONFIG_FORCEDETH is not set
# CONFIG_DGRS is not set
CONFIG_EEPRO100=y
# CONFIG_EEPRO100_PIO is not set
@@ -354,6 +349,7 @@ CONFIG_EEPRO100=y
# CONFIG_SUNDANCE is not set
# CONFIG_TLAN is not set
# CONFIG_VIA_RHINE is not set
+# CONFIG_VIA_VELOCITY is not set
#
# Ethernet (1000 Mbit)
@@ -373,55 +369,43 @@ CONFIG_E1000_NAPI=y
# Ethernet (10000 Mbit)
#
# CONFIG_IXGB is not set
-# CONFIG_FDDI is not set
-# CONFIG_HIPPI is not set
-# CONFIG_PPP is not set
-# CONFIG_SLIP is not set
+# CONFIG_S2IO is not set
#
-# Wireless LAN (non-hamradio)
+# Token Ring devices
#
-# CONFIG_NET_RADIO is not set
+# CONFIG_TR is not set
#
-# Token Ring devices (depends on LLC=y)
+# Wireless LAN (non-hamradio)
#
-# CONFIG_RCPCI is not set
-# CONFIG_SHAPER is not set
+# CONFIG_NET_RADIO is not set
#
# Wan interfaces
#
# CONFIG_WAN is not set
-
-#
-# IrDA (infrared) support
-#
-# CONFIG_IRDA is not set
-
-#
-# Amateur Radio support
-#
-# CONFIG_HAMRADIO is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
#
# ATA/ATAPI/MFM/RLL support
#
CONFIG_IDE=y
-
-#
-# IDE, ATA and ATAPI Block devices
-#
CONFIG_BLK_DEV_IDE=y
#
# Please see Documentation/ide.txt for help/info on IDE drives
#
-# CONFIG_BLK_DEV_HD is not set
+# CONFIG_BLK_DEV_IDE_SATA is not set
CONFIG_BLK_DEV_IDEDISK=y
# CONFIG_IDEDISK_MULTI_MODE is not set
-# CONFIG_IDEDISK_STROKE is not set
CONFIG_BLK_DEV_IDECD=y
+# CONFIG_BLK_DEV_IDETAPE is not set
# CONFIG_BLK_DEV_IDEFLOPPY is not set
# CONFIG_IDE_TASK_IOCTL is not set
# CONFIG_IDE_TASKFILE_IO is not set
@@ -429,16 +413,17 @@ CONFIG_BLK_DEV_IDECD=y
#
# IDE chipset support/bugfixes
#
+CONFIG_IDE_GENERIC=y
CONFIG_BLK_DEV_IDEPCI=y
-# CONFIG_BLK_DEV_GENERIC is not set
# CONFIG_IDEPCI_SHARE_IRQ is not set
-CONFIG_BLK_DEV_IDEDMA_PCI=y
-# CONFIG_BLK_DEV_IDE_TCQ is not set
# CONFIG_BLK_DEV_OFFBOARD is not set
+# CONFIG_BLK_DEV_GENERIC is not set
+# CONFIG_BLK_DEV_OPTI621 is not set
+# CONFIG_BLK_DEV_SL82C105 is not set
+CONFIG_BLK_DEV_IDEDMA_PCI=y
# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
CONFIG_IDEDMA_PCI_AUTO=y
# CONFIG_IDEDMA_ONLYDISK is not set
-CONFIG_BLK_DEV_IDEDMA=y
CONFIG_BLK_DEV_ADMA=y
# CONFIG_BLK_DEV_AEC62XX is not set
# CONFIG_BLK_DEV_ALI15X3 is not set
@@ -447,12 +432,12 @@ CONFIG_BLK_DEV_CMD64X=y
# CONFIG_BLK_DEV_TRIFLEX is not set
# CONFIG_BLK_DEV_CY82C693 is not set
# CONFIG_BLK_DEV_CS5520 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
# CONFIG_BLK_DEV_HPT34X is not set
# CONFIG_BLK_DEV_HPT366 is not set
# CONFIG_BLK_DEV_SC1200 is not set
# CONFIG_BLK_DEV_PIIX is not set
# CONFIG_BLK_DEV_NS87415 is not set
-# CONFIG_BLK_DEV_OPTI621 is not set
# CONFIG_BLK_DEV_PDC202XX_OLD is not set
# CONFIG_BLK_DEV_PDC202XX_NEW is not set
# CONFIG_BLK_DEV_SVWKS is not set
@@ -460,9 +445,11 @@ CONFIG_BLK_DEV_CMD64X=y
# CONFIG_BLK_DEV_SLC90E66 is not set
# CONFIG_BLK_DEV_TRM290 is not set
# CONFIG_BLK_DEV_VIA82CXXX is not set
-# CONFIG_BLK_DEV_SL82C105 is not set
-CONFIG_IDEDMA_AUTO=y
+# CONFIG_IDE_ARM is not set
+CONFIG_BLK_DEV_IDEDMA=y
# CONFIG_IDEDMA_IVB is not set
+CONFIG_IDEDMA_AUTO=y
+# CONFIG_BLK_DEV_HD is not set
#
# SCSI device support
@@ -470,7 +457,11 @@ CONFIG_IDEDMA_AUTO=y
# CONFIG_SCSI is not set
#
-# IEEE 1394 (FireWire) support (EXPERIMENTAL)
+# Fusion MPT device support
+#
+
+#
+# IEEE 1394 (FireWire) support
#
# CONFIG_IEEE1394 is not set
@@ -482,16 +473,24 @@ CONFIG_IDEDMA_AUTO=y
#
# ISDN subsystem
#
-# CONFIG_ISDN_BOOL is not set
+# CONFIG_ISDN is not set
#
# Input device support
#
-# CONFIG_INPUT is not set
+CONFIG_INPUT=y
#
# Userland interfaces
#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
#
# Input I/O drivers
@@ -499,14 +498,23 @@ CONFIG_IDEDMA_AUTO=y
# CONFIG_GAMEPORT is not set
CONFIG_SOUND_GAMEPORT=y
# CONFIG_SERIO is not set
+# CONFIG_SERIO_I8042 is not set
#
# Input Device Drivers
#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
#
# Character devices
#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
# CONFIG_SERIAL_NONSTANDARD is not set
#
@@ -514,40 +522,17 @@ CONFIG_SOUND_GAMEPORT=y
#
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=4
# CONFIG_SERIAL_8250_EXTENDED is not set
#
# Non-8250 serial port support
#
-# CONFIG_SERIAL_DZ is not set
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
CONFIG_UNIX98_PTYS=y
-CONFIG_UNIX98_PTY_COUNT=256
-
-#
-# I2C support
-#
-# CONFIG_I2C is not set
-
-#
-# I2C Hardware Sensors Mainboard support
-#
-
-#
-# I2C Hardware Sensors Chip support
-#
-# CONFIG_I2C_SENSOR is not set
-
-#
-# L3 serial bus support
-#
-# CONFIG_L3 is not set
-
-#
-# Mice
-#
-# CONFIG_BUSMOUSE is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_QIC02_TAPE is not set
#
@@ -573,39 +558,21 @@ CONFIG_UNIX98_PTY_COUNT=256
# CONFIG_AGP is not set
# CONFIG_DRM is not set
# CONFIG_RAW_DRIVER is not set
-# CONFIG_HANGCHECK_TIMER is not set
-
-#
-# Multimedia devices
-#
-CONFIG_VIDEO_DEV=y
#
-# Video For Linux
-#
-# CONFIG_VIDEO_PROC_FS is not set
-
-#
-# Video Adapters
+# I2C support
#
-# CONFIG_VIDEO_PMS is not set
-# CONFIG_VIDEO_CPIA is not set
-# CONFIG_VIDEO_STRADIS is not set
-# CONFIG_VIDEO_HEXIUM_ORION is not set
-# CONFIG_VIDEO_HEXIUM_GEMINI is not set
+# CONFIG_I2C is not set
#
-# Radio Adapters
+# Multimedia devices
#
-# CONFIG_RADIO_GEMTEK_PCI is not set
-# CONFIG_RADIO_MAXIRADIO is not set
-# CONFIG_RADIO_MAESTRO is not set
+# CONFIG_VIDEO_DEV is not set
#
# Digital Video Broadcasting Devices
#
# CONFIG_DVB is not set
-# CONFIG_VIDEO_BTCX is not set
#
# File systems
@@ -639,10 +606,11 @@ CONFIG_EXT2_FS=y
# Pseudo filesystems
#
CONFIG_PROC_FS=y
+CONFIG_SYSFS=y
# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS=y
# CONFIG_DEVPTS_FS_XATTR is not set
CONFIG_TMPFS=y
+# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
#
@@ -651,6 +619,7 @@ CONFIG_RAMFS=y
# CONFIG_ADFS_FS is not set
# CONFIG_AFFS_FS is not set
# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
# CONFIG_BEFS_FS is not set
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
@@ -671,17 +640,17 @@ CONFIG_JFFS2_FS_DEBUG=0
CONFIG_NFS_FS=y
# CONFIG_NFS_V3 is not set
# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
# CONFIG_NFSD is not set
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
# CONFIG_EXPORTFS is not set
CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_GSS is not set
+# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_SMB_FS is not set
# CONFIG_CIFS is not set
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
-# CONFIG_INTERMEZZO_FS is not set
# CONFIG_AFS_FS is not set
#
@@ -699,46 +668,51 @@ CONFIG_MSDOS_PARTITION=y
# CONFIG_SOLARIS_X86_PARTITION is not set
# CONFIG_UNIXWARE_DISKLABEL is not set
# CONFIG_LDM_PARTITION is not set
-# CONFIG_NEC98_PARTITION is not set
# CONFIG_SGI_PARTITION is not set
# CONFIG_ULTRIX_PARTITION is not set
# CONFIG_SUN_PARTITION is not set
# CONFIG_EFI_PARTITION is not set
#
-# Graphics support
+# Native Language Support
#
-# CONFIG_FB is not set
+# CONFIG_NLS is not set
#
-# Sound
+# Profiling support
#
-# CONFIG_SOUND is not set
+# CONFIG_PROFILING is not set
#
-# Misc devices
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Console display driver support
#
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_MDA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
#
-# Multimedia Capabilities Port drivers
+# Sound
#
-# CONFIG_MCP is not set
+# CONFIG_SOUND is not set
#
-# Console Switches
+# Misc devices
#
-# CONFIG_SWITCHES is not set
#
# USB support
#
# CONFIG_USB is not set
-# CONFIG_USB_GADGET is not set
#
-# Bluetooth support
+# USB Gadget Support
#
-# CONFIG_BT is not set
+# CONFIG_USB_GADGET is not set
#
# Kernel hacking
@@ -754,6 +728,7 @@ CONFIG_DEBUG_KERNEL=y
CONFIG_DEBUG_BUGVERBOSE=y
CONFIG_DEBUG_ERRORS=y
CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_ICEDCC is not set
#
# Security options
@@ -768,6 +743,8 @@ CONFIG_DEBUG_LL=y
#
# Library routines
#
-# CONFIG_CRC32 is not set
+# CONFIG_CRC_CCITT is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
diff --git a/arch/arm/configs/iq80310_defconfig b/arch/arm/configs/mx1ads_defconfig
index e67d114f1bee14..89da10c664893d 100644
--- a/arch/arm/configs/iq80310_defconfig
+++ b/arch/arm/configs/mx1ads_defconfig
@@ -10,27 +10,38 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y
# Code maturity level options
#
CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_STANDALONE=y
+CONFIG_BROKEN_ON_SMP=y
#
# General setup
#
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_SYSCTL is not set
+# CONFIG_AUDIT is not set
CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_EMBEDDED is not set
-CONFIG_KALLSYMS=y
+# CONFIG_HOTPLUG is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_EMBEDDED=y
+# CONFIG_KALLSYMS is not set
CONFIG_FUTEX=y
CONFIG_EPOLL=y
-CONFIG_IOSCHED_AS=y
+# CONFIG_IOSCHED_NOOP is not set
+# CONFIG_IOSCHED_AS is not set
CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
#
# Loadable module support
#
CONFIG_MODULES=y
-# CONFIG_MODULE_UNLOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
CONFIG_OBSOLETE_MODPARM=y
# CONFIG_MODVERSIONS is not set
CONFIG_KMOD=y
@@ -38,110 +49,80 @@ CONFIG_KMOD=y
#
# System Type
#
-# CONFIG_ARCH_ADIFCC is not set
# CONFIG_ARCH_CLPS7500 is not set
# CONFIG_ARCH_CLPS711X is not set
# CONFIG_ARCH_CO285 is not set
-# CONFIG_ARCH_PXA is not set
# CONFIG_ARCH_EBSA110 is not set
# CONFIG_ARCH_CAMELOT is not set
# CONFIG_ARCH_FOOTBRIDGE is not set
# CONFIG_ARCH_INTEGRATOR is not set
-CONFIG_ARCH_IOP3XX=y
+# CONFIG_ARCH_IOP3XX is not set
+# CONFIG_ARCH_IXP4XX is not set
# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_PXA is not set
# CONFIG_ARCH_RPC is not set
# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_VERSATILE_PB is not set
+CONFIG_ARCH_IMX=y
#
-# CLPS711X/EP721X Implementations
-#
-
-#
-# Epxa10db
-#
-
-#
-# Footbridge Implementations
-#
-
-#
-# IOP3xx Implementation Options
-#
-CONFIG_ARCH_IQ80310=y
-# CONFIG_ARCH_IQ80321 is not set
-CONFIG_ARCH_IOP310=y
-# CONFIG_ARCH_IOP321 is not set
-
-#
-# IOP3xx Chipset Features
-#
-# CONFIG_IOP3XX_AAU is not set
-# CONFIG_IOP3XX_DMA is not set
-# CONFIG_IOP3XX_MU is not set
-# CONFIG_IOP3XX_PMON is not set
-
-#
-# ADIFCC Implementation Options
-#
-
-#
-# ADI Board Types
-#
-
-#
-# Intel PXA250/210 Implementations
-#
-
-#
-# SA11x0 Implementations
+# IMX Implementations
#
+CONFIG_ARCH_MX1ADS=y
#
# Processor Type
#
CONFIG_CPU_32=y
-CONFIG_CPU_XSCALE=y
-CONFIG_XS80200=y
-CONFIG_CPU_32v5=y
+CONFIG_CPU_ARM920T=y
+CONFIG_CPU_32v4=y
+CONFIG_CPU_ABRT_EV4T=y
+CONFIG_CPU_CACHE_V4WT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
#
# Processor Features
#
-CONFIG_ARM_THUMB=y
-CONFIG_XSCALE_PMU=y
+# CONFIG_ARM_THUMB is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
#
# General setup
#
-CONFIG_PCI=y
+CONFIG_ISA=y
# CONFIG_ZBOOT_ROM is not set
-CONFIG_ZBOOT_ROM_TEXT=0x00060000
-CONFIG_ZBOOT_ROM_BSS=0xa1008000
-# CONFIG_PCI_LEGACY_PROC is not set
-CONFIG_PCI_NAMES=y
-# CONFIG_HOTPLUG is not set
-
-#
-# MMC/SD Card support
-#
-# CONFIG_MMC is not set
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+# CONFIG_CPU_FREQ is not set
#
# At least one math emulation must be selected
#
CONFIG_FPE_NWFPE=y
-# CONFIG_FPE_NWFPE_XP is not set
-# CONFIG_FPE_FASTFPE is not set
-CONFIG_KCORE_ELF=y
-# CONFIG_KCORE_AOUT is not set
-CONFIG_BINFMT_AOUT=y
+CONFIG_FPE_NWFPE_XP=y
+CONFIG_FPE_FASTFPE=y
+# CONFIG_VFP is not set
CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_AOUT is not set
# CONFIG_BINFMT_MISC is not set
+
+#
+# Generic Driver Options
+#
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_DEBUG_DRIVER is not set
# CONFIG_PM is not set
-# CONFIG_PREEMPT is not set
+CONFIG_PREEMPT=y
# CONFIG_ARTHUR is not set
-CONFIG_CMDLINE="console=ttyS0,115200 ip=bootp mem=32M root=/dev/nfs initrd=0xc0800000,4M"
+CONFIG_CMDLINE="console=ttySMX0,57600n8 ip=bootp root=/dev/nfs"
+# CONFIG_LEDS is not set
CONFIG_ALIGNMENT_TRAP=y
#
@@ -156,7 +137,7 @@ CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
CONFIG_MTD_PARTITIONS=y
# CONFIG_MTD_CONCAT is not set
-CONFIG_MTD_REDBOOT_PARTS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
# CONFIG_MTD_CMDLINE_PARTS is not set
# CONFIG_MTD_AFS_PARTS is not set
@@ -172,15 +153,10 @@ CONFIG_MTD_BLOCK=y
#
# RAM/ROM/Flash chip drivers
#
-CONFIG_MTD_CFI=y
+# CONFIG_MTD_CFI is not set
# CONFIG_MTD_JEDECPROBE is not set
-CONFIG_MTD_GEN_PROBE=y
-# CONFIG_MTD_CFI_ADV_OPTIONS is not set
-CONFIG_MTD_CFI_INTELEXT=y
-# CONFIG_MTD_CFI_AMDSTD is not set
-# CONFIG_MTD_CFI_STAA is not set
# CONFIG_MTD_RAM is not set
-# CONFIG_MTD_ROM is not set
+CONFIG_MTD_ROM=y
# CONFIG_MTD_ABSENT is not set
# CONFIG_MTD_OBSOLETE_CHIPS is not set
@@ -188,15 +164,11 @@ CONFIG_MTD_CFI_INTELEXT=y
# Mapping drivers for chip access
#
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
-# CONFIG_MTD_PHYSMAP is not set
-# CONFIG_MTD_ARM_INTEGRATOR is not set
-CONFIG_MTD_IQ80310=y
-# CONFIG_MTD_EDB7312 is not set
+CONFIG_MTD_MX1ADS=y
#
# Self-contained MTD device drivers
#
-# CONFIG_MTD_PMC551 is not set
# CONFIG_MTD_SLRAM is not set
# CONFIG_MTD_MTDRAM is not set
# CONFIG_MTD_BLKMTD is not set
@@ -222,15 +194,11 @@ CONFIG_MTD_IQ80310=y
# Block devices
#
# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_CPQ_DA is not set
-# CONFIG_BLK_CPQ_CISS_DA is not set
-# CONFIG_BLK_DEV_DAC960 is not set
-# CONFIG_BLK_DEV_UMEM is not set
-# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_XD is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
# CONFIG_BLK_DEV_NBD is not set
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_BLK_DEV_INITRD=y
+# CONFIG_BLK_DEV_RAM is not set
#
# Multi-device support (RAID and LVM)
@@ -245,82 +213,72 @@ CONFIG_NET=y
#
# Networking options
#
-# CONFIG_PACKET is not set
+CONFIG_PACKET=m
+CONFIG_PACKET_MMAP=y
# CONFIG_NETLINK_DEV is not set
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
CONFIG_UNIX=y
# CONFIG_NET_KEY is not set
CONFIG_INET=y
# CONFIG_IP_MULTICAST is not set
# CONFIG_IP_ADVANCED_ROUTER is not set
CONFIG_IP_PNP=y
-# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_DHCP=y
CONFIG_IP_PNP_BOOTP=y
# CONFIG_IP_PNP_RARP is not set
# CONFIG_NET_IPIP is not set
# CONFIG_NET_IPGRE is not set
# CONFIG_ARPD is not set
-# CONFIG_INET_ECN is not set
# CONFIG_SYN_COOKIES is not set
# CONFIG_INET_AH is not set
# CONFIG_INET_ESP is not set
# CONFIG_INET_IPCOMP is not set
-
-#
-# IP: Netfilter Configuration
-#
-# CONFIG_IP_NF_CONNTRACK is not set
-# CONFIG_IP_NF_QUEUE is not set
-# CONFIG_IP_NF_IPTABLES is not set
-# CONFIG_IP_NF_ARPTABLES is not set
-# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
-# CONFIG_IP_NF_COMPAT_IPFWADM is not set
-
-#
-# IP: Virtual Server Configuration
-#
-# CONFIG_IP_VS is not set
# CONFIG_IPV6 is not set
-# CONFIG_XFRM_USER is not set
+# CONFIG_NETFILTER is not set
#
# SCTP Configuration (EXPERIMENTAL)
#
-CONFIG_IPV6_SCTP__=y
# CONFIG_IP_SCTP is not set
# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
# CONFIG_VLAN_8021Q is not set
-# CONFIG_LLC is not set
# CONFIG_DECNET is not set
-# CONFIG_BRIDGE is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
# CONFIG_X25 is not set
# CONFIG_LAPB is not set
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# QoS and/or fair queueing
#
# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
#
# Network testing
#
# CONFIG_NET_PKTGEN is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
#
# ARCnet devices
#
# CONFIG_ARCNET is not set
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
#
# Ethernet (10 or 100Mbit)
@@ -328,129 +286,73 @@ CONFIG_NETDEVICES=y
CONFIG_NET_ETHERNET=y
CONFIG_MII=y
# CONFIG_SMC91X is not set
-# CONFIG_HAPPYMEAL is not set
-# CONFIG_SUNGEM is not set
# CONFIG_NET_VENDOR_3COM is not set
-
-#
-# Tulip family network device support
-#
-# CONFIG_NET_TULIP is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
# CONFIG_HP100 is not set
-CONFIG_NET_PCI=y
-# CONFIG_PCNET32 is not set
-# CONFIG_AMD8111_ETH is not set
-# CONFIG_ADAPTEC_STARFIRE is not set
-# CONFIG_B44 is not set
-# CONFIG_DGRS is not set
-CONFIG_EEPRO100=y
-# CONFIG_EEPRO100_PIO is not set
-# CONFIG_E100 is not set
-# CONFIG_FEALNX is not set
-# CONFIG_NATSEMI is not set
-# CONFIG_NE2K_PCI is not set
-# CONFIG_8139CP is not set
-# CONFIG_8139TOO is not set
-# CONFIG_SIS900 is not set
-# CONFIG_EPIC100 is not set
-# CONFIG_SUNDANCE is not set
-# CONFIG_TLAN is not set
-# CONFIG_VIA_RHINE is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_NET_POCKET is not set
#
# Ethernet (1000 Mbit)
#
-# CONFIG_ACENIC is not set
-# CONFIG_DL2K is not set
-# CONFIG_E1000 is not set
-# CONFIG_NS83820 is not set
-# CONFIG_HAMACHI is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_R8169 is not set
-# CONFIG_SK98LIN is not set
-# CONFIG_TIGON3 is not set
#
# Ethernet (10000 Mbit)
#
-# CONFIG_IXGB is not set
-# CONFIG_FDDI is not set
-# CONFIG_HIPPI is not set
-# CONFIG_PPP is not set
-# CONFIG_SLIP is not set
#
-# Wireless LAN (non-hamradio)
+# Token Ring devices
#
-# CONFIG_NET_RADIO is not set
+# CONFIG_TR is not set
#
-# Token Ring devices (depends on LLC=y)
+# Wireless LAN (non-hamradio)
#
-# CONFIG_RCPCI is not set
-# CONFIG_SHAPER is not set
+# CONFIG_NET_RADIO is not set
#
# Wan interfaces
#
# CONFIG_WAN is not set
+CONFIG_PPP=y
+# CONFIG_PPP_MULTILINK is not set
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=y
+# CONFIG_PPP_SYNC_TTY is not set
+CONFIG_PPP_DEFLATE=y
+CONFIG_PPP_BSDCOMP=y
+# CONFIG_PPPOE is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
#
-# IrDA (infrared) support
-#
-# CONFIG_IRDA is not set
-
-#
-# Amateur Radio support
-#
-# CONFIG_HAMRADIO is not set
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
-CONFIG_IDE=y
-
-#
-# IDE, ATA and ATAPI Block devices
-#
-CONFIG_BLK_DEV_IDE=y
-
-#
-# Please see Documentation/ide.txt for help/info on IDE drives
-#
-# CONFIG_BLK_DEV_HD is not set
-CONFIG_BLK_DEV_IDEDISK=y
-# CONFIG_IDEDISK_MULTI_MODE is not set
-# CONFIG_IDEDISK_STROKE is not set
-CONFIG_BLK_DEV_IDECD=y
-# CONFIG_BLK_DEV_IDEFLOPPY is not set
-# CONFIG_IDE_TASK_IOCTL is not set
-# CONFIG_IDE_TASKFILE_IO is not set
-
-#
-# IDE chipset support/bugfixes
+# SCSI device support
#
-# CONFIG_BLK_DEV_IDEPCI is not set
+# CONFIG_SCSI is not set
#
-# SCSI device support
+# Fusion MPT device support
#
-# CONFIG_SCSI is not set
#
-# IEEE 1394 (FireWire) support (EXPERIMENTAL)
+# IEEE 1394 (FireWire) support
#
# CONFIG_IEEE1394 is not set
#
# I2O device support
#
-# CONFIG_I2O is not set
#
# ISDN subsystem
#
-# CONFIG_ISDN_BOOL is not set
+# CONFIG_ISDN is not set
#
# Input device support
@@ -467,6 +369,7 @@ CONFIG_BLK_DEV_IDECD=y
# CONFIG_GAMEPORT is not set
CONFIG_SOUND_GAMEPORT=y
# CONFIG_SERIO is not set
+# CONFIG_SERIO_I8042 is not set
#
# Input Device Drivers
@@ -475,47 +378,23 @@ CONFIG_SOUND_GAMEPORT=y
#
# Character devices
#
+# CONFIG_VT is not set
# CONFIG_SERIAL_NONSTANDARD is not set
#
# Serial drivers
#
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250 is not set
#
# Non-8250 serial port support
#
-# CONFIG_SERIAL_DZ is not set
+CONFIG_SERIAL_IMX=y
+CONFIG_SERIAL_IMX_CONSOLE=y
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
CONFIG_UNIX98_PTYS=y
-CONFIG_UNIX98_PTY_COUNT=256
-
-#
-# I2C support
-#
-# CONFIG_I2C is not set
-
-#
-# I2C Hardware Sensors Mainboard support
-#
-
-#
-# I2C Hardware Sensors Chip support
-#
-# CONFIG_I2C_SENSOR is not set
-
-#
-# L3 serial bus support
-#
-# CONFIG_L3 is not set
-
-#
-# Mice
-#
-# CONFIG_BUSMOUSE is not set
+# CONFIG_LEGACY_PTYS is not set
# CONFIG_QIC02_TAPE is not set
#
@@ -528,7 +407,7 @@ CONFIG_UNIX98_PTY_COUNT=256
#
# CONFIG_WATCHDOG is not set
# CONFIG_NVRAM is not set
-# CONFIG_RTC is not set
+CONFIG_RTC=m
# CONFIG_GEN_RTC is not set
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
@@ -541,72 +420,26 @@ CONFIG_UNIX98_PTY_COUNT=256
# CONFIG_AGP is not set
# CONFIG_DRM is not set
# CONFIG_RAW_DRIVER is not set
-# CONFIG_HANGCHECK_TIMER is not set
-
-#
-# Multimedia devices
-#
-CONFIG_VIDEO_DEV=y
#
-# Video For Linux
-#
-# CONFIG_VIDEO_PROC_FS is not set
-
-#
-# Video Adapters
+# I2C support
#
-# CONFIG_VIDEO_PMS is not set
-# CONFIG_VIDEO_CPIA is not set
-# CONFIG_VIDEO_STRADIS is not set
-# CONFIG_VIDEO_HEXIUM_ORION is not set
-# CONFIG_VIDEO_HEXIUM_GEMINI is not set
+# CONFIG_I2C is not set
#
-# Radio Adapters
+# Multimedia devices
#
-# CONFIG_RADIO_GEMTEK_PCI is not set
-# CONFIG_RADIO_MAXIRADIO is not set
-# CONFIG_RADIO_MAESTRO is not set
+# CONFIG_VIDEO_DEV is not set
#
# Digital Video Broadcasting Devices
#
-CONFIG_DVB=y
-CONFIG_DVB_CORE=y
-
-#
-# Supported Frontend Modules
-#
-# CONFIG_DVB_STV0299 is not set
-# CONFIG_DVB_ALPS_BSRV2 is not set
-# CONFIG_DVB_ALPS_TDLB7 is not set
-# CONFIG_DVB_ALPS_TDMB7 is not set
-# CONFIG_DVB_ATMEL_AT76C651 is not set
-# CONFIG_DVB_CX24110 is not set
-# CONFIG_DVB_GRUNDIG_29504_491 is not set
-# CONFIG_DVB_GRUNDIG_29504_401 is not set
-# CONFIG_DVB_MT312 is not set
-# CONFIG_DVB_VES1820 is not set
-# CONFIG_DVB_TDA1004X is not set
-
-#
-# Supported SAA7146 based PCI Adapters
-#
-# CONFIG_DVB_AV7110 is not set
-# CONFIG_DVB_BUDGET is not set
-
-#
-# Supported FlexCopII (B2C2) Adapters
-#
-# CONFIG_DVB_B2C2_SKYSTAR is not set
-# CONFIG_VIDEO_BTCX is not set
+# CONFIG_DVB is not set
#
# File systems
#
-CONFIG_EXT2_FS=y
-# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS is not set
# CONFIG_EXT3_FS is not set
# CONFIG_JBD is not set
# CONFIG_REISERFS_FS is not set
@@ -627,17 +460,24 @@ CONFIG_EXT2_FS=y
#
# DOS/FAT/NT Filesystems
#
-# CONFIG_FAT_FS is not set
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
# CONFIG_NTFS_FS is not set
#
# Pseudo filesystems
#
CONFIG_PROC_FS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS=y
+CONFIG_SYSFS=y
+CONFIG_DEVFS_FS=y
+CONFIG_DEVFS_MOUNT=y
+# CONFIG_DEVFS_DEBUG is not set
# CONFIG_DEVPTS_FS_XATTR is not set
CONFIG_TMPFS=y
+# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
#
@@ -646,6 +486,7 @@ CONFIG_RAMFS=y
# CONFIG_ADFS_FS is not set
# CONFIG_AFFS_FS is not set
# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
# CONFIG_BEFS_FS is not set
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
@@ -653,7 +494,7 @@ CONFIG_RAMFS=y
CONFIG_JFFS2_FS=y
CONFIG_JFFS2_FS_DEBUG=0
# CONFIG_JFFS2_FS_NAND is not set
-# CONFIG_CRAMFS is not set
+CONFIG_CRAMFS=y
# CONFIG_VXFS_FS is not set
# CONFIG_HPFS_FS is not set
# CONFIG_QNX4FS_FS is not set
@@ -664,41 +505,75 @@ CONFIG_JFFS2_FS_DEBUG=0
# Network File Systems
#
CONFIG_NFS_FS=y
-# CONFIG_NFS_V3 is not set
+CONFIG_NFS_V3=y
# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
# CONFIG_NFSD is not set
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
# CONFIG_EXPORTFS is not set
CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_GSS is not set
+# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_SMB_FS is not set
# CONFIG_CIFS is not set
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
-# CONFIG_INTERMEZZO_FS is not set
# CONFIG_AFS_FS is not set
#
# Partition Types
#
-CONFIG_PARTITION_ADVANCED=y
-# CONFIG_ACORN_PARTITION is not set
-# CONFIG_OSF_PARTITION is not set
-# CONFIG_AMIGA_PARTITION is not set
-# CONFIG_ATARI_PARTITION is not set
-# CONFIG_MAC_PARTITION is not set
-CONFIG_MSDOS_PARTITION=y
-# CONFIG_BSD_DISKLABEL is not set
-# CONFIG_MINIX_SUBPARTITION is not set
-# CONFIG_SOLARIS_X86_PARTITION is not set
-# CONFIG_UNIXWARE_DISKLABEL is not set
-# CONFIG_LDM_PARTITION is not set
-# CONFIG_NEC98_PARTITION is not set
-# CONFIG_SGI_PARTITION is not set
-# CONFIG_ULTRIX_PARTITION is not set
-# CONFIG_SUN_PARTITION is not set
-# CONFIG_EFI_PARTITION is not set
+# CONFIG_PARTITION_ADVANCED is not set
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
#
# Graphics support
@@ -715,40 +590,28 @@ CONFIG_MSDOS_PARTITION=y
#
#
-# Multimedia Capabilities Port drivers
-#
-# CONFIG_MCP is not set
-
-#
-# Console Switches
-#
-# CONFIG_SWITCHES is not set
-
-#
# USB support
#
-# CONFIG_USB is not set
-# CONFIG_USB_GADGET is not set
#
-# Bluetooth support
+# USB Gadget Support
#
-# CONFIG_BT is not set
+# CONFIG_USB_GADGET is not set
#
# Kernel hacking
#
CONFIG_FRAME_POINTER=y
CONFIG_DEBUG_USER=y
-# CONFIG_DEBUG_INFO is not set
+CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_KERNEL=y
# CONFIG_DEBUG_SLAB is not set
-# CONFIG_MAGIC_SYSRQ is not set
+CONFIG_MAGIC_SYSRQ=y
# CONFIG_DEBUG_SPINLOCK is not set
# CONFIG_DEBUG_WAITQ is not set
CONFIG_DEBUG_BUGVERBOSE=y
CONFIG_DEBUG_ERRORS=y
-CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_LL is not set
#
# Security options
@@ -758,11 +621,32 @@ CONFIG_DEBUG_LL=y
#
# Cryptographic options
#
-# CONFIG_CRYPTO is not set
+CONFIG_CRYPTO=y
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_TEST is not set
#
# Library routines
#
-# CONFIG_CRC32 is not set
+CONFIG_CRC16=y
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
diff --git a/arch/arm/configs/s3c2410_defconfig b/arch/arm/configs/s3c2410_defconfig
index d9e45878ffac6c..9919e7ff08600f 100644
--- a/arch/arm/configs/s3c2410_defconfig
+++ b/arch/arm/configs/s3c2410_defconfig
@@ -78,6 +78,12 @@ CONFIG_ARCH_SMDK2410=y
CONFIG_MACH_VR1000=y
#
+# S3C2410 Setup
+#
+CONFIG_S3C2410_DMA=y
+# CONFIG_S3C2410_DMA_DEBUG is not set
+
+#
# Processor Type
#
CONFIG_CPU_32=y
@@ -601,6 +607,8 @@ CONFIG_ROMFS_FS=y
CONFIG_FAT_FS=y
CONFIG_MSDOS_FS=y
CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
# CONFIG_NTFS_FS is not set
#
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index 1a85e39d79bebd..67d874abad7abf 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -19,6 +19,9 @@ obj-$(CONFIG_ARTHUR) += arthur.o
obj-$(CONFIG_ISA_DMA) += dma-isa.o
obj-$(CONFIG_PCI) += bios32.o
+obj-$(CONFIG_IWMMXT) += iwmmxt.o
+AFLAGS_iwmmxt.o := -Wa,-mcpu=iwmmxt
+
ifneq ($(CONFIG_ARCH_EBSA110),y)
obj-y += io.o
endif
diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c
index c5413242161111..3f22b6356cd8a2 100644
--- a/arch/arm/kernel/asm-offsets.c
+++ b/arch/arm/kernel/asm-offsets.c
@@ -13,6 +13,7 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <asm/mach/arch.h>
+#include <asm/thread_info.h>
/*
* Make sure that the compiler and target are compatible.
@@ -48,10 +49,23 @@ int main(void)
{
DEFINE(TSK_ACTIVE_MM, offsetof(struct task_struct, active_mm));
BLANK();
+ DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
+ DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count));
+ DEFINE(TI_ADDR_LIMIT, offsetof(struct thread_info, addr_limit));
+ DEFINE(TI_TASK, offsetof(struct thread_info, task));
+ DEFINE(TI_EXEC_DOMAIN, offsetof(struct thread_info, exec_domain));
+ DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
+ DEFINE(TI_CPU_DOMAIN, offsetof(struct thread_info, cpu_domain));
+ DEFINE(TI_CPU_SAVE, offsetof(struct thread_info, cpu_context));
+ DEFINE(TI_USED_CP, offsetof(struct thread_info, used_cp));
+ DEFINE(TI_FPSTATE, offsetof(struct thread_info, fpstate));
+ DEFINE(TI_VFPSTATE, offsetof(struct thread_info, vfpstate));
+ DEFINE(TI_IWMMXT_STATE, (offsetof(struct thread_info, fpstate)+4)&~7);
+ BLANK();
#if __LINUX_ARM_ARCH__ >= 6
DEFINE(MM_CONTEXT_ID, offsetof(struct mm_struct, context.id));
-#endif
BLANK();
+#endif
DEFINE(VMA_VM_MM, offsetof(struct vm_area_struct, vm_mm));
DEFINE(VMA_VM_FLAGS, offsetof(struct vm_area_struct, vm_flags));
BLANK();
diff --git a/arch/arm/kernel/debug.S b/arch/arm/kernel/debug.S
index 822dbde5af8c75..166cb3c3fd4b16 100644
--- a/arch/arm/kernel/debug.S
+++ b/arch/arm/kernel/debug.S
@@ -411,9 +411,7 @@
.macro addruart,rx
mov \rx, #0xfe000000 @ physical
-#ifdef CONFIG_ARCH_IQ80310
- orr \rx, \rx, #0x00810000 @ location of the UART
-#elif defined(CONFIG_ARCH_IQ80321)
+#if defined(CONFIG_ARCH_IQ80321)
orr \rx, \rx, #0x00800000 @ location of the UART
#else
#error Unknown IOP3XX implementation
@@ -615,6 +613,30 @@
tst \rd, #1 << 3 @ UARTFLGUBUSY - 1 when busy
bne 1001b
.endm
+
+#elif defined(CONFIG_ARCH_IMX)
+
+ .macro addruart,rx
+ mrc p15, 0, \rx, c1, c0
+ tst \rx, #1 @ MMU enabled?
+ moveq \rx, #0x00000000 @ physical
+ movne \rx, #0xe0000000 @ virtual
+ orr \rx, \rx, #0x00200000
+ orr \rx, \rx, #0x00006000 @ UART1 offset
+ .endm
+
+ .macro senduart,rd,rx
+ str \rd, [\rx, #0x40] @ TXDATA
+ .endm
+
+ .macro waituart,rd,rx
+ .endm
+
+ .macro busyuart,rd,rx
+1002: ldr \rd, [\rx, #0x98] @ SR2
+ tst \rd, #1 << 3 @ TXDC
+ beq 1002b @ wait until transmit done
+ .endm
#else
#error Unknown architecture
#endif
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 7fe5c2d39efdf5..19eed8bdbcaf40 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -562,40 +562,6 @@ ENTRY(soft_irq_mask)
.macro irq_prio_table
.endm
-#elif defined(CONFIG_ARCH_IOP310)
-
- .macro disable_fiq
- .endm
-
- .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
- mrc p13, 0, \irqstat, c4, c0, 0 @ get INTSRC
- mrc p13, 0, \base, c0, c0, 0 @ get INTCTL
-
- tst \irqstat, #(1<<29) @ if INTSRC_BI
- tstne \base, #(1<<3) @ and INTCTL_BM
- movne \irqnr, #IRQ_XS80200_BCU
- bne 1001f
-
- tst \irqstat, #(1<<28) @ if INTSRC_PI
- tstne \base, #(1<<2) @ and INTCTL_PM
- movne \irqnr, #IRQ_XS80200_PMU
- bne 1001f
-
- tst \irqstat, #(1<<31) @ if INTSRC_FI
- tstne \base, #(1<<0) @ and INTCTL_FM
- movne \irqnr, #IRQ_XS80200_EXTFIQ
- bne 1001f
-
- tst \irqstat, #(1<<30) @ if INTSRC_II
- tstne \base, #(1<<1) @ and INTCTL_IM
- movne \irqnr, #IRQ_XS80200_EXTIRQ
-
-1001:
- .endm
-
- .macro irq_prio_table
- .endm
-
#elif defined(CONFIG_ARCH_IOP321)
.macro disable_fiq
.endm
@@ -884,6 +850,31 @@ ENTRY(soft_irq_mask)
.macro irq_prio_table
.endm
+#elif defined(CONFIG_ARCH_IMX)
+
+ .macro disable_fiq
+ .endm
+#define AITC_NIVECSR 0x40
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+ ldr \irqstat, =IO_ADDRESS(IMX_AITC_BASE)
+ @ Load offset & priority of the highest priority
+ @ interrupt pending.
+ ldr \irqnr, [\irqstat, #AITC_NIVECSR]
+ @ Shift off the priority leaving the offset or
+ @ "interrupt number"
+ mov \irqnr, \irqnr, lsr #16
+ ldr \irqstat, =1 @ dummy compare
+ ldr \base, =0xFFFF // invalid interrupt
+ cmp \irqnr, \base
+ bne 1001f
+ ldr \irqstat, =0
+1001:
+ tst \irqstat, #1 @ to make the condition code = TRUE
+ .endm
+
+ .macro irq_prio_table
+ .endm
+
#else
#error Unknown architecture
#endif
@@ -1174,7 +1165,7 @@ __und_usr: sub sp, sp, #S_FRAME_SIZE @ Allocate frame size in one go
* r0 - instruction opcode.
* r10 - this threads thread_info structure.
*/
-call_fpe: enable_irq r10 @ Enable interrupts
+call_fpe:
tst r0, #0x08000000 @ only CDP/CPRT/LDC/STC have bit 27
#if defined(CONFIG_CPU_ARM610) || defined(CONFIG_CPU_ARM710)
and r8, r0, #0x0f000000 @ mask out op-code bits
@@ -1186,6 +1177,14 @@ call_fpe: enable_irq r10 @ Enable interrupts
mov r7, #1
add r6, r10, #TI_USED_CP
strb r7, [r6, r8, lsr #8] @ set appropriate used_cp[]
+#ifdef CONFIG_IWMMXT
+ @ Test if we need to give access to iWMMXt coprocessors
+ ldr r5, [r10, #TI_FLAGS]
+ rsbs r7, r8, #(1 << 8) @ CP 0 or 1 only
+ movcss r7, r5, lsr #(TIF_USING_IWMMXT + 1)
+ bcs iwmmxt_task_enable
+#endif
+ enable_irq r7
add pc, pc, r8, lsr #6
mov r0, r0
@@ -1264,7 +1263,11 @@ ENTRY(ret_from_exception)
ENTRY(__switch_to)
add ip, r1, #TI_CPU_SAVE
ldr r3, [r2, #TI_CPU_DOMAIN]!
- stmia ip, {r4 - sl, fp, sp, lr} @ Store most regs on stack
+ stmia ip!, {r4 - sl, fp, sp, lr} @ Store most regs on stack
+#if defined(CONFIG_CPU_XSCALE) && !defined(CONFIG_IWMMXT)
+ mra r4, r5, acc0
+ stmia ip, {r4, r5}
+#endif
mcr p15, 0, r3, c3, c0, 0 @ Set domain register
#ifdef CONFIG_VFP
@ Always disable VFP so we can lazily save/restore the old
@@ -1273,6 +1276,13 @@ ENTRY(__switch_to)
bic r4, r4, #FPEXC_ENABLE
VFPFMXR FPEXC, r4
#endif
+#if defined(CONFIG_IWMMXT)
+ bl iwmmxt_task_switch
+#elif defined(CONFIG_CPU_XSCALE)
+ add r4, r2, #40 @ cpu_context_save->extra
+ ldmib r4, {r4, r5}
+ mar acc0, r4, r5
+#endif
ldmib r2, {r4 - sl, fp, sp, pc} @ Load all regs saved previously
__INIT
diff --git a/arch/arm/kernel/iwmmxt.S b/arch/arm/kernel/iwmmxt.S
new file mode 100644
index 00000000000000..8f74e24536ba7b
--- /dev/null
+++ b/arch/arm/kernel/iwmmxt.S
@@ -0,0 +1,320 @@
+/*
+ * linux/arch/arm/kernel/iwmmxt.S
+ *
+ * XScale iWMMXt (Concan) context switching and handling
+ *
+ * Initial code:
+ * Copyright (c) 2003, Intel Corporation
+ *
+ * Full lazy switching support, optimizations and more, by Nicolas Pitre
+* Copyright (c) 2003-2004, MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/linkage.h>
+#include <asm/ptrace.h>
+#include <asm/thread_info.h>
+#include <asm/constants.h>
+
+#define MMX_WR0 (0x00)
+#define MMX_WR1 (0x08)
+#define MMX_WR2 (0x10)
+#define MMX_WR3 (0x18)
+#define MMX_WR4 (0x20)
+#define MMX_WR5 (0x28)
+#define MMX_WR6 (0x30)
+#define MMX_WR7 (0x38)
+#define MMX_WR8 (0x40)
+#define MMX_WR9 (0x48)
+#define MMX_WR10 (0x50)
+#define MMX_WR11 (0x58)
+#define MMX_WR12 (0x60)
+#define MMX_WR13 (0x68)
+#define MMX_WR14 (0x70)
+#define MMX_WR15 (0x78)
+#define MMX_WCSSF (0x80)
+#define MMX_WCASF (0x84)
+#define MMX_WCGR0 (0x88)
+#define MMX_WCGR1 (0x8C)
+#define MMX_WCGR2 (0x90)
+#define MMX_WCGR3 (0x94)
+
+#define MMX_SIZE (0x98)
+
+ .text
+
+/*
+ * Lazy switching of Concan coprocessor context
+ *
+ * r10 = struct thread_info pointer
+ * r9 = ret_from_exception
+ * lr = undefined instr exit
+ *
+ * called from prefetch exception handler with interrupts disabled
+ */
+
+ENTRY(iwmmxt_task_enable)
+
+ mrc p15, 0, r2, c15, c1, 0
+ tst r2, #0x3 @ CP0 and CP1 accessible?
+ movne pc, lr @ if so no business here
+ orr r2, r2, #0x3 @ enable access to CP0 and CP1
+ mcr p15, 0, r2, c15, c1, 0
+
+ ldr r3, =concan_owner
+ add r0, r10, #TI_IWMMXT_STATE @ get task Concan save area
+ ldr r2, [sp, #60] @ current task pc value
+ ldr r1, [r3] @ get current Concan owner
+ str r0, [r3] @ this task now owns Concan regs
+ sub r2, r2, #4 @ adjust pc back
+ str r2, [sp, #60]
+
+ mrc p15, 0, r2, c2, c0, 0
+ mov r2, r2 @ cpwait
+
+ teq r1, #0 @ test for last ownership
+ mov lr, r9 @ normal exit from exception
+ beq concan_load @ no owner, skip save
+
+concan_save:
+
+ tmrc r2, wCon
+
+ @ CUP? wCx
+ tst r2, #0x1
+ beq 1f
+
+concan_dump:
+
+ wstrw wCSSF, [r1, #MMX_WCSSF]
+ wstrw wCASF, [r1, #MMX_WCASF]
+ wstrw wCGR0, [r1, #MMX_WCGR0]
+ wstrw wCGR1, [r1, #MMX_WCGR1]
+ wstrw wCGR2, [r1, #MMX_WCGR2]
+ wstrw wCGR3, [r1, #MMX_WCGR3]
+
+1: @ MUP? wRn
+ tst r2, #0x2
+ beq 2f
+
+ wstrd wR0, [r1, #MMX_WR0]
+ wstrd wR1, [r1, #MMX_WR1]
+ wstrd wR2, [r1, #MMX_WR2]
+ wstrd wR3, [r1, #MMX_WR3]
+ wstrd wR4, [r1, #MMX_WR4]
+ wstrd wR5, [r1, #MMX_WR5]
+ wstrd wR6, [r1, #MMX_WR6]
+ wstrd wR7, [r1, #MMX_WR7]
+ wstrd wR8, [r1, #MMX_WR8]
+ wstrd wR9, [r1, #MMX_WR9]
+ wstrd wR10, [r1, #MMX_WR10]
+ wstrd wR11, [r1, #MMX_WR11]
+ wstrd wR12, [r1, #MMX_WR12]
+ wstrd wR13, [r1, #MMX_WR13]
+ wstrd wR14, [r1, #MMX_WR14]
+ wstrd wR15, [r1, #MMX_WR15]
+
+2: teq r0, #0 @ anything to load?
+ moveq pc, lr
+
+concan_load:
+
+ @ Load wRn
+ wldrd wR0, [r0, #MMX_WR0]
+ wldrd wR1, [r0, #MMX_WR1]
+ wldrd wR2, [r0, #MMX_WR2]
+ wldrd wR3, [r0, #MMX_WR3]
+ wldrd wR4, [r0, #MMX_WR4]
+ wldrd wR5, [r0, #MMX_WR5]
+ wldrd wR6, [r0, #MMX_WR6]
+ wldrd wR7, [r0, #MMX_WR7]
+ wldrd wR8, [r0, #MMX_WR8]
+ wldrd wR9, [r0, #MMX_WR9]
+ wldrd wR10, [r0, #MMX_WR10]
+ wldrd wR11, [r0, #MMX_WR11]
+ wldrd wR12, [r0, #MMX_WR12]
+ wldrd wR13, [r0, #MMX_WR13]
+ wldrd wR14, [r0, #MMX_WR14]
+ wldrd wR15, [r0, #MMX_WR15]
+
+ @ Load wCx
+ wldrw wCSSF, [r0, #MMX_WCSSF]
+ wldrw wCASF, [r0, #MMX_WCASF]
+ wldrw wCGR0, [r0, #MMX_WCGR0]
+ wldrw wCGR1, [r0, #MMX_WCGR1]
+ wldrw wCGR2, [r0, #MMX_WCGR2]
+ wldrw wCGR3, [r0, #MMX_WCGR3]
+
+ @ clear CUP/MUP (only if r1 != 0)
+ teq r1, #0
+ mov r2, #0
+ moveq pc, lr
+ tmcr wCon, r2
+ mov pc, lr
+
+/*
+ * Back up Concan regs to save area and disable access to them
+ * (mainly for gdb or sleep mode usage)
+ *
+ * r0 = struct thread_info pointer of target task or NULL for any
+ */
+
+ENTRY(iwmmxt_task_disable)
+
+ stmfd sp!, {r4, lr}
+
+ mrs ip, cpsr
+ orr r2, ip, #PSR_I_BIT @ disable interrupts
+ msr cpsr_c, r2
+
+ ldr r3, =concan_owner
+ add r2, r0, #TI_IWMMXT_STATE @ get task Concan save area
+ ldr r1, [r3] @ get current Concan owner
+ teq r1, #0 @ any current owner?
+ beq 1f @ no: quit
+ teq r0, #0 @ any owner?
+ teqne r1, r2 @ or specified one?
+ bne 1f @ no: quit
+
+ mrc p15, 0, r4, c15, c1, 0
+ orr r4, r4, #0x3 @ enable access to CP0 and CP1
+ mcr p15, 0, r4, c15, c1, 0
+ mov r0, #0 @ nothing to load
+ str r0, [r3] @ no more current owner
+ mrc p15, 0, r2, c2, c0, 0
+ mov r2, r2 @ cpwait
+ bl concan_save
+
+ bic r4, r4, #0x3 @ disable access to CP0 and CP1
+ mcr p15, 0, r4, c15, c1, 0
+ mrc p15, 0, r2, c2, c0, 0
+ mov r2, r2 @ cpwait
+
+1: msr cpsr_c, ip @ restore interrupt mode
+ ldmfd sp!, {r4, pc}
+
+/*
+ * Copy Concan state to given memory address
+ *
+ * r0 = struct thread_info pointer of target task
+ * r1 = memory address where to store Concan state
+ *
+ * this is called mainly in the creation of signal stack frames
+ */
+
+ENTRY(iwmmxt_task_copy)
+
+ mrs ip, cpsr
+ orr r2, ip, #PSR_I_BIT @ disable interrupts
+ msr cpsr_c, r2
+
+ ldr r3, =concan_owner
+ add r2, r0, #TI_IWMMXT_STATE @ get task Concan save area
+ ldr r3, [r3] @ get current Concan owner
+ teq r2, r3 @ does this task own it...
+ beq 1f
+
+ @ current Concan values are in the task save area
+ msr cpsr_c, ip @ restore interrupt mode
+ mov r0, r1
+ mov r1, r2
+ mov r2, #MMX_SIZE
+ b memcpy
+
+1: @ this task owns Concan regs -- grab a copy from there
+ mov r0, #0 @ nothing to load
+ mov r2, #3 @ save all regs
+ mov r3, lr @ preserve return address
+ bl concan_dump
+ msr cpsr_c, ip @ restore interrupt mode
+ mov pc, r3
+
+/*
+ * Restore Concan state from given memory address
+ *
+ * r0 = struct thread_info pointer of target task
+ * r1 = memory address where to get Concan state from
+ *
+ * this is used to restore Concan state when unwinding a signal stack frame
+ */
+
+ENTRY(iwmmxt_task_restore)
+
+ mrs ip, cpsr
+ orr r2, ip, #PSR_I_BIT @ disable interrupts
+ msr cpsr_c, r2
+
+ ldr r3, =concan_owner
+ add r2, r0, #TI_IWMMXT_STATE @ get task Concan save area
+ ldr r3, [r3] @ get current Concan owner
+ bic r2, r2, #0x7 @ 64-bit alignment
+ teq r2, r3 @ does this task own it...
+ beq 1f
+
+ @ this task doesn't own Concan regs -- use its save area
+ msr cpsr_c, ip @ restore interrupt mode
+ mov r0, r2
+ mov r2, #MMX_SIZE
+ b memcpy
+
+1: @ this task owns Concan regs -- load them directly
+ mov r0, r1
+ mov r1, #0 @ don't clear CUP/MUP
+ mov r3, lr @ preserve return address
+ bl concan_load
+ msr cpsr_c, ip @ restore interrupt mode
+ mov pc, r3
+
+/*
+ * Concan handling on task switch
+ *
+ * r0 = previous task_struct pointer (must be preserved)
+ * r1 = previous thread_info pointer
+ * r2 = next thread_info.cpu_domain pointer (must be preserved)
+ *
+ * Called only from __switch_to with task preemption disabled.
+ * No need to care about preserving r4 and above.
+ */
+ENTRY(iwmmxt_task_switch)
+
+ mrc p15, 0, r4, c15, c1, 0
+ tst r4, #0x3 @ CP0 and CP1 accessible?
+ bne 1f @ yes: block them for next task
+
+ ldr r5, =concan_owner
+ add r6, r2, #(TI_IWMMXT_STATE - TI_CPU_DOMAIN) @ get next task Concan save area
+ ldr r5, [r5] @ get current Concan owner
+ teq r5, r6 @ next task owns it?
+ movne pc, lr @ no: leave Concan disabled
+
+1: eor r4, r4, #3 @ flip Concan access
+ mcr p15, 0, r4, c15, c1, 0
+
+ mrc p15, 0, r4, c2, c0, 0
+ sub pc, lr, r4, lsr #32 @ cpwait and return
+
+/*
+ * Remove Concan ownership of given task
+ *
+ * r0 = struct thread_info pointer
+ */
+ENTRY(iwmmxt_task_release)
+
+ mrs r2, cpsr
+ orr ip, r2, #PSR_I_BIT @ disable interrupts
+ msr cpsr_c, ip
+ ldr r3, =concan_owner
+ add r0, r0, #TI_IWMMXT_STATE @ get task Concan save area
+ ldr r1, [r3] @ get current Concan owner
+ eors r0, r0, r1 @ if equal...
+ streq r0, [r3] @ then clear ownership
+ msr cpsr_c, r2 @ restore interrupts
+ mov pc, lr
+
+ .data
+concan_owner:
+ .word 0
+
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 56498dbf760561..1301b0378f0365 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -313,6 +313,9 @@ void flush_thread(void)
memset(thread->used_cp, 0, sizeof(thread->used_cp));
memset(&tsk->thread.debug, 0, sizeof(struct debug_info));
+#if defined(CONFIG_IWMMXT)
+ iwmmxt_task_release(thread);
+#endif
fp_init(&thread->fpstate);
#if defined(CONFIG_VFP)
vfp_flush_thread(&thread->vfpstate);
@@ -324,6 +327,9 @@ void release_thread(struct task_struct *dead_task)
#if defined(CONFIG_VFP)
vfp_release_thread(&dead_task->thread_info->vfpstate);
#endif
+#if defined(CONFIG_IWMMXT)
+ iwmmxt_task_release(dead_task->thread_info);
+#endif
}
asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 835010c55597a4..99710cc73bf91c 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -57,7 +57,6 @@ extern unsigned int mem_fclk_21285;
extern void paging_init(struct meminfo *, struct machine_desc *desc);
extern void convert_to_tag_list(struct tag *tags);
extern void squash_mem_tags(struct tag *tag);
-extern void bootmem_init(struct meminfo *);
extern void reboot_setup(char *str);
extern int root_mountflags;
extern int _stext, _text, _etext, _edata, _end;
@@ -720,7 +719,6 @@ void __init setup_arch(char **cmdline_p)
memcpy(saved_command_line, from, COMMAND_LINE_SIZE);
saved_command_line[COMMAND_LINE_SIZE-1] = '\0';
parse_cmdline(cmdline_p, from);
- bootmem_init(&meminfo);
paging_init(&meminfo, mdesc);
request_standard_resources(&meminfo, mdesc);
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index d214e8d494f603..69a61186a18add 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -145,6 +145,100 @@ struct rt_sigframe
unsigned long retcode;
};
+#ifdef CONFIG_IWMMXT
+
+/* iwmmxt_area is 0x98 bytes long, preceeded by 8 bytes of signature */
+#define IWMMXT_STORAGE_SIZE (0x98 + 8)
+#define IWMMXT_MAGIC0 0x12ef842a
+#define IWMMXT_MAGIC1 0x1c07ca71
+
+static int page_present(struct mm_struct *mm, unsigned long addr, int wr)
+{
+ pgd_t *pgd = pgd_offset(mm, addr);
+ if (pgd_present(*pgd)) {
+ pmd_t *pmd = pmd_offset(pgd, addr);
+ if (pmd_present(*pmd)) {
+ pte_t *pte = pte_offset_map(pmd, addr);
+ return (pte_present(*pte) && (!wr || pte_write(*pte)));
+ }
+ }
+ return 0;
+}
+
+static int
+preserve_iwmmxt_context(void *iwmmxt_save_area)
+{
+ int err = 0;
+
+ /* the iWMMXt context must be 64 bit aligned */
+ long *iwmmxt_storage = (long *)(((long)iwmmxt_save_area + 4) & ~7);
+
+again:
+ __put_user_error(IWMMXT_MAGIC0, iwmmxt_storage+0, err);
+ __put_user_error(IWMMXT_MAGIC1, iwmmxt_storage+1, err);
+ /*
+ * iwmmxt_task_copy() doesn't check user permissions.
+ * Let's do a dummy write on the upper boundary to ensure
+ * access to user mem is OK all way up.
+ */
+ __put_user_error(0, iwmmxt_storage+IWMMXT_STORAGE_SIZE/4-1, err);
+ if (!err) {
+ /* Let's make sure the user mapping won't disappear under us */
+ struct mm_struct *mm = current->mm;
+ unsigned long addr = (unsigned long)iwmmxt_storage;
+ spin_lock(&mm->page_table_lock);
+ if ( !page_present(mm, addr, 1) ||
+ !page_present(mm, addr+IWMMXT_STORAGE_SIZE-1, 1) ) {
+ /* our user area has gone before grabbing the lock */
+ spin_unlock(&mm->page_table_lock);
+ goto again;
+ }
+ iwmmxt_task_copy(current_thread_info(), iwmmxt_storage+2);
+ spin_unlock(&mm->page_table_lock);
+ return 0;
+ }
+ return err;
+}
+
+static int
+restore_iwmmxt_context(void *iwmmxt_save_area)
+{
+ int err = 0;
+ long *iwmmxt_storage, magic0, magic1, dummy;
+
+ /* the iWMMXt context is 64 bit aligned */
+ iwmmxt_storage = (long *)(((long)iwmmxt_save_area + 4) & ~7);
+
+ /*
+ * Validate iWMMXt context signature.
+ * Also, iwmmxt_task_restore() doesn't check user permissions.
+ * Let's do a dummy write on the upper boundary to ensure
+ * access to user mem is OK all way up.
+ */
+again:
+ __get_user_error(magic0, iwmmxt_storage+0, err);
+ __get_user_error(magic1, iwmmxt_storage+1, err);
+ if (!err && magic0 == IWMMXT_MAGIC0 && magic1 == IWMMXT_MAGIC1 &&
+ !__get_user(dummy, iwmmxt_storage+IWMMXT_STORAGE_SIZE/4-1)) {
+ /* Let's make sure the user mapping won't disappear under us */
+ struct mm_struct *mm = current->mm;
+ unsigned long addr = (unsigned long)iwmmxt_storage;
+ spin_lock(&mm->page_table_lock);
+ if ( !page_present(mm, addr, 0) ||
+ !page_present(mm, addr+IWMMXT_STORAGE_SIZE-1, 0) ) {
+ /* our user area has gone before grabbing the lock */
+ spin_unlock(&mm->page_table_lock);
+ goto again;
+ }
+ iwmmxt_task_restore(current_thread_info(), iwmmxt_storage+2);
+ spin_unlock(&mm->page_table_lock);
+ return 0;
+ }
+ return -1;
+}
+
+#endif
+
static int
restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
{
@@ -208,6 +302,11 @@ asmlinkage int sys_sigreturn(struct pt_regs *regs)
if (restore_sigcontext(regs, &frame->sc))
goto badframe;
+#ifdef CONFIG_IWMMXT
+ if (test_thread_flag(TIF_USING_IWMMXT) && restore_iwmmxt_context(frame+1))
+ goto badframe;
+#endif
+
/* Send SIGTRAP if we're single-stepping */
if (current->ptrace & PT_SINGLESTEP) {
ptrace_cancel_bpt(current);
@@ -256,6 +355,11 @@ asmlinkage int sys_rt_sigreturn(struct pt_regs *regs)
if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->ARM_sp) == -EFAULT)
goto badframe;
+#ifdef CONFIG_IWMMXT
+ if (test_thread_flag(TIF_USING_IWMMXT) && restore_iwmmxt_context(frame+1))
+ goto badframe;
+#endif
+
/* Send SIGTRAP if we're single-stepping */
if (current->ptrace & PT_SINGLESTEP) {
ptrace_cancel_bpt(current);
@@ -306,6 +410,11 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, int framesize)
{
unsigned long sp = regs->ARM_sp;
+#ifdef CONFIG_IWMMXT
+ if (test_thread_flag(TIF_USING_IWMMXT))
+ framesize = (framesize + 4 + IWMMXT_STORAGE_SIZE) & ~7;
+#endif
+
/*
* This is the X/Open sanctioned signal stack switching.
*/
@@ -394,6 +503,11 @@ setup_frame(int usig, struct k_sigaction *ka, sigset_t *set, struct pt_regs *reg
sizeof(frame->extramask));
}
+#ifdef CONFIG_IWMMXT
+ if (test_thread_flag(TIF_USING_IWMMXT))
+ err |= preserve_iwmmxt_context(frame+1);
+#endif
+
if (err == 0)
err = setup_return(regs, ka, &frame->retcode, frame, usig);
@@ -428,6 +542,11 @@ setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info,
regs, set->sig[0]);
err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
+#ifdef CONFIG_IWMMXT
+ if (test_thread_flag(TIF_USING_IWMMXT))
+ err |= preserve_iwmmxt_context(frame+1);
+#endif
+
if (err == 0)
err = setup_return(regs, ka, &frame->retcode, frame, usig);
diff --git a/arch/arm/lib/getuser.S b/arch/arm/lib/getuser.S
index cf3920459c969a..9478e01d1aa1ae 100644
--- a/arch/arm/lib/getuser.S
+++ b/arch/arm/lib/getuser.S
@@ -32,59 +32,34 @@
.global __get_user_1
__get_user_1:
- bic r1, sp, #0x1f00
- bic r1, r1, #0x00ff
- ldr r1, [r1, #TI_ADDR_LIMIT]
- sub r1, r1, #1
- cmp r0, r1
-1: ldrlsbt r1, [r0]
- movls r0, #0
- movls pc, lr
- b __get_user_bad
+1: ldrbt r1, [r0]
+ mov r0, #0
+ mov pc, lr
.global __get_user_2
__get_user_2:
- bic r2, sp, #0x1f00
- bic r2, r2, #0x00ff
- ldr r2, [r2, #TI_ADDR_LIMIT]
- sub r2, r2, #2
- cmp r0, r2
-2: ldrlsbt r1, [r0], #1
-3: ldrlsbt r2, [r0]
+2: ldrbt r1, [r0], #1
+3: ldrbt r2, [r0]
#ifndef __ARMEB__
- orrls r1, r1, r2, lsl #8
+ orr r1, r1, r2, lsl #8
#else
- orrls r1, r2, r1, lsl #8
+ orr r1, r2, r1, lsl #8
#endif
- movls r0, #0
- movls pc, lr
- b __get_user_bad
+ mov r0, #0
+ mov pc, lr
.global __get_user_4
__get_user_4:
- bic r1, sp, #0x1f00
- bic r1, r1, #0x00ff
- ldr r1, [r1, #TI_ADDR_LIMIT]
- sub r1, r1, #4
- cmp r0, r1
-4: ldrlst r1, [r0]
- movls r0, #0
- movls pc, lr
- b __get_user_bad
+4: ldrt r1, [r0]
+ mov r0, #0
+ mov pc, lr
.global __get_user_8
__get_user_8:
- bic r2, sp, #0x1f00
- bic r2, r2, #0x00ff
- ldr r2, [r2, #TI_ADDR_LIMIT]
- sub r2, r2, #8
- cmp r0, r2
-5: ldrlst r1, [r0], #4
-6: ldrlst r2, [r0]
- movls r0, #0
- movls pc, lr
-
- /* fall through */
+5: ldrt r1, [r0], #4
+6: ldrt r2, [r0]
+ mov r0, #0
+ mov pc, lr
__get_user_bad_8:
mov r2, #0
diff --git a/arch/arm/lib/putuser.S b/arch/arm/lib/putuser.S
index 293de2d2cde7d8..b978885a1d60a0 100644
--- a/arch/arm/lib/putuser.S
+++ b/arch/arm/lib/putuser.S
@@ -32,60 +32,35 @@
.global __put_user_1
__put_user_1:
- bic ip, sp, #0x1f00
- bic ip, ip, #0x00ff
- ldr ip, [ip, #TI_ADDR_LIMIT]
- sub ip, ip, #1
- cmp r0, ip
-1: strlsbt r1, [r0]
- movls r0, #0
- movls pc, lr
- b __put_user_bad
+1: strbt r1, [r0]
+ mov r0, #0
+ mov pc, lr
.global __put_user_2
__put_user_2:
- bic ip, sp, #0x1f00
- bic ip, ip, #0x00ff
- ldr ip, [ip, #TI_ADDR_LIMIT]
- sub ip, ip, #2
- cmp r0, ip
- movls ip, r1, lsr #8
+ mov ip, r1, lsr #8
#ifndef __ARMEB__
-2: strlsbt r1, [r0], #1
-3: strlsbt ip, [r0]
+2: strbt r1, [r0], #1
+3: strbt ip, [r0]
#else
-2: strlsbt ip, [r0], #1
-3: strlsbt r1, [r0]
+2: strbt ip, [r0], #1
+3: strbt r1, [r0]
#endif
- movls r0, #0
- movls pc, lr
- b __put_user_bad
+ mov r0, #0
+ mov pc, lr
.global __put_user_4
__put_user_4:
- bic ip, sp, #0x1f00
- bic ip, ip, #0x00ff
- ldr ip, [ip, #TI_ADDR_LIMIT]
- sub ip, ip, #4
- cmp r0, ip
-4: strlst r1, [r0]
- movls r0, #0
- movls pc, lr
- b __put_user_bad
+4: strt r1, [r0]
+ mov r0, #0
+ mov pc, lr
.global __put_user_8
__put_user_8:
- bic ip, sp, #0x1f00
- bic ip, ip, #0x00ff
- ldr ip, [ip, #TI_ADDR_LIMIT]
- sub ip, ip, #8
- cmp r0, ip
-5: strlst r1, [r0], #4
-6: strlst r2, [r0]
- movls r0, #0
- movls pc, lr
-
- /* fall through */
+5: strt r1, [r0], #4
+6: strt r2, [r0]
+ mov r0, #0
+ mov pc, lr
__put_user_bad:
mov r0, #-EFAULT
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
new file mode 100644
index 00000000000000..ec85813ee5dc7c
--- /dev/null
+++ b/arch/arm/mach-imx/Kconfig
@@ -0,0 +1,10 @@
+menu "IMX Implementations"
+ depends on ARCH_IMX
+
+config ARCH_MX1ADS
+ bool "mx1ads"
+ depends on ARCH_IMX
+ help
+ Say Y here if you are using the Motorola MX1ADS board
+
+endmenu
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
new file mode 100644
index 00000000000000..0b27d79f2efdaf
--- /dev/null
+++ b/arch/arm/mach-imx/Makefile
@@ -0,0 +1,19 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+
+# Object file lists.
+
+obj-y += irq.o time.o dma.o generic.o
+
+# Specific board support
+obj-$(CONFIG_ARCH_MX1ADS) += mx1ads.o
+
+# Support for blinky lights
+led-y := leds.o
+
+obj-$(CONFIG_LEDS) += $(led-y)
+led-$(CONFIG_ARCH_MX1ADS) += leds-mx1ads.o
diff --git a/arch/arm/mach-imx/dma.c b/arch/arm/mach-imx/dma.c
new file mode 100644
index 00000000000000..7387ccbd8720fd
--- /dev/null
+++ b/arch/arm/mach-imx/dma.c
@@ -0,0 +1,203 @@
+/*
+ * linux/arch/arm/mach-imx/dma.c
+ *
+ * imx DMA registration and IRQ dispatching
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 03/03/2004 Sascha Hauer <sascha@saschahauer.de>
+ * initial version heavily inspired by
+ * linux/arch/arm/mach-pxa/dma.c
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/errno.h>
+
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <asm/hardware.h>
+#include <asm/dma.h>
+
+static struct dma_channel {
+ char *name;
+ void (*irq_handler) (int, void *, struct pt_regs *);
+ void (*err_handler) (int, void *, struct pt_regs *);
+ void *data;
+} dma_channels[11];
+
+/* set err_handler to NULL to have the standard info-only error handler */
+int
+imx_request_dma(char *name, imx_dma_prio prio,
+ void (*irq_handler) (int, void *, struct pt_regs *),
+ void (*err_handler) (int, void *, struct pt_regs *), void *data)
+{
+ unsigned long flags;
+ int i, found = 0;
+
+ /* basic sanity checks */
+ if (!name || !irq_handler)
+ return -EINVAL;
+
+ local_irq_save(flags);
+
+ /* try grabbing a DMA channel with the requested priority */
+ for (i = prio; i < prio + (prio == DMA_PRIO_LOW) ? 8 : 4; i++) {
+ if (!dma_channels[i].name) {
+ found = 1;
+ break;
+ }
+ }
+
+ if (!found) {
+ /* requested prio group is full, try hier priorities */
+ for (i = prio - 1; i >= 0; i--) {
+ if (!dma_channels[i].name) {
+ found = 1;
+ break;
+ }
+ }
+ }
+
+ if (found) {
+ DIMR &= ~(1 << i);
+ dma_channels[i].name = name;
+ dma_channels[i].irq_handler = irq_handler;
+ dma_channels[i].err_handler = err_handler;
+ dma_channels[i].data = data;
+ } else {
+ printk(KERN_WARNING "No more available DMA channels for %s\n",
+ name);
+ i = -ENODEV;
+ }
+
+ local_irq_restore(flags);
+ return i;
+}
+
+void
+imx_free_dma(int dma_ch)
+{
+ unsigned long flags;
+
+ if (!dma_channels[dma_ch].name) {
+ printk(KERN_CRIT
+ "%s: trying to free channel %d which is already freed\n",
+ __FUNCTION__, dma_ch);
+ return;
+ }
+
+ local_irq_save(flags);
+ DIMR &= ~(1 << dma_ch);
+ dma_channels[dma_ch].name = NULL;
+ local_irq_restore(flags);
+}
+
+static irqreturn_t
+dma_err_handler(int irq, void *dev_id, struct pt_regs *regs)
+{
+ int i;
+ struct dma_channel *channel;
+ unsigned int err_mask = DBTOSR | DRTOSR | DSESR | DBOSR;
+
+ for (i = 0; i < 11; i++) {
+ channel = &dma_channels[i];
+
+ if ( (err_mask & 1<<i) && channel->name && channel->err_handler) {
+ channel->err_handler(i, channel->data, regs);
+ continue;
+ }
+
+ if (DBTOSR & (1 << i)) {
+ printk(KERN_WARNING
+ "Burst timeout on channel %d (%s)\n",
+ i, channel->name);
+ DBTOSR |= (1 << i);
+ }
+ if (DRTOSR & (1 << i)) {
+ printk(KERN_WARNING
+ "Request timeout on channel %d (%s)\n",
+ i, channel->name);
+ DRTOSR |= (1 << i);
+ }
+ if (DSESR & (1 << i)) {
+ printk(KERN_WARNING
+ "Transfer timeout on channel %d (%s)\n",
+ i, channel->name);
+ DSESR |= (1 << i);
+ }
+ if (DBOSR & (1 << i)) {
+ printk(KERN_WARNING
+ "Buffer overflow timeout on channel %d (%s)\n",
+ i, channel->name);
+ DBOSR |= (1 << i);
+ }
+ DISR |= (1 << i);
+ }
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t
+dma_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
+{
+ int i, disr = DISR;
+
+ for (i = 0; i < 11; i++) {
+ if (disr & (1 << i)) {
+ struct dma_channel *channel = &dma_channels[i];
+ if (channel->name && channel->irq_handler) {
+ channel->irq_handler(i, channel->data, regs);
+ } else {
+ /*
+ * IRQ for an unregistered DMA channel:
+ * let's clear the interrupts and disable it.
+ */
+ printk(KERN_WARNING
+ "spurious IRQ for DMA channel %d\n", i);
+ DISR |= (1 << i);
+ }
+ }
+ }
+ return IRQ_HANDLED;
+}
+
+static int __init
+imx_dma_init(void)
+{
+ int ret;
+
+ /* reset DMA module */
+ DCR = DCR_DRST;
+
+ ret = request_irq(DMA_INT, dma_irq_handler, 0, "DMA", NULL);
+ if (ret) {
+ printk(KERN_CRIT "Wow! Can't register IRQ for DMA\n");
+ return ret;
+ }
+
+ ret = request_irq(DMA_ERR, dma_err_handler, 0, "DMA", NULL);
+ if (ret) {
+ printk(KERN_CRIT "Wow! Can't register ERRIRQ for DMA\n");
+ free_irq(DMA_INT, NULL);
+ }
+
+ /* enable DMA module */
+ DCR = DCR_DEN;
+
+ /* clear all interrupts */
+ DISR = 0x3ff;
+
+ /* enable interrupts */
+ DIMR = 0;
+
+ return ret;
+}
+
+arch_initcall(imx_dma_init);
+
+EXPORT_SYMBOL(imx_request_dma);
+EXPORT_SYMBOL(imx_free_dma);
diff --git a/arch/arm/mach-imx/generic.c b/arch/arm/mach-imx/generic.c
new file mode 100644
index 00000000000000..4954653ec6ae9b
--- /dev/null
+++ b/arch/arm/mach-imx/generic.c
@@ -0,0 +1,274 @@
+/*
+ * arch/arm/mach-imx/generic.c
+ *
+ * author: Sascha Hauer
+ * Created: april 20th, 2004
+ * Copyright: Synertronixx GmbH
+ *
+ * Common code for i.MX machines
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <asm/hardware.h>
+
+#include <asm/mach/map.h>
+
+void imx_gpio_mode(int gpio_mode)
+{
+ unsigned int pin = gpio_mode & GPIO_PIN_MASK;
+ unsigned int port = (gpio_mode & GPIO_PORT_MASK) >> 5;
+ unsigned int ocr = (gpio_mode & GPIO_OCR_MASK) >> 10;
+ unsigned int tmp;
+
+ /* Pullup enable */
+ if(gpio_mode & GPIO_PUEN)
+ PUEN(port) |= (1<<pin);
+ else
+ PUEN(port) &= ~(1<<pin);
+
+ /* Data direction */
+ if(gpio_mode & GPIO_OUT)
+ DDIR(port) |= 1<<pin;
+ else
+ DDIR(port) &= ~(1<<pin);
+
+ /* Primary / alternate function */
+ if(gpio_mode & GPIO_AF)
+ GPR(port) |= (1<<pin);
+ else
+ GPR(port) &= ~(1<<pin);
+
+ /* use as gpio? */
+ if( ocr == 3 )
+ GIUS(port) |= (1<<pin);
+ else
+ GIUS(port) &= ~(1<<pin);
+
+ /* Output / input configuration */
+ /* FIXME: I'm not very sure about OCR and ICONF, someone
+ * should have a look over it
+ */
+ if(pin<16) {
+ tmp = OCR1(port);
+ tmp &= ~( 3<<(pin*2));
+ tmp |= (ocr << (pin*2));
+ OCR1(port) = tmp;
+
+ if( gpio_mode & GPIO_AOUT )
+ ICONFA1(port) &= ~( 3<<(pin*2));
+ if( gpio_mode & GPIO_BOUT )
+ ICONFB1(port) &= ~( 3<<(pin*2));
+ } else {
+ tmp = OCR2(port);
+ tmp &= ~( 3<<((pin-16)*2));
+ tmp |= (ocr << ((pin-16)*2));
+ OCR2(port) = tmp;
+
+ if( gpio_mode & GPIO_AOUT )
+ ICONFA2(port) &= ~( 3<<((pin-16)*2));
+ if( gpio_mode & GPIO_BOUT )
+ ICONFB2(port) &= ~( 3<<((pin-16)*2));
+ }
+}
+
+EXPORT_SYMBOL(imx_gpio_mode);
+
+/*
+ * get the system pll clock in Hz
+ *
+ * mfi + mfn / (mfd +1)
+ * f = 2 * f_ref * --------------------
+ * pd + 1
+ */
+static unsigned int imx_decode_pll(unsigned int pll)
+{
+ u32 mfi = (pll >> 10) & 0xf;
+ u32 mfn = pll & 0x3f;
+ u32 mfd = (pll >> 16) & 0x3f;
+ u32 pd = (pll >> 26) & 0xf;
+ u32 f_ref = (CSCR & CSCR_SYSTEM_SEL) ? 16000000 : (CLK32 * 512);
+
+ mfi = mfi <= 5 ? 5 : mfi;
+
+ return (2 * (f_ref>>10) * ( (mfi<<10) + (mfn<<10) / (mfd+1) )) / (pd+1);
+}
+
+unsigned int imx_get_system_clk(void)
+{
+ return imx_decode_pll(SPCTL0);
+}
+EXPORT_SYMBOL(imx_get_system_clk);
+
+unsigned int imx_get_mcu_clk(void)
+{
+ return imx_decode_pll(MPCTL0);
+}
+EXPORT_SYMBOL(imx_get_mcu_clk);
+
+/*
+ * get peripheral clock 1 ( UART[12], Timer[12], PWM )
+ */
+unsigned int imx_get_perclk1(void)
+{
+ return imx_get_system_clk() / (((PCDR) & 0xf)+1);
+}
+EXPORT_SYMBOL(imx_get_perclk1);
+
+/*
+ * get peripheral clock 2 ( LCD, SD, SPI[12] )
+ */
+unsigned int imx_get_perclk2(void)
+{
+ return imx_get_system_clk() / (((PCDR>>4) & 0xf)+1);
+}
+EXPORT_SYMBOL(imx_get_perclk2);
+
+/*
+ * get peripheral clock 3 ( SSI )
+ */
+unsigned int imx_get_perclk3(void)
+{
+ return imx_get_system_clk() / (((PCDR>>16) & 0x7f)+1);
+}
+EXPORT_SYMBOL(imx_get_perclk3);
+
+/*
+ * get hclk ( SDRAM, CSI, Memory Stick, I2C, DMA )
+ */
+unsigned int imx_get_hclk(void)
+{
+ return imx_get_system_clk() / (((CSCR>>10) & 0xf)+1);
+}
+EXPORT_SYMBOL(imx_get_hclk);
+
+static struct resource imx_mmc_resources[] = {
+ [0] = {
+ .start = 0x00214000,
+ .end = 0x002140FF,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = (SDHC_INT),
+ .end = (SDHC_INT),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device imx_mmc_device = {
+ .name = "imx-mmc",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(imx_mmc_resources),
+ .resource = imx_mmc_resources,
+};
+
+static struct resource imx_uart1_resources[] = {
+ [0] = {
+ .start = 0x00206000,
+ .end = 0x002060FF,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = (UART1_MINT_RX),
+ .end = (UART1_MINT_RX),
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = (UART1_MINT_TX),
+ .end = (UART1_MINT_TX),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device imx_uart1_device = {
+ .name = "imx-uart",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(imx_uart1_resources),
+ .resource = imx_uart1_resources,
+};
+
+static struct resource imx_uart2_resources[] = {
+ [0] = {
+ .start = 0x00207000,
+ .end = 0x002070FF,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = (UART2_MINT_RX),
+ .end = (UART2_MINT_RX),
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = (UART2_MINT_TX),
+ .end = (UART2_MINT_TX),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device imx_uart2_device = {
+ .name = "imx-uart",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(imx_uart2_resources),
+ .resource = imx_uart2_resources,
+};
+
+static struct resource imxfb_resources[] = {
+ [0] = {
+ .start = 0x00205000,
+ .end = 0x002050FF,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = LCDC_INT,
+ .end = LCDC_INT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device imxfb_device = {
+ .name = "imx-fb",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(imxfb_resources),
+ .resource = imxfb_resources,
+};
+
+static struct platform_device *devices[] __initdata = {
+ &imx_mmc_device,
+ &imxfb_device,
+ &imx_uart1_device,
+ &imx_uart2_device,
+};
+
+static struct map_desc imx_io_desc[] __initdata = {
+ /* virtual physical length type */
+ {IMX_IO_BASE, IMX_IO_PHYS, IMX_IO_SIZE, MT_DEVICE},
+};
+
+void __init
+imx_map_io(void)
+{
+ iotable_init(imx_io_desc, ARRAY_SIZE(imx_io_desc));
+}
+
+static int __init imx_init(void)
+{
+ return platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+subsys_initcall(imx_init);
diff --git a/arch/arm/mach-imx/generic.h b/arch/arm/mach-imx/generic.h
new file mode 100644
index 00000000000000..31e1911b12e54c
--- /dev/null
+++ b/arch/arm/mach-imx/generic.h
@@ -0,0 +1,14 @@
+/*
+ * linux/arch/arm/mach-imx/generic.h
+ *
+ * Author: Sascha Hauer <sascha@saschahauer.de>
+ * Copyright: Synertronixx GmbH
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+extern void __init imx_map_io(void);
+extern void __init imx_init_irq(void);
+extern void __init imx_init_time(void);
diff --git a/arch/arm/mach-imx/irq.c b/arch/arm/mach-imx/irq.c
new file mode 100644
index 00000000000000..0c2713426dfd60
--- /dev/null
+++ b/arch/arm/mach-imx/irq.c
@@ -0,0 +1,252 @@
+/*
+ * linux/arch/arm/mach-imx/irq.c
+ *
+ * Copyright (C) 1999 ARM Limited
+ * Copyright (C) 2002 Shane Nay (shane@minirl.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * 03/03/2004 Sascha Hauer <sascha@saschahauer.de>
+ * Copied from the motorola bsp package and added gpio demux
+ * interrupt handler
+ */
+
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+
+#include <asm/mach/irq.h>
+
+/*
+ *
+ * We simply use the ENABLE DISABLE registers inside of the IMX
+ * to turn on/off specific interrupts. FIXME- We should
+ * also add support for the accelerated interrupt controller
+ * by putting offets to irq jump code in the appropriate
+ * places.
+ *
+ */
+
+#define INTENNUM_OFF 0x8
+#define INTDISNUM_OFF 0xC
+
+#define VA_AITC_BASE IO_ADDRESS(IMX_AITC_BASE)
+#define IMX_AITC_INTDISNUM (VA_AITC_BASE + INTDISNUM_OFF)
+#define IMX_AITC_INTENNUM (VA_AITC_BASE + INTENNUM_OFF)
+
+#if 0
+#define DEBUG_IRQ(fmt...) printk(fmt)
+#else
+#define DEBUG_IRQ(fmt...) do { } while (0)
+#endif
+
+static void
+imx_mask_irq(unsigned int irq)
+{
+ __raw_writel(irq, IMX_AITC_INTDISNUM);
+}
+
+static void
+imx_unmask_irq(unsigned int irq)
+{
+ __raw_writel(irq, IMX_AITC_INTENNUM);
+}
+
+static int
+imx_gpio_irq_type(unsigned int _irq, unsigned int type)
+{
+ unsigned int irq_type = 0, irq, reg, bit;
+
+ irq = _irq - IRQ_GPIOA(0);
+ reg = irq >> 5;
+ bit = 1 << (irq % 32);
+
+ if (type == IRQT_PROBE) {
+ /* Don't mess with enabled GPIOs using preconfigured edges or
+ GPIOs set to alternate function during probe */
+ /* TODO: support probe */
+// if ((GPIO_IRQ_rising_edge[idx] | GPIO_IRQ_falling_edge[idx]) &
+// GPIO_bit(gpio))
+// return 0;
+// if (GAFR(gpio) & (0x3 << (((gpio) & 0xf)*2)))
+// return 0;
+// type = __IRQT_RISEDGE | __IRQT_FALEDGE;
+ }
+
+ GIUS(reg) |= bit;
+ DDIR(reg) &= ~(bit);
+
+ DEBUG_IRQ("setting type of irq %d to ", _irq);
+
+ if (type & __IRQT_RISEDGE) {
+ DEBUG_IRQ("rising edges\n");
+ irq_type = 0x0;
+ }
+ if (type & __IRQT_FALEDGE) {
+ DEBUG_IRQ("falling edges\n");
+ irq_type = 0x1;
+ }
+ if (type & __IRQT_LOWLVL) {
+ DEBUG_IRQ("low level\n");
+ irq_type = 0x3;
+ }
+ if (type & __IRQT_HIGHLVL) {
+ DEBUG_IRQ("high level\n");
+ irq_type = 0x2;
+ }
+
+ if (irq % 32 < 16) {
+ ICR1(reg) = (ICR1(reg) & ~(0x3 << ((irq % 16) * 2))) |
+ (irq_type << ((irq % 16) * 2));
+ } else {
+ ICR2(reg) = (ICR2(reg) & ~(0x3 << ((irq % 16) * 2))) |
+ (irq_type << ((irq % 16) * 2));
+ }
+
+ return 0;
+
+}
+
+static void
+imx_gpio_ack_irq(unsigned int irq)
+{
+ DEBUG_IRQ("%s: irq %d\n", __FUNCTION__, irq);
+ ISR(IRQ_TO_REG(irq)) |= 1 << ((irq - IRQ_GPIOA(0)) % 32);
+}
+
+static void
+imx_gpio_mask_irq(unsigned int irq)
+{
+ DEBUG_IRQ("%s: irq %d\n", __FUNCTION__, irq);
+ IMR(IRQ_TO_REG(irq)) &= ~( 1 << ((irq - IRQ_GPIOA(0)) % 32));
+}
+
+static void
+imx_gpio_unmask_irq(unsigned int irq)
+{
+ DEBUG_IRQ("%s: irq %d\n", __FUNCTION__, irq);
+ IMR(IRQ_TO_REG(irq)) |= 1 << ((irq - IRQ_GPIOA(0)) % 32);
+}
+
+static void
+imx_gpio_handler(unsigned int mask, unsigned int irq,
+ struct irqdesc *desc, struct pt_regs *regs)
+{
+ desc = irq_desc + irq;
+ while (mask) {
+ if (mask & 1) {
+ DEBUG_IRQ("handling irq %d\n", irq);
+ desc->handle(irq, desc, regs);
+ }
+ irq++;
+ desc++;
+ mask >>= 1;
+ }
+}
+
+static void
+imx_gpioa_demux_handler(unsigned int irq_unused, struct irqdesc *desc,
+ struct pt_regs *regs)
+{
+ unsigned int mask, irq;
+
+ mask = ISR(0);
+ irq = IRQ_GPIOA(0);
+ imx_gpio_handler(mask, irq, desc, regs);
+}
+
+static void
+imx_gpiob_demux_handler(unsigned int irq_unused, struct irqdesc *desc,
+ struct pt_regs *regs)
+{
+ unsigned int mask, irq;
+
+ mask = ISR(1);
+ irq = IRQ_GPIOB(0);
+ imx_gpio_handler(mask, irq, desc, regs);
+}
+
+static void
+imx_gpioc_demux_handler(unsigned int irq_unused, struct irqdesc *desc,
+ struct pt_regs *regs)
+{
+ unsigned int mask, irq;
+
+ mask = ISR(2);
+ irq = IRQ_GPIOC(0);
+ imx_gpio_handler(mask, irq, desc, regs);
+}
+
+static void
+imx_gpiod_demux_handler(unsigned int irq_unused, struct irqdesc *desc,
+ struct pt_regs *regs)
+{
+ unsigned int mask, irq;
+
+ mask = ISR(3);
+ irq = IRQ_GPIOD(0);
+ imx_gpio_handler(mask, irq, desc, regs);
+}
+
+static struct irqchip imx_internal_chip = {
+ .ack = imx_mask_irq,
+ .mask = imx_mask_irq,
+ .unmask = imx_unmask_irq,
+};
+
+static struct irqchip imx_gpio_chip = {
+ .ack = imx_gpio_ack_irq,
+ .mask = imx_gpio_mask_irq,
+ .unmask = imx_gpio_unmask_irq,
+ .type = imx_gpio_irq_type,
+};
+
+void __init
+imx_init_irq(void)
+{
+ unsigned int irq;
+
+ DEBUG_IRQ("Initializing imx interrupts\n");
+
+ /* Mask all interrupts initially */
+ IMR(0) = 0;
+ IMR(1) = 0;
+ IMR(2) = 0;
+ IMR(3) = 0;
+
+ for (irq = 0; irq < IMX_IRQS; irq++) {
+ set_irq_chip(irq, &imx_internal_chip);
+ set_irq_handler(irq, do_level_IRQ);
+ set_irq_flags(irq, IRQF_VALID);
+ }
+
+ for (irq = IRQ_GPIOA(0); irq < IRQ_GPIOD(32); irq++) {
+ set_irq_chip(irq, &imx_gpio_chip);
+ set_irq_handler(irq, do_edge_IRQ);
+ set_irq_flags(irq, IRQF_VALID);
+ }
+
+ set_irq_chained_handler(GPIO_INT_PORTA, imx_gpioa_demux_handler);
+ set_irq_chained_handler(GPIO_INT_PORTB, imx_gpiob_demux_handler);
+ set_irq_chained_handler(GPIO_INT_PORTC, imx_gpioc_demux_handler);
+ set_irq_chained_handler(GPIO_INT_PORTD, imx_gpiod_demux_handler);
+
+ /* Disable all interrupts initially. */
+ /* In IMX this is done in the bootloader. */
+}
diff --git a/arch/arm/mach-imx/leds-mx1ads.c b/arch/arm/mach-imx/leds-mx1ads.c
new file mode 100644
index 00000000000000..e6399b06e4a474
--- /dev/null
+++ b/arch/arm/mach-imx/leds-mx1ads.c
@@ -0,0 +1,54 @@
+/*
+ * linux/arch/arm/mach-imx/leds-mx1ads.c
+ *
+ * Copyright (c) 2004 Sascha Hauer <sascha@saschahauer.de>
+ *
+ * Original (leds-footbridge.c) by Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <asm/hardware.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/leds.h>
+#include <asm/mach-types.h>
+#include "leds.h"
+
+/*
+ * The MX1ADS Board has only one usable LED,
+ * so select only the timer led or the
+ * cpu usage led
+ */
+void
+mx1ads_leds_event(led_event_t ledevt)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+
+ switch (ledevt) {
+#ifdef CONFIG_LEDS_CPU
+ case led_idle_start:
+ DR(0) &= ~(1<<2);
+ break;
+
+ case led_idle_end:
+ DR(0) |= 1<<2;
+ break;
+#endif
+
+#ifdef CONFIG_LEDS_TIMER
+ case led_timer:
+ DR(0) ^= 1<<2;
+#endif
+ default:
+ break;
+ }
+ local_irq_restore(flags);
+}
diff --git a/arch/arm/mach-imx/leds.c b/arch/arm/mach-imx/leds.c
new file mode 100644
index 00000000000000..471c1db7c57f09
--- /dev/null
+++ b/arch/arm/mach-imx/leds.c
@@ -0,0 +1,31 @@
+/*
+ * linux/arch/arm/mach-imx/leds.h
+ *
+ * Copyright (C) 2004 Sascha Hauer <sascha@saschahauer.de>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/leds.h>
+#include <asm/mach-types.h>
+
+#include "leds.h"
+
+static int __init
+leds_init(void)
+{
+ if (machine_is_mx1ads()) {
+ leds_event = mx1ads_leds_event;
+ }
+
+ return 0;
+}
+
+__initcall(leds_init);
diff --git a/arch/arm/mach-imx/leds.h b/arch/arm/mach-imx/leds.h
new file mode 100644
index 00000000000000..83fa21e795a999
--- /dev/null
+++ b/arch/arm/mach-imx/leds.h
@@ -0,0 +1,9 @@
+/*
+ * include/asm-arm/arch-imx/leds.h
+ *
+ * Copyright (c) 2004 Sascha Hauer <sascha@saschahauer.de>
+ *
+ * blinky lights for IMX-based systems
+ *
+ */
+extern void mx1ads_leds_event(led_event_t evt);
diff --git a/arch/arm/mach-imx/mx1ads.c b/arch/arm/mach-imx/mx1ads.c
new file mode 100644
index 00000000000000..bd92b909a77341
--- /dev/null
+++ b/arch/arm/mach-imx/mx1ads.c
@@ -0,0 +1,88 @@
+/*
+ * arch/arm/mach-imx/mx1ads.c
+ *
+ * Initially based on:
+ * linux-2.6.7-imx/arch/arm/mach-imx/scb9328.c
+ * Copyright (c) 2004 Sascha Hauer <sascha@saschahauer.de>
+ *
+ * 2004 (c) MontaVista Software, Inc.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/device.h>
+#include <linux/init.h>
+#include <asm/system.h>
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+
+#include <asm/mach/map.h>
+#include <asm/mach-types.h>
+
+#include <asm/mach/arch.h>
+#include <linux/interrupt.h>
+#include "generic.h"
+#include <asm/serial.h>
+
+static struct resource mx1ads_resources[] = {
+ [0] = {
+ .start = IMX_CS4_VIRT,
+ .end = IMX_CS4_VIRT + 16,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 13,
+ .end = 13,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device mx1ads_device = {
+ .name = "mx1ads",
+ .num_resources = ARRAY_SIZE(mx1ads_resources),
+ .resource = mx1ads_resources,
+};
+
+static struct platform_device *devices[] __initdata = {
+ &mx1ads_device,
+};
+
+static void __init
+mx1ads_init(void)
+{
+#ifdef CONFIG_LEDS
+ imx_gpio_mode(GPIO_PORTA | GPIO_OUT | GPIO_GPIO | 2);
+#endif
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+static struct map_desc mx1ads_io_desc[] __initdata = {
+ /* virtual physical length type */
+ {IMX_CS0_VIRT, IMX_CS0_PHYS, IMX_CS0_SIZE, MT_DEVICE},
+ {IMX_CS1_VIRT, IMX_CS1_PHYS, IMX_CS1_SIZE, MT_DEVICE},
+ {IMX_CS2_VIRT, IMX_CS2_PHYS, IMX_CS2_SIZE, MT_DEVICE},
+ {IMX_CS3_VIRT, IMX_CS3_PHYS, IMX_CS3_SIZE, MT_DEVICE},
+ {IMX_CS4_VIRT, IMX_CS4_PHYS, IMX_CS4_SIZE, MT_DEVICE},
+ {IMX_CS5_VIRT, IMX_CS5_PHYS, IMX_CS5_SIZE, MT_DEVICE},
+};
+
+static void __init
+mx1ads_map_io(void)
+{
+ imx_map_io();
+ iotable_init(mx1ads_io_desc, ARRAY_SIZE(mx1ads_io_desc));
+}
+
+MACHINE_START(MX1ADS, "Motorola MX1ADS")
+ MAINTAINER("Sascha Hauer, Pengutronix")
+ BOOT_MEM(0x08000000, 0x00200000, 0xe0200000)
+ BOOT_PARAMS(0x08000100)
+ MAPIO(mx1ads_map_io)
+ INITIRQ(imx_init_irq)
+ INITTIME(imx_init_time)
+ INIT_MACHINE(mx1ads_init)
+MACHINE_END
diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c
new file mode 100644
index 00000000000000..0d66bee9f09ccb
--- /dev/null
+++ b/arch/arm/mach-imx/time.c
@@ -0,0 +1,95 @@
+/*
+ * linux/arch/arm/mach-imx/time.c
+ *
+ * Copyright (C) 2000-2001 Deep Blue Solutions
+ * Copyright (C) 2002 Shane Nay (shane@minirl.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/time.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/leds.h>
+#include <asm/irq.h>
+#include <asm/mach/time.h>
+
+/* Use timer 1 as system timer */
+#define TIMER_BASE IMX_TIM1_BASE
+
+/*
+ * Returns number of ms since last clock interrupt. Note that interrupts
+ * will have been disabled by do_gettimeoffset()
+ */
+static unsigned long
+imx_gettimeoffset(void)
+{
+ unsigned long ticks;
+
+ /*
+ * Get the current number of ticks. Note that there is a race
+ * condition between us reading the timer and checking for
+ * an interrupt. We get around this by ensuring that the
+ * counter has not reloaded between our two reads.
+ */
+ ticks = IMX_TCR(TIMER_BASE);
+
+ /*
+ * Interrupt pending? If so, we've reloaded once already.
+ */
+ if (IMX_TSTAT(TIMER_BASE) & TSTAT_COMP)
+ ticks += LATCH;
+
+ /*
+ * Convert the ticks to usecs
+ */
+ return (1000000 / CLK32) * ticks;
+}
+
+/*
+ * IRQ handler for the timer
+ */
+static irqreturn_t
+imx_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+ /* clear the interrupt */
+ if (IMX_TSTAT(TIMER_BASE))
+ IMX_TSTAT(TIMER_BASE) = 0;
+
+ timer_tick(regs);
+ return IRQ_HANDLED;
+}
+
+static struct irqaction imx_timer_irq = {
+ .name = "i.MX Timer Tick",
+ .flags = SA_INTERRUPT,
+ .handler = imx_timer_interrupt
+};
+
+/*
+ * Set up timer interrupt, and return the current time in seconds.
+ */
+void __init
+imx_init_time(void)
+{
+ /*
+ * Initialise to a known state (all timers off, and timing reset)
+ */
+ IMX_TCTL(TIMER_BASE) = 0;
+ IMX_TPRER(TIMER_BASE) = 0;
+ IMX_TCMP(TIMER_BASE) = LATCH;
+ IMX_TCTL(TIMER_BASE) = TCTL_CLK_32 | TCTL_IRQEN | TCTL_TEN;
+
+ /*
+ * Make irqs happen for the system timer
+ */
+ setup_irq(TIM1_INT, &imx_timer_irq);
+ gettimeoffset = imx_gettimeoffset;
+}
diff --git a/arch/arm/mach-integrator/cpu.c b/arch/arm/mach-integrator/cpu.c
index e2a07dedaa8669..71c58bff304c4e 100644
--- a/arch/arm/mach-integrator/cpu.c
+++ b/arch/arm/mach-integrator/cpu.c
@@ -79,7 +79,7 @@ static int integrator_set_target(struct cpufreq_policy *policy,
unsigned int target_freq,
unsigned int relation)
{
- unsigned long cpus_allowed;
+ cpumask_t cpus_allowed;
int cpu = policy->cpu;
struct icst525_vco vco;
struct cpufreq_freqs freqs;
@@ -94,7 +94,7 @@ static int integrator_set_target(struct cpufreq_policy *policy,
* Bind to the specified CPU. When this call returns,
* we should be running on the right CPU.
*/
- set_cpus_allowed(current, 1 << cpu);
+ set_cpus_allowed(current, cpumask_of_cpu(cpu));
BUG_ON(cpu != smp_processor_id());
/* get current setting */
@@ -154,14 +154,14 @@ static int integrator_set_target(struct cpufreq_policy *policy,
static unsigned int integrator_get(unsigned int cpu)
{
- unsigned long cpus_allowed;
+ cpumask_t cpus_allowed;
unsigned int current_freq;
u_int cm_osc;
struct icst525_vco vco;
cpus_allowed = current->cpus_allowed;
- set_cpus_allowed(current, 1 << cpu);
+ set_cpus_allowed(current, cpumask_of_cpu(cpu));
BUG_ON(cpu != smp_processor_id());
/* detect memory etc. */
diff --git a/arch/arm/mach-iop3xx/Kconfig b/arch/arm/mach-iop3xx/Kconfig
index 6a388e273bad38..8d4919f43ad040 100644
--- a/arch/arm/mach-iop3xx/Kconfig
+++ b/arch/arm/mach-iop3xx/Kconfig
@@ -4,13 +4,7 @@ menu "IOP3xx Implementation Options"
choice
prompt "IOP3xx System Type"
- default ARCH_IQ80310
-
-config ARCH_IQ80310
- bool "IQ80310"
- help
- Say Y here if you want to run your kernel on the Intel IQ80310
- evaluation kit for the IOP310 chipset.
+ default ARCH_IQ80321
config ARCH_IQ80321
bool "IQ80321"
@@ -20,12 +14,6 @@ config ARCH_IQ80321
endchoice
# Which IOP variant are we running?
-config ARCH_IOP310
- bool
- default ARCH_IQ80310
- help
- The IQ80310 uses the IOP310 variant.
-
config ARCH_IOP321
bool
default ARCH_IQ80321
@@ -42,14 +30,6 @@ config IOP3XX_DMA
bool "Support Intel IOP3xx DMA (EXPERIMENTAL)"
depends on EXPERIMENTAL
-config IOP3XX_MU
- bool "Support Intel IOP3xx Messaging Unit (EXPERIMENTAL)"
- depends on EXPERIMENTAL
-
-config IOP3XX_PMON
- bool "Support Intel IOP3xx Performance Monitor (EXPERIMENTAL)"
- depends on EXPERIMENTAL
-
endmenu
endif
diff --git a/arch/arm/mach-iop3xx/Makefile b/arch/arm/mach-iop3xx/Makefile
index a6d1cf98b75a1e..30a2895c9caa3c 100644
--- a/arch/arm/mach-iop3xx/Makefile
+++ b/arch/arm/mach-iop3xx/Makefile
@@ -10,21 +10,9 @@ obj-m :=
obj-n :=
obj- :=
-obj-$(CONFIG_ARCH_IOP310) += xs80200-irq.o iop310-irq.o iop310-pci.o mm.o
-
-obj-$(CONFIG_ARCH_IQ80310) += iq80310-pci.o iq80310-irq.o
-
obj-$(CONFIG_ARCH_IOP321) += iop321-irq.o iop321-pci.o mm-321.o iop321-time.o
obj-$(CONFIG_ARCH_IQ80321) += iq80321-pci.o
-ifeq ($(CONFIG_ARCH_IQ80310),y)
- ifneq ($(CONFIG_XSCALE_PMU_TIMER),y)
- obj-y += iq80310-time.o
- endif
-endif
-
obj-$(CONFIG_IOP3XX_AAU) += aau.o
obj-$(CONFIG_IOP3XX_DMA) += dma.o
-obj-$(CONFIG_IOP3XX_MU) += message.o
-obj-$(CONFIG_IOP3XX_PMON) += pmon.o
diff --git a/arch/arm/mach-iop3xx/arch.c b/arch/arm/mach-iop3xx/arch.c
index 3df5e454c7722d..bdda3f1051cb29 100644
--- a/arch/arm/mach-iop3xx/arch.c
+++ b/arch/arm/mach-iop3xx/arch.c
@@ -21,49 +21,23 @@
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
-#ifdef CONFIG_ARCH_IQ80310
-extern void iq80310_map_io(void);
-extern void iq80310_init_irq(void);
-#endif
-
#ifdef CONFIG_ARCH_IQ80321
extern void iq80321_map_io(void);
extern void iop321_init_irq(void);
extern void iop321_init_time(void);
#endif
-#ifdef CONFIG_ARCH_IQ80310
-static void __init
-fixup_iq80310(struct machine_desc *desc, struct tag *tags,
- char **cmdline, struct meminfo *mi)
-{
- system_rev = (*(volatile unsigned int*)0xfe830000) & 0x0f;
-
- if (system_rev)
- system_rev = 0xF;
-}
-#endif
-
#ifdef CONFIG_ARCH_IQ80321
static void __init
-fixup_iop321(struct machine_desc *desc, struct param_struct *params,
+fixup_iop321(struct machine_desc *desc, struct tag *tags,
char **cmdline, struct meminfo *mi)
{
}
#endif
-#ifdef CONFIG_ARCH_IQ80310
-MACHINE_START(IQ80310, "Cyclone IQ80310")
- MAINTAINER("MontaVista Software Inc.")
- BOOT_MEM(0xa0000000, 0xfe000000, 0xfe000000)
- FIXUP(fixup_iq80310)
- MAPIO(iq80310_map_io)
- INITIRQ(iq80310_init_irq)
-MACHINE_END
-
-#elif defined(CONFIG_ARCH_IQ80321)
+#if defined(CONFIG_ARCH_IQ80321)
MACHINE_START(IQ80321, "Intel IQ80321")
- MAINTAINER("MontaVista Software, Inc.")
+ MAINTAINER("Intel Corporation")
BOOT_MEM(PHYS_OFFSET, IQ80321_UART1, 0xfe800000)
FIXUP(fixup_iop321)
MAPIO(iq80321_map_io)
@@ -72,5 +46,5 @@ MACHINE_START(IQ80321, "Intel IQ80321")
MACHINE_END
#else
-#error No machine descriptor defined for this IOP310 implementation
+#error No machine descriptor defined for this IOP3xx implementation
#endif
diff --git a/arch/arm/mach-iop3xx/iop310-irq.c b/arch/arm/mach-iop3xx/iop310-irq.c
deleted file mode 100644
index a05e7e958b96bf..00000000000000
--- a/arch/arm/mach-iop3xx/iop310-irq.c
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * linux/arch/arm/mach-iop3xx/iop310-irq.c
- *
- * Generic IOP310 IRQ handling functionality
- *
- * Author: Nicolas Pitre
- * Copyright: (C) 2001 MontaVista Software Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Added IOP310 chipset and IQ80310 board demuxing, masking code. - DS
- *
- */
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-
-#include <asm/mach/irq.h>
-#include <asm/irq.h>
-#include <asm/hardware.h>
-
-extern void xs80200_irq_mask(unsigned int);
-extern void xs80200_irq_unmask(unsigned int);
-extern void xs80200_init_irq(void);
-
-extern void do_IRQ(int, struct pt_regs *);
-
-static u32 iop310_mask /* = 0 */;
-
-static void iop310_irq_mask (unsigned int irq)
-{
- iop310_mask ++;
-
- /*
- * No mask bits on the 80312, so we have to
- * mask everything from the outside!
- */
- if (iop310_mask == 1) {
- disable_irq(IRQ_XS80200_EXTIRQ);
- irq_desc[IRQ_XS80200_EXTIRQ].chip->mask(IRQ_XS80200_EXTIRQ);
- }
-}
-
-static void iop310_irq_unmask (unsigned int irq)
-{
- if (iop310_mask)
- iop310_mask --;
-
- /*
- * Check if all 80312 sources are unmasked now
- */
- if (iop310_mask == 0)
- enable_irq(IRQ_XS80200_EXTIRQ);
-}
-
-struct irqchip ext_chip = {
- .ack = iop310_irq_mask,
- .mask = iop310_irq_mask,
- .unmask = iop310_irq_unmask,
-};
-
-void
-iop310_irq_demux(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
-{
- u32 fiq1isr = *((volatile u32*)IOP310_FIQ1ISR);
- u32 fiq2isr = *((volatile u32*)IOP310_FIQ2ISR);
- struct irqdesc *d;
- unsigned int irqno = 0;
-
- if(fiq1isr)
- {
- if(fiq1isr & 0x1)
- irqno = IRQ_IOP310_DMA0;
- if(fiq1isr & 0x2)
- irqno = IRQ_IOP310_DMA1;
- if(fiq1isr & 0x4)
- irqno = IRQ_IOP310_DMA2;
- if(fiq1isr & 0x10)
- irqno = IRQ_IOP310_PMON;
- if(fiq1isr & 0x20)
- irqno = IRQ_IOP310_AAU;
- }
- else
- {
- if(fiq2isr & 0x2)
- irqno = IRQ_IOP310_I2C;
- if(fiq2isr & 0x4)
- irqno = IRQ_IOP310_MU;
- }
-
- if (irqno) {
- d = irq_desc + irqno;
- d->handle(irqno, d, regs);
- }
-}
-
-void __init iop310_init_irq(void)
-{
- unsigned int i;
-
- for(i = IOP310_IRQ_OFS; i < NR_IOP310_IRQS; i++)
- {
- set_irq_chip(i, &ext_chip);
- set_irq_handler(i, do_level_IRQ);
- set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
- }
-
- xs80200_init_irq();
-}
diff --git a/arch/arm/mach-iop3xx/iop310-pci.c b/arch/arm/mach-iop3xx/iop310-pci.c
deleted file mode 100644
index 8e54013847283d..00000000000000
--- a/arch/arm/mach-iop3xx/iop310-pci.c
+++ /dev/null
@@ -1,434 +0,0 @@
-/*
- * arch/arm/mach-iop3xx/iop310-pci.c
- *
- * PCI support for the Intel IOP310 chipset
- *
- * Matt Porter <mporter@mvista.com>
- *
- * Copyright (C) 2001 MontaVista Software, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/init.h>
-#include <linux/ioport.h>
-
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/system.h>
-#include <asm/hardware.h>
-#include <asm/mach/pci.h>
-
-#include <asm/arch/iop310.h>
-
-/*
- * *** Special note - why the IOP310 should NOT be used ***
- *
- * The PCI ATU is a brain dead implementation, only allowing 32-bit
- * accesses to PCI configuration space. This is especially brain
- * dead for writes to this space. A simple for-instance:
- *
- * You want to modify the command register *without* corrupting the
- * status register.
- *
- * To perform this, you need to read *32* bits of data from offset 4,
- * mask off the low 16, replace them with the new data, and write *32*
- * bits back.
- *
- * Writing the status register at offset 6 with status bits set *clears*
- * the status.
- *
- * Hello? Could we have a *SANE* implementation of a PCI ATU some day
- * *PLEASE*?
- */
-#undef DEBUG
-#ifdef DEBUG
-#define DBG(x...) printk(x)
-#else
-#define DBG(x...) do { } while (0)
-#endif
-
-/*
- * Calculate the address, etc from the bus, devfn and register
- * offset. Note that we have two root buses, so we need some
- * method to determine whether we need config type 0 or 1 cycles.
- * We use a root bus number in our bus->sysdata structure for this.
- */
-static u32 iop310_cfg_address(struct pci_bus *bus, int devfn, int where)
-{
- struct pci_sys_data *sys = bus->sysdata;
- u32 addr;
-
- if (sys->busnr == bus->number)
- addr = 1 << (PCI_SLOT(devfn) + 16);
- else
- addr = bus->number << 16 | PCI_SLOT(devfn) << 11 | 1;
-
- addr |= PCI_FUNC(devfn) << 8 | (where & ~3);
-
- return addr;
-}
-
-/*
- * Primary PCI interface support.
- */
-static int iop310_pri_pci_status(void)
-{
- unsigned int status;
- int ret = 0;
-
- status = *IOP310_PATUSR;
- if (status & 0xf900) {
- *IOP310_PATUSR = status & 0xf900;
- ret = 1;
- }
- status = *IOP310_PATUISR;
- if (status & 0x0000018f) {
- *IOP310_PATUISR = status & 0x0000018f;
- ret = 1;
- }
- status = *IOP310_PSR;
- if (status & 0xf900) {
- *IOP310_PSR = status & 0xf900;
- ret = 1;
- }
- status = *IOP310_PBISR;
- if (status & 0x003f) {
- *IOP310_PBISR = status & 0x003f;
- ret = 1;
- }
- return ret;
-}
-
-/*
- * Simply write the address register and read the configuration
- * data. Note that the 4 nop's ensure that we are able to handle
- * a delayed abort (in theory.)
- */
-static inline u32 iop310_pri_read(unsigned long addr)
-{
- u32 val;
-
- __asm__ __volatile__(
- "str %1, [%2]\n\t"
- "ldr %0, [%3]\n\t"
- "nop\n\t"
- "nop\n\t"
- "nop\n\t"
- "nop\n\t"
- : "=r" (val)
- : "r" (addr), "r" (IOP310_POCCAR), "r" (IOP310_POCCDR));
-
- return val;
-}
-
-static int
-iop310_pri_read_config(struct pci_bus *bus, unsigned int devfn, int where,
- int size, u32 *value)
-{
- unsigned long addr = iop310_cfg_address(bus, devfn, where);
- u32 val = iop310_pri_read(addr) >> ((where & 3) * 8);
-
- if (iop310_pri_pci_status())
- val = 0xffffffff;
-
- *value = val;
-
- return PCIBIOS_SUCCESSFUL;
-}
-
-static int
-iop310_pri_write_config(struct pci_bus *bus, unsigned int devfn, int where,
- int size, u32 value)
-{
- unsigned long addr = iop310_cfg_address(bus, devfn, where);
- u32 val;
-
- if (size != 4) {
- val = iop310_pri_read(addr);
- if (!iop310_pri_pci_status() == 0)
- return PCIBIOS_SUCCESSFUL;
-
- where = (where & 3) * 8;
-
- if (size == 1)
- val &= ~(0xff << where);
- else
- val &= ~(0xffff << where);
-
- *IOP310_POCCDR = val | value << where;
- } else {
- asm volatile(
- "str %1, [%2]\n\t"
- "str %0, [%3]\n\t"
- "nop\n\t"
- "nop\n\t"
- "nop\n\t"
- "nop\n\t"
- :
- : "r" (value), "r" (addr),
- "r" (IOP310_POCCAR), "r" (IOP310_POCCDR));
- }
-
- return PCIBIOS_SUCCESSFUL;
-}
-
-static struct pci_ops iop310_primary_ops = {
- .read = iop310_pri_read_config,
- .write = iop310_pri_write_config,
-};
-
-/*
- * Secondary PCI interface support.
- */
-static int iop310_sec_pci_status(void)
-{
- unsigned int usr, uisr;
- int ret = 0;
-
- usr = *IOP310_SATUSR;
- uisr = *IOP310_SATUISR;
- if (usr & 0xf900) {
- *IOP310_SATUSR = usr & 0xf900;
- ret = 1;
- }
- if (uisr & 0x0000069f) {
- *IOP310_SATUISR = uisr & 0x0000069f;
- ret = 1;
- }
- if (ret)
- DBG("ERROR (%08x %08x)", usr, uisr);
- return ret;
-}
-
-/*
- * Simply write the address register and read the configuration
- * data. Note that the 4 nop's ensure that we are able to handle
- * a delayed abort (in theory.)
- */
-static inline u32 iop310_sec_read(unsigned long addr)
-{
- u32 val;
-
- __asm__ __volatile__(
- "str %1, [%2]\n\t"
- "ldr %0, [%3]\n\t"
- "nop\n\t"
- "nop\n\t"
- "nop\n\t"
- "nop\n\t"
- : "=r" (val)
- : "r" (addr), "r" (IOP310_SOCCAR), "r" (IOP310_SOCCDR));
-
- return val;
-}
-
-static int
-iop310_sec_read_config(struct pci_bus *bus, unsigned int devfn, int where,
- int size, u32 *value)
-{
- unsigned long addr = iop310_cfg_address(bus, devfn, where);
- u32 val = iop310_sec_read(addr) >> ((where & 3) * 8);
-
- if (iop310_sec_pci_status())
- val = 0xffffffff;
-
- *value = val;
-
- return PCIBIOS_SUCCESSFUL;
-}
-
-static int
-iop310_sec_write_config(struct pci_bus *bus, unsigned int devfn, int where,
- int size, u32 value)
-{
- unsigned long addr = iop310_cfg_address(bus, devfn, where);
- u32 val;
-
- if (size != 4) {
- val = iop310_sec_read(addr);
-
- if (!iop310_sec_pci_status() == 0)
- return PCIBIOS_SUCCESSFUL;
-
- where = (where & 3) * 8;
-
- if (size == 1)
- val &= ~(0xff << where);
- else
- val &= ~(0xffff << where);
-
- *IOP310_SOCCDR = val | value << where;
- } else {
- asm volatile(
- "str %1, [%2]\n\t"
- "str %0, [%3]\n\t"
- "nop\n\t"
- "nop\n\t"
- "nop\n\t"
- "nop\n\t"
- :
- : "r" (value), "r" (addr),
- "r" (IOP310_SOCCAR), "r" (IOP310_SOCCDR));
- }
-
- return PCIBIOS_SUCCESSFUL;
-}
-
-static struct pci_ops iop310_secondary_ops = {
- .read = iop310_sec_read_config,
- .write = iop310_sec_write_config,
-};
-
-/*
- * When a PCI device does not exist during config cycles, the 80200 gets
- * an external abort instead of returning 0xffffffff. If it was an
- * imprecise abort, we need to correct the return address to point after
- * the instruction. Also note that the Xscale manual says:
- *
- * "if a stall-until-complete LD or ST instruction triggers an
- * imprecise fault, then that fault will be seen by the program
- * within 3 instructions."
- *
- * This does not appear to be the case. With 8 NOPs after the load, we
- * see the imprecise abort occurring on the STM of iop310_sec_pci_status()
- * which is about 10 instructions away.
- *
- * Always trust reality!
- */
-static int
-iop310_pci_abort(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
-{
- DBG("PCI abort: address = 0x%08lx fsr = 0x%03x PC = 0x%08lx LR = 0x%08lx\n",
- addr, fsr, regs->ARM_pc, regs->ARM_lr);
-
- /*
- * If it was an imprecise abort, then we need to correct the
- * return address to be _after_ the instruction.
- */
- if (fsr & (1 << 10))
- regs->ARM_pc += 4;
-
- return 0;
-}
-
-/*
- * Scan an IOP310 PCI bus. sys->bus defines which bus we scan.
- */
-struct pci_bus *iop310_scan_bus(int nr, struct pci_sys_data *sys)
-{
- struct pci_ops *ops;
-
- if (nr)
- ops = &iop310_secondary_ops;
- else
- ops = &iop310_primary_ops;
-
- return pci_scan_bus(sys->busnr, ops, sys);
-}
-
-/*
- * Setup the system data for controller 'nr'. Return 0 if none found,
- * 1 if found, or negative error.
- *
- * We can alter:
- * io_offset - offset between IO resources and PCI bus BARs
- * mem_offset - offset between mem resources and PCI bus BARs
- * resource[0] - parent IO resource
- * resource[1] - parent non-prefetchable memory resource
- * resource[2] - parent prefetchable memory resource
- * swizzle - bridge swizzling function
- * map_irq - irq mapping function
- *
- * Note that 'io_offset' and 'mem_offset' are left as zero since
- * the IOP310 doesn't attempt to perform any address translation
- * on accesses from the host to the bus.
- */
-int iop310_setup(int nr, struct pci_sys_data *sys)
-{
- struct resource *res;
-
- if (nr >= 2)
- return 0;
-
- res = kmalloc(sizeof(struct resource) * 2, GFP_KERNEL);
- if (!res)
- panic("PCI: unable to alloc resources");
-
- memset(res, 0, sizeof(struct resource) * 2);
-
- switch (nr) {
- case 0:
- res[0].start = IOP310_PCIPRI_LOWER_IO + 0x6e000000;
- res[0].end = IOP310_PCIPRI_LOWER_IO + 0x6e00ffff;
- res[0].name = "PCI IO Primary";
- res[0].flags = IORESOURCE_IO;
-
- res[1].start = IOP310_PCIPRI_LOWER_MEM;
- res[1].end = IOP310_PCIPRI_LOWER_MEM + IOP310_PCI_WINDOW_SIZE;
- res[1].name = "PCI Memory Primary";
- res[1].flags = IORESOURCE_MEM;
- break;
-
- case 1:
- res[0].start = IOP310_PCISEC_LOWER_IO + 0x6e000000;
- res[0].end = IOP310_PCISEC_LOWER_IO + 0x6e00ffff;
- res[0].name = "PCI IO Secondary";
- res[0].flags = IORESOURCE_IO;
-
- res[1].start = IOP310_PCISEC_LOWER_MEM;
- res[1].end = IOP310_PCISEC_LOWER_MEM + IOP310_PCI_WINDOW_SIZE;
- res[1].name = "PCI Memory Secondary";
- res[1].flags = IORESOURCE_MEM;
- break;
- }
-
- request_resource(&ioport_resource, &res[0]);
- request_resource(&iomem_resource, &res[1]);
-
- sys->resource[0] = &res[0];
- sys->resource[1] = &res[1];
- sys->resource[2] = NULL;
- sys->io_offset = 0x6e000000;
-
- return 1;
-}
-
-void iop310_init(void)
-{
- DBG("PCI: Intel 80312 PCI-to-PCI init code.\n");
- DBG(" ATU secondary: ATUCR =0x%08x\n", *IOP310_ATUCR);
- DBG(" ATU secondary: SOMWVR=0x%08x SOIOWVR=0x%08x\n",
- *IOP310_SOMWVR, *IOP310_SOIOWVR);
- DBG(" ATU secondary: SIABAR=0x%08x SIALR =0x%08x SIATVR=%08x\n",
- *IOP310_SIABAR, *IOP310_SIALR, *IOP310_SIATVR);
- DBG(" ATU primary: POMWVR=0x%08x POIOWVR=0x%08x\n",
- *IOP310_POMWVR, *IOP310_POIOWVR);
- DBG(" ATU primary: PIABAR=0x%08x PIALR =0x%08x PIATVR=%08x\n",
- *IOP310_PIABAR, *IOP310_PIALR, *IOP310_PIATVR);
- DBG(" P2P: PCR=0x%04x BCR=0x%04x EBCR=0x%04x\n",
- *IOP310_PCR, *IOP310_BCR, *IOP310_EBCR);
-
- /*
- * Windows have to be carefully opened via a nice set of calls
- * here or just some direct register fiddling in the board
- * specific init when we want transactions to occur between the
- * two PCI hoses.
- *
- * To do this, we will have manage RETRY assertion between the
- * firmware and the kernel. This will ensure that the host
- * system's enumeration code is held off until we have tweaked
- * the interrupt routing and public/private IDSELs.
- *
- * For now we will simply default to disabling the integrated type
- * 81 P2P bridge.
- */
- *IOP310_PCR &= 0xfff8;
-
- hook_fault_code(16+6, iop310_pci_abort, SIGBUS, "imprecise external abort");
-}
diff --git a/arch/arm/mach-iop3xx/iop321-pci.c b/arch/arm/mach-iop3xx/iop321-pci.c
index 3ae69a1ffba7d0..be36f53836d36d 100644
--- a/arch/arm/mach-iop3xx/iop321-pci.c
+++ b/arch/arm/mach-iop3xx/iop321-pci.c
@@ -158,6 +158,7 @@ iop321_write_config(struct pci_bus *bus, unsigned int devfn, int where,
: "r" (value), "r" (addr),
"r" (IOP321_OCCAR), "r" (IOP321_OCCDR));
}
+ return PCIBIOS_SUCCESSFUL;
}
static struct pci_ops iop321_ops = {
diff --git a/arch/arm/mach-iop3xx/iop321-time.c b/arch/arm/mach-iop3xx/iop321-time.c
index be36c70690b153..7d4e8124579426 100644
--- a/arch/arm/mach-iop3xx/iop321-time.c
+++ b/arch/arm/mach-iop3xx/iop321-time.c
@@ -79,7 +79,7 @@ extern int setup_arm_irq(int, struct irqaction*);
void __init iop321_init_time(void)
{
u32 timer_ctl;
- u32 latch = LATCH;
+/* u32 latch = LATCH; */
gettimeoffset = iop321_gettimeoffset;
setup_irq(IRQ_IOP321_TIMER0, &iop321_timer_irq);
diff --git a/arch/arm/mach-iop3xx/iq80310-irq.c b/arch/arm/mach-iop3xx/iq80310-irq.c
deleted file mode 100644
index 93315378145377..00000000000000
--- a/arch/arm/mach-iop3xx/iq80310-irq.c
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * linux/arch/arm/mach-iop3xx/iq80310-irq.c
- *
- * IRQ hadling/demuxing for IQ80310 board
- *
- * Author: Nicolas Pitre
- * Copyright: (C) 2001 MontaVista Software Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * 2.4.7-rmk1-iop310.1
- * Moved demux from asm to C - DS
- * Fixes for various revision boards - DS
- */
-#include <linux/init.h>
-#include <linux/list.h>
-
-#include <asm/irq.h>
-#include <asm/mach/irq.h>
-#include <asm/hardware.h>
-#include <asm/system.h>
-
-extern void iop310_init_irq(void);
-extern void iop310_irq_demux(unsigned int, struct irqdesc *, struct pt_regs *);
-
-static void iq80310_irq_mask(unsigned int irq)
-{
- *(volatile char *)IQ80310_INT_MASK |= (1 << (irq - IQ80310_IRQ_OFS));
-}
-
-static void iq80310_irq_unmask(unsigned int irq)
-{
- *(volatile char *)IQ80310_INT_MASK &= ~(1 << (irq - IQ80310_IRQ_OFS));
-}
-
-static struct irqchip iq80310_irq_chip = {
- .ack = iq80310_irq_mask,
- .mask = iq80310_irq_mask,
- .unmask = iq80310_irq_unmask,
-};
-
-extern struct irqchip ext_chip;
-
-static void
-iq80310_cpld_irq_handler(unsigned int irq, struct irqdesc *desc,
- struct pt_regs *regs)
-{
- unsigned int irq_stat = *(volatile u8*)IQ80310_INT_STAT;
- unsigned int irq_mask = *(volatile u8*)IQ80310_INT_MASK;
- unsigned int i, handled = 0;
- struct irqdesc *d;
-
- desc->chip->ack(irq);
-
- /*
- * Mask out the interrupts which aren't enabled.
- */
- irq_stat &= 0x1f & ~irq_mask;
-
- /*
- * Test each IQ80310 CPLD interrupt
- */
- for (i = IRQ_IQ80310_TIMER, d = irq_desc + IRQ_IQ80310_TIMER;
- irq_stat; i++, d++, irq_stat >>= 1)
- if (irq_stat & 1) {
- d->handle(i, d, regs);
- handled++;
- }
-
- /*
- * If running on a board later than REV D.1, we can
- * decode the PCI interrupt status.
- */
- if (system_rev) {
- irq_stat = *((volatile u8*)IQ80310_PCI_INT_STAT) & 7;
-
- for (i = IRQ_IQ80310_INTA, d = irq_desc + IRQ_IQ80310_INTA;
- irq_stat; i++, d++, irq_stat >>= 1)
- if (irq_stat & 0x1) {
- d->handle(i, d, regs);
- handled++;
- }
- }
-
- /*
- * If on a REV D.1 or lower board, we just assumed INTA
- * since PCI is not routed, and it may actually be an
- * on-chip interrupt.
- *
- * Note that we're giving on-chip interrupts slightly
- * higher priority than PCI by handling them first.
- *
- * On boards later than REV D.1, if we didn't read a
- * CPLD interrupt, we assume it's from a device on the
- * chipset itself.
- */
- if (system_rev == 0 || handled == 0)
- iop310_irq_demux(irq, desc, regs);
-
- desc->chip->unmask(irq);
-}
-
-void __init iq80310_init_irq(void)
-{
- volatile char *mask = (volatile char *)IQ80310_INT_MASK;
- unsigned int i;
-
- iop310_init_irq();
-
- /*
- * Setup PIRSR to route PCI interrupts into xs80200
- */
- *IOP310_PIRSR = 0xff;
-
- /*
- * Setup the IRQs in the FE820000/FE860000 registers
- */
- for (i = IQ80310_IRQ_OFS; i <= IRQ_IQ80310_INTD; i++) {
- set_irq_chip(i, &iq80310_irq_chip);
- set_irq_handler(i, do_level_IRQ);
- set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
- }
-
- /*
- * Setup the PCI IRQs
- */
- for (i = IRQ_IQ80310_INTA; i < IRQ_IQ80310_INTC; i++) {
- set_irq_chip(i, &ext_chip);
- set_irq_handler(i, do_level_IRQ);
- set_irq_flags(i, IRQF_VALID);
- }
-
- *mask = 0xff; /* mask all sources */
-
- set_irq_chained_handler(IRQ_XS80200_EXTIRQ,
- &iq80310_cpld_irq_handler);
-}
diff --git a/arch/arm/mach-iop3xx/iq80310-pci.c b/arch/arm/mach-iop3xx/iq80310-pci.c
deleted file mode 100644
index fa92f3e8afc9c8..00000000000000
--- a/arch/arm/mach-iop3xx/iq80310-pci.c
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * arch/arm/mach-iop3xx/iq80310-pci.c
- *
- * PCI support for the Intel IQ80310 reference board
- *
- * Matt Porter <mporter@mvista.com>
- *
- * Copyright (C) 2001 MontaVista Software, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-
-#include <asm/hardware.h>
-#include <asm/irq.h>
-#include <asm/mach/pci.h>
-#include <asm/mach-types.h>
-
-/*
- * The following macro is used to lookup irqs in a standard table
- * format for those systems that do not already have PCI
- * interrupts properly routed. We assume 1 <= pin <= 4
- */
-#define PCI_IRQ_TABLE_LOOKUP(minid,maxid) \
-({ int _ctl_ = -1; \
- unsigned int _idsel = idsel - minid; \
- if (_idsel <= maxid) \
- _ctl_ = pci_irq_table[_idsel][pin-1]; \
- _ctl_; })
-
-#define INTA IRQ_IQ80310_INTA
-#define INTB IRQ_IQ80310_INTB
-#define INTC IRQ_IQ80310_INTC
-#define INTD IRQ_IQ80310_INTD
-
-#define INTE IRQ_IQ80310_I82559
-
-typedef u8 irq_table[4];
-
-/*
- * IRQ tables for primary bus.
- *
- * On a Rev D.1 and older board, INT A-C are not routed, so we
- * just fake it as INTA and than we take care of handling it
- * correctly in the IRQ demux routine.
- */
-static irq_table pci_pri_d_irq_table[] = {
-/* Pin: A B C D */
- { INTA, INTD, INTA, INTA }, /* PCI Slot J3 */
- { INTD, INTA, INTA, INTA }, /* PCI Slot J4 */
-};
-
-static irq_table pci_pri_f_irq_table[] = {
-/* Pin: A B C D */
- { INTC, INTD, INTA, INTB }, /* PCI Slot J3 */
- { INTD, INTA, INTB, INTC }, /* PCI Slot J4 */
-};
-
-static int __init
-iq80310_pri_map_irq(struct pci_dev *dev, u8 idsel, u8 pin)
-{
- irq_table *pci_irq_table;
-
- BUG_ON(pin < 1 || pin > 4);
-
- if (!system_rev) {
- pci_irq_table = pci_pri_d_irq_table;
- } else {
- pci_irq_table = pci_pri_f_irq_table;
- }
-
- return PCI_IRQ_TABLE_LOOKUP(2, 3);
-}
-
-/*
- * IRQ tables for secondary bus.
- *
- * On a Rev D.1 and older board, INT A-C are not routed, so we
- * just fake it as INTA and than we take care of handling it
- * correctly in the IRQ demux routine.
- */
-static irq_table pci_sec_d_irq_table[] = {
-/* Pin: A B C D */
- { INTA, INTA, INTA, INTD }, /* PCI Slot J1 */
- { INTA, INTA, INTD, INTA }, /* PCI Slot J5 */
- { INTE, INTE, INTE, INTE }, /* P2P Bridge */
-};
-
-static irq_table pci_sec_f_irq_table[] = {
-/* Pin: A B C D */
- { INTA, INTB, INTC, INTD }, /* PCI Slot J1 */
- { INTB, INTC, INTD, INTA }, /* PCI Slot J5 */
- { INTE, INTE, INTE, INTE }, /* P2P Bridge */
-};
-
-static int __init
-iq80310_sec_map_irq(struct pci_dev *dev, u8 idsel, u8 pin)
-{
- irq_table *pci_irq_table;
-
- BUG_ON(pin < 1 || pin > 4);
-
- if (!system_rev) {
- pci_irq_table = pci_sec_d_irq_table;
- } else {
- pci_irq_table = pci_sec_f_irq_table;
- }
-
- return PCI_IRQ_TABLE_LOOKUP(0, 2);
-}
-
-static int iq80310_pri_host;
-
-static int iq80310_setup(int nr, struct pci_sys_data *sys)
-{
- switch (nr) {
- case 0:
- if (!iq80310_pri_host)
- return 0;
-
- sys->map_irq = iq80310_pri_map_irq;
- break;
-
- case 1:
- sys->map_irq = iq80310_sec_map_irq;
- break;
-
- default:
- return 0;
- }
-
- return iop310_setup(nr, sys);
-}
-
-static void iq80310_preinit(void)
-{
- iq80310_pri_host = *(volatile u32 *)IQ80310_BACKPLANE & 1;
-
- printk(KERN_INFO "PCI: IQ80310 is a%s\n",
- iq80310_pri_host ? " system controller" : "n agent");
-
- iop310_init();
-}
-
-static struct hw_pci iq80310_pci __initdata = {
- .swizzle = pci_std_swizzle,
- .nr_controllers = 2,
- .setup = iq80310_setup,
- .scan = iop310_scan_bus,
- .preinit = iq80310_preinit,
-};
-
-static int __init iq80310_pci_init(void)
-{
- if (machine_is_iq80310())
- pci_common_init(&iq80310_pci);
- return 0;
-}
-
-subsys_initcall(iq80310_pci_init);
diff --git a/arch/arm/mach-iop3xx/iq80310-time.c b/arch/arm/mach-iop3xx/iq80310-time.c
deleted file mode 100644
index 2698938d928ae1..00000000000000
--- a/arch/arm/mach-iop3xx/iq80310-time.c
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * linux/arch/arm/mach-iop3xx/time-iq80310.c
- *
- * Timer functions for IQ80310 onboard timer
- *
- * Author: Nicolas Pitre
- * Copyright: (C) 2001 MontaVista Software Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-#include <linux/kernel.h>
-#include <linux/interrupt.h>
-#include <linux/time.h>
-#include <linux/init.h>
-#include <linux/timex.h>
-
-#include <asm/hardware.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/uaccess.h>
-#include <asm/mach/irq.h>
-
-static void iq80310_write_timer (u_long val)
-{
- volatile u_char *la0 = (volatile u_char *)IQ80310_TIMER_LA0;
- volatile u_char *la1 = (volatile u_char *)IQ80310_TIMER_LA1;
- volatile u_char *la2 = (volatile u_char *)IQ80310_TIMER_LA2;
-
- *la0 = val;
- *la1 = val >> 8;
- *la2 = (val >> 16) & 0x3f;
-}
-
-static u_long iq80310_read_timer (void)
-{
- volatile u_char *la0 = (volatile u_char *)IQ80310_TIMER_LA0;
- volatile u_char *la1 = (volatile u_char *)IQ80310_TIMER_LA1;
- volatile u_char *la2 = (volatile u_char *)IQ80310_TIMER_LA2;
- volatile u_char *la3 = (volatile u_char *)IQ80310_TIMER_LA3;
- u_long b0, b1, b2, b3, val;
-
- b0 = *la0; b1 = *la1; b2 = *la2; b3 = *la3;
- b0 = (((b0 & 0x40) >> 1) | (b0 & 0x1f));
- b1 = (((b1 & 0x40) >> 1) | (b1 & 0x1f));
- b2 = (((b2 & 0x40) >> 1) | (b2 & 0x1f));
- b3 = (b3 & 0x0f);
- val = ((b0 << 0) | (b1 << 6) | (b2 << 12) | (b3 << 18));
- return val;
-}
-
-/*
- * IRQs are disabled before entering here from do_gettimeofday().
- * Note that the counter may wrap. When it does, 'elapsed' will
- * be small, but we will have a pending interrupt.
- */
-static unsigned long iq80310_gettimeoffset (void)
-{
- unsigned long elapsed, usec;
- unsigned int stat1, stat2;
-
- stat1 = *(volatile u8 *)IQ80310_INT_STAT;
- elapsed = iq80310_read_timer();
- stat2 = *(volatile u8 *)IQ80310_INT_STAT;
-
- /*
- * If an interrupt was pending before we read the timer,
- * we've already wrapped. Factor this into the time.
- * If an interrupt was pending after we read the timer,
- * it may have wrapped between checking the interrupt
- * status and reading the timer. Re-read the timer to
- * be sure its value is after the wrap.
- */
- if (stat1 & 1)
- elapsed += LATCH;
- else if (stat2 & 1)
- elapsed = LATCH + iq80310_read_timer();
-
- /*
- * Now convert them to usec.
- */
- usec = (unsigned long)(elapsed * (tick_nsec / 1000))/LATCH;
-
- return usec;
-}
-
-
-static irqreturn_t
-iq80310_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
- volatile u_char *timer_en = (volatile u_char *)IQ80310_TIMER_EN;
-
- /* clear timer interrupt */
- *timer_en &= ~2;
- *timer_en |= 2;
-
- do_timer(regs);
-
- return IRQ_HANDLED;
-}
-
-extern unsigned long (*gettimeoffset)(void);
-
-static struct irqaction timer_irq = {
- .name = "timer",
- .handler = iq80310_timer_interrupt,
-};
-
-
-void __init time_init(void)
-{
- volatile u_char *timer_en = (volatile u_char *)IQ80310_TIMER_EN;
-
- gettimeoffset = iq80310_gettimeoffset;
-
- setup_irq(IRQ_IQ80310_TIMER, &timer_irq);
-
- *timer_en = 0;
- iq80310_write_timer(LATCH);
- *timer_en |= 2;
- *timer_en |= 1;
-}
diff --git a/arch/arm/mach-iop3xx/mm.c b/arch/arm/mach-iop3xx/mm.c
deleted file mode 100644
index 110381a2041dce..00000000000000
--- a/arch/arm/mach-iop3xx/mm.c
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * linux/arch/arm/mach-iop3xx/mm.c
- *
- * Low level memory initialization for IOP310 based systems
- *
- * Author: Nicolas Pitre <npitre@mvista.com>
- *
- * Copyright 2000-2001 MontaVista Software Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- */
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/init.h>
-
-#include <asm/io.h>
-#include <asm/pgtable.h>
-#include <asm/page.h>
-
-#include <asm/mach/map.h>
-
-#ifdef CONFIG_IOP310_MU
-#include "message.h"
-#endif
-
-/*
- * Standard IO mapping for all IOP310 based systems
- */
-static struct map_desc iop80310_std_desc[] __initdata = {
- /* virtual physical length type */
- // IOP310 Memory Mapped Registers
- { 0xe8001000, 0x00001000, 0x00001000, MT_DEVICE },
- // PCI I/O Space
- { 0xfe000000, 0x90000000, 0x00020000, MT_DEVICE }
-};
-
-void __init iop310_map_io(void)
-{
- iotable_init(iop80310_std_desc, ARRAY_SIZE(iop80310_std_desc));
-}
-
-/*
- * IQ80310 specific IO mappings
- */
-#ifdef CONFIG_ARCH_IQ80310
-static struct map_desc iq80310_io_desc[] __initdata = {
- /* virtual physical length type */
- // IQ80310 On-Board Devices
- { 0xfe800000, 0xfe800000, 0x00100000, MT_DEVICE }
-};
-
-void __init iq80310_map_io(void)
-{
-#ifdef CONFIG_IOP310_MU
- /* acquiring 1MB of memory aligned on 1MB boundary for MU */
- mu_mem = __alloc_bootmem(0x100000, 0x100000, 0);
-#endif
-
- iop310_map_io();
-
- iotable_init(iq80310_io_desc, ARRAY_SIZE(iq80310_io_desc));
-}
-#endif // CONFIG_ARCH_IQ80310
-
diff --git a/arch/arm/mach-iop3xx/xs80200-irq.c b/arch/arm/mach-iop3xx/xs80200-irq.c
deleted file mode 100644
index 70304dd260f5a2..00000000000000
--- a/arch/arm/mach-iop3xx/xs80200-irq.c
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * linux/arch/arm/mach-iop3xx/xs80200-irq.c
- *
- * Generic IRQ handling for the XS80200 XScale core.
- *
- * Author: Nicolas Pitre
- * Copyright: (C) 2001 MontaVista Software Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/init.h>
-#include <linux/list.h>
-
-#include <asm/mach/irq.h>
-#include <asm/irq.h>
-#include <asm/hardware.h>
-
-static void xs80200_irq_mask (unsigned int irq)
-{
- unsigned long intctl;
- asm ("mrc p13, 0, %0, c0, c0, 0" : "=r" (intctl));
- switch (irq) {
- case IRQ_XS80200_BCU: intctl &= ~(1<<3); break;
- case IRQ_XS80200_PMU: intctl &= ~(1<<2); break;
- case IRQ_XS80200_EXTIRQ: intctl &= ~(1<<1); break;
- case IRQ_XS80200_EXTFIQ: intctl &= ~(1<<0); break;
- }
- asm ("mcr p13, 0, %0, c0, c0, 0" : : "r" (intctl));
-}
-
-static void xs80200_irq_unmask (unsigned int irq)
-{
- unsigned long intctl;
- asm ("mrc p13, 0, %0, c0, c0, 0" : "=r" (intctl));
- switch (irq) {
- case IRQ_XS80200_BCU: intctl |= (1<<3); break;
- case IRQ_XS80200_PMU: intctl |= (1<<2); break;
- case IRQ_XS80200_EXTIRQ: intctl |= (1<<1); break;
- case IRQ_XS80200_EXTFIQ: intctl |= (1<<0); break;
- }
- asm ("mcr p13, 0, %0, c0, c0, 0" : : "r" (intctl));
-}
-
-static struct irqchip xs80200_chip = {
- .ack = xs80200_irq_mask,
- .mask = xs80200_irq_mask,
- .unmask = xs80200_irq_unmask,
-};
-
-void __init xs80200_init_irq(void)
-{
- unsigned int i;
-
- asm("mcr p13, 0, %0, c0, c0, 0" : : "r" (0));
-
- for (i = 0; i < NR_XS80200_IRQS; i++) {
- set_irq_chip(i, &xs80200_chip);
- set_irq_handler(i, do_level_IRQ);
- set_irq_flags(i, IRQF_VALID);
- }
-}
diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c
index a4edbe0eb90967..24ffa323895c02 100644
--- a/arch/arm/mach-ixp4xx/common.c
+++ b/arch/arm/mach-ixp4xx/common.c
@@ -207,7 +207,7 @@ void __init ixp4xx_init_irq(void)
static unsigned volatile last_jiffy_time;
-#define CLOCK_TICKS_PER_USEC (CLOCK_TICK_RATE / USEC_PER_SEC)
+#define CLOCK_TICKS_PER_USEC ((CLOCK_TICK_RATE + USEC_PER_SEC/2) / USEC_PER_SEC)
/* IRQs are disabled before entering here from do_gettimeofday() */
static unsigned long ixp4xx_gettimeoffset(void)
diff --git a/arch/arm/mach-omap/Makefile b/arch/arm/mach-omap/Makefile
index 5fcb1e5c76270d..b483092dd2832e 100644
--- a/arch/arm/mach-omap/Makefile
+++ b/arch/arm/mach-omap/Makefile
@@ -3,25 +3,29 @@
#
# Common support
-obj-y := common.o irq.o dma.o clocks.o mux.o bus.o gpio.o time.o
+obj-y := common.o time.o irq.o dma.o clocks.o mux.o gpio.o mcbsp.o
obj-m :=
obj-n :=
obj- :=
led-y := leds.o
# Specific board support
+obj-$(CONFIG_MACH_OMAP_H2) += board-h2.o
obj-$(CONFIG_MACH_OMAP_INNOVATOR) += board-innovator.o
obj-$(CONFIG_MACH_OMAP_GENERIC) += board-generic.o
obj-$(CONFIG_MACH_OMAP_PERSEUS2) += board-perseus2.o
obj-$(CONFIG_MACH_OMAP_OSK) += board-osk.o
+obj-$(CONFIG_MACH_OMAP_H3) += board-h3.o
-# OCPI interconnect support for 1610 and 5912
+# OCPI interconnect support for 1710, 1610 and 5912
+obj-$(CONFIG_ARCH_OMAP1710) += ocpi.o
obj-$(CONFIG_ARCH_OMAP1610) += ocpi.o
obj-$(CONFIG_ARCH_OMAP5912) += ocpi.o
# LEDs support
+led-$(CONFIG_MACH_OMAP_H2) += leds-h2p2-debug.o
led-$(CONFIG_MACH_OMAP_INNOVATOR) += leds-innovator.o
-led-$(CONFIG_MACH_OMAP_PERSEUS2) += leds-perseus2.o
+led-$(CONFIG_MACH_OMAP_PERSEUS2) += leds-h2p2-debug.o
obj-$(CONFIG_LEDS) += $(led-y)
# Power Management
diff --git a/arch/arm/mach-omap/board-generic.c b/arch/arm/mach-omap/board-generic.c
index 447046b24a082d..03da924c778677 100644
--- a/arch/arm/mach-omap/board-generic.c
+++ b/arch/arm/mach-omap/board-generic.c
@@ -25,9 +25,13 @@
#include <asm/arch/clocks.h>
#include <asm/arch/gpio.h>
#include <asm/arch/mux.h>
+#include <asm/arch/usb.h>
+#include <asm/arch/board.h>
#include "common.h"
+extern void __init omap_init_time(void);
+
static void __init omap_generic_init_irq(void)
{
omap_init_irq();
@@ -36,17 +40,49 @@ static void __init omap_generic_init_irq(void)
/*
* Muxes the serial ports on
*/
+#ifdef CONFIG_ARCH_OMAP1510
static void __init omap_early_serial_init(void)
{
+#ifdef CONFIG_OMAP_LL_DEBUG_UART1
omap_cfg_reg(UART1_TX);
omap_cfg_reg(UART1_RTS);
+#endif
+#ifdef CONFIG_OMAP_LL_DEBUG_UART2
omap_cfg_reg(UART2_TX);
omap_cfg_reg(UART2_RTS);
+#endif
+#ifdef CONFIG_OMAP_LL_DEBUG_UART1
omap_cfg_reg(UART3_TX);
omap_cfg_reg(UART3_RX);
+#endif
}
+#endif
+
+/* assume no Mini-AB port */
+
+#ifdef CONFIG_ARCH_OMAP1510
+static struct omap_usb_config generic1510_usb_config __initdata = {
+ .register_host = 1,
+ .register_dev = 1,
+ .hmc_mode = 16,
+ .pins[0] = 3,
+};
+#endif
+
+#ifdef CONFIG_ARCH_OMAP1610
+static struct omap_usb_config generic1610_usb_config __initdata = {
+ .register_host = 1,
+ .register_dev = 1,
+ .hmc_mode = 16,
+ .pins[0] = 6,
+};
+#endif
+
+static struct omap_board_config_kernel generic_config[] = {
+ { OMAP_TAG_USB, NULL },
+};
static void __init omap_generic_init(void)
{
@@ -55,9 +91,19 @@ static void __init omap_generic_init(void)
* You have to mux them off in device drivers later on
* if not needed.
*/
+#ifdef CONFIG_ARCH_OMAP1510
if (cpu_is_omap1510()) {
omap_early_serial_init();
+ generic_config[0].data = &generic1510_usb_config;
}
+#endif
+#ifdef CONFIG_ARCH_OMAP1610
+ if (!cpu_is_omap1510()) {
+ generic_config[0].data = &generic1610_usb_config;
+ }
+#endif
+ omap_board_config = generic_config;
+ omap_board_config_size = ARRAY_SIZE(generic_config);
}
static void __init omap_generic_map_io(void)
@@ -65,18 +111,12 @@ static void __init omap_generic_map_io(void)
omap_map_io();
}
-static void __init omap_generic_init_time(void)
-{
- omap_init_time();
-}
-
-MACHINE_START(OMAP_GENERIC, "Generic OMAP-1510/1610/1710")
+MACHINE_START(OMAP_GENERIC, "Generic OMAP1510/1610/1710")
MAINTAINER("Tony Lindgren <tony@atomide.com>")
BOOT_MEM(0x10000000, 0xfff00000, 0xfef00000)
BOOT_PARAMS(0x10000100)
MAPIO(omap_generic_map_io)
INITIRQ(omap_generic_init_irq)
INIT_MACHINE(omap_generic_init)
- INITTIME(omap_generic_init_time)
+ INITTIME(omap_init_time)
MACHINE_END
-
diff --git a/arch/arm/mach-omap/board-h2.c b/arch/arm/mach-omap/board-h2.c
new file mode 100644
index 00000000000000..1441089d94fa0b
--- /dev/null
+++ b/arch/arm/mach-omap/board-h2.c
@@ -0,0 +1,115 @@
+/*
+ * linux/arch/arm/mach-omap/board-h2.c
+ *
+ * Board specific inits for OMAP-1610 H2
+ *
+ * Copyright (C) 2001 RidgeRun, Inc.
+ * Author: Greg Lonnon <glonnon@ridgerun.com>
+ *
+ * Copyright (C) 2002 MontaVista Software, Inc.
+ *
+ * Separated FPGA interrupts from innovator1510.c and cleaned up for 2.6
+ * Copyright (C) 2004 Nokia Corporation by Tony Lindrgen <tony@atomide.com>
+ *
+ * H2 specific changes and cleanup
+ * Copyright (C) 2004 Nokia Corporation by Imre Deak <imre.deak@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <asm/arch/clocks.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/usb.h>
+
+#include "common.h"
+
+extern void __init omap_init_time(void);
+
+static struct map_desc h2_io_desc[] __initdata = {
+{ OMAP1610_ETHR_BASE, OMAP1610_ETHR_START, OMAP1610_ETHR_SIZE,MT_DEVICE },
+{ OMAP1610_NOR_FLASH_BASE, OMAP1610_NOR_FLASH_START, OMAP1610_NOR_FLASH_SIZE,
+ MT_DEVICE },
+};
+
+static struct resource h2_smc91x_resources[] = {
+ [0] = {
+ .start = OMAP1610_ETHR_START, /* Physical */
+ .end = OMAP1610_ETHR_START + SZ_4K,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 0, /* Really GPIO 0 */
+ .end = 0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device h2_smc91x_device = {
+ .name = "smc91x",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(h2_smc91x_resources),
+ .resource = h2_smc91x_resources,
+};
+
+static struct platform_device *h2_devices[] __initdata = {
+ &h2_smc91x_device,
+};
+
+void h2_init_irq(void)
+{
+ omap_init_irq();
+}
+
+static struct omap_usb_config h2_usb_config __initdata = {
+ /* usb1 has a Mini-AB port and external isp1301 transceiver */
+ .otg = 2,
+
+#ifdef CONFIG_USB_GADGET_OMAP
+ .hmc_mode = 19, // 0:host(off) 1:dev|otg 2:disabled
+ // .hmc_mode = 21, // 0:host(off) 1:dev(loopback) 2:host(loopback)
+#elif defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+ /* NONSTANDARD CABLE NEEDED (B-to-Mini-B) */
+ .hmc_mode = 20, // 1:dev|otg(off) 1:host 2:disabled
+#endif
+
+ .pins[1] = 3,
+};
+
+static struct omap_board_config_kernel h2_config[] = {
+ { OMAP_TAG_USB, &h2_usb_config },
+};
+
+static void __init h2_init(void)
+{
+ platform_add_devices(h2_devices, ARRAY_SIZE(h2_devices));
+ omap_board_config = h2_config;
+ omap_board_config_size = ARRAY_SIZE(h2_config);
+}
+
+static void __init h2_map_io(void)
+{
+ omap_map_io();
+ iotable_init(h2_io_desc, ARRAY_SIZE(h2_io_desc));
+}
+
+MACHINE_START(OMAP_H2, "TI-H2")
+ MAINTAINER("Imre Deak <imre.deak@nokia.com>")
+ BOOT_MEM(0x10000000, 0xfff00000, 0xfef00000)
+ BOOT_PARAMS(0x10000100)
+ MAPIO(h2_map_io)
+ INITIRQ(h2_init_irq)
+ INIT_MACHINE(h2_init)
+ INITTIME(omap_init_time)
+MACHINE_END
diff --git a/arch/arm/mach-omap/board-h3.c b/arch/arm/mach-omap/board-h3.c
new file mode 100644
index 00000000000000..d573b0cdf4bb33
--- /dev/null
+++ b/arch/arm/mach-omap/board-h3.c
@@ -0,0 +1,90 @@
+/*
+ * linux/arch/arm/mach-omap/board-h3.c
+ *
+ * This file contains OMAP1710 H3 specific code.
+ *
+ * Copyright (C) 2004 Texas Instruments, Inc.
+ * Copyright (C) 2002 MontaVista Software, Inc.
+ * Copyright (C) 2001 RidgeRun, Inc.
+ * Author: RidgeRun, Inc.
+ * Greg Lonnon (glonnon@ridgerun.com) or info@ridgerun.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/major.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+
+#include <asm/setup.h>
+#include <asm/page.h>
+#include <asm/hardware.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/arch/irqs.h>
+#include <asm/arch/gpio.h>
+#include <asm/mach-types.h>
+#include "common.h"
+
+extern void __init omap_init_time(void);
+
+void h3_init_irq(void)
+{
+ omap_init_irq();
+}
+
+static struct resource smc91x_resources[] = {
+ [0] = {
+ .start = OMAP1710_ETHR_START, /* Physical */
+ .end = OMAP1710_ETHR_START + OMAP1710_ETHR_SIZE,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 0,
+ .end = 0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device smc91x_device = {
+ .name = "smc91x",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(smc91x_resources),
+ .resource = smc91x_resources,
+};
+
+static struct platform_device *devices[] __initdata = {
+ &smc91x_device,
+};
+
+static void __init h3_init(void)
+{
+ (void) platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+static struct map_desc h3_io_desc[] __initdata = {
+{ OMAP1710_ETHR_BASE, OMAP1710_ETHR_START, OMAP1710_ETHR_SIZE, MT_DEVICE },
+{ OMAP_NOR_FLASH_BASE, OMAP_NOR_FLASH_START, OMAP_NOR_FLASH_SIZE, MT_DEVICE },
+};
+
+static void __init h3_map_io(void)
+{
+ omap_map_io();
+ iotable_init(h3_io_desc, ARRAY_SIZE(h3_io_desc));
+}
+
+MACHINE_START(OMAP_H3, "TI OMAP1710 H3 board")
+ MAINTAINER("Texas Instruments, Inc.")
+ BOOT_MEM(0x10000000, 0xfff00000, 0xfef00000)
+ BOOT_PARAMS(0x10000100)
+ MAPIO(h3_map_io)
+ INITIRQ(h3_init_irq)
+ INIT_MACHINE(h3_init)
+ INITTIME(omap_init_time)
+MACHINE_END
diff --git a/arch/arm/mach-omap/board-innovator.c b/arch/arm/mach-omap/board-innovator.c
index 6ef4d8dcf90398..8fd97e7af54972 100644
--- a/arch/arm/mach-omap/board-innovator.c
+++ b/arch/arm/mach-omap/board-innovator.c
@@ -29,9 +29,12 @@
#include <asm/arch/clocks.h>
#include <asm/arch/gpio.h>
#include <asm/arch/fpga.h>
+#include <asm/arch/usb.h>
#include "common.h"
+extern void __init omap_init_time(void);
+
#ifdef CONFIG_ARCH_OMAP1510
extern int omap_gpio_init(void);
@@ -49,8 +52,8 @@ static struct resource innovator1510_smc91x_resources[] = {
.flags = IORESOURCE_MEM,
},
[1] = {
- .start = INT_ETHER,
- .end = INT_ETHER,
+ .start = OMAP1510_INT_ETHER,
+ .end = OMAP1510_INT_ETHER,
.flags = IORESOURCE_IRQ,
},
};
@@ -108,11 +111,43 @@ void innovator_init_irq(void)
#ifdef CONFIG_ARCH_OMAP1510
if (cpu_is_omap1510()) {
omap_gpio_init();
- fpga_init_irq();
+ omap1510_fpga_init_irq();
}
#endif
}
+#ifdef CONFIG_ARCH_OMAP1510
+static struct omap_usb_config innovator1510_usb_config __initdata = {
+ /* has usb host and device, but no Mini-AB port */
+ .register_host = 1,
+ .register_dev = 1,
+ /* Assume bad Innovator wiring; Use internal host only with custom cable */
+ .hmc_mode = 16,
+ .pins[0] = 2,
+};
+#endif
+
+#ifdef CONFIG_ARCH_OMAP1610
+static struct omap_usb_config h2_usb_config __initdata = {
+ /* usb1 has a Mini-AB port and external isp1301 transceiver */
+ .otg = 2,
+
+#ifdef CONFIG_USB_GADGET_OMAP
+ .hmc_mode = 19, // 0:host(off) 1:dev|otg 2:disabled
+ // .hmc_mode = 21, // 0:host(off) 1:dev(loopback) 2:host(loopback)
+#elif defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+ /* NONSTANDARD CABLE NEEDED (B-to-Mini-B) */
+ .hmc_mode = 20, // 1:dev|otg(off) 1:host 2:disabled
+#endif
+
+ .pins[1] = 3,
+};
+#endif
+
+static struct omap_board_config_kernel innovator_config[] = {
+ { OMAP_TAG_USB, NULL },
+};
+
static void __init innovator_init(void)
{
#ifdef CONFIG_ARCH_OMAP1510
@@ -121,10 +156,21 @@ static void __init innovator_init(void)
}
#endif
#ifdef CONFIG_ARCH_OMAP1610
- if (cpu_is_omap1610()) {
+ if (!cpu_is_omap1510()) {
platform_add_devices(innovator1610_devices, ARRAY_SIZE(innovator1610_devices));
}
#endif
+
+#ifdef CONFIG_ARCH_OMAP1510
+ if (cpu_is_omap1510())
+ innovator_config[0].data = &innovator1510_usb_config;
+#endif
+#ifdef CONFIG_ARCH_OMAP1610
+ if (cpu_is_omap1610())
+ innovator_config[0].data = &h2_usb_config;
+#endif
+ omap_board_config = innovator_config;
+ omap_board_config_size = ARRAY_SIZE(innovator_config);
}
static void __init innovator_map_io(void)
@@ -144,7 +190,7 @@ static void __init innovator_map_io(void)
}
#endif
#ifdef CONFIG_ARCH_OMAP1610
- if (cpu_is_omap1610()) {
+ if (!cpu_is_omap1510()) {
iotable_init(innovator1610_io_desc, ARRAY_SIZE(innovator1610_io_desc));
}
#endif
@@ -156,6 +202,6 @@ MACHINE_START(OMAP_INNOVATOR, "TI-Innovator")
BOOT_PARAMS(0x10000100)
MAPIO(innovator_map_io)
INITIRQ(innovator_init_irq)
- INITTIME(omap_init_time)
INIT_MACHINE(innovator_init)
+ INITTIME(omap_init_time)
MACHINE_END
diff --git a/arch/arm/mach-omap/board-osk.c b/arch/arm/mach-omap/board-osk.c
index 16ecd6be5a6099..85d9a0ac33e32d 100644
--- a/arch/arm/mach-omap/board-osk.c
+++ b/arch/arm/mach-omap/board-osk.c
@@ -41,6 +41,8 @@
#include "common.h"
+extern void __init omap_init_time(void);
+
static struct map_desc osk5912_io_desc[] __initdata = {
{ OMAP_OSK_ETHR_BASE, OMAP_OSK_ETHR_START, OMAP_OSK_ETHR_SIZE,MT_DEVICE },
{ OMAP_OSK_NOR_FLASH_BASE, OMAP_OSK_NOR_FLASH_START, OMAP_OSK_NOR_FLASH_SIZE,
@@ -94,6 +96,6 @@ MACHINE_START(OMAP_OSK, "TI-OSK")
BOOT_PARAMS(0x10000100)
MAPIO(osk_map_io)
INITIRQ(osk_init_irq)
- INITTIME(omap_init_time)
INIT_MACHINE(osk_init)
+ INITTIME(omap_init_time)
MACHINE_END
diff --git a/arch/arm/mach-omap/board-perseus2.c b/arch/arm/mach-omap/board-perseus2.c
index 8015d10fc75e30..95833f3b942325 100644
--- a/arch/arm/mach-omap/board-perseus2.c
+++ b/arch/arm/mach-omap/board-perseus2.c
@@ -23,9 +23,12 @@
#include <asm/arch/clocks.h>
#include <asm/arch/gpio.h>
#include <asm/arch/mux.h>
+#include <asm/arch/fpga.h>
#include "common.h"
+extern void __init omap_init_time(void);
+
void omap_perseus2_init_irq(void)
{
omap_init_irq();
@@ -33,14 +36,14 @@ void omap_perseus2_init_irq(void)
static struct resource smc91x_resources[] = {
[0] = {
- .start = OMAP730_FPGA_ETHR_START, /* Physical */
- .end = OMAP730_FPGA_ETHR_START + SZ_4K,
+ .start = H2P2_DBG_FPGA_ETHR_START, /* Physical */
+ .end = H2P2_DBG_FPGA_ETHR_START + SZ_4K,
.flags = IORESOURCE_MEM,
},
[1] = {
- .start = 0,
+ .start = INT_730_MPU_EXT_NIRQ,
.end = 0,
- .flags = INT_ETHER,
+ .flags = IORESOURCE_IRQ,
},
};
@@ -62,7 +65,7 @@ static void __init omap_perseus2_init(void)
/* Only FPGA needs to be mapped here. All others are done with ioremap */
static struct map_desc omap_perseus2_io_desc[] __initdata = {
- {OMAP730_FPGA_BASE, OMAP730_FPGA_START, OMAP730_FPGA_SIZE,
+ {H2P2_DBG_FPGA_BASE, H2P2_DBG_FPGA_START, H2P2_DBG_FPGA_SIZE,
MT_DEVICE},
};
@@ -111,6 +114,6 @@ MACHINE_START(OMAP_PERSEUS2, "OMAP730 Perseus2")
BOOT_PARAMS(0x10000100)
MAPIO(omap_perseus2_map_io)
INITIRQ(omap_perseus2_init_irq)
- INITTIME(omap_init_time)
INIT_MACHINE(omap_perseus2_init)
+ INITTIME(omap_init_time)
MACHINE_END
diff --git a/arch/arm/mach-omap/bus.c b/arch/arm/mach-omap/bus.c
deleted file mode 100644
index 24a57f2a8dd04a..00000000000000
--- a/arch/arm/mach-omap/bus.c
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * linux/arch/arm/mach-omap/bus.c
- *
- * Virtual bus for OMAP. Allows better power management, such as managing
- * shared clocks, and mapping of bus addresses to Local Bus addresses.
- *
- * See drivers/usb/host/ohci-omap.c or drivers/video/omap/omapfb.c for
- * examples on how to register drivers to this bus.
- *
- * Copyright (C) 2003 - 2004 Nokia Corporation
- * Written by Tony Lindgren <tony@atomide.com>
- * Portions of code based on sa1111.c.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/delay.h>
-#include <linux/ptrace.h>
-#include <linux/errno.h>
-#include <linux/ioport.h>
-#include <linux/device.h>
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-
-#include <asm/hardware.h>
-#include <asm/mach-types.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/mach/irq.h>
-
-#include <asm/arch/bus.h>
-
-static int omap_bus_match(struct device *_dev, struct device_driver *_drv);
-static int omap_bus_suspend(struct device *dev, u32 state);
-static int omap_bus_resume(struct device *dev);
-
-/*
- * OMAP bus definitions
- *
- * NOTE: Most devices should use TIPB. LBUS does automatic address mapping
- * to Local Bus addresses, and should only be used for Local Bus devices.
- * We may add new buses later on for power management reasons. Basically
- * we want to be able to turn off any bus if it's not used by device
- * drivers.
- */
-static struct device omap_bus_devices[OMAP_NR_BUSES] = {
- {
- .bus_id = OMAP_BUS_NAME_TIPB
- }, {
- .bus_id = OMAP_BUS_NAME_LBUS
- },
-};
-
-static struct bus_type omap_bus_types[OMAP_NR_BUSES] = {
- {
- .name = OMAP_BUS_NAME_TIPB,
- .match = omap_bus_match,
- .suspend = omap_bus_suspend,
- .resume = omap_bus_resume,
- }, {
- .name = OMAP_BUS_NAME_LBUS, /* Local bus on 1510 */
- .match = omap_bus_match,
- .suspend = omap_bus_suspend,
- .resume = omap_bus_resume,
- },
-};
-
-static int omap_bus_match(struct device *dev, struct device_driver *drv)
-{
- struct omap_dev *omapdev = OMAP_DEV(dev);
- struct omap_driver *omapdrv = OMAP_DRV(drv);
-
- return omapdev->devid == omapdrv->devid;
-}
-
-static int omap_bus_suspend(struct device *dev, u32 state)
-{
- struct omap_dev *omapdev = OMAP_DEV(dev);
- struct omap_driver *omapdrv = OMAP_DRV(dev->driver);
- int ret = 0;
-
- if (omapdrv && omapdrv->suspend)
- ret = omapdrv->suspend(omapdev, state);
- return ret;
-}
-
-static int omap_bus_resume(struct device *dev)
-{
- struct omap_dev *omapdev = OMAP_DEV(dev);
- struct omap_driver *omapdrv = OMAP_DRV(dev->driver);
- int ret = 0;
-
- if (omapdrv && omapdrv->resume)
- ret = omapdrv->resume(omapdev);
- return ret;
-}
-
-static int omap_device_probe(struct device *dev)
-{
- struct omap_dev *omapdev = OMAP_DEV(dev);
- struct omap_driver *omapdrv = OMAP_DRV(dev->driver);
- int ret = -ENODEV;
-
- if (omapdrv && omapdrv->probe)
- ret = omapdrv->probe(omapdev);
-
- return ret;
-}
-
-static int omap_device_remove(struct device *dev)
-{
- struct omap_dev *omapdev = OMAP_DEV(dev);
- struct omap_driver *omapdrv = OMAP_DRV(dev->driver);
- int ret = 0;
-
- if (omapdrv && omapdrv->remove)
- ret = omapdrv->remove(omapdev);
- return ret;
-}
-
-int omap_device_register(struct omap_dev *odev)
-{
- if (!odev)
- return -EINVAL;
-
- if (odev->busid < 0 || odev->busid >= OMAP_NR_BUSES) {
- printk(KERN_ERR "%s: busid invalid: %s: bus: %i\n",
- __FUNCTION__, odev->name, odev->busid);
- return -EINVAL;
- }
-
- odev->dev.parent = &omap_bus_devices[odev->busid];
- odev->dev.bus = &omap_bus_types[odev->busid];
-
- /* This is needed for USB OHCI to work */
- if (odev->dma_mask)
- odev->dev.dma_mask = odev->dma_mask;
-
- if (odev->coherent_dma_mask)
- odev->dev.coherent_dma_mask = odev->coherent_dma_mask;
-
- snprintf(odev->dev.bus_id, BUS_ID_SIZE, "%s%u",
- odev->name, odev->devid);
-
- printk("Registering OMAP device '%s'. Parent at %s\n",
- odev->dev.bus_id, odev->dev.parent->bus_id);
-
- return device_register(&odev->dev);
-}
-
-void omap_device_unregister(struct omap_dev *odev)
-{
- if (odev)
- device_unregister(&odev->dev);
-}
-
-int omap_driver_register(struct omap_driver *driver)
-{
- int ret;
-
- if (driver->busid < 0 || driver->busid >= OMAP_NR_BUSES) {
- printk(KERN_ERR "%s: busid invalid: bus: %i device: %i\n",
- __FUNCTION__, driver->busid, driver->devid);
- return -EINVAL;
- }
-
- driver->drv.probe = omap_device_probe;
- driver->drv.remove = omap_device_remove;
- driver->drv.bus = &omap_bus_types[driver->busid];
-
- /*
- * driver_register calls bus_add_driver
- */
- ret = driver_register(&driver->drv);
-
- return ret;
-}
-
-void omap_driver_unregister(struct omap_driver *driver)
-{
- driver_unregister(&driver->drv);
-}
-
-static int __init omap_bus_init(void)
-{
- int i, ret;
-
- /* Initialize all OMAP virtual buses */
- for (i = 0; i < OMAP_NR_BUSES; i++) {
- ret = device_register(&omap_bus_devices[i]);
- if (ret != 0) {
- printk(KERN_ERR "Unable to register bus device %s\n",
- omap_bus_devices[i].bus_id);
- continue;
- }
- ret = bus_register(&omap_bus_types[i]);
- if (ret != 0) {
- printk(KERN_ERR "Unable to register bus %s\n",
- omap_bus_types[i].name);
- device_unregister(&omap_bus_devices[i]);
- }
- }
- printk("OMAP virtual buses initialized\n");
-
- return ret;
-}
-
-static void __exit omap_bus_exit(void)
-{
- int i;
-
- /* Unregister all OMAP virtual buses */
- for (i = 0; i < OMAP_NR_BUSES; i++) {
- bus_unregister(&omap_bus_types[i]);
- device_unregister(&omap_bus_devices[i]);
- }
-}
-
-postcore_initcall(omap_bus_init);
-module_exit(omap_bus_exit);
-
-MODULE_DESCRIPTION("Virtual bus for OMAP");
-MODULE_LICENSE("GPL");
-
-EXPORT_SYMBOL(omap_bus_types);
-EXPORT_SYMBOL(omap_driver_register);
-EXPORT_SYMBOL(omap_driver_unregister);
-EXPORT_SYMBOL(omap_device_register);
-EXPORT_SYMBOL(omap_device_unregister);
-
diff --git a/arch/arm/mach-omap/clocks.c b/arch/arm/mach-omap/clocks.c
index bda7c6f381ee3c..b507856597321c 100644
--- a/arch/arm/mach-omap/clocks.c
+++ b/arch/arm/mach-omap/clocks.c
@@ -36,6 +36,8 @@
#include <asm/arch/clocks.h>
#include <asm/arch/board.h>
+extern void start_mputimer1(unsigned long load_val);
+
/* Input clock in MHz */
static unsigned int source_clock = 12;
@@ -239,7 +241,7 @@ int ck_auto_unclock = 1;
int ck_debug = 0;
#define CK_MAX_PLL_FREQ OMAP_CK_MAX_RATE
-static __u8 ck_valid_table[CK_MAX_PLL_FREQ / 8 + 1];
+static __u32 ck_valid_table[CK_MAX_PLL_FREQ / 32 + 1];
static __u8 ck_lookup_table[CK_MAX_PLL_FREQ];
int
@@ -615,11 +617,11 @@ __ck_make_lookup_table(void)
int __init
init_ck(void)
{
- const struct omap_clock_info *info;
+ const struct omap_clock_config *info;
int crystal_type = 0; /* Default 12 MHz */
__ck_make_lookup_table();
- info = omap_get_per_info(OMAP_TAG_CLOCK, struct omap_clock_info);
+ info = omap_get_config(OMAP_TAG_CLOCK, struct omap_clock_config);
if (info != NULL) {
if (!cpu_is_omap1510())
crystal_type = info->system_clock_type;
@@ -645,7 +647,8 @@ init_ck(void)
#elif defined(CONFIG_OMAP_ARM_182MHZ) && defined(CONFIG_ARCH_OMAP730)
omap_writew(0x250E, ARM_CKCTL);
omap_writew(0x2710, DPLL_CTL);
-#elif defined(CONFIG_OMAP_ARM_192MHZ) && (defined(CONFIG_ARCH_OMAP1610) || defined(CONFIG_ARCH_OMAP5912))
+#elif defined(CONFIG_OMAP_ARM_192MHZ) && (defined(CONFIG_ARCH_OMAP1610) || defined(CONFIG_ARCH_OMAP5912) \
+ || defined(CONFIG_ARCH_OMAP1710))
omap_writew(0x150f, ARM_CKCTL);
if (crystal_type == 2) {
source_clock = 13; /* MHz */
diff --git a/arch/arm/mach-omap/common.c b/arch/arm/mach-omap/common.c
index 43aaa1c6c5458b..17d82a7f3a3f8d 100644
--- a/arch/arm/mach-omap/common.c
+++ b/arch/arm/mach-omap/common.c
@@ -104,7 +104,7 @@ static struct map_desc omap1510_io_desc[] __initdata = {
};
#endif
-#ifdef CONFIG_ARCH_OMAP1610
+#if defined(CONFIG_ARCH_OMAP1610) || defined(CONFIG_ARCH_OMAP1710)
static struct map_desc omap1610_io_desc[] __initdata = {
{ OMAP1610_DSP_BASE, OMAP1610_DSP_START, OMAP1610_DSP_SIZE, MT_DEVICE },
{ OMAP1610_DSPREG_BASE, OMAP1610_DSPREG_START, OMAP1610_DSPREG_SIZE, MT_DEVICE },
@@ -147,8 +147,8 @@ static void __init _omap_map_io(void)
iotable_init(omap1510_io_desc, ARRAY_SIZE(omap1510_io_desc));
}
#endif
-#ifdef CONFIG_ARCH_OMAP1610
- if (cpu_is_omap1610()) {
+#if defined(CONFIG_ARCH_OMAP1610) || defined(CONFIG_ARCH_OMAP1710)
+ if (cpu_is_omap1610() || cpu_is_omap1710()) {
iotable_init(omap1610_io_desc, ARRAY_SIZE(omap1610_io_desc));
}
#endif
@@ -181,13 +181,18 @@ void omap_map_io(void)
extern int omap_bootloader_tag_len;
extern u8 omap_bootloader_tag[];
-const void *__omap_get_per_info(u16 tag, size_t len)
+struct omap_board_config_kernel *omap_board_config;
+int omap_board_config_size = 0;
+
+const void *__omap_get_config(u16 tag, size_t len)
{
- struct omap_board_info_entry *info = NULL;
+ struct omap_board_config_entry *info = NULL;
+ struct omap_board_config_kernel *kinfo = NULL;
+ int i;
#ifdef CONFIG_OMAP_BOOT_TAG
if (omap_bootloader_tag_len > 4)
- info = (struct omap_board_info_entry *) omap_bootloader_tag;
+ info = (struct omap_board_config_entry *) omap_bootloader_tag;
while (info != NULL) {
u8 *next;
@@ -198,26 +203,38 @@ const void *__omap_get_per_info(u16 tag, size_t len)
if (next >= omap_bootloader_tag + omap_bootloader_tag_len)
info = NULL;
else
- info = (struct omap_board_info_entry *) next;
+ info = (struct omap_board_config_entry *) next;
+ }
+ if (info != NULL) {
+ /* Check the length as a lame attempt to check for
+ * binary inconsistancy. */
+ if (info->len != len) {
+ printk(KERN_ERR "OMAP peripheral config: Length mismatch with tag %x (want %d, got %d)\n",
+ tag, len, info->len);
+ return NULL;
+ }
+ return info->data;
}
#endif
- if (info == NULL)
- return NULL;
- if (info->len != len) {
- printk(KERN_ERR "OMAP per_info: Length mismatch with tag %x (want %d, got %d)\n",
- tag, len, info->len);
- return NULL;
+ /* Try to find the config from the board-specific structures
+ * in the kernel. */
+ for (i = 0; i < omap_board_config_size; i++) {
+ if (omap_board_config[i].tag == tag) {
+ kinfo = &omap_board_config[i];
+ break;
+ }
}
-
- return info->data;
+ if (kinfo == NULL)
+ return NULL;
+ return kinfo->data;
}
-EXPORT_SYMBOL(__omap_get_per_info);
+EXPORT_SYMBOL(__omap_get_config);
static int __init omap_add_serial_console(void)
{
- const struct omap_uart_info *info;
+ const struct omap_uart_config *info;
- info = omap_get_per_info(OMAP_TAG_UART, struct omap_uart_info);
+ info = omap_get_config(OMAP_TAG_UART, struct omap_uart_config);
if (info != NULL && info->console_uart) {
static char speed[11], *opt = NULL;
diff --git a/arch/arm/mach-omap/common.h b/arch/arm/mach-omap/common.h
index 96dcb3c5397360..1cc559dd2f8172 100644
--- a/arch/arm/mach-omap/common.h
+++ b/arch/arm/mach-omap/common.h
@@ -28,7 +28,6 @@
#define __ARCH_ARM_MACH_OMAP_COMMON_H
extern void omap_map_io(void);
-extern void omap_init_time(void);
#endif /* __ARCH_ARM_MACH_OMAP_COMMON_H */
diff --git a/arch/arm/mach-omap/dma.c b/arch/arm/mach-omap/dma.c
index 385b4d1cc055c9..cfb23d894a958a 100644
--- a/arch/arm/mach-omap/dma.c
+++ b/arch/arm/mach-omap/dma.c
@@ -118,7 +118,7 @@ void omap_set_dma_constant_fill(int lch, u32 color)
u16 w;
#ifdef CONFIG_DEBUG_KERNEL
- if (omap_dma_in_1510_mode) {
+ if (omap_dma_in_1510_mode()) {
printk(KERN_ERR "OMAP DMA constant fill not available in 1510 mode.");
BUG();
return;
@@ -141,7 +141,7 @@ void omap_set_dma_transparent_copy(int lch, u32 color)
u16 w;
#ifdef CONFIG_DEBUG_KERNEL
- if (omap_dma_in_1510_mode) {
+ if (omap_dma_in_1510_mode()) {
printk(KERN_ERR "OMAP DMA transparent copy not available in 1510 mode.");
BUG();
}
@@ -266,46 +266,78 @@ void omap_set_dma_dest_burst_mode(int lch, int burst_mode)
omap_writew(w, OMAP_DMA_CSDP(lch));
}
-void omap_start_dma(int lch)
+static inline void init_intr(int lch)
{
u16 w;
- if (!omap_dma_in_1510_mode()) {
- int next_lch;
-
- next_lch = dma_chan[lch].next_lch;
-
- /* Enable the queue, if needed so. */
- if (next_lch != -1) {
- /* Clear the STOP_LNK bits */
- w = omap_readw(OMAP_DMA_CLNK_CTRL(lch));
- w &= ~(1 << 14);
- omap_writew(w, OMAP_DMA_CLNK_CTRL(lch));
- w = omap_readw(OMAP_DMA_CLNK_CTRL(next_lch));
- w &= ~(1 << 14);
- omap_writew(w, OMAP_DMA_CLNK_CTRL(next_lch));
-
- /* And set the ENABLE_LNK bits */
- omap_writew(next_lch | (1 << 15),
- OMAP_DMA_CLNK_CTRL(lch));
- /* The loop case */
- if (dma_chan[next_lch].next_lch == lch)
- omap_writew(lch | (1 << 15),
- OMAP_DMA_CLNK_CTRL(next_lch));
-
- /* Read CSR to make sure it's cleared. */
- w = omap_readw(OMAP_DMA_CSR(next_lch));
- /* Enable some nice interrupts. */
- omap_writew(dma_chan[next_lch].enabled_irqs,
- OMAP_DMA_CICR(next_lch));
- dma_chan[next_lch].flags |= OMAP_DMA_ACTIVE;
- }
- }
-
/* Read CSR to make sure it's cleared. */
w = omap_readw(OMAP_DMA_CSR(lch));
/* Enable some nice interrupts. */
omap_writew(dma_chan[lch].enabled_irqs, OMAP_DMA_CICR(lch));
+ dma_chan[lch].flags |= OMAP_DMA_ACTIVE;
+}
+
+static inline void enable_lnk(int lch)
+{
+ u16 w;
+
+ /* Clear the STOP_LNK bits */
+ w = omap_readw(OMAP_DMA_CLNK_CTRL(lch));
+ w &= ~(1 << 14);
+ omap_writew(w, OMAP_DMA_CLNK_CTRL(lch));
+
+ /* And set the ENABLE_LNK bits */
+ if (dma_chan[lch].next_lch != -1)
+ omap_writew(dma_chan[lch].next_lch | (1 << 15),
+ OMAP_DMA_CLNK_CTRL(lch));
+}
+
+static inline void disable_lnk(int lch)
+{
+ u16 w;
+
+ /* Disable interrupts */
+ omap_writew(0, OMAP_DMA_CICR(lch));
+
+ /* Set the STOP_LNK bit */
+ w = omap_readw(OMAP_DMA_CLNK_CTRL(lch));
+ w |= (1 << 14);
+ w = omap_writew(w, OMAP_DMA_CLNK_CTRL(lch));
+
+ dma_chan[lch].flags &= ~OMAP_DMA_ACTIVE;
+}
+
+void omap_start_dma(int lch)
+{
+ u16 w;
+
+ if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) {
+ int next_lch, cur_lch;
+ char dma_chan_link_map[OMAP_LOGICAL_DMA_CH_COUNT];
+
+ dma_chan_link_map[lch] = 1;
+ /* Set the link register of the first channel */
+ enable_lnk(lch);
+
+ memset(dma_chan_link_map, 0, sizeof(dma_chan_link_map));
+ cur_lch = dma_chan[lch].next_lch;
+ do {
+ next_lch = dma_chan[cur_lch].next_lch;
+
+ /* The loop case: we've been here already */
+ if (dma_chan_link_map[cur_lch])
+ break;
+ /* Mark the current channel */
+ dma_chan_link_map[cur_lch] = 1;
+
+ enable_lnk(cur_lch);
+ init_intr(cur_lch);
+
+ cur_lch = next_lch;
+ } while (next_lch != -1);
+ }
+
+ init_intr(lch);
w = omap_readw(OMAP_DMA_CCR(lch));
w |= OMAP_DMA_CCR_EN;
@@ -316,37 +348,34 @@ void omap_start_dma(int lch)
void omap_stop_dma(int lch)
{
u16 w;
- int next_lch;
- /* Disable all interrupts on the channel */
- omap_writew(0, OMAP_DMA_CICR(lch));
+ if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) {
+ int next_lch, cur_lch = lch;
+ char dma_chan_link_map[OMAP_LOGICAL_DMA_CH_COUNT];
- if (omap_dma_in_1510_mode()) {
- w = omap_readw(OMAP_DMA_CCR(lch));
- w &= ~OMAP_DMA_CCR_EN;
- omap_writew(w, OMAP_DMA_CCR(lch));
- dma_chan[lch].flags &= ~OMAP_DMA_ACTIVE;
- return;
- }
+ memset(dma_chan_link_map, 0, sizeof(dma_chan_link_map));
+ do {
+ /* The loop case: we've been here already */
+ if (dma_chan_link_map[cur_lch])
+ break;
+ /* Mark the current channel */
+ dma_chan_link_map[cur_lch] = 1;
- next_lch = dma_chan[lch].next_lch;
+ disable_lnk(cur_lch);
- /*
- * According to thw HW spec, enabling the STOP_LNK bit
- * resets the CCR_EN bit at the same time.
- */
- w = omap_readw(OMAP_DMA_CLNK_CTRL(lch));
- w |= (1 << 14);
- w = omap_writew(w, OMAP_DMA_CLNK_CTRL(lch));
- dma_chan[lch].flags &= ~OMAP_DMA_ACTIVE;
+ next_lch = dma_chan[cur_lch].next_lch;
+ cur_lch = next_lch;
+ } while (next_lch != -1);
- if (next_lch != -1) {
- omap_writew(0, OMAP_DMA_CICR(next_lch));
- w = omap_readw(OMAP_DMA_CLNK_CTRL(next_lch));
- w |= (1 << 14);
- w = omap_writew(w, OMAP_DMA_CLNK_CTRL(next_lch));
- dma_chan[next_lch].flags &= ~OMAP_DMA_ACTIVE;
+ return;
}
+ /* Disable all interrupts on the channel */
+ omap_writew(0, OMAP_DMA_CICR(lch));
+
+ w = omap_readw(OMAP_DMA_CCR(lch));
+ w &= ~OMAP_DMA_CCR_EN;
+ omap_writew(w, OMAP_DMA_CCR(lch));
+ dma_chan[lch].flags &= ~OMAP_DMA_ACTIVE;
}
void omap_enable_dma_irq(int lch, u16 bits)
@@ -445,7 +474,7 @@ int omap_request_dma(int dev_id, const char *dev_name,
chan->data = data;
chan->enabled_irqs = OMAP_DMA_TOUT_IRQ | OMAP_DMA_DROP_IRQ | OMAP_DMA_BLOCK_IRQ;
- if (cpu_is_omap1610() || cpu_is_omap5912()) {
+ if (cpu_is_omap1610() || cpu_is_omap5912() || cpu_is_omap730() || cpu_is_omap1710()) {
/* If the sync device is set, configure it dynamically. */
if (dev_id != 0) {
set_gdma_dev(free_ch + 1, dev_id);
@@ -533,7 +562,6 @@ void omap_dma_unlink_lch (int lch_head, int lch_queue)
}
dma_chan[lch_head].next_lch = -1;
- dma_chan[lch_queue].next_lch = -1;
}
@@ -713,7 +741,7 @@ static int __init omap_init_dma(void)
printk(KERN_INFO "DMA support for OMAP1510 initialized\n");
dma_chan_count = 9;
enable_1510_mode = 1;
- } else if (cpu_is_omap1610() || cpu_is_omap5912()) {
+ } else if (cpu_is_omap1610() || cpu_is_omap5912() || cpu_is_omap730() || cpu_is_omap1710()) {
printk(KERN_INFO "OMAP DMA hardware version %d\n",
omap_readw(OMAP_DMA_HW_ID));
printk(KERN_INFO "DMA capabilities: %08x:%08x:%04x:%04x:%04x\n",
@@ -771,6 +799,8 @@ EXPORT_SYMBOL(omap_request_dma);
EXPORT_SYMBOL(omap_free_dma);
EXPORT_SYMBOL(omap_start_dma);
EXPORT_SYMBOL(omap_stop_dma);
+EXPORT_SYMBOL(omap_enable_dma_irq);
+EXPORT_SYMBOL(omap_disable_dma_irq);
EXPORT_SYMBOL(omap_set_dma_transfer_params);
EXPORT_SYMBOL(omap_set_dma_constant_fill);
diff --git a/arch/arm/mach-omap/fpga.c b/arch/arm/mach-omap/fpga.c
index d9246b1dcc1e61..f0ce5c12a2ad96 100644
--- a/arch/arm/mach-omap/fpga.c
+++ b/arch/arm/mach-omap/fpga.c
@@ -31,19 +31,9 @@
#include <asm/arch/fpga.h>
#include <asm/arch/gpio.h>
-unsigned char fpga_read(int reg)
-{
- return __raw_readb(reg);
-}
-
-void fpga_write(unsigned char val, int reg)
-{
- __raw_writeb(val, reg);
-}
-
static void fpga_mask_irq(unsigned int irq)
{
- irq -= IH_FPGA_BASE;
+ irq -= OMAP1510_IH_FPGA_BASE;
if (irq < 8)
__raw_writeb((__raw_readb(OMAP1510_FPGA_IMR_LO)
@@ -76,7 +66,7 @@ static void fpga_ack_irq(unsigned int irq)
static void fpga_unmask_irq(unsigned int irq)
{
- irq -= IH_FPGA_BASE;
+ irq -= OMAP1510_IH_FPGA_BASE;
if (irq < 8)
__raw_writeb((__raw_readb(OMAP1510_FPGA_IMR_LO) | (1 << irq)),
@@ -114,8 +104,8 @@ void innovator_fpga_IRQ_demux(unsigned int irq, struct irqdesc *desc,
break;
}
- for (fpga_irq = IH_FPGA_BASE;
- (fpga_irq < (IH_FPGA_BASE + NR_FPGA_IRQS)) && stat;
+ for (fpga_irq = OMAP1510_IH_FPGA_BASE;
+ (fpga_irq < (OMAP1510_IH_FPGA_BASE + NR_FPGA_IRQS)) && stat;
fpga_irq++, stat >>= 1) {
if (stat & 1) {
d = irq_desc + fpga_irq;
@@ -162,7 +152,7 @@ static struct irqchip omap_fpga_irq = {
* interrupts at the interrupt controller via disable_irq/enable_irq
* could pose a problem.
*/
-void fpga_init_irq(void)
+void omap1510_fpga_init_irq(void)
{
int i;
@@ -170,9 +160,9 @@ void fpga_init_irq(void)
__raw_writeb(0, OMAP1510_FPGA_IMR_HI);
__raw_writeb(0, INNOVATOR_FPGA_IMR2);
- for (i = IH_FPGA_BASE; i < (IH_FPGA_BASE + NR_FPGA_IRQS); i++) {
+ for (i = OMAP1510_IH_FPGA_BASE; i < (OMAP1510_IH_FPGA_BASE + NR_FPGA_IRQS); i++) {
- if (i == INT_FPGA_TS) {
+ if (i == OMAP1510_INT_FPGA_TS) {
/*
* The touchscreen interrupt is level-sensitive, so
* we'll use the regular mask_ack routine for it.
@@ -201,9 +191,7 @@ void fpga_init_irq(void)
omap_request_gpio(13);
omap_set_gpio_direction(13, 1);
omap_set_gpio_edge_ctrl(13, OMAP_GPIO_RISING_EDGE);
- set_irq_chained_handler(INT_FPGA, innovator_fpga_IRQ_demux);
+ set_irq_chained_handler(OMAP1510_INT_FPGA, innovator_fpga_IRQ_demux);
}
-EXPORT_SYMBOL(fpga_init_irq);
-EXPORT_SYMBOL(fpga_read);
-EXPORT_SYMBOL(fpga_write);
+EXPORT_SYMBOL(omap1510_fpga_init_irq);
diff --git a/arch/arm/mach-omap/gpio.c b/arch/arm/mach-omap/gpio.c
index 2f052a959af178..206bee968329f2 100644
--- a/arch/arm/mach-omap/gpio.c
+++ b/arch/arm/mach-omap/gpio.c
@@ -94,7 +94,7 @@ struct gpio_bank {
#define METHOD_GPIO_1610 2
#define METHOD_GPIO_730 3
-#if defined(CONFIG_ARCH_OMAP1610) || defined(CONFIG_ARCH_OMAP5912)
+#if defined(CONFIG_ARCH_OMAP1610) || defined(CONFIG_ARCH_OMAP1710) || defined(CONFIG_ARCH_OMAP5912)
static struct gpio_bank gpio_bank_1610[5] = {
{ OMAP_MPUIO_BASE, INT_MPUIO, IH_MPUIO_BASE, METHOD_MPUIO},
{ OMAP1610_GPIO1_BASE, INT_GPIO_BANK1, IH_GPIO_BASE, METHOD_GPIO_1610 },
@@ -113,7 +113,7 @@ static struct gpio_bank gpio_bank_1510[2] = {
#ifdef CONFIG_ARCH_OMAP730
static struct gpio_bank gpio_bank_730[7] = {
- { OMAP_MPUIO_BASE, INT_MPUIO, IH_MPUIO_BASE, METHOD_MPUIO },
+ { OMAP_MPUIO_BASE, INT_730_MPUIO, IH_MPUIO_BASE, METHOD_MPUIO },
{ OMAP730_GPIO1_BASE, INT_GPIO_BANK1, IH_GPIO_BASE, METHOD_GPIO_730 },
{ OMAP730_GPIO2_BASE, INT_730_GPIO_BANK2, IH_GPIO_BASE + 32, METHOD_GPIO_730 },
{ OMAP730_GPIO3_BASE, INT_730_GPIO_BANK3, IH_GPIO_BASE + 64, METHOD_GPIO_730 },
@@ -135,8 +135,8 @@ static inline struct gpio_bank *get_gpio_bank(int gpio)
return &gpio_bank[1];
}
#endif
-#if defined(CONFIG_ARCH_OMAP1610) || defined(CONFIG_ARCH_OMAP5912)
- if (cpu_is_omap1610() || cpu_is_omap5912()) {
+#if defined(CONFIG_ARCH_OMAP1610) || defined(CONFIG_ARCH_OMAP1710) || defined(CONFIG_ARCH_OMAP5912)
+ if (cpu_is_omap1610() || cpu_is_omap1710() || cpu_is_omap5912()) {
if (OMAP_GPIO_IS_MPUIO(gpio))
return &gpio_bank[0];
return &gpio_bank[1 + (gpio >> 4)];
@@ -172,8 +172,8 @@ static inline int gpio_valid(int gpio)
if (cpu_is_omap1510() && gpio < 16)
return 0;
#endif
-#if defined(CONFIG_ARCH_OMAP1610) || defined(CONFIG_ARCH_OMAP5912)
- if ((cpu_is_omap1610() || cpu_is_omap5912()) && gpio < 64)
+#if defined(CONFIG_ARCH_OMAP1610) || defined(CONFIG_ARCH_OMAP1710) || defined(CONFIG_ARCH_OMAP5912)
+ if ((cpu_is_omap1610() || cpu_is_omap1710() || cpu_is_omap5912()) && gpio < 64)
return 0;
#endif
#ifdef CONFIG_ARCH_OMAP730
@@ -554,7 +554,7 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc,
if (bank->method == METHOD_GPIO_1510)
isr_reg = bank->base + OMAP1510_GPIO_INT_STATUS;
#endif
-#if defined(CONFIG_ARCH_OMAP1610) || defined(CONFIG_ARCH_OMAP5912)
+#if defined(CONFIG_ARCH_OMAP1610) || defined(CONFIG_ARCH_OMAP1710) || defined(CONFIG_ARCH_OMAP5912)
if (bank->method == METHOD_GPIO_1610)
isr_reg = bank->base + OMAP1610_GPIO_IRQSTATUS1;
#endif
@@ -588,7 +588,7 @@ static void gpio_ack_irq(unsigned int irq)
if (bank->method == METHOD_GPIO_1510)
__raw_writew(1 << (gpio & 0x0f), bank->base + OMAP1510_GPIO_INT_STATUS);
#endif
-#if defined(CONFIG_ARCH_OMAP1610) || defined(CONFIG_ARCH_OMAP5912)
+#if defined(CONFIG_ARCH_OMAP1610) || defined(CONFIG_ARCH_OMAP1710) || defined(CONFIG_ARCH_OMAP5912)
if (bank->method == METHOD_GPIO_1610)
__raw_writew(1 << (gpio & 0x0f), bank->base + OMAP1610_GPIO_IRQSTATUS1);
#endif
@@ -629,7 +629,7 @@ static void mpuio_mask_irq(unsigned int irq)
unsigned int gpio = OMAP_MPUIO(irq - IH_MPUIO_BASE);
struct gpio_bank *bank = get_gpio_bank(gpio);
- _set_gpio_irqenable(bank, gpio, 0);
+ _set_gpio_irqenable(bank, get_gpio_index(gpio), 0);
}
static void mpuio_unmask_irq(unsigned int irq)
@@ -637,7 +637,7 @@ static void mpuio_unmask_irq(unsigned int irq)
unsigned int gpio = OMAP_MPUIO(irq - IH_MPUIO_BASE);
struct gpio_bank *bank = get_gpio_bank(gpio);
- _set_gpio_irqenable(bank, gpio, 1);
+ _set_gpio_irqenable(bank, get_gpio_index(gpio), 1);
}
static struct irqchip gpio_irq_chip = {
@@ -668,8 +668,8 @@ static int __init _omap_gpio_init(void)
gpio_bank = gpio_bank_1510;
}
#endif
-#if defined(CONFIG_ARCH_OMAP1610) || defined(CONFIG_ARCH_OMAP5912)
- if (cpu_is_omap1610() || cpu_is_omap5912()) {
+#if defined(CONFIG_ARCH_OMAP1610) || defined(CONFIG_ARCH_OMAP1710) || defined(CONFIG_ARCH_OMAP5912)
+ if (cpu_is_omap1610() || cpu_is_omap1710() || cpu_is_omap5912()) {
int rev;
gpio_bank_count = 5;
@@ -702,7 +702,7 @@ static int __init _omap_gpio_init(void)
__raw_writew(0x0000, bank->base + OMAP1510_GPIO_INT_STATUS);
}
#endif
-#if defined(CONFIG_ARCH_OMAP1610) || defined(CONFIG_ARCH_OMAP5912)
+#if defined(CONFIG_ARCH_OMAP1610) || defined(CONFIG_ARCH_OMAP1710) || defined(CONFIG_ARCH_OMAP5912)
if (bank->method == METHOD_GPIO_1610) {
__raw_writew(0x0000, bank->base + OMAP1610_GPIO_IRQENABLE1);
__raw_writew(0xffff, bank->base + OMAP1610_GPIO_IRQSTATUS1);
@@ -731,7 +731,7 @@ static int __init _omap_gpio_init(void)
/* Enable system clock for GPIO module.
* The CAM_CLK_CTRL *is* really the right place. */
- if (cpu_is_omap1610())
+ if (cpu_is_omap1610() || cpu_is_omap1710())
omap_writel(omap_readl(ULPD_CAM_CLK_CTRL) | 0x04, ULPD_CAM_CLK_CTRL);
return 0;
diff --git a/arch/arm/mach-omap/irq.c b/arch/arm/mach-omap/irq.c
index 18da117f6c1c1c..3eec2986b40bae 100644
--- a/arch/arm/mach-omap/irq.c
+++ b/arch/arm/mach-omap/irq.c
@@ -140,7 +140,9 @@ static struct omap_irq_bank omap1510_irq_banks[] = {
};
#endif
-#if defined(CONFIG_ARCH_OMAP1610) || defined(CONFIG_ARCH_OMAP5912)
+#if defined(CONFIG_ARCH_OMAP1610) || defined(CONFIG_ARCH_OMAP5912) \
+ || defined(CONFIG_ARCH_OMAP1710)
+
static struct omap_irq_bank omap1610_irq_banks[] = {
{ .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3fefe8f },
{ .base_reg = OMAP_IH2_BASE, .trigger_map = 0xfffff7ff },
@@ -171,8 +173,9 @@ void __init omap_init_irq(void)
irq_bank_count = ARRAY_SIZE(omap1510_irq_banks);
}
#endif
-#if defined(CONFIG_ARCH_OMAP1610) || defined(CONFIG_ARCH_OMAP5912)
- if (cpu_is_omap1610() || cpu_is_omap5912()) {
+#if defined(CONFIG_ARCH_OMAP1610) || defined(CONFIG_ARCH_OMAP5912) \
+ || defined(CONFIG_ARCH_OMAP1710)
+ if (cpu_is_omap1610() || cpu_is_omap5912() || cpu_is_omap1710()) {
irq_banks = omap1610_irq_banks;
irq_bank_count = ARRAY_SIZE(omap1610_irq_banks);
}
@@ -190,6 +193,11 @@ void __init omap_init_irq(void)
irq_bank_writel(0x03, 0, IRQ_CONTROL_REG_OFFSET);
irq_bank_writel(0x03, 1, IRQ_CONTROL_REG_OFFSET);
+ /* Enable interrupts in global mask */
+ if (cpu_is_omap730()) {
+ irq_bank_writel(0x0, 0, IRQ_GMR_REG_OFFSET);
+ }
+
/* Install the interrupt handlers for each bank */
for (i = 0; i < irq_bank_count; i++) {
for (j = i * 32; j < (i + 1) * 32; j++) {
@@ -205,5 +213,9 @@ void __init omap_init_irq(void)
}
/* Unmask level 2 handler */
- omap_unmask_irq(INT_IH2_IRQ);
+ if (cpu_is_omap730()) {
+ omap_unmask_irq(INT_730_IH2_IRQ);
+ } else {
+ omap_unmask_irq(INT_IH2_IRQ);
+ }
}
diff --git a/arch/arm/mach-omap/leds-perseus2.c b/arch/arm/mach-omap/leds-h2p2-debug.c
index 8dafc0daef9c1a..8ff27af0b7c1ba 100644
--- a/arch/arm/mach-omap/leds-perseus2.c
+++ b/arch/arm/mach-omap/leds-h2p2-debug.c
@@ -1,5 +1,5 @@
/*
- * linux/arch/arm/mach-omap/leds-perseus2.c
+ * linux/arch/arm/mach-omap/leds-h2p2-debug.c
*
* Copyright 2003 by Texas Instruments Incorporated
*
@@ -15,9 +15,11 @@
#include <asm/leds.h>
#include <asm/system.h>
+#include <asm/arch/fpga.h>
+
#include "leds.h"
-void perseus2_leds_event(led_event_t evt)
+void h2p2_dbg_leds_event(led_event_t evt)
{
unsigned long flags;
static unsigned long hw_led_state = 0;
@@ -26,19 +28,19 @@ void perseus2_leds_event(led_event_t evt)
switch (evt) {
case led_start:
- hw_led_state |= OMAP730_FPGA_LED_STARTSTOP;
+ hw_led_state |= H2P2_DBG_FPGA_LED_STARTSTOP;
break;
case led_stop:
- hw_led_state &= ~OMAP730_FPGA_LED_STARTSTOP;
+ hw_led_state &= ~H2P2_DBG_FPGA_LED_STARTSTOP;
break;
case led_claim:
- hw_led_state |= OMAP730_FPGA_LED_CLAIMRELEASE;
+ hw_led_state |= H2P2_DBG_FPGA_LED_CLAIMRELEASE;
break;
case led_release:
- hw_led_state &= ~OMAP730_FPGA_LED_CLAIMRELEASE;
+ hw_led_state &= ~H2P2_DBG_FPGA_LED_CLAIMRELEASE;
break;
#ifdef CONFIG_LEDS_TIMER
@@ -46,28 +48,28 @@ void perseus2_leds_event(led_event_t evt)
/*
* Toggle Timer LED
*/
- if (hw_led_state & OMAP730_FPGA_LED_TIMER)
- hw_led_state &= ~OMAP730_FPGA_LED_TIMER;
+ if (hw_led_state & H2P2_DBG_FPGA_LED_TIMER)
+ hw_led_state &= ~H2P2_DBG_FPGA_LED_TIMER;
else
- hw_led_state |= OMAP730_FPGA_LED_TIMER;
+ hw_led_state |= H2P2_DBG_FPGA_LED_TIMER;
break;
#endif
#ifdef CONFIG_LEDS_CPU
case led_idle_start:
- hw_led_state |= OMAP730_FPGA_LED_IDLE;
+ hw_led_state |= H2P2_DBG_FPGA_LED_IDLE;
break;
case led_idle_end:
- hw_led_state &= ~OMAP730_FPGA_LED_IDLE;
+ hw_led_state &= ~H2P2_DBG_FPGA_LED_IDLE;
break;
#endif
case led_halted:
- if (hw_led_state & OMAP730_FPGA_LED_HALTED)
- hw_led_state &= ~OMAP730_FPGA_LED_HALTED;
+ if (hw_led_state & H2P2_DBG_FPGA_LED_HALTED)
+ hw_led_state &= ~H2P2_DBG_FPGA_LED_HALTED;
else
- hw_led_state |= OMAP730_FPGA_LED_HALTED;
+ hw_led_state |= H2P2_DBG_FPGA_LED_HALTED;
break;
case led_green_on:
@@ -96,7 +98,7 @@ void perseus2_leds_event(led_event_t evt)
/*
* Actually burn the LEDs
*/
- __raw_writew(~hw_led_state & 0xffff, OMAP730_FPGA_LEDS);
+ __raw_writew(~hw_led_state & 0xffff, H2P2_DBG_FPGA_LEDS);
local_irq_restore(flags);
}
diff --git a/arch/arm/mach-omap/leds.c b/arch/arm/mach-omap/leds.c
index e3f378b4a6998a..b6d0c7203dab86 100644
--- a/arch/arm/mach-omap/leds.c
+++ b/arch/arm/mach-omap/leds.c
@@ -3,6 +3,7 @@
*
* OMAP LEDs dispatcher
*/
+#include <linux/kernel.h>
#include <linux/init.h>
#include <asm/leds.h>
@@ -11,17 +12,17 @@
#include "leds.h"
static int __init
-omap1510_leds_init(void)
+omap_leds_init(void)
{
if (machine_is_omap_innovator())
leds_event = innovator_leds_event;
- else if (machine_is_omap_perseus2()) {
- leds_event = perseus2_leds_event;
+ else if (machine_is_omap_h2() || machine_is_omap_perseus2()) {
+ leds_event = h2p2_dbg_leds_event;
}
leds_event(led_start);
return 0;
}
-__initcall(omap1510_leds_init);
+__initcall(omap_leds_init);
diff --git a/arch/arm/mach-omap/leds.h b/arch/arm/mach-omap/leds.h
index ba2eb59d1b87fd..7571e2d635e34c 100644
--- a/arch/arm/mach-omap/leds.h
+++ b/arch/arm/mach-omap/leds.h
@@ -1,2 +1,2 @@
extern void innovator_leds_event(led_event_t evt);
-extern void perseus2_leds_event(led_event_t evt);
+extern void h2p2_dbg_leds_event(led_event_t evt);
diff --git a/arch/arm/mach-omap/mcbsp.c b/arch/arm/mach-omap/mcbsp.c
new file mode 100644
index 00000000000000..d334395f16ac8a
--- /dev/null
+++ b/arch/arm/mach-omap/mcbsp.c
@@ -0,0 +1,669 @@
+/*
+ * linux/arch/arm/omap/mcbsp.c
+ *
+ * Copyright (C) 2004 Nokia Corporation
+ * Author: Samuel Ortiz <samuel.ortiz@nokia.com>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Multichannel mode not supported.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/wait.h>
+#include <linux/completion.h>
+#include <linux/interrupt.h>
+
+#include <asm/delay.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+
+#include <asm/arch/dma.h>
+#include <asm/arch/mux.h>
+#include <asm/arch/irqs.h>
+#include <asm/arch/mcbsp.h>
+
+#ifdef CONFIG_MCBSP_DEBUG
+#define DBG(x...) printk(x)
+#else
+#define DBG(x...) do { } while (0)
+#endif
+
+struct omap_mcbsp {
+ u32 io_base;
+ u8 id;
+ u8 free;
+ omap_mcbsp_word_length rx_word_length;
+ omap_mcbsp_word_length tx_word_length;
+
+ /* IRQ based TX/RX */
+ int rx_irq;
+ int tx_irq;
+
+ /* DMA stuff */
+ u8 dma_rx_sync;
+ short dma_rx_lch;
+ u8 dma_tx_sync;
+ short dma_tx_lch;
+
+ /* Completion queues */
+ struct completion tx_irq_completion;
+ struct completion rx_irq_completion;
+ struct completion tx_dma_completion;
+ struct completion rx_dma_completion;
+
+ spinlock_t lock;
+};
+
+static struct omap_mcbsp mcbsp[OMAP_MAX_MCBSP_COUNT];
+
+
+static void omap_mcbsp_dump_reg(u8 id)
+{
+ DBG("**** MCBSP%d regs ****\n", mcbsp[id].id);
+ DBG("DRR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, DRR2));
+ DBG("DRR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, DRR1));
+ DBG("DXR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, DXR2));
+ DBG("DXR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, DXR1));
+ DBG("SPCR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, SPCR2));
+ DBG("SPCR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, SPCR1));
+ DBG("RCR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, RCR2));
+ DBG("RCR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, RCR1));
+ DBG("XCR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, XCR2));
+ DBG("XCR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, XCR1));
+ DBG("SRGR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, SRGR2));
+ DBG("SRGR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, SRGR1));
+ DBG("PCR0: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, PCR0));
+ DBG("***********************\n");
+}
+
+
+static irqreturn_t omap_mcbsp_tx_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
+{
+ struct omap_mcbsp * mcbsp_tx = (struct omap_mcbsp *)(dev_id);
+
+ DBG("TX IRQ callback : 0x%x\n", OMAP_MCBSP_READ(mcbsp_tx->io_base, SPCR2));
+
+ complete(&mcbsp_tx->tx_irq_completion);
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t omap_mcbsp_rx_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
+{
+ struct omap_mcbsp * mcbsp_rx = (struct omap_mcbsp *)(dev_id);
+
+ DBG("RX IRQ callback : 0x%x\n", OMAP_MCBSP_READ(mcbsp_rx->io_base, SPCR2));
+
+ complete(&mcbsp_rx->rx_irq_completion);
+ return IRQ_HANDLED;
+}
+
+
+static void omap_mcbsp_tx_dma_callback(int lch, u16 ch_status, void *data)
+{
+ struct omap_mcbsp * mcbsp_dma_tx = (struct omap_mcbsp *)(data);
+
+ DBG("TX DMA callback : 0x%x\n", OMAP_MCBSP_READ(mcbsp_dma_tx->io_base, SPCR2));
+
+ /* We can free the channels */
+ omap_free_dma(mcbsp_dma_tx->dma_tx_lch);
+ mcbsp_dma_tx->dma_tx_lch = -1;
+
+ complete(&mcbsp_dma_tx->tx_dma_completion);
+}
+
+static void omap_mcbsp_rx_dma_callback(int lch, u16 ch_status, void *data)
+{
+ struct omap_mcbsp * mcbsp_dma_rx = (struct omap_mcbsp *)(data);
+
+ DBG("RX DMA callback : 0x%x\n", OMAP_MCBSP_READ(mcbsp_dma_rx->io_base, SPCR2));
+
+ /* We can free the channels */
+ omap_free_dma(mcbsp_dma_rx->dma_rx_lch);
+ mcbsp_dma_rx->dma_rx_lch = -1;
+
+ complete(&mcbsp_dma_rx->rx_dma_completion);
+}
+
+
+/*
+ * omap_mcbsp_config simply write a config to the
+ * appropriate McBSP.
+ * You either call this function or set the McBSP registers
+ * by yourself before calling omap_mcbsp_start().
+ */
+
+void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg * config)
+{
+ u32 io_base = mcbsp[id].io_base;
+
+ DBG("OMAP-McBSP: McBSP%d io_base: 0x%8x\n", id+1, io_base);
+
+ /* We write the given config */
+ OMAP_MCBSP_WRITE(io_base, SPCR2, config->spcr2);
+ OMAP_MCBSP_WRITE(io_base, SPCR1, config->spcr1);
+ OMAP_MCBSP_WRITE(io_base, RCR2, config->rcr2);
+ OMAP_MCBSP_WRITE(io_base, RCR1, config->rcr1);
+ OMAP_MCBSP_WRITE(io_base, XCR2, config->xcr2);
+ OMAP_MCBSP_WRITE(io_base, XCR1, config->xcr1);
+ OMAP_MCBSP_WRITE(io_base, SRGR2, config->srgr2);
+ OMAP_MCBSP_WRITE(io_base, SRGR1, config->srgr1);
+ OMAP_MCBSP_WRITE(io_base, SRGR2, config->mcr2);
+ OMAP_MCBSP_WRITE(io_base, SRGR1, config->mcr1);
+ OMAP_MCBSP_WRITE(io_base, PCR0, config->pcr0);
+}
+
+
+
+static int omap_mcbsp_check(unsigned int id)
+{
+ if (cpu_is_omap730()) {
+ if (id > OMAP_MAX_MCBSP_COUNT - 1) {
+ printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n", id + 1);
+ return -1;
+ }
+ return 0;
+ }
+
+ if (cpu_is_omap1510() || cpu_is_omap1610() || cpu_is_omap1710()) {
+ if (id > OMAP_MAX_MCBSP_COUNT) {
+ printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n", id + 1);
+ return -1;
+ }
+ return 0;
+ }
+
+ return -1;
+}
+
+#define DSP_RSTCT2 0xe1008014
+
+static void omap_mcbsp_dsp_request(void)
+{
+ if (cpu_is_omap1510() || cpu_is_omap1610() || cpu_is_omap1710()) {
+ omap_writew((omap_readw(ARM_RSTCT1) | (1 << 1) | (1 << 2)),
+ ARM_RSTCT1);
+ omap_writew((omap_readw(ARM_CKCTL) | 1 << EN_DSPCK),
+ ARM_CKCTL);
+ omap_writew((omap_readw(ARM_IDLECT2) | (1 << EN_APICK)),
+ ARM_IDLECT2);
+
+ /* enable 12MHz clock to mcbsp 1 & 3 */
+ __raw_writew(__raw_readw(DSP_IDLECT2) | (1 << EN_XORPCK),
+ DSP_IDLECT2);
+ __raw_writew(__raw_readw(DSP_RSTCT2) | 1 | 1 << 1,
+ DSP_RSTCT2);
+ }
+}
+
+static void omap_mcbsp_dsp_free(void)
+{
+ /* Useless for now */
+}
+
+
+int omap_mcbsp_request(unsigned int id)
+{
+ int err;
+
+ if (omap_mcbsp_check(id) < 0)
+ return -EINVAL;
+
+ /*
+ * On 1510, 1610 and 1710, McBSP1 and McBSP3
+ * are DSP public peripherals.
+ */
+ if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3)
+ omap_mcbsp_dsp_request();
+
+ spin_lock(&mcbsp[id].lock);
+ if (!mcbsp[id].free) {
+ printk (KERN_ERR "OMAP-McBSP: McBSP%d is currently in use\n", id + 1);
+ spin_unlock(&mcbsp[id].lock);
+ return -1;
+ }
+
+ mcbsp[id].free = 0;
+ spin_unlock(&mcbsp[id].lock);
+
+ /* We need to get IRQs here */
+ err = request_irq(mcbsp[id].tx_irq, omap_mcbsp_tx_irq_handler, 0,
+ "McBSP",
+ (void *) (&mcbsp[id]));
+ if (err != 0) {
+ printk(KERN_ERR "OMAP-McBSP: Unable to request TX IRQ %d for McBSP%d\n",
+ mcbsp[id].tx_irq, mcbsp[id].id);
+ return err;
+ }
+
+ init_completion(&(mcbsp[id].tx_irq_completion));
+
+
+ err = request_irq(mcbsp[id].rx_irq, omap_mcbsp_rx_irq_handler, 0,
+ "McBSP",
+ (void *) (&mcbsp[id]));
+ if (err != 0) {
+ printk(KERN_ERR "OMAP-McBSP: Unable to request RX IRQ %d for McBSP%d\n",
+ mcbsp[id].rx_irq, mcbsp[id].id);
+ free_irq(mcbsp[id].tx_irq, (void *) (&mcbsp[id]));
+ return err;
+ }
+
+ init_completion(&(mcbsp[id].rx_irq_completion));
+ return 0;
+
+}
+
+void omap_mcbsp_free(unsigned int id)
+{
+ if (omap_mcbsp_check(id) < 0)
+ return;
+
+ if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3)
+ omap_mcbsp_dsp_free();
+
+ spin_lock(&mcbsp[id].lock);
+ if (mcbsp[id].free) {
+ printk (KERN_ERR "OMAP-McBSP: McBSP%d was not reserved\n", id + 1);
+ spin_unlock(&mcbsp[id].lock);
+ return;
+ }
+
+ mcbsp[id].free = 1;
+ spin_unlock(&mcbsp[id].lock);
+
+ /* Free IRQs */
+ free_irq(mcbsp[id].rx_irq, (void *) (&mcbsp[id]));
+ free_irq(mcbsp[id].tx_irq, (void *) (&mcbsp[id]));
+}
+
+/*
+ * Here we start the McBSP, by enabling the sample
+ * generator, both transmitter and receivers,
+ * and the frame sync.
+ */
+void omap_mcbsp_start(unsigned int id)
+{
+ u32 io_base;
+ u16 w;
+
+ if (omap_mcbsp_check(id) < 0)
+ return;
+
+ io_base = mcbsp[id].io_base;
+
+ mcbsp[id].rx_word_length = ((OMAP_MCBSP_READ(io_base, RCR1) >> 5) & 0x7);
+ mcbsp[id].tx_word_length = ((OMAP_MCBSP_READ(io_base, XCR1) >> 5) & 0x7);
+
+ /* Start the sample generator */
+ w = OMAP_MCBSP_READ(io_base, SPCR2);
+ OMAP_MCBSP_WRITE(io_base, SPCR2, w | (1 << 6));
+
+ /* Enable transmitter and receiver */
+ w = OMAP_MCBSP_READ(io_base, SPCR2);
+ OMAP_MCBSP_WRITE(io_base, SPCR2, w | 1);
+
+ w = OMAP_MCBSP_READ(io_base, SPCR1);
+ OMAP_MCBSP_WRITE(io_base, SPCR1, w | 1);
+
+ udelay(100);
+
+ /* Start frame sync */
+ w = OMAP_MCBSP_READ(io_base, SPCR2);
+ OMAP_MCBSP_WRITE(io_base, SPCR2, w | (1 << 7));
+
+ /* Dump McBSP Regs */
+ omap_mcbsp_dump_reg(id);
+
+}
+
+void omap_mcbsp_stop(unsigned int id)
+{
+ u32 io_base;
+ u16 w;
+
+ if (omap_mcbsp_check(id) < 0)
+ return;
+
+ io_base = mcbsp[id].io_base;
+
+ /* Reset transmitter */
+ w = OMAP_MCBSP_READ(io_base, SPCR2);
+ OMAP_MCBSP_WRITE(io_base, SPCR2, w & ~(1));
+
+ /* Reset receiver */
+ w = OMAP_MCBSP_READ(io_base, SPCR1);
+ OMAP_MCBSP_WRITE(io_base, SPCR1, w & ~(1));
+
+ /* Reset the sample rate generator */
+ w = OMAP_MCBSP_READ(io_base, SPCR2);
+ OMAP_MCBSP_WRITE(io_base, SPCR2, w & ~(1 << 6));
+}
+
+
+/*
+ * IRQ based word transmission.
+ */
+void omap_mcbsp_xmit_word(unsigned int id, u32 word)
+{
+ u32 io_base;
+ omap_mcbsp_word_length word_length = mcbsp[id].tx_word_length;
+
+ if (omap_mcbsp_check(id) < 0)
+ return;
+
+ io_base = mcbsp[id].io_base;
+
+ wait_for_completion(&(mcbsp[id].tx_irq_completion));
+
+ if (word_length > OMAP_MCBSP_WORD_16)
+ OMAP_MCBSP_WRITE(io_base, DXR2, word >> 16);
+ OMAP_MCBSP_WRITE(io_base, DXR1, word & 0xffff);
+}
+
+u32 omap_mcbsp_recv_word(unsigned int id)
+{
+ u32 io_base;
+ u16 word_lsb, word_msb = 0;
+ omap_mcbsp_word_length word_length = mcbsp[id].rx_word_length;
+
+ if (omap_mcbsp_check(id) < 0)
+ return -EINVAL;
+
+ io_base = mcbsp[id].io_base;
+
+ wait_for_completion(&(mcbsp[id].rx_irq_completion));
+
+ if (word_length > OMAP_MCBSP_WORD_16)
+ word_msb = OMAP_MCBSP_READ(io_base, DRR2);
+ word_lsb = OMAP_MCBSP_READ(io_base, DRR1);
+
+ return (word_lsb | (word_msb << 16));
+}
+
+
+/*
+ * Simple DMA based buffer rx/tx routines.
+ * Nothing fancy, just a single buffer tx/rx through DMA.
+ * The DMA resources are released once the transfer is done.
+ * For anything fancier, you should use your own customized DMA
+ * routines and callbacks.
+ */
+int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer, unsigned int length)
+{
+ int dma_tx_ch;
+
+ if (omap_mcbsp_check(id) < 0)
+ return -EINVAL;
+
+ if (omap_request_dma(mcbsp[id].dma_tx_sync, "McBSP TX", omap_mcbsp_tx_dma_callback,
+ &mcbsp[id],
+ &dma_tx_ch)) {
+ printk("OMAP-McBSP: Unable to request DMA channel for McBSP%d TX. Trying IRQ based TX\n", id+1);
+ return -EAGAIN;
+ }
+ mcbsp[id].dma_tx_lch = dma_tx_ch;
+
+ DBG("TX DMA on channel %d\n", dma_tx_ch);
+
+ init_completion(&(mcbsp[id].tx_dma_completion));
+
+ omap_set_dma_transfer_params(mcbsp[id].dma_tx_lch,
+ OMAP_DMA_DATA_TYPE_S16,
+ length >> 1, 1,
+ OMAP_DMA_SYNC_ELEMENT);
+
+ omap_set_dma_dest_params(mcbsp[id].dma_tx_lch,
+ OMAP_DMA_PORT_TIPB,
+ OMAP_DMA_AMODE_CONSTANT,
+ mcbsp[id].io_base + OMAP_MCBSP_REG_DXR1);
+
+ omap_set_dma_src_params(mcbsp[id].dma_tx_lch,
+ OMAP_DMA_PORT_EMIFF,
+ OMAP_DMA_AMODE_POST_INC,
+ buffer);
+
+ omap_start_dma(mcbsp[id].dma_tx_lch);
+ wait_for_completion(&(mcbsp[id].tx_dma_completion));
+ return 0;
+}
+
+
+int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer, unsigned int length)
+{
+ int dma_rx_ch;
+
+ if (omap_mcbsp_check(id) < 0)
+ return -EINVAL;
+
+ if (omap_request_dma(mcbsp[id].dma_rx_sync, "McBSP RX", omap_mcbsp_rx_dma_callback,
+ &mcbsp[id],
+ &dma_rx_ch)) {
+ printk("Unable to request DMA channel for McBSP%d RX. Trying IRQ based RX\n", id+1);
+ return -EAGAIN;
+ }
+ mcbsp[id].dma_rx_lch = dma_rx_ch;
+
+ DBG("RX DMA on channel %d\n", dma_rx_ch);
+
+ init_completion(&(mcbsp[id].rx_dma_completion));
+
+ omap_set_dma_transfer_params(mcbsp[id].dma_rx_lch,
+ OMAP_DMA_DATA_TYPE_S16,
+ length >> 1, 1,
+ OMAP_DMA_SYNC_ELEMENT);
+
+ omap_set_dma_src_params(mcbsp[id].dma_rx_lch,
+ OMAP_DMA_PORT_TIPB,
+ OMAP_DMA_AMODE_CONSTANT,
+ mcbsp[id].io_base + OMAP_MCBSP_REG_DRR1);
+
+ omap_set_dma_dest_params(mcbsp[id].dma_rx_lch,
+ OMAP_DMA_PORT_EMIFF,
+ OMAP_DMA_AMODE_POST_INC,
+ buffer);
+
+ omap_start_dma(mcbsp[id].dma_rx_lch);
+ wait_for_completion(&(mcbsp[id].rx_dma_completion));
+ return 0;
+}
+
+
+/*
+ * SPI wrapper.
+ * Since SPI setup is much simpler than the generic McBSP one,
+ * this wrapper just need an omap_mcbsp_spi_cfg structure as an input.
+ * Once this is done, you can call omap_mcbsp_start().
+ */
+void omap_mcbsp_set_spi_mode(unsigned int id, const struct omap_mcbsp_spi_cfg * spi_cfg)
+{
+ struct omap_mcbsp_reg_cfg mcbsp_cfg;
+
+ if (omap_mcbsp_check(id) < 0)
+ return;
+
+ memset(&mcbsp_cfg, 0, sizeof(struct omap_mcbsp_reg_cfg));
+
+ /* SPI has only one frame */
+ mcbsp_cfg.rcr1 |= (RWDLEN1(spi_cfg->word_length) | RFRLEN1(0));
+ mcbsp_cfg.xcr1 |= (XWDLEN1(spi_cfg->word_length) | XFRLEN1(0));
+
+ /* Clock stop mode */
+ if (spi_cfg->clk_stp_mode == OMAP_MCBSP_CLK_STP_MODE_NO_DELAY)
+ mcbsp_cfg.spcr1 |= (1 << 12);
+ else
+ mcbsp_cfg.spcr1 |= (3 << 11);
+
+ /* Set clock parities */
+ if (spi_cfg->rx_clock_polarity == OMAP_MCBSP_CLK_RISING)
+ mcbsp_cfg.pcr0 |= CLKRP;
+ else
+ mcbsp_cfg.pcr0 &= ~CLKRP;
+
+ if (spi_cfg->tx_clock_polarity == OMAP_MCBSP_CLK_RISING)
+ mcbsp_cfg.pcr0 &= ~CLKXP;
+ else
+ mcbsp_cfg.pcr0 |= CLKXP;
+
+ /* Set SCLKME to 0 and CLKSM to 1 */
+ mcbsp_cfg.pcr0 &= ~SCLKME;
+ mcbsp_cfg.srgr2 |= CLKSM;
+
+ /* Set FSXP */
+ if (spi_cfg->fsx_polarity == OMAP_MCBSP_FS_ACTIVE_HIGH)
+ mcbsp_cfg.pcr0 &= ~FSXP;
+ else
+ mcbsp_cfg.pcr0 |= FSXP;
+
+ if (spi_cfg->spi_mode == OMAP_MCBSP_SPI_MASTER) {
+ mcbsp_cfg.pcr0 |= CLKXM;
+ mcbsp_cfg.srgr1 |= CLKGDV(spi_cfg->clk_div -1);
+ mcbsp_cfg.pcr0 |= FSXM;
+ mcbsp_cfg.srgr2 &= ~FSGM;
+ mcbsp_cfg.xcr2 |= XDATDLY(1);
+ mcbsp_cfg.rcr2 |= RDATDLY(1);
+ }
+ else {
+ mcbsp_cfg.pcr0 &= ~CLKXM;
+ mcbsp_cfg.srgr1 |= CLKGDV(1);
+ mcbsp_cfg.pcr0 &= ~FSXM;
+ mcbsp_cfg.xcr2 &= ~XDATDLY(3);
+ mcbsp_cfg.rcr2 &= ~RDATDLY(3);
+ }
+
+ mcbsp_cfg.xcr2 &= ~XPHASE;
+ mcbsp_cfg.rcr2 &= ~RPHASE;
+
+ omap_mcbsp_config(id, &mcbsp_cfg);
+}
+
+
+/*
+ * McBSP1 and McBSP3 are directly mapped on 1610 and 1510.
+ * 730 has only 2 McBSP, and both of them are MPU peripherals.
+ */
+struct omap_mcbsp_info {
+ u32 virt_base;
+ u8 dma_rx_sync, dma_tx_sync;
+ u16 rx_irq, tx_irq;
+};
+
+#ifdef CONFIG_ARCH_OMAP730
+static const struct omap_mcbsp_info mcbsp_730[] = {
+ [0] = { .virt_base = io_p2v(OMAP730_MCBSP1_BASE),
+ .dma_rx_sync = OMAP_DMA_MCBSP1_RX,
+ .dma_tx_sync = OMAP_DMA_MCBSP1_TX,
+ .rx_irq = INT_730_McBSP1RX,
+ .tx_irq = INT_730_McBSP1TX },
+ [1] = { .virt_base = io_p2v(OMAP730_MCBSP2_BASE),
+ .dma_rx_sync = OMAP_DMA_MCBSP3_RX,
+ .dma_tx_sync = OMAP_DMA_MCBSP3_TX,
+ .rx_irq = INT_730_McBSP2RX,
+ .tx_irq = INT_730_McBSP2TX },
+};
+#endif
+
+#ifdef CONFIG_ARCH_OMAP1510
+static const struct omap_mcbsp_info mcbsp_1510[] = {
+ [0] = { .virt_base = OMAP1510_MCBSP1_BASE,
+ .dma_rx_sync = OMAP_DMA_MCBSP1_RX,
+ .dma_tx_sync = OMAP_DMA_MCBSP1_TX,
+ .rx_irq = INT_McBSP1RX,
+ .tx_irq = INT_McBSP1TX },
+ [1] = { .virt_base = io_p2v(OMAP1510_MCBSP2_BASE),
+ .dma_rx_sync = OMAP_DMA_MCBSP2_RX,
+ .dma_tx_sync = OMAP_DMA_MCBSP2_TX,
+ .rx_irq = INT_1510_SPI_RX,
+ .tx_irq = INT_1510_SPI_TX },
+ [2] = { .virt_base = OMAP1510_MCBSP3_BASE,
+ .dma_rx_sync = OMAP_DMA_MCBSP3_RX,
+ .dma_tx_sync = OMAP_DMA_MCBSP3_TX,
+ .rx_irq = INT_McBSP3RX,
+ .tx_irq = INT_McBSP3TX },
+};
+#endif
+
+#if defined(CONFIG_ARCH_OMAP1610) || defined(CONFIG_ARCH_OMAP1710)
+static const struct omap_mcbsp_info mcbsp_1610[] = {
+ [0] = { .virt_base = OMAP1610_MCBSP1_BASE,
+ .dma_rx_sync = OMAP_DMA_MCBSP1_RX,
+ .dma_tx_sync = OMAP_DMA_MCBSP1_TX,
+ .rx_irq = INT_McBSP1RX,
+ .tx_irq = INT_McBSP1TX },
+ [1] = { .virt_base = io_p2v(OMAP1610_MCBSP2_BASE),
+ .dma_rx_sync = OMAP_DMA_MCBSP2_RX,
+ .dma_tx_sync = OMAP_DMA_MCBSP2_TX,
+ .rx_irq = INT_1610_McBSP2_RX,
+ .tx_irq = INT_1610_McBSP2_TX },
+ [2] = { .virt_base = OMAP1610_MCBSP3_BASE,
+ .dma_rx_sync = OMAP_DMA_MCBSP3_RX,
+ .dma_tx_sync = OMAP_DMA_MCBSP3_TX,
+ .rx_irq = INT_McBSP3RX,
+ .tx_irq = INT_McBSP3TX },
+};
+#endif
+
+static int __init omap_mcbsp_init(void)
+{
+ int mcbsp_count = 0, i;
+ static const struct omap_mcbsp_info *mcbsp_info;
+
+ printk("Initializing OMAP McBSP system\n");
+#ifdef CONFIG_ARCH_OMAP730
+ if (cpu_is_omap730()) {
+ mcbsp_info = mcbsp_730;
+ mcbsp_count = ARRAY_SIZE(mcbsp_730);
+ }
+#endif
+#ifdef CONFIG_ARCH_OMAP1510
+ if (cpu_is_omap1510()) {
+ mcbsp_info = mcbsp_1510;
+ mcbsp_count = ARRAY_SIZE(mcbsp_1510);
+ }
+#endif
+#if defined(CONFIG_ARCH_OMAP1610) || defined(CONFIG_ARCH_OMAP1710)
+ if (cpu_is_omap1610() || cpu_is_omap1710()) {
+ mcbsp_info = mcbsp_1610;
+ mcbsp_count = ARRAY_SIZE(mcbsp_1610);
+ }
+#endif
+ for (i = 0; i < OMAP_MAX_MCBSP_COUNT ; i++) {
+ if (i >= mcbsp_count) {
+ mcbsp[i].io_base = 0;
+ mcbsp[i].free = 0;
+ continue;
+ }
+ mcbsp[i].id = i + 1;
+ mcbsp[i].free = 1;
+ mcbsp[i].dma_tx_lch = -1;
+ mcbsp[i].dma_rx_lch = -1;
+
+ mcbsp[i].io_base = mcbsp_info[i].virt_base;
+ mcbsp[i].tx_irq = mcbsp_info[i].tx_irq;
+ mcbsp[i].rx_irq = mcbsp_info[i].rx_irq;
+ mcbsp[i].dma_rx_sync = mcbsp_info[i].dma_rx_sync;
+ mcbsp[i].dma_tx_sync = mcbsp_info[i].dma_tx_sync;
+ spin_lock_init(&mcbsp[i].lock);
+ }
+
+ return 0;
+}
+
+
+arch_initcall(omap_mcbsp_init);
+
+EXPORT_SYMBOL(omap_mcbsp_config);
+EXPORT_SYMBOL(omap_mcbsp_request);
+EXPORT_SYMBOL(omap_mcbsp_free);
+EXPORT_SYMBOL(omap_mcbsp_start);
+EXPORT_SYMBOL(omap_mcbsp_stop);
+EXPORT_SYMBOL(omap_mcbsp_xmit_word);
+EXPORT_SYMBOL(omap_mcbsp_recv_word);
+EXPORT_SYMBOL(omap_mcbsp_xmit_buffer);
+EXPORT_SYMBOL(omap_mcbsp_recv_buffer);
+EXPORT_SYMBOL(omap_mcbsp_set_spi_mode);
diff --git a/arch/arm/mach-omap/ocpi.c b/arch/arm/mach-omap/ocpi.c
index 944c294186cbe3..93c7f4aca3bfab 100644
--- a/arch/arm/mach-omap/ocpi.c
+++ b/arch/arm/mach-omap/ocpi.c
@@ -59,8 +59,8 @@ int ocpi_enable(void)
/* Make sure there's clock for OCPI */
-#ifdef CONFIG_ARCH_OMAP1610
- if (cpu_is_omap1610()) {
+#if defined(CONFIG_ARCH_OMAP1610) || defined(CONFIG_ARCH_OMAP1710)
+ if (cpu_is_omap1610() || cpu_is_omap1710()) {
val = omap_readl(OMAP1610_ARM_IDLECT3);
val |= EN_OCPI_CK;
val &= ~IDLOCPI_ARM;
diff --git a/arch/arm/mach-omap/usb.c b/arch/arm/mach-omap/usb.c
new file mode 100644
index 00000000000000..f3451d269159d8
--- /dev/null
+++ b/arch/arm/mach-omap/usb.c
@@ -0,0 +1,541 @@
+/*
+ * arch/arm/mach-omap/usb.c -- platform level USB initialization
+ *
+ * Copyright (C) 2004 Texas Instruments, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#undef DEBUG
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/usb_otg.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+
+#include <asm/arch/mux.h>
+#include <asm/arch/usb.h>
+#include <asm/arch/board.h>
+
+/* These routines should handle the standard chip-specific modes
+ * for usb0/1/2 ports, covering basic mux and transceiver setup.
+ * Call omap_usb_init() once, from INIT_MACHINE().
+ *
+ * Some board-*.c files will need to set up additional mux options,
+ * like for suspend handling, vbus sensing, GPIOs, and the D+ pullup.
+ */
+
+/* TESTED ON:
+ * - 1611B H2 (with usb1 mini-AB)
+ * - 1510 Innovator with built-in transceiver (custom cable feeding 5V VBUS)
+ * - 1710 custom development board using alternate pin group
+ */
+
+/*-------------------------------------------------------------------------*/
+
+#ifdef CONFIG_ARCH_OMAP_OTG
+
+static struct otg_transceiver *xceiv;
+
+/**
+ * otg_get_transceiver - find the (single) OTG transceiver driver
+ *
+ * Returns the transceiver driver, after getting a refcount to it; or
+ * null if there is no such transceiver. The caller is responsible for
+ * releasing that count.
+ */
+struct otg_transceiver *otg_get_transceiver(void)
+{
+ if (xceiv)
+ get_device(xceiv->dev);
+ return xceiv;
+}
+EXPORT_SYMBOL(otg_get_transceiver);
+
+int otg_set_transceiver(struct otg_transceiver *x)
+{
+ if (xceiv && x)
+ return -EBUSY;
+ xceiv = x;
+ return 0;
+}
+EXPORT_SYMBOL(otg_set_transceiver);
+
+#endif
+
+/*-------------------------------------------------------------------------*/
+
+static u32 __init omap_usb0_init(unsigned nwires, unsigned is_device)
+{
+ u32 syscon1 = 0;
+
+ if (nwires == 0) {
+ USB_TRANSCEIVER_CTRL_REG &= ~(1 << 3);
+ return 0;
+ }
+
+ /*
+ * VP and VM are needed for all active usb0 configurations.
+ * USB0_VP and USB0_VM are always set on 1510, there's no muxing
+ * available for them.
+ */
+ if (nwires >= 2 && !cpu_is_omap1510()) {
+ omap_cfg_reg(AA9_USB0_VP);
+ omap_cfg_reg(R9_USB0_VM);
+ }
+
+ /* internal transceiver */
+ if (nwires == 2) {
+ if (cpu_is_omap1510()) {
+ /* This works for OHCI on 1510-Innovator, nothing to mux */
+ return 0;
+ }
+
+#if 0
+ /* NOTE: host OR device mode for now, no OTG */
+ USB_TRANSCEIVER_CTRL_REG &= ~(3 << 4);
+ if (is_device) {
+ omap_cfg_reg(W4_USB_PUEN);
+ omap_cfg_reg(R18_1510_USB_GPIO0);
+ // omap_cfg_reg(USB0_VBUS);
+ // omap_cfg_reg(USB0_PUEN);
+ // USB_TRANSCEIVER_CTRL_REG.CONF_USB0_PORT_R = 7
+ // when USB0_PUEN is needed
+ } else /* host mode needs D+ and D- pulldowns */
+ USB_TRANSCEIVER_CTRL_REG &= ~(3 << 1);
+ return 3 << 16;
+#else
+ /* FIXME: 1610 needs to return the right value here */
+ printk(KERN_ERR "usb0 internal transceiver, nyet\n");
+ return 0;
+#endif
+ }
+
+ /* alternate pin config, external transceiver */
+ omap_cfg_reg(V6_USB0_TXD);
+ omap_cfg_reg(W9_USB0_TXEN);
+ omap_cfg_reg(W5_USB0_SE0);
+
+#ifdef CONFIG_ARCH_OMAP_USB_SPEED
+ /* FIXME: there's good chance that pin V9 is used for MMC2 port cmddir */
+ omap_cfg_reg(V9_USB0_SPEED);
+ // omap_cfg_reg(V9_USB0_SUSP);
+#endif
+
+ if (nwires != 3)
+ omap_cfg_reg(Y5_USB0_RCV);
+
+ switch (nwires) {
+ case 3:
+ syscon1 = 2;
+ break;
+ case 4:
+ syscon1 = 1;
+ break;
+ case 6:
+ syscon1 = 3;
+ /* REVISIT: Is CONF_USB2_UNI_R only needed when nwires = 6? */
+ USB_TRANSCEIVER_CTRL_REG |= CONF_USB2_UNI_R;
+ break;
+ default:
+ printk(KERN_ERR "illegal usb%d %d-wire transceiver\n",
+ 0, nwires);
+ }
+ return syscon1 << 16;
+}
+
+static u32 __init omap_usb1_init(unsigned nwires)
+{
+ u32 syscon1 = 0;
+
+ if (nwires != 6)
+ USB_TRANSCEIVER_CTRL_REG &= ~CONF_USB1_UNI_R;
+ if (nwires == 0)
+ return 0;
+
+ /* external transceiver */
+ omap_cfg_reg(USB1_TXD);
+ omap_cfg_reg(USB1_TXEN);
+ if (cpu_is_omap1510()) {
+ omap_cfg_reg(USB1_SEO);
+ omap_cfg_reg(USB1_SPEED);
+ // SUSP
+ } else if (cpu_is_omap1610() || cpu_is_omap5912() || cpu_is_omap1710()) {
+ omap_cfg_reg(W13_1610_USB1_SE0);
+ omap_cfg_reg(R13_1610_USB1_SPEED);
+ // SUSP
+ } else {
+ pr_debug("usb unrecognized\n");
+ }
+ if (nwires != 3)
+ omap_cfg_reg(USB1_RCV);
+
+ switch (nwires) {
+ case 3:
+ syscon1 = 2;
+ break;
+ case 4:
+ syscon1 = 1;
+ break;
+ case 6:
+ syscon1 = 3;
+ omap_cfg_reg(USB1_VP);
+ omap_cfg_reg(USB1_VM);
+ USB_TRANSCEIVER_CTRL_REG |= CONF_USB1_UNI_R;
+ break;
+ default:
+ printk(KERN_ERR "illegal usb%d %d-wire transceiver\n",
+ 1, nwires);
+ }
+ return syscon1 << 20;
+}
+
+static u32 __init omap_usb2_init(unsigned nwires, unsigned alt_pingroup)
+{
+ u32 syscon1 = 0;
+
+ if (alt_pingroup)
+ return 0;
+ if (nwires != 6)
+ USB_TRANSCEIVER_CTRL_REG &= ~CONF_USB2_UNI_R;
+ if (nwires == 0)
+ return 0;
+
+ /* external transceiver */
+ if (cpu_is_omap1510()) {
+ omap_cfg_reg(USB2_TXD);
+ omap_cfg_reg(USB2_TXEN);
+ omap_cfg_reg(USB2_SEO);
+ if (nwires != 3)
+ omap_cfg_reg(USB2_RCV);
+ } else if (cpu_is_omap1610() || cpu_is_omap5912() || cpu_is_omap1710()) {
+ omap_cfg_reg(V6_USB2_TXD);
+ omap_cfg_reg(W9_USB2_TXEN);
+ omap_cfg_reg(W5_USB2_SE0);
+ if (nwires != 3)
+ omap_cfg_reg(Y5_USB2_RCV);
+ } else {
+ pr_debug("usb unrecognized\n");
+ }
+ // omap_cfg_reg(USB2_SUSP);
+ // FIXME omap_cfg_reg(USB2_SPEED);
+
+ switch (nwires) {
+ case 3:
+ syscon1 = 2;
+ break;
+ case 4:
+ syscon1 = 1;
+ break;
+ case 6:
+ syscon1 = 3;
+ if (cpu_is_omap1510()) {
+ omap_cfg_reg(USB2_VP);
+ omap_cfg_reg(USB2_VM);
+ } else {
+ omap_cfg_reg(AA9_USB2_VP);
+ omap_cfg_reg(R9_USB2_VM);
+ }
+ USB_TRANSCEIVER_CTRL_REG |= CONF_USB2_UNI_R;
+ break;
+ default:
+ printk(KERN_ERR "illegal usb%d %d-wire transceiver\n",
+ 2, nwires);
+ }
+ return syscon1 << 24;
+}
+
+/*-------------------------------------------------------------------------*/
+
+#if defined(CONFIG_USB_GADGET_OMAP) || \
+ defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) || \
+ (defined(CONFIG_USB_OTG) && defined(CONFIG_ARCH_OMAP_OTG))
+static void usb_release(struct device *dev)
+{
+ /* normally not freed */
+}
+#endif
+
+#ifdef CONFIG_USB_GADGET_OMAP
+
+static struct resource udc_resources[] = {
+ /* order is significant! */
+ { /* registers */
+ .start = IO_ADDRESS(UDC_BASE),
+ .end = IO_ADDRESS(UDC_BASE + 0xff),
+ .flags = IORESOURCE_MEM,
+ }, { /* general IRQ */
+ .start = IH2_BASE + 20,
+ .flags = IORESOURCE_IRQ,
+ }, { /* PIO IRQ */
+ .start = IH2_BASE + 30,
+ .flags = IORESOURCE_IRQ,
+ }, { /* SOF IRQ */
+ .start = IH2_BASE + 29,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 udc_dmamask = ~(u32)0;
+
+static struct platform_device udc_device = {
+ .name = "omap_udc",
+ .id = -1,
+ .dev = {
+ .release = usb_release,
+ .dma_mask = &udc_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(udc_resources),
+ .resource = udc_resources,
+};
+
+#endif
+
+#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+
+/* The dmamask must be set for OHCI to work */
+static u64 ohci_dmamask = ~(u32)0;
+
+static struct resource ohci_resources[] = {
+ {
+ .start = IO_ADDRESS(OMAP_OHCI_BASE),
+ .end = IO_ADDRESS(OMAP_OHCI_BASE + 4096),
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_USB_HHC_1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device ohci_device = {
+ .name = "ohci",
+ .id = -1,
+ .dev = {
+ .release = usb_release,
+ .dma_mask = &ohci_dmamask,
+ .coherent_dma_mask = 0x0fffffff,
+ },
+ .num_resources = ARRAY_SIZE(ohci_resources),
+ .resource = ohci_resources,
+};
+
+#endif
+
+#if defined(CONFIG_USB_OTG) && defined(CONFIG_ARCH_OMAP_OTG)
+
+static struct resource otg_resources[] = {
+ /* order is significant! */
+ {
+ .start = IO_ADDRESS(OTG_BASE),
+ .end = IO_ADDRESS(OTG_BASE + 0xff),
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = IH2_BASE + 8,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device otg_device = {
+ .name = "omap_otg",
+ .id = -1,
+ .dev = {
+ .release = usb_release,
+ },
+ .num_resources = ARRAY_SIZE(otg_resources),
+ .resource = otg_resources,
+};
+
+#endif
+
+/*-------------------------------------------------------------------------*/
+
+// FIXME correct answer depends on hmc_mode,
+// as does any nonzero value for config->otg port number
+#define is_usb0_device(config) 0
+
+/*-------------------------------------------------------------------------*/
+
+#ifdef CONFIG_ARCH_OMAP_OTG
+
+void __init
+omap_otg_init(struct omap_usb_config *config)
+{
+ u32 syscon = OTG_SYSCON_1_REG & 0xffff;
+ int status;
+ int alt_pingroup = 0;
+
+ /* NOTE: no bus or clock setup (yet?) */
+
+ syscon = OTG_SYSCON_1_REG & 0xffff;
+ if (!(syscon & OTG_RESET_DONE))
+ pr_debug("USB resets not complete?\n");
+
+ // OTG_IRQ_EN_REG = 0;
+
+ /* pin muxing and transceiver pinouts */
+ if (config->pins[0] > 2) /* alt pingroup 2 */
+ alt_pingroup = 1;
+ syscon |= omap_usb0_init(config->pins[0], is_usb0_device(config));
+ syscon |= omap_usb1_init(config->pins[1]);
+ syscon |= omap_usb2_init(config->pins[2], alt_pingroup);
+ pr_debug("OTG_SYSCON_1_REG = %08x\n", syscon);
+ OTG_SYSCON_1_REG = syscon;
+
+ syscon = config->hmc_mode;
+ syscon |= USBX_SYNCHRO | (4 << 16) /* B_ASE0_BRST */;
+ if (config->otg || config->register_host)
+ syscon |= UHOST_EN;
+#ifdef CONFIG_USB_OTG
+ if (config->otg)
+ syscon |= OTG_EN;
+#endif
+ pr_debug("OTG_SYSCON_2_REG = %08x\n", syscon);
+ OTG_SYSCON_2_REG = syscon;
+
+ printk("USB: hmc %d", config->hmc_mode);
+ if (alt_pingroup)
+ printk(", usb2 alt %d wires", config->pins[2]);
+ else if (config->pins[0])
+ printk(", usb0 %d wires%s", config->pins[2],
+ is_usb0_device(config) ? " (dev)" : "");
+ if (config->pins[1])
+ printk(", usb1 %d wires", config->pins[1]);
+ if (!alt_pingroup && config->pins[2])
+ printk(", usb2 %d wires", config->pins[2]);
+ if (config->otg)
+ printk(", Mini-AB on usb%d", config->otg - 1);
+ printk("\n");
+
+ /* don't clock unused USB controllers */
+ syscon = OTG_SYSCON_1_REG;
+ syscon |= HST_IDLE_EN|DEV_IDLE_EN|OTG_IDLE_EN;
+
+#ifdef CONFIG_USB_GADGET_OMAP
+ if (config->otg || config->register_dev) {
+ syscon &= ~DEV_IDLE_EN;
+ udc_device.dev.platform_data = config;
+ status = platform_device_register(&udc_device);
+ if (status)
+ pr_debug("can't register UDC device, %d\n", status);
+ }
+#endif
+
+#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+ if (config->otg || config->register_host) {
+ syscon &= ~HST_IDLE_EN;
+ ohci_device.dev.platform_data = config;
+ status = platform_device_register(&ohci_device);
+ if (status)
+ pr_debug("can't register OHCI device, %d\n", status);
+ }
+#endif
+
+#ifdef CONFIG_USB_OTG
+ if (config->otg) {
+ syscon &= ~OTG_IDLE_EN;
+ if (cpu_is_omap730())
+ otg_resources[1].start = INT_730_USB_OTG;
+ status = platform_device_register(&otg_device);
+ // ...
+ }
+#endif
+ pr_debug("OTG_SYSCON_1_REG = %08x\n", syscon);
+ OTG_SYSCON_1_REG = syscon;
+
+ status = 0;
+}
+
+#else
+static inline void omap_otg_init(struct omap_usb_config *config) {}
+#endif
+
+/*-------------------------------------------------------------------------*/
+
+#ifdef CONFIG_ARCH_OMAP1510
+
+static void __init omap_1510_usb_init(struct omap_usb_config *config)
+{
+ int status;
+ unsigned int val;
+
+ omap_usb0_init(config->pins[0], is_usb0_device(config));
+ omap_usb1_init(config->pins[1]);
+ omap_usb2_init(config->pins[2], 0);
+
+ val = omap_readl(MOD_CONF_CTRL_0) & ~(0x3f << 1);
+ val |= (config->hmc_mode << 1);
+ omap_writel(val, MOD_CONF_CTRL_0);
+
+ // FIXME this has a UDC controller too
+
+#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+ if (config->otg || config->register_host) {
+ ohci_device.dev.platform_data = config;
+ status = platform_device_register(&ohci_device);
+ if (status)
+ pr_debug("can't register OHCI device, %d\n", status);
+ }
+ // FIXME completely untested ...
+#endif
+
+}
+
+#else
+static inline void omap_1510_usb_init(struct omap_usb_config *config) {}
+#endif
+
+/*-------------------------------------------------------------------------*/
+
+static struct omap_usb_config platform_data;
+
+static int __init
+omap_usb_init(void)
+{
+ const struct omap_usb_config *config;
+
+ config = omap_get_config(OMAP_TAG_USB, struct omap_usb_config);
+ if (config == NULL) {
+ printk(KERN_ERR "USB: No board-specific platform config found\n");
+ return -ENODEV;
+ }
+ platform_data = *config;
+
+ if (cpu_is_omap730()
+ || cpu_is_omap1610()
+ || cpu_is_omap1710()
+ || cpu_is_omap5912())
+ omap_otg_init(&platform_data);
+ else if (cpu_is_omap1510())
+ omap_1510_usb_init(&platform_data);
+ else {
+ printk(KERN_ERR "USB: No init for your chip yet\n");
+ return -ENODEV;
+ }
+ return 0;
+}
+
+subsys_initcall(omap_usb_init);
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig
index d394f6957444cc..bb28824d8cd1e3 100644
--- a/arch/arm/mach-pxa/Kconfig
+++ b/arch/arm/mach-pxa/Kconfig
@@ -12,7 +12,7 @@ config ARCH_LUBBOCK
config MACH_MAINSTONE
bool "Intel HCDDBBVA0 Development Platform"
select PXA27x
- #select IWMMXT
+ select IWMMXT
config ARCH_PXA_IDP
bool "Accelent Xscale IDP"
@@ -32,4 +32,9 @@ config PXA27x
help
Select code specific to PXA27x variants
+config IWMMXT
+ bool
+ help
+ Enable support for iWMMXt
+
endif
diff --git a/arch/arm/mach-s3c2410/Kconfig b/arch/arm/mach-s3c2410/Kconfig
index 40e78bc4460a19..6e10ac8b65409a 100644
--- a/arch/arm/mach-s3c2410/Kconfig
+++ b/arch/arm/mach-s3c2410/Kconfig
@@ -32,4 +32,26 @@ config MACH_VR1000
endmenu
+comment "S3C2410 Setup"
+
+config S3C2410_DMA
+ bool "S3C2410 DMA support"
+ depends on ARCH_S3C2410
+ help
+ S3C2410 DMA support. This is needed for drivers like sound which
+ use the S3C2410's DMA system to move data to and from the
+ peripheral blocks.
+
+config S3C2410_DMA_DEBUG
+ bool "S3C2410 DMA support debug"
+ depends on ARCH_S3C2410 && S3C2410_DMA
+ help
+ Enable debugging output for the DMA code. This option sends info
+ to the kernel log, at priority KERN_DEBUG.
+
+ Note, it is easy to create and fill the log buffer in a small
+ amount of time, as well as using an significant percantage of
+ the CPU time doing so.
+
+
endif
diff --git a/arch/arm/mach-s3c2410/Makefile b/arch/arm/mach-s3c2410/Makefile
index 476c6ca78a657e..4679d6b8a8a3c6 100644
--- a/arch/arm/mach-s3c2410/Makefile
+++ b/arch/arm/mach-s3c2410/Makefile
@@ -4,11 +4,13 @@
# Object file lists.
-obj-y := s3c2410.o irq.o time.o gpio.o
+obj-y := s3c2410.o irq.o time.o gpio.o clock.o devs.o
obj-m :=
obj-n :=
obj- :=
+obj-$(CONFIG_S3C2410_DMA) += dma.o
+
obj-$(CONFIG_ARCH_BAST) += mach-bast.o
obj-$(CONFIG_MACH_H1940) += mach-h1940.o
obj-$(CONFIG_ARCH_H1940) += mach-h1940.o
diff --git a/arch/arm/mach-s3c2410/clock.c b/arch/arm/mach-s3c2410/clock.c
new file mode 100644
index 00000000000000..169c28b5f6b200
--- /dev/null
+++ b/arch/arm/mach-s3c2410/clock.c
@@ -0,0 +1,304 @@
+/* linux/arch/arm/mach-s3c2410/gpio.c
+ *
+ * Copyright (c) 2004 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2410 Clock control support
+ *
+ * Based on, and code from linux/arch/arm/mach-versatile/clock.c
+ **
+ ** Copyright (C) 2004 ARM Limited.
+ ** Written by Deep Blue Solutions Limited.
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+
+#include <asm/hardware.h>
+#include <asm/atomic.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+
+#include <asm/hardware/clock.h>
+#include <asm/arch/regs-clock.h>
+
+#include "clock.h"
+
+
+static LIST_HEAD(clocks);
+static DECLARE_MUTEX(clocks_sem);
+
+
+/* old functions */
+
+void s3c2410_clk_enable(unsigned int clocks, unsigned int enable)
+{
+ unsigned long clkcon;
+ unsigned long flags;
+
+ local_irq_save(flags);
+
+ clkcon = __raw_readl(S3C2410_CLKCON);
+ clkcon &= ~clocks;
+
+ if (enable)
+ clkcon |= clocks;
+
+ __raw_writel(clkcon, S3C2410_CLKCON);
+
+ local_irq_restore(flags);
+}
+
+
+/* Clock API calls */
+
+struct clk *clk_get(struct device *dev, const char *id)
+{
+ struct clk *p;
+ struct clk *clk = ERR_PTR(-ENOENT);
+
+ down(&clocks_sem);
+ list_for_each_entry(p, &clocks, list) {
+ if (strcmp(id, p->name) == 0 &&
+ try_module_get(p->owner)) {
+ clk = p;
+ break;
+ }
+ }
+ up(&clocks_sem);
+
+ return clk;
+}
+
+void clk_put(struct clk *clk)
+{
+ module_put(clk->owner);
+}
+
+int clk_enable(struct clk *clk)
+{
+ s3c2410_clk_enable(clk->ctrlbit, 1);
+ return 0;
+}
+
+void clk_disable(struct clk *clk)
+{
+ s3c2410_clk_enable(clk->ctrlbit, 0);
+}
+
+
+int clk_use(struct clk *clk)
+{
+ atomic_inc(&clk->used);
+ return 0;
+}
+
+
+void clk_unuse(struct clk *clk)
+{
+ atomic_dec(&clk->used);
+}
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+ if (clk->parent != NULL)
+ return clk->parent->rate;
+
+ return clk->rate;
+}
+
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+ return rate;
+}
+
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+ return -EINVAL;
+}
+
+struct clk *clk_get_parent(struct clk *clk)
+{
+ return clk->parent;
+}
+
+EXPORT_SYMBOL(clk_get);
+EXPORT_SYMBOL(clk_put);
+EXPORT_SYMBOL(clk_enable);
+EXPORT_SYMBOL(clk_disable);
+EXPORT_SYMBOL(clk_use);
+EXPORT_SYMBOL(clk_unuse);
+EXPORT_SYMBOL(clk_get_rate);
+EXPORT_SYMBOL(clk_round_rate);
+EXPORT_SYMBOL(clk_set_rate);
+EXPORT_SYMBOL(clk_get_parent);
+
+/* base clocks */
+
+static struct clk clk_f = {
+ .name = "fclk",
+ .rate = 0,
+ .parent = NULL,
+ .ctrlbit = 0
+};
+
+static struct clk clk_h = {
+ .name = "hclk",
+ .rate = 0,
+ .parent = NULL,
+ .ctrlbit = 0
+};
+
+static struct clk clk_p = {
+ .name = "pclk",
+ .rate = 0,
+ .parent = NULL,
+ .ctrlbit = 0
+};
+
+/* clock definitions */
+
+static struct clk init_clocks[] = {
+ { .name = "nand",
+ .parent = &clk_h,
+ .ctrlbit = S3C2410_CLKCON_NAND
+ },
+ { .name = "lcd",
+ .parent = &clk_h,
+ .ctrlbit = S3C2410_CLKCON_LCDC
+ },
+ { .name = "usb-host",
+ .parent = &clk_h,
+ .ctrlbit = S3C2410_CLKCON_USBH
+ },
+ { .name = "usb-device",
+ .parent = &clk_h,
+ .ctrlbit = S3C2410_CLKCON_USBD
+ },
+ { .name = "timers",
+ .parent = &clk_p,
+ .ctrlbit = S3C2410_CLKCON_PWMT
+ },
+ { .name = "sdi",
+ .parent = &clk_p,
+ .ctrlbit = S3C2410_CLKCON_SDI
+ },
+ { .name = "uart0",
+ .parent = &clk_p,
+ .ctrlbit = S3C2410_CLKCON_UART0
+ },
+ { .name = "uart1",
+ .parent = &clk_p,
+ .ctrlbit = S3C2410_CLKCON_UART1
+ },
+ { .name = "uart2",
+ .parent = &clk_p,
+ .ctrlbit = S3C2410_CLKCON_UART2
+ },
+ { .name = "gpio",
+ .parent = &clk_p,
+ .ctrlbit = S3C2410_CLKCON_GPIO
+ },
+ { .name = "rtc",
+ .parent = &clk_p,
+ .ctrlbit = S3C2410_CLKCON_RTC
+ },
+ { .name = "adc",
+ .parent = &clk_p,
+ .ctrlbit = S3C2410_CLKCON_ADC
+ },
+ { .name = "i2c",
+ .parent = &clk_p,
+ .ctrlbit = S3C2410_CLKCON_IIC
+ },
+ { .name = "iis",
+ .parent = &clk_p,
+ .ctrlbit = S3C2410_CLKCON_IIS
+ },
+ { .name = "spi",
+ .parent = &clk_p,
+ .ctrlbit = S3C2410_CLKCON_SPI
+ }
+};
+
+/* initialise the clock system */
+
+int s3c2410_register_clock(struct clk *clk)
+{
+ clk->owner = THIS_MODULE;
+ atomic_set(&clk->used, 0);
+
+ /* add to the list of available clocks */
+
+ down(&clocks_sem);
+ list_add(&clk->list, &clocks);
+ up(&clocks_sem);
+
+ return 0;
+}
+
+/* initalise all the clocks */
+
+static int __init s3c2410_init_clocks(void)
+{
+ struct clk *clkp = init_clocks;
+ int ptr;
+ int ret;
+
+ printk(KERN_INFO "S3C2410 Clock control, (c) 2004 Simtec Electronics\n");
+
+ /* initialise the main system clocks */
+
+ clk_h.rate = s3c2410_hclk;
+ clk_p.rate = s3c2410_pclk;
+ clk_f.rate = s3c2410_fclk;
+
+ /* set the enabled clocks to a minimal (known) state */
+ __raw_writel(S3C2410_CLKCON_PWMT | S3C2410_CLKCON_UART0 | S3C2410_CLKCON_UART1 | S3C2410_CLKCON_UART2 | S3C2410_CLKCON_GPIO | S3C2410_CLKCON_RTC, S3C2410_CLKCON);
+
+ /* register our clocks */
+
+ if (s3c2410_register_clock(&clk_f) < 0)
+ printk(KERN_ERR "failed to register cpu fclk\n");
+
+ if (s3c2410_register_clock(&clk_h) < 0)
+ printk(KERN_ERR "failed to register cpu fclk\n");
+
+ if (s3c2410_register_clock(&clk_p) < 0)
+ printk(KERN_ERR "failed to register cpu fclk\n");
+
+ for (ptr = 0; ptr < ARRAY_SIZE(init_clocks); ptr++, clkp++) {
+ ret = s3c2410_register_clock(clkp);
+ if (ret < 0) {
+ printk(KERN_ERR "Failed to register clock %s (%d)\n",
+ clkp->name, ret);
+ }
+ }
+
+ return 0;
+}
+
+arch_initcall(s3c2410_init_clocks);
+
diff --git a/arch/arm/mach-s3c2410/clock.h b/arch/arm/mach-s3c2410/clock.h
new file mode 100644
index 00000000000000..4c7b94e87533a4
--- /dev/null
+++ b/arch/arm/mach-s3c2410/clock.h
@@ -0,0 +1,20 @@
+/*
+ * linux/arch/arm/mach-s3c2410/clock.h
+ *
+ * Copyright (c) 2004 Simtec Electronics
+ * Written by Ben Dooks, <ben@simtec.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+struct clk {
+ struct list_head list;
+ struct module *owner;
+ struct clk *parent;
+ const char *name;
+ atomic_t used;
+ unsigned long rate;
+ unsigned long ctrlbit;
+};
diff --git a/arch/arm/mach-s3c2410/devs.c b/arch/arm/mach-s3c2410/devs.c
new file mode 100644
index 00000000000000..e1c44d656a361e
--- /dev/null
+++ b/arch/arm/mach-s3c2410/devs.c
@@ -0,0 +1,341 @@
+/* linux/arch/arm/mach-s3c2410/devs.c
+ *
+ * Copyright (c) 2004 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * Base S3C2410 platform device definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Modifications:
+ * 18-Aug-2004 BJD Created initial version
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/device.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+
+#include "devs.h"
+
+/* USB Host Controller */
+
+static struct resource s3c_usb_resource[] = {
+ [0] = {
+ .start = S3C2410_PA_USBHOST,
+ .end = S3C2410_PA_USBHOST + S3C2410_SZ_USBHOST,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_USBH,
+ .end = IRQ_USBH,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static u64 s3c_device_usb_dmamask = 0xffffffffUL;
+
+struct platform_device s3c_device_usb = {
+ .name = "s3c2410-ohci",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s3c_usb_resource),
+ .resource = s3c_usb_resource,
+ .dev = {
+ .dma_mask = &s3c_device_usb_dmamask,
+ .coherent_dma_mask = 0xffffffffUL
+ }
+};
+
+EXPORT_SYMBOL(s3c_device_usb);
+
+/* LCD Controller */
+
+static struct resource s3c_lcd_resource[] = {
+ [0] = {
+ .start = S3C2410_PA_LCD,
+ .end = S3C2410_PA_LCD + S3C2410_SZ_LCD,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_LCD,
+ .end = IRQ_LCD,
+ .flags = IORESOURCE_IRQ,
+ }
+
+};
+
+static u64 s3c_device_lcd_dmamask = 0xffffffffUL;
+
+struct platform_device s3c_device_lcd = {
+ .name = "s3c2410-lcd",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s3c_lcd_resource),
+ .resource = s3c_lcd_resource,
+ .dev = {
+ .dma_mask = &s3c_device_lcd_dmamask,
+ .coherent_dma_mask = 0xffffffffUL
+ }
+};
+
+EXPORT_SYMBOL(s3c_device_lcd);
+
+/* NAND Controller */
+
+static struct resource s3c_nand_resource[] = {
+ [0] = {
+ .start = S3C2410_PA_NAND,
+ .end = S3C2410_PA_NAND + S3C2410_SZ_NAND,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_S3CUART_RX0,
+ .end = IRQ_S3CUART_ERR0,
+ .flags = IORESOURCE_IRQ,
+ }
+
+};
+
+struct platform_device s3c_device_nand = {
+ .name = "s3c2410-nand",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s3c_nand_resource),
+ .resource = s3c_nand_resource,
+};
+
+EXPORT_SYMBOL(s3c_device_nand);
+
+/* USB Device (Gadget)*/
+
+static struct resource s3c_usbgadget_resource[] = {
+ [0] = {
+ .start = S3C2410_PA_USBDEV,
+ .end = S3C2410_PA_USBDEV + S3C2410_SZ_USBDEV,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_USBD,
+ .end = IRQ_USBD,
+ .flags = IORESOURCE_IRQ,
+ }
+
+};
+
+struct platform_device s3c_device_usbgadget = {
+ .name = "s3c2410-usbgadget",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s3c_usbgadget_resource),
+ .resource = s3c_usbgadget_resource,
+};
+
+EXPORT_SYMBOL(s3c_device_usbgadget);
+
+/* Watchdog */
+
+static struct resource s3c_wdt_resource[] = {
+ [0] = {
+ .start = S3C2410_PA_WATCHDOG,
+ .end = S3C2410_PA_WATCHDOG + S3C2410_SZ_WATCHDOG,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_WDT,
+ .end = IRQ_WDT,
+ .flags = IORESOURCE_IRQ,
+ }
+
+};
+
+struct platform_device s3c_device_wdt = {
+ .name = "s3c2410-wdt",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s3c_wdt_resource),
+ .resource = s3c_wdt_resource,
+};
+
+EXPORT_SYMBOL(s3c_device_wdt);
+
+/* I2C */
+
+static struct resource s3c_i2c_resource[] = {
+ [0] = {
+ .start = S3C2410_PA_IIC,
+ .end = S3C2410_PA_IIC + S3C2410_SZ_IIC,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_IIC,
+ .end = IRQ_IIC,
+ .flags = IORESOURCE_IRQ,
+ }
+
+};
+
+struct platform_device s3c_device_i2c = {
+ .name = "s3c2410-i2c",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s3c_i2c_resource),
+ .resource = s3c_i2c_resource,
+};
+
+EXPORT_SYMBOL(s3c_device_i2c);
+
+/* IIS */
+
+static struct resource s3c_iis_resource[] = {
+ [0] = {
+ .start = S3C2410_PA_IIS,
+ .end = S3C2410_PA_IIS + S3C2410_SZ_IIS,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static u64 s3c_device_iis_dmamask = 0xffffffffUL;
+
+struct platform_device s3c_device_iis = {
+ .name = "s3c2410-iis",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s3c_iis_resource),
+ .resource = s3c_iis_resource,
+ .dev = {
+ .dma_mask = &s3c_device_iis_dmamask,
+ .coherent_dma_mask = 0xffffffffUL
+ }
+};
+
+EXPORT_SYMBOL(s3c_device_iis);
+
+/* RTC */
+
+static struct resource s3c_rtc_resource[] = {
+ [0] = {
+ .start = S3C2410_PA_RTC,
+ .end = S3C2410_PA_RTC + 0xff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_RTC,
+ .end = IRQ_RTC,
+ .flags = IORESOURCE_IRQ,
+ }
+
+};
+
+struct platform_device s3c_device_rtc = {
+ .name = "s3c2410-rtc",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s3c_rtc_resource),
+ .resource = s3c_rtc_resource,
+};
+
+EXPORT_SYMBOL(s3c_device_rtc);
+
+/* ADC */
+
+static struct resource s3c_adc_resource[] = {
+ [0] = {
+ .start = S3C2410_PA_ADC,
+ .end = S3C2410_PA_ADC + S3C2410_SZ_ADC,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_TC,
+ .end = IRQ_ADC,
+ .flags = IORESOURCE_IRQ,
+ }
+
+};
+
+struct platform_device s3c_device_adc = {
+ .name = "s3c2410-adc",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s3c_adc_resource),
+ .resource = s3c_adc_resource,
+};
+
+/* SDI */
+
+static struct resource s3c_sdi_resource[] = {
+ [0] = {
+ .start = S3C2410_PA_SDI,
+ .end = S3C2410_PA_SDI + S3C2410_SZ_SDI,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_SDI,
+ .end = IRQ_SDI,
+ .flags = IORESOURCE_IRQ,
+ }
+
+};
+
+struct platform_device s3c_device_sdi = {
+ .name = "s3c2410-sdi",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s3c_sdi_resource),
+ .resource = s3c_sdi_resource,
+};
+
+EXPORT_SYMBOL(s3c_device_sdi);
+
+/* SPI (0) */
+
+static struct resource s3c_spi0_resource[] = {
+ [0] = {
+ .start = S3C2410_PA_SPI,
+ .end = S3C2410_PA_SPI + 0x1f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_SPI0,
+ .end = IRQ_SPI0,
+ .flags = IORESOURCE_IRQ,
+ }
+
+};
+
+struct platform_device s3c_device_spi0 = {
+ .name = "s3c2410-spi",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s3c_spi0_resource),
+ .resource = s3c_spi0_resource,
+};
+
+EXPORT_SYMBOL(s3c_device_spi0);
+
+/* SPI (1) */
+
+static struct resource s3c_spi1_resource[] = {
+ [0] = {
+ .start = S3C2410_PA_SPI + 0x20,
+ .end = S3C2410_PA_SPI + 0x20 + 0x1f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_SPI1,
+ .end = IRQ_SPI1,
+ .flags = IORESOURCE_IRQ,
+ }
+
+};
+
+struct platform_device s3c_device_spi1 = {
+ .name = "s3c2410-spi",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(s3c_spi1_resource),
+ .resource = s3c_spi1_resource,
+};
+
+EXPORT_SYMBOL(s3c_device_spi1);
diff --git a/arch/arm/mach-s3c2410/devs.h b/arch/arm/mach-s3c2410/devs.h
new file mode 100644
index 00000000000000..226fb2b02d37cb
--- /dev/null
+++ b/arch/arm/mach-s3c2410/devs.h
@@ -0,0 +1,31 @@
+/* arch/arm/mach-s3c2410/devs.h
+ *
+ * Copyright (c) 2004 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * Header file for s3c2410 standard platform devices
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Modifications:
+ * 18-Aug-2004 BJD Created initial version
+ *
+*/
+
+extern struct platform_device s3c_device_usb;
+extern struct platform_device s3c_device_lcd;
+extern struct platform_device s3c_device_wdt;
+extern struct platform_device s3c_device_i2c;
+extern struct platform_device s3c_device_iis;
+extern struct platform_device s3c_device_rtc;
+extern struct platform_device s3c_device_adc;
+extern struct platform_device s3c_device_sdi;
+
+extern struct platform_device s3c_device_spi0;
+extern struct platform_device s3c_device_spi1;
+
+extern struct platform_device s3c_device_nand;
+
+extern struct platform_device s3c_device_usbgadget;
diff --git a/arch/arm/mach-s3c2410/dma.c b/arch/arm/mach-s3c2410/dma.c
new file mode 100644
index 00000000000000..819e5af16e1e68
--- /dev/null
+++ b/arch/arm/mach-s3c2410/dma.c
@@ -0,0 +1,1085 @@
+/* linux/arch/arm/mach-bast/dma.c
+ *
+ * (c) 2003,2004 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2410 DMA core
+ *
+ * http://www.simtec.co.uk/products/EB2410ITX/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Changelog:
+ * 08-Aug-2004 BJD Apply rmk's suggestions
+ * 21-Jul-2004 BJD Ported to linux 2.6
+ * 12-Jul-2004 BJD Finished re-write and change of API
+ * 06-Jul-2004 BJD Rewrote dma code to try and cope with various problems
+ * 23-May-2003 BJD Created file
+ * 19-Aug-2003 BJD Cleanup, header fix, added URL
+ *
+ * This file is based on the Sangwook Lee/Samsung patches, re-written due
+ * to various ommisions from the code (such as flexible dma configuration)
+ * for use with the BAST system board.
+ *
+ * The re-write is pretty much complete, and should be good enough for any
+ * possible DMA function
+ */
+
+#include <linux/config.h>
+
+#ifdef CONFIG_S3C2410_DMA_DEBUG
+#define DEBUG
+#endif
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/dma.h>
+
+#include <asm/mach/dma.h>
+#include <asm/arch/map.h>
+
+/* io map for dma */
+static void *dma_base;
+
+/* dma channel state information */
+s3c2410_dma_chan_t s3c2410_chans[S3C2410_DMA_CHANNELS];
+
+/* debugging functions */
+
+#define BUF_MAGIC (0xcafebabe)
+
+#define dmawarn(fmt...) printk(KERN_DEBUG fmt)
+
+#define dma_regaddr(chan, reg) ((chan)->regs + (reg))
+
+#if 1
+#define dma_wrreg(chan, reg, val) writel((val), (chan)->regs + (reg))
+#else
+static inline void
+dma_wrreg(s3c2410_dma_chan_t *chan, int reg, unsigned long val)
+{
+ pr_debug("writing %08x to register %08x\n",(unsigned int)val,reg);
+ writel(val, dma_regaddr(chan, reg));
+}
+
+#endif
+
+#define dma_rdreg(chan, reg) readl((chan)->regs + (reg))
+
+/* captured register state for debug */
+
+struct s3c2410_dma_regstate {
+ unsigned long dcsrc;
+ unsigned long disrc;
+ unsigned long dstat;
+ unsigned long dcon;
+ unsigned long dmsktrig;
+};
+
+#ifdef CONFIG_S3C2410_DMA_DEBUG
+
+/* dmadbg_showregs
+ *
+ * simple debug routine to print the current state of the dma registers
+*/
+
+static void
+dmadbg_capture(s3c2410_dma_chan_t *chan, struct s3c2410_dma_regstate *regs)
+{
+ regs->dcsrc = dma_rdreg(chan, S3C2410_DMA_DCSRC);
+ regs->disrc = dma_rdreg(chan, S3C2410_DMA_DISRC);
+ regs->dstat = dma_rdreg(chan, S3C2410_DMA_DSTAT);
+ regs->dcon = dma_rdreg(chan, S3C2410_DMA_DCON);
+ regs->dmsktrig = dma_rdreg(chan, S3C2410_DMA_DMASKTRIG);
+}
+
+static void
+dmadbg_showregs(const char *fname, int line, s3c2410_dma_chan_t *chan,
+ struct s3c2410_dma_regstate *regs)
+{
+ printk(KERN_DEBUG "dma%d: %s:%d: DCSRC=%08lx, DISRC=%08lx, DSTAT=%08lx DMT=%02lx, DCON=%08lx\n",
+ chan->number, fname, line,
+ regs->dcsrc, regs->disrc, regs->dstat, regs->dmsktrig,
+ regs->dcon);
+}
+
+static void
+dmadbg_showchan(const char *fname, int line, s3c2410_dma_chan_t *chan)
+{
+ struct s3c2410_dma_regstate state;
+
+ dmadbg_capture(chan, &state);
+
+ printk(KERN_DEBUG "dma%d: %s:%d: ls=%d, cur=%p, %p %p\n",
+ chan->number, fname, line, chan->load_state,
+ chan->curr, chan->next, chan->end);
+
+ dmadbg_showregs(fname, line, chan, &state);
+}
+
+#define dbg_showregs(chan) dmadbg_showregs(__FUNCTION__, __LINE__, (chan))
+#define dbg_showchan(chan) dmadbg_showchan(__FUNCTION__, __LINE__, (chan))
+#else
+#define dbg_showregs(chan) do { } while(0)
+#define dbg_showchan(chan) do { } while(0)
+#endif /* CONFIG_S3C2410_DMA_DEBUG */
+
+#define check_channel(chan) \
+ do { if ((chan) >= S3C2410_DMA_CHANNELS) { \
+ printk(KERN_ERR "%s: invalid channel %d\n", __FUNCTION__, (chan)); \
+ return -EINVAL; \
+ } } while(0)
+
+
+/* s3c2410_dma_stats_timeout
+ *
+ * Update DMA stats from timeout info
+*/
+
+static void
+s3c2410_dma_stats_timeout(s3c2410_dma_stats_t *stats, int val)
+{
+ if (stats == NULL)
+ return;
+
+ if (val > stats->timeout_longest)
+ stats->timeout_longest = val;
+ if (val < stats->timeout_shortest)
+ stats->timeout_shortest = val;
+
+ stats->timeout_avg += val;
+}
+
+/* s3c2410_dma_waitforload
+ *
+ * wait for the DMA engine to load a buffer, and update the state accordingly
+*/
+
+static int
+s3c2410_dma_waitforload(s3c2410_dma_chan_t *chan, int line)
+{
+ int timeout = chan->load_timeout;
+ int took;
+
+ if (chan->load_state != S3C2410_DMALOAD_1LOADED) {
+ printk(KERN_ERR "dma%d: s3c2410_dma_waitforload() called in loadstate %d from line %d\n", chan->number, chan->load_state, line);
+ return 0;
+ }
+
+ if (chan->stats != NULL)
+ chan->stats->loads++;
+
+ while (--timeout > 0) {
+ if ((dma_rdreg(chan, S3C2410_DMA_DSTAT) << (32-20)) != 0) {
+ took = chan->load_timeout - timeout;
+
+ s3c2410_dma_stats_timeout(chan->stats, took);
+
+ switch (chan->load_state) {
+ case S3C2410_DMALOAD_1LOADED:
+ chan->load_state = S3C2410_DMALOAD_1RUNNING;
+ break;
+
+ default:
+ printk(KERN_ERR "dma%d: unknown load_state in s3c2410_dma_waitforload() %d\n", chan->number, chan->load_state);
+ }
+
+ return 1;
+ }
+ }
+
+ if (chan->stats != NULL) {
+ chan->stats->timeout_failed++;
+ }
+
+ return 0;
+}
+
+
+
+/* s3c2410_dma_loadbuffer
+ *
+ * load a buffer, and update the channel state
+*/
+
+static inline int
+s3c2410_dma_loadbuffer(s3c2410_dma_chan_t *chan,
+ s3c2410_dma_buf_t *buf)
+{
+ unsigned long reload;
+
+ pr_debug("s3c2410_chan_loadbuffer: loading buff %p (0x%08lx,0x%06x)\n",
+ buf, (unsigned long)buf->data, buf->size);
+
+ if (buf == NULL) {
+ dmawarn("buffer is NULL\n");
+ return -EINVAL;
+ }
+
+ /* check the state of the channel before we do anything */
+
+ if (chan->load_state == S3C2410_DMALOAD_1LOADED) {
+ dmawarn("load_state is S3C2410_DMALOAD_1LOADED\n");
+ }
+
+ if (chan->load_state == S3C2410_DMALOAD_1LOADED_1RUNNING) {
+ dmawarn("state is S3C2410_DMALOAD_1LOADED_1RUNNING\n");
+ }
+
+ /* it would seem sensible if we are the last buffer to not bother
+ * with the auto-reload bit, so that the DMA engine will not try
+ * and load another transfer after this one has finished...
+ */
+ if (chan->load_state == S3C2410_DMALOAD_NONE) {
+ pr_debug("load_state is none, checking for noreload (next=%p)\n",
+ buf->next);
+ reload = (buf->next == NULL) ? S3C2410_DCON_NORELOAD : 0;
+ } else {
+ pr_debug("load_state is %d => autoreload\n", chan->load_state);
+ reload = S3C2410_DCON_AUTORELOAD;
+ }
+
+ writel(buf->data, chan->addr_reg);
+
+ dma_wrreg(chan, S3C2410_DMA_DCON,
+ chan->dcon | reload | (buf->size/chan->xfer_unit));
+
+ chan->next = buf->next;
+
+ /* update the state of the channel */
+
+ switch (chan->load_state) {
+ case S3C2410_DMALOAD_NONE:
+ chan->load_state = S3C2410_DMALOAD_1LOADED;
+ break;
+
+ case S3C2410_DMALOAD_1RUNNING:
+ chan->load_state = S3C2410_DMALOAD_1LOADED_1RUNNING;
+ break;
+
+ default:
+ dmawarn("dmaload: unknown state %d in loadbuffer\n",
+ chan->load_state);
+ break;
+ }
+
+ return 0;
+}
+
+/* s3c2410_dma_call_op
+ *
+ * small routine to call the op routine with the given op if it has been
+ * registered
+*/
+
+static void
+s3c2410_dma_call_op(s3c2410_dma_chan_t *chan, s3c2410_chan_op_t op)
+{
+ if (chan->op_fn != NULL) {
+ (chan->op_fn)(chan, op);
+ }
+}
+
+/* s3c2410_dma_buffdone
+ *
+ * small wrapper to check if callback routine needs to be called, and
+ * if so, call it
+*/
+
+static inline void
+s3c2410_dma_buffdone(s3c2410_dma_chan_t *chan, s3c2410_dma_buf_t *buf,
+ s3c2410_dma_buffresult_t result)
+{
+ pr_debug("callback_fn=%p, buf=%p, id=%p, size=%d, result=%d\n",
+ chan->callback_fn, buf, buf->id, buf->size, result);
+
+ if (chan->callback_fn != NULL) {
+ (chan->callback_fn)(chan, buf->id, buf->size, result);
+ }
+}
+
+/* s3c2410_dma_start
+ *
+ * start a dma channel going
+*/
+
+static int s3c2410_dma_start(s3c2410_dma_chan_t *chan)
+{
+ unsigned long tmp;
+ unsigned long flags;
+
+ pr_debug("s3c2410_start_dma: channel=%d\n", chan->number);
+
+ local_irq_save(flags);
+
+ if (chan->state == S3C2410_DMA_RUNNING) {
+ pr_debug("s3c2410_start_dma: already running (%d)\n", chan->state);
+ local_irq_restore(flags);
+ return 0;
+ }
+
+ chan->state = S3C2410_DMA_RUNNING;
+
+ /* check wether there is anything to load, and if not, see
+ * if we can find anything to load
+ */
+
+ if (chan->load_state == S3C2410_DMALOAD_NONE) {
+ if (chan->next == NULL) {
+ printk(KERN_ERR "dma%d: channel has nothing loaded\n",
+ chan->number);
+ chan->state = S3C2410_DMA_IDLE;
+ local_irq_restore(flags);
+ return -EINVAL;
+ }
+
+ s3c2410_dma_loadbuffer(chan, chan->next);
+ }
+
+ dbg_showchan(chan);
+
+ /* enable the channel */
+
+ if (!chan->irq_enabled) {
+ enable_irq(chan->irq);
+ chan->irq_enabled = 1;
+ }
+
+ /* start the channel going */
+
+ tmp = dma_rdreg(chan, S3C2410_DMA_DMASKTRIG);
+ tmp &= ~S3C2410_DMASKTRIG_STOP;
+ tmp |= S3C2410_DMASKTRIG_ON;
+ dma_wrreg(chan, S3C2410_DMA_DMASKTRIG, tmp);
+
+ pr_debug("wrote %08lx to DMASKTRIG\n", tmp);
+
+#if 0
+ /* the dma buffer loads should take care of clearing the AUTO
+ * reloading feature */
+ tmp = dma_rdreg(chan, S3C2410_DMA_DCON);
+ tmp &= ~S3C2410_DCON_NORELOAD;
+ dma_wrreg(chan, S3C2410_DMA_DCON, tmp);
+#endif
+
+ s3c2410_dma_call_op(chan, S3C2410_DMAOP_START);
+
+ dbg_showchan(chan);
+
+ local_irq_restore(flags);
+ return 0;
+}
+
+/* s3c2410_dma_canload
+ *
+ * work out if we can queue another buffer into the DMA engine
+*/
+
+static int
+s3c2410_dma_canload(s3c2410_dma_chan_t *chan)
+{
+ if (chan->load_state == S3C2410_DMALOAD_NONE ||
+ chan->load_state == S3C2410_DMALOAD_1RUNNING)
+ return 1;
+
+ return 0;
+}
+
+
+/* s3c2410_dma_enqueue
+ *
+ * queue an given buffer for dma transfer.
+ *
+ * id the device driver's id information for this buffer
+ * data the physical address of the buffer data
+ * size the size of the buffer in bytes
+ *
+ * If the channel is not running, then the flag S3C2410_DMAF_AUTOSTART
+ * is checked, and if set, the channel is started. If this flag isn't set,
+ * then an error will be returned.
+ *
+ * It is possible to queue more than one DMA buffer onto a channel at
+ * once, and the code will deal with the re-loading of the next buffer
+ * when necessary.
+*/
+
+int s3c2410_dma_enqueue(unsigned int channel, void *id,
+ dma_addr_t data, int size)
+{
+ s3c2410_dma_chan_t *chan = &s3c2410_chans[channel];
+ s3c2410_dma_buf_t *buf;
+ unsigned long flags;
+
+ check_channel(channel);
+
+ pr_debug("%s: id=%p, data=%08x, size=%d\n",
+ __FUNCTION__, id, (unsigned int)data, size);
+
+ buf = (s3c2410_dma_buf_t *)kmalloc(sizeof(*buf), GFP_ATOMIC);
+ if (buf == NULL) {
+ pr_debug("%s: out of memory (%d alloc)\n",
+ __FUNCTION__, sizeof(*buf));
+ return -ENOMEM;
+ }
+
+ pr_debug("%s: new buffer %p\n", __FUNCTION__, buf);
+
+ //dbg_showchan(chan);
+
+ buf->next = NULL;
+ buf->data = buf->ptr = data;
+ buf->size = size;
+ buf->id = id;
+ buf->magic = BUF_MAGIC;
+
+ local_irq_save(flags);
+
+ if (chan->curr == NULL) {
+ /* we've got nothing loaded... */
+ pr_debug("%s: buffer %p queued onto empty channel\n",
+ __FUNCTION__, buf);
+
+ chan->curr = buf;
+ chan->end = buf;
+ chan->next = NULL;
+ } else {
+ pr_debug("dma%d: %s: buffer %p queued onto non-empty channel\n",
+ chan->number, __FUNCTION__, buf);
+
+ if (chan->end == NULL)
+ pr_debug("dma%d: %s: %p not empty, and chan->end==NULL?\n",
+ chan->number, __FUNCTION__, chan);
+
+ chan->end->next = buf;
+ chan->end = buf;
+ }
+
+ /* if necessary, update the next buffer field */
+ if (chan->next == NULL)
+ chan->next = buf;
+
+ /* check to see if we can load a buffer */
+ if (chan->state == S3C2410_DMA_RUNNING) {
+ if (chan->load_state == S3C2410_DMALOAD_1LOADED && 1) {
+ if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {
+ printk(KERN_ERR "dma%d: loadbuffer:"
+ "timeout loading buffer\n",
+ chan->number);
+ dbg_showchan(chan);
+ local_irq_restore(flags);
+ return -EINVAL;
+ }
+ }
+
+ while (s3c2410_dma_canload(chan) && chan->next != NULL) {
+ s3c2410_dma_loadbuffer(chan, chan->next);
+ }
+ } else if (chan->state == S3C2410_DMA_IDLE) {
+ if (chan->flags & S3C2410_DMAF_AUTOSTART) {
+ s3c2410_dma_ctrl(chan->number, S3C2410_DMAOP_START);
+ } else {
+ printk(KERN_DEBUG "dma%d: cannot load onto stopped channel'n", chan->number);
+ local_irq_restore(flags);
+ return -EINVAL;
+ }
+ }
+
+ local_irq_restore(flags);
+ return 0;
+}
+
+static inline void
+s3c2410_dma_freebuf(s3c2410_dma_buf_t *buf)
+{
+ int magicok = (buf->magic == BUF_MAGIC);
+
+ buf->magic = -1;
+
+ if (magicok) {
+ kfree(buf);
+ } else {
+ printk("s3c2410_dma_freebuf: buff %p with bad magic\n", buf);
+ }
+}
+
+/* s3c2410_dma_lastxfer
+ *
+ * called when the system is out of buffers, to ensure that the channel
+ * is prepared for shutdown.
+*/
+
+static inline void
+s3c2410_dma_lastxfer(s3c2410_dma_chan_t *chan)
+{
+ pr_debug("dma%d: s3c2410_dma_lastxfer: load_state %d\n",
+ chan->number, chan->load_state);
+
+ switch (chan->load_state) {
+ case S3C2410_DMALOAD_NONE:
+ break;
+
+ case S3C2410_DMALOAD_1LOADED:
+ if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {
+ /* flag error? */
+ printk(KERN_ERR "dma%d: timeout waiting for load\n",
+ chan->number);
+ return;
+ }
+ break;
+
+ default:
+ pr_debug("dma%d: lastxfer: unhandled load_state %d with no next",
+ chan->number, chan->load_state);
+ return;
+
+ }
+
+ /* hopefully this'll shut the damned thing up after the transfer... */
+ dma_wrreg(chan, S3C2410_DMA_DCON, chan->dcon | S3C2410_DCON_NORELOAD);
+}
+
+
+#define dmadbg2(x...)
+
+static irqreturn_t
+s3c2410_dma_irq(int irq, void *devpw, struct pt_regs *regs)
+{
+ s3c2410_dma_chan_t *chan = (s3c2410_dma_chan_t *)devpw;
+ s3c2410_dma_buf_t *buf;
+
+ buf = chan->curr;
+
+ dbg_showchan(chan);
+
+ /* modify the channel state */
+
+ switch (chan->load_state) {
+ case S3C2410_DMALOAD_1RUNNING:
+ /* TODO - if we are running only one buffer, we probably
+ * want to reload here, and then worry about the buffer
+ * callback */
+
+ chan->load_state = S3C2410_DMALOAD_NONE;
+ break;
+
+ case S3C2410_DMALOAD_1LOADED:
+ /* iirc, we should go back to NONE loaded here, we
+ * had a buffer, and it was never verified as being
+ * loaded.
+ */
+
+ chan->load_state = S3C2410_DMALOAD_NONE;
+ break;
+
+ case S3C2410_DMALOAD_1LOADED_1RUNNING:
+ /* we'll worry about checking to see if another buffer is
+ * ready after we've called back the owner. This should
+ * ensure we do not wait around too long for the DMA
+ * engine to start the next transfer
+ */
+
+ chan->load_state = S3C2410_DMALOAD_1LOADED;
+ break;
+
+ case S3C2410_DMALOAD_NONE:
+ printk(KERN_ERR "dma%d: IRQ with no loaded buffer?\n",
+ chan->number);
+ break;
+
+ default:
+ printk(KERN_ERR "dma%d: IRQ in invalid load_state %d\n",
+ chan->number, chan->load_state);
+ break;
+ }
+
+ if (buf != NULL) {
+ /* update the chain to make sure that if we load any more
+ * buffers when we call the callback function, things should
+ * work properly */
+
+ chan->curr = buf->next;
+ buf->next = NULL;
+
+ if (buf->magic != BUF_MAGIC) {
+ printk(KERN_ERR "dma%d: %s: buf %p incorrect magic\n",
+ chan->number, __FUNCTION__, buf);
+ return IRQ_HANDLED;
+ }
+
+ s3c2410_dma_buffdone(chan, buf, S3C2410_RES_OK);
+
+ /* free resouces */
+ s3c2410_dma_freebuf(buf);
+ } else {
+ }
+
+ if (chan->next != NULL) {
+ unsigned long flags;
+
+ switch (chan->load_state) {
+ case S3C2410_DMALOAD_1RUNNING:
+ /* don't need to do anything for this state */
+ break;
+
+ case S3C2410_DMALOAD_NONE:
+ /* can load buffer immediately */
+ break;
+
+ case S3C2410_DMALOAD_1LOADED:
+ if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {
+ /* flag error? */
+ printk(KERN_ERR "dma%d: timeout waiting for load\n",
+ chan->number);
+ return IRQ_HANDLED;
+ }
+
+ break;
+
+ default:
+ printk(KERN_ERR "dma%d: unknown load_state in irq, %d\n",
+ chan->number, chan->load_state);
+ return IRQ_HANDLED;
+ }
+
+ local_irq_save(flags);
+ s3c2410_dma_loadbuffer(chan, chan->next);
+ local_irq_restore(flags);
+ } else {
+ s3c2410_dma_lastxfer(chan);
+
+ /* see if we can stop this channel.. */
+ if (chan->load_state == S3C2410_DMALOAD_NONE) {
+ pr_debug("dma%d: end of transfer, stopping channel (%ld)\n",
+ chan->number, jiffies);
+ s3c2410_dma_ctrl(chan->number, S3C2410_DMAOP_STOP);
+ }
+ }
+
+ return IRQ_HANDLED;
+}
+
+
+
+/* s3c2410_request_dma
+ *
+ * get control of an dma channel
+*/
+
+int s3c2410_dma_request(unsigned int channel, s3c2410_dma_client_t *client,
+ void *dev)
+{
+ s3c2410_dma_chan_t *chan = &s3c2410_chans[channel];
+ unsigned long flags;
+ int err;
+
+ pr_debug("dma%d: s3c2410_request_dma: client=%s, dev=%p\n",
+ channel, client->name, dev);
+
+ check_channel(channel);
+
+ local_irq_save(flags);
+
+ dbg_showchan(chan);
+
+ if (chan->in_use) {
+ if (client != chan->client) {
+ printk(KERN_ERR "dma%d: already in use\n", channel);
+ local_irq_restore(flags);
+ return -EBUSY;
+ } else {
+ printk(KERN_ERR "dma%d: client already has channel\n", channel);
+ }
+ }
+
+ chan->client = client;
+ chan->in_use = 1;
+
+ if (!chan->irq_claimed) {
+ pr_debug("dma%d: %s : requesting irq %d\n",
+ channel, __FUNCTION__, chan->irq);
+
+ err = request_irq(chan->irq, s3c2410_dma_irq, SA_INTERRUPT,
+ client->name, (void *)chan);
+
+ if (err) {
+ chan->in_use = 0;
+ local_irq_restore(flags);
+
+ printk(KERN_ERR "%s: cannot get IRQ %d for DMA %d\n",
+ client->name, chan->irq, chan->number);
+ return err;
+ }
+
+ chan->irq_claimed = 1;
+ chan->irq_enabled = 1;
+ }
+
+ local_irq_restore(flags);
+
+ /* need to setup */
+
+ pr_debug("%s: channel initialised, %p\n", __FUNCTION__, chan);
+
+ return 0;
+}
+
+/* s3c2410_dma_free
+ *
+ * release the given channel back to the system, will stop and flush
+ * any outstanding transfers, and ensure the channel is ready for the
+ * next claimant.
+ *
+ * Note, although a warning is currently printed if the freeing client
+ * info is not the same as the registrant's client info, the free is still
+ * allowed to go through.
+*/
+
+int s3c2410_dma_free(dmach_t channel, s3c2410_dma_client_t *client)
+{
+ s3c2410_dma_chan_t *chan = &s3c2410_chans[channel];
+ unsigned long flags;
+
+ check_channel(channel);
+
+ local_irq_save(flags);
+
+
+ if (chan->client != client) {
+ printk(KERN_WARNING "dma%d: possible free from different client (channel %p, passed %p)\n",
+ channel, chan->client, client);
+ }
+
+ /* sort out stopping and freeing the channel */
+
+ if (chan->state != S3C2410_DMA_IDLE) {
+ pr_debug("%s: need to stop dma channel %p\n",
+ __FUNCTION__, chan);
+
+ /* possibly flush the channel */
+ s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STOP);
+ }
+
+ chan->client = NULL;
+ chan->in_use = 0;
+
+ local_irq_restore(flags);
+
+ return 0;
+}
+
+static int s3c2410_dma_dostop(s3c2410_dma_chan_t *chan)
+{
+ unsigned long tmp;
+ unsigned long flags;
+
+ pr_debug("%s:\n", __FUNCTION__);
+
+ dbg_showchan(chan);
+
+ local_irq_save(flags);
+
+ s3c2410_dma_call_op(chan, S3C2410_DMAOP_STOP);
+
+ tmp = dma_rdreg(chan, S3C2410_DMA_DMASKTRIG);
+ tmp |= S3C2410_DMASKTRIG_STOP;
+ dma_wrreg(chan, S3C2410_DMA_DMASKTRIG, tmp);
+
+#if 0
+ /* should also clear interrupts, according to WinCE BSP */
+ tmp = dma_rdreg(chan, S3C2410_DMA_DCON);
+ tmp |= S3C2410_DCON_NORELOAD;
+ dma_wrreg(chan, S3C2410_DMA_DCON, tmp);
+#endif
+
+ chan->state = S3C2410_DMA_IDLE;
+ chan->load_state = S3C2410_DMALOAD_NONE;
+
+ local_irq_restore(flags);
+
+ return 0;
+}
+
+/* s3c2410_dma_flush
+ *
+ * stop the channel, and remove all current and pending transfers
+*/
+
+static int s3c2410_dma_flush(s3c2410_dma_chan_t *chan)
+{
+ s3c2410_dma_buf_t *buf, *next;
+ unsigned long flags;
+
+ pr_debug("%s:\n", __FUNCTION__);
+
+ local_irq_save(flags);
+
+ if (chan->state != S3C2410_DMA_IDLE) {
+ pr_debug("%s: stopping channel...\n", __FUNCTION__ );
+ s3c2410_dma_ctrl(chan->number, S3C2410_DMAOP_STOP);
+ }
+
+ buf = chan->curr;
+ if (buf == NULL)
+ buf = chan->next;
+
+ chan->curr = chan->next = chan->end = NULL;
+
+ if (buf != NULL) {
+ for ( ; buf != NULL; buf = next) {
+ next = buf->next;
+
+ pr_debug("%s: free buffer %p, next %p\n",
+ __FUNCTION__, buf, buf->next);
+
+ s3c2410_dma_buffdone(chan, buf, S3C2410_RES_ABORT);
+ s3c2410_dma_freebuf(buf);
+ }
+ }
+
+ local_irq_restore(flags);
+
+ return 0;
+}
+
+
+int
+s3c2410_dma_ctrl(dmach_t channel, s3c2410_chan_op_t op)
+{
+ s3c2410_dma_chan_t *chan = &s3c2410_chans[channel];
+
+ check_channel(channel);
+
+ switch (op) {
+ case S3C2410_DMAOP_START:
+ return s3c2410_dma_start(chan);
+
+ case S3C2410_DMAOP_STOP:
+ return s3c2410_dma_dostop(chan);
+
+ case S3C2410_DMAOP_PAUSE:
+ return -ENOENT;
+
+ case S3C2410_DMAOP_RESUME:
+ return -ENOENT;
+
+ case S3C2410_DMAOP_FLUSH:
+ return s3c2410_dma_flush(chan);
+
+ case S3C2410_DMAOP_TIMEOUT:
+ return 0;
+
+ }
+
+ return -ENOENT; /* unknown, don't bother */
+}
+
+
+/* DMA configuration for each channel
+ *
+ * DISRCC -> source of the DMA (AHB,APB)
+ * DISRC -> source address of the DMA
+ * DIDSTC -> destination of the DMA (AHB,APD)
+ * DIDST -> destination address of the DMA
+*/
+
+/* s3c2410_dma_config
+ *
+ * xfersize: size of unit in bytes (1,2,4)
+ * dcon: base value of the DCONx register
+*/
+
+int s3c2410_dma_config(dmach_t channel,
+ int xferunit,
+ int dcon)
+{
+ s3c2410_dma_chan_t *chan = &s3c2410_chans[channel];
+
+ pr_debug("%s: chan=%d, xfer_unit=%d, dcon=%08x\n",
+ __FUNCTION__, channel, xferunit, dcon);
+
+ check_channel(channel);
+
+ switch (xferunit) {
+ case 1:
+ dcon |= S3C2410_DCON_BYTE;
+ break;
+
+ case 2:
+ dcon |= S3C2410_DCON_HALFWORD;
+ break;
+
+ case 4:
+ dcon |= S3C2410_DCON_WORD;
+ break;
+
+ default:
+ pr_debug("%s: bad transfer size %d\n", __FUNCTION__, xferunit);
+ return -EINVAL;
+ }
+
+ dcon |= S3C2410_DCON_HWTRIG;
+ dcon |= S3C2410_DCON_INTREQ;
+
+ pr_debug("%s: dcon now %08x\n", __FUNCTION__, dcon);
+
+ chan->dcon = dcon;
+ chan->xfer_unit = xferunit;
+
+ return 0;
+}
+
+
+int s3c2410_dma_setflags(dmach_t channel, unsigned int flags)
+{
+ s3c2410_dma_chan_t *chan = &s3c2410_chans[channel];
+
+ check_channel(channel);
+
+ pr_debug("%s: chan=%p, flags=%08x\n", __FUNCTION__, chan, flags);
+
+ chan->flags = flags;
+
+ return 0;
+}
+
+/* do we need to protect the settings of the fields from
+ * irq?
+*/
+
+int s3c2410_dma_set_opfn(dmach_t channel, s3c2410_dma_opfn_t rtn)
+{
+ s3c2410_dma_chan_t *chan = &s3c2410_chans[channel];
+
+ check_channel(channel);
+
+ pr_debug("%s: chan=%p, op rtn=%p\n", __FUNCTION__, chan, rtn);
+
+ chan->op_fn = rtn;
+
+ return 0;
+}
+
+int s3c2410_dma_set_buffdone_fn(dmach_t channel, s3c2410_dma_cbfn_t rtn)
+{
+ s3c2410_dma_chan_t *chan = &s3c2410_chans[channel];
+
+ check_channel(channel);
+
+ pr_debug("%s: chan=%p, callback rtn=%p\n", __FUNCTION__, chan, rtn);
+
+ chan->callback_fn = rtn;
+
+ return 0;
+}
+
+/* s3c2410_dma_devconfig
+ *
+ * configure the dma source/destination hardware type and address
+ *
+ * source: S3C2410_DMASRC_HW: source is hardware
+ * S3C2410_DMASRC_MEM: source is memory
+ *
+ * hwcfg: the value for xxxSTCn register,
+ * bit 0: 0=increment pointer, 1=leave pointer
+ * bit 1: 0=soucre is AHB, 1=soucre is APB
+ *
+ * devaddr: physical address of the source
+*/
+
+int s3c2410_dma_devconfig(int channel,
+ s3c2410_dmasrc_t source,
+ int hwcfg,
+ unsigned long devaddr)
+{
+ s3c2410_dma_chan_t *chan = &s3c2410_chans[channel];
+
+ check_channel(channel);
+
+ pr_debug("%s: source=%d, hwcfg=%08x, devaddr=%08lx\n",
+ __FUNCTION__, (int)source, hwcfg, devaddr);
+
+ chan->source = source;
+ chan->dev_addr = devaddr;
+
+ switch (source) {
+ case S3C2410_DMASRC_HW:
+ /* source is hardware */
+ pr_debug("%s: hw source, devaddr=%08lx, hwcfg=%d\n",
+ __FUNCTION__, devaddr, hwcfg);
+ dma_wrreg(chan, S3C2410_DMA_DISRCC, hwcfg & 3);
+ dma_wrreg(chan, S3C2410_DMA_DISRC, devaddr);
+ dma_wrreg(chan, S3C2410_DMA_DIDSTC, (0<<1) | (0<<0));
+
+ chan->addr_reg = dma_regaddr(chan, S3C2410_DMA_DIDST);
+ return 0;
+
+ case S3C2410_DMASRC_MEM:
+ /* source is memory */
+ pr_debug( "%s: mem source, devaddr=%08lx, hwcfg=%d\n",
+ __FUNCTION__, devaddr, hwcfg);
+ dma_wrreg(chan, S3C2410_DMA_DISRCC, (0<<1) | (0<<0));
+ dma_wrreg(chan, S3C2410_DMA_DIDST, devaddr);
+ dma_wrreg(chan, S3C2410_DMA_DIDSTC, hwcfg & 3);
+
+ chan->addr_reg = dma_regaddr(chan, S3C2410_DMA_DISRC);
+ return 0;
+ }
+
+ printk(KERN_ERR "dma%d: invalid source type (%d)\n", channel, source);
+ return -EINVAL;
+}
+
+/* initialisation code */
+
+static int __init s3c2410_init_dma(void)
+{
+ int channel;
+ s3c2410_dma_chan_t *cp;
+
+ printk("S3C2410 DMA Driver, (c) 2003-2004 Simtec Electronics\n");
+
+ dma_base = ioremap(S3C2410_PA_DMA, 0x200);
+ if (dma_base == NULL) {
+ printk(KERN_ERR "dma failed to remap register block\n");
+ return -ENOMEM;
+ }
+
+ for (channel = 0; channel < S3C2410_DMA_CHANNELS; channel++) {
+ cp = &s3c2410_chans[channel];
+
+ memset(cp, 0, sizeof(s3c2410_dma_chan_t));
+
+ /* dma channel irqs are in order.. */
+ cp->number = channel;
+ cp->irq = channel + IRQ_DMA0;
+ cp->regs = (unsigned long)dma_base + (channel*0x40);
+
+ /* point current stats somewhere */
+ cp->stats = &cp->stats_store;
+ cp->stats_store.timeout_shortest = LONG_MAX;
+
+ /* basic channel configuration */
+
+ cp->load_timeout = 1<<18;
+
+ printk("DMA channel %d at %08lx, irq %d\n",
+ cp->number, cp->regs, cp->irq);
+ }
+
+ return 0;
+}
+
+__initcall(s3c2410_init_dma);
diff --git a/arch/arm/mach-s3c2410/irq.c b/arch/arm/mach-s3c2410/irq.c
index 878b9740d63e12..35f8072c034b63 100644
--- a/arch/arm/mach-s3c2410/irq.c
+++ b/arch/arm/mach-s3c2410/irq.c
@@ -1,6 +1,6 @@
/* linux/arch/arm/mach-s3c2410/irq.c
*
- * Copyright (c) 2003 Simtec Electronics
+ * Copyright (c) 2003,2004 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
*
* This program is free software; you can redistribute it and/or modify
@@ -17,6 +17,16 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
+ * Changelog:
+ *
+ * 22-Jul-2004 Ben Dooks <ben@simtec.co.uk>
+ * Fixed compile warnings
+ *
+ * 22-Jul-2004 Roc Wu <cooloney@yahoo.com.cn>
+ * Fixed s3c_extirq_type
+ *
+ * 21-Jul-2004 Arnaud Patard (Rtp) <arnaud.patard@rtp-net.org>
+ * Addition of ADC/TC demux
*/
@@ -34,7 +44,7 @@
#include <asm/mach/irq.h>
#include <asm/arch/regs-irq.h>
-#include <asm/arch/regs-lcd.h>
+#include <asm/arch/regs-gpio.h>
#if 0
#include <asm/debug-ll.h>
@@ -177,12 +187,77 @@ s3c_irqext_unmask(unsigned int irqno)
s3c_irq_unmask((irqno <= (IRQ_EINT7 - EXTINT_OFF)) ? IRQ_EINT4t7 : IRQ_EINT8t23);
}
-/* todo - put type handler in here */
-
static int
s3c_irqext_type(unsigned int irq, unsigned int type)
{
- irqdbf("s3c_irqext_type: called for irq %d, type %d\n", irq, type);
+ unsigned long extint_reg;
+ unsigned long gpcon_reg;
+ unsigned long gpcon_offset, extint_offset;
+ unsigned long newvalue = 0, value;
+
+ if ((irq >= IRQ_EINT0) && (irq <= IRQ_EINT7))
+ {
+ gpcon_reg = S3C2410_GPFCON;
+ extint_reg = S3C2410_EXTINT0;
+ gpcon_offset = (irq - IRQ_EINT0) * 2;
+ extint_offset = (irq - IRQ_EINT0) * 4;
+ }
+ else if ((irq >= IRQ_EINT8) && (irq <= IRQ_EINT15))
+ {
+ gpcon_reg = S3C2410_GPGCON;
+ extint_reg = S3C2410_EXTINT1;
+ gpcon_offset = (irq - IRQ_EINT8) * 2;
+ extint_offset = (irq - IRQ_EINT8) * 4;
+ }
+ else if ((irq >= IRQ_EINT16) && (irq <= IRQ_EINT23))
+ {
+ gpcon_reg = S3C2410_GPGCON;
+ extint_reg = S3C2410_EXTINT2;
+ gpcon_offset = (irq - IRQ_EINT8) * 2;
+ extint_offset = (irq - IRQ_EINT16) * 4;
+ } else
+ return -1;
+
+ /* Set the GPIO to external interrupt mode */
+ value = __raw_readl(gpcon_reg);
+ value = (value & ~(3 << gpcon_offset)) | (0x02 << gpcon_offset);
+ __raw_writel(value, gpcon_reg);
+
+ /* Set the external interrupt to pointed trigger type */
+ switch (type)
+ {
+ case IRQT_NOEDGE:
+ printk(KERN_WARNING "No edge setting!\n");
+ break;
+
+ case IRQT_RISING:
+ newvalue = S3C2410_EXTINT_RISEEDGE;
+ break;
+
+ case IRQT_FALLING:
+ newvalue = S3C2410_EXTINT_FALLEDGE;
+ break;
+
+ case IRQT_BOTHEDGE:
+ newvalue = S3C2410_EXTINT_BOTHEDGE;
+ break;
+
+ case IRQT_LOW:
+ newvalue = S3C2410_EXTINT_LOWLEV;
+ break;
+
+ case IRQT_HIGH:
+ newvalue = S3C2410_EXTINT_HILEV;
+ break;
+
+ default:
+ printk(KERN_ERR "No such irq type %d", type);
+ return -1;
+ }
+
+ value = __raw_readl(extint_reg);
+ value = (value & ~(7 << extint_offset)) | (newvalue << extint_offset);
+ __raw_writel(value, extint_reg);
return 0;
}
@@ -368,37 +443,37 @@ static struct irqchip s3c_irq_adc = {
.ack = s3c_irq_adc_ack,
};
-#if 0
-/* LCD (todo) */
-
-static void
-s3c_irq_lcd_mask(unsigned int irqno)
+/* irq demux for adc */
+static void s3c_irq_demux_adc(unsigned int irq,
+ struct irqdesc *desc,
+ struct pt_regs *regs)
{
+ unsigned int subsrc, submsk;
+ unsigned int offset = 9;
+ struct irqdesc *mydesc;
-}
-
-static void
-s3c_irq_lcd_unmask(unsigned int irqno)
-{
+ /* read the current pending interrupts, and the mask
+ * for what it is available */
-}
+ subsrc = __raw_readl(S3C2410_SUBSRCPND);
+ submsk = __raw_readl(S3C2410_INTSUBMSK);
-static void
-s3c_irq_lcd_ack(unsigned int irqno)
-{
+ subsrc &= ~submsk;
+ subsrc >>= offset;
+ subsrc &= 3;
+ if (subsrc != 0) {
+ if (subsrc & 1) {
+ mydesc = irq_desc + IRQ_TC;
+ mydesc->handle( IRQ_TC, mydesc, regs);
+ }
+ if (subsrc & 2) {
+ mydesc = irq_desc + IRQ_ADC;
+ mydesc->handle(IRQ_ADC, mydesc, regs);
+ }
+ }
}
-static struct irqchip s3c_irq_lcd = {
- .mask = s3c_irq_lcd_mask,
- .unmask = s3c_irq_lcd_unmask,
- .ack = s3c_irq_lcd_ack,
-};
-#endif
-
-/* irq demux */
-
-
static void s3c_irq_demux_uart(unsigned int start,
struct pt_regs *regs)
{
@@ -466,7 +541,10 @@ s3c_irq_demux_uart2(unsigned int irq,
s3c_irq_demux_uart(IRQ_S3CUART_RX2, regs);
}
-
+/* s3c2410_init_irq
+ *
+ * Initialise S3C2410 IRQ system
+*/
void __init s3c2410_init_irq(void)
{
@@ -509,7 +587,7 @@ void __init s3c2410_init_irq(void)
irqdbf("s3c2410_init_irq: registering s3c2410 interrupt handlers\n");
- for (irqno = IRQ_EINT0; irqno < IRQ_ADCPARENT; irqno++) {
+ for (irqno = IRQ_EINT0; irqno <= IRQ_ADCPARENT; irqno++) {
/* set all the s3c2410 internal irqs */
switch (irqno) {
@@ -549,8 +627,7 @@ void __init s3c2410_init_irq(void)
set_irq_chained_handler(IRQ_UART0, s3c_irq_demux_uart0);
set_irq_chained_handler(IRQ_UART1, s3c_irq_demux_uart1);
set_irq_chained_handler(IRQ_UART2, s3c_irq_demux_uart2);
- //set_irq_chained_handler(IRQ_LCD, s3c_irq_demux_);
- //set_irq_chained_handler(IRQ_ADCPARENT, s3c_irq_demux_);
+ set_irq_chained_handler(IRQ_ADCPARENT, s3c_irq_demux_adc);
/* external interrupts */
diff --git a/arch/arm/mach-s3c2410/s3c2410.h b/arch/arm/mach-s3c2410/s3c2410.h
index 862a7c86d2945d..cc139f43ede0d6 100644
--- a/arch/arm/mach-s3c2410/s3c2410.h
+++ b/arch/arm/mach-s3c2410/s3c2410.h
@@ -1,4 +1,18 @@
-
+/* arch/arm/mach-s3c2410/s3c2410.h
+ *
+ * Copyright (c) 2004 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * Header file for s3c2410 machine directory
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Modifications:
+ * 18-Aug-2004 BJD Created initial version
+ *
+*/
extern void s3c2410_map_io(struct map_desc *, int count);
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 545a548b1f69fe..616d4b6e8cccd9 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -59,7 +59,7 @@ config CPU_ARM720T
# ARM920T
config CPU_ARM920T
bool "Support ARM920T processor" if !ARCH_S3C2410
- depends on ARCH_INTEGRATOR || ARCH_S3C2410
+ depends on ARCH_INTEGRATOR || ARCH_S3C2410 || ARCH_IMX
default y if ARCH_S3C2410
select CPU_32v4
select CPU_ABRT_EV4T
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 060fea2e10cb03..cc2f7a8b3f2929 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -344,7 +344,7 @@ static inline void free_bootmem_node_bank(int node, struct meminfo *mi)
* Initialise the bootmem allocator for all nodes. This is called
* early during the architecture specific initialisation.
*/
-void __init bootmem_init(struct meminfo *mi)
+static void __init bootmem_init(struct meminfo *mi)
{
struct node_info node_info[MAX_NUMNODES], *np = node_info;
unsigned int bootmap_pages, bootmap_pfn, map_pg;
@@ -412,9 +412,7 @@ void __init bootmem_init(struct meminfo *mi)
}
#endif
- if (map_pg != bootmap_pfn + bootmap_pages)
- BUG();
-
+ BUG_ON(map_pg != bootmap_pfn + bootmap_pages);
}
/*
@@ -426,6 +424,8 @@ void __init paging_init(struct meminfo *mi, struct machine_desc *mdesc)
void *zero_page;
int node;
+ bootmem_init(mi);
+
memcpy(&meminfo, mi, sizeof(meminfo));
/*
diff --git a/arch/arm/mm/proc-xscale.S b/arch/arm/mm/proc-xscale.S
index 2652d141fad9bc..047847d74b7db5 100644
--- a/arch/arm/mm/proc-xscale.S
+++ b/arch/arm/mm/proc-xscale.S
@@ -585,7 +585,12 @@ __xscale_setup:
mcr p15, 0, r4, c2, c0, 0 @ load page table pointer
mov r0, #0x1f @ Domains 0, 1 = client
mcr p15, 0, r0, c3, c0, 0 @ load domain access register
- mov r0, #1 @ Allow access to CP0 and CP13
+#ifdef CONFIG_IWMMXT
+ mov r0, #0 @ initially disallow access to CP0/CP1
+#else
+ mov r0, #1 @ Allow access to CP0
+#endif
+ orr r0, r0, #1 << 6 @ cp6 for IOP3xx and Bulverde
orr r0, r0, #1 << 13 @ Its undefined whether this
mcr p15, 0, r0, c15, c1, 0 @ affects USR or SVC modes
mrc p15, 0, r0, c1, c0, 0 @ get control register
diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types
index d2ce223722dabd..f85856f024a760 100644
--- a/arch/arm/tools/mach-types
+++ b/arch/arm/tools/mach-types
@@ -6,7 +6,7 @@
# To add an entry into this database, please see Documentation/arm/README,
# or contact rmk@arm.linux.org.uk
#
-# Last update: Fri Jul 2 11:58:36 2004
+# Last update: Mon Aug 16 19:22:37 2004
#
# machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number
#
@@ -559,3 +559,30 @@ lpc2294 MACH_LPC2294 LPC2294 548
switchgrass MACH_SWITCHGRASS SWITCHGRASS 549
ens_cmu MACH_ENS_CMU ENS_CMU 550
mm6_sdb MACH_MM6_SDB MM6_SDB 551
+saturn MACH_SATURN SATURN 552
+argonplusevb MACH_ARGONPLUSEVB ARGONPLUSEVB 553
+scma11evb MACH_SCMA11EVB SCMA11EVB 554
+smdk2800 MACH_SMDK2800 SMDK2800 555
+mtwilson MACH_MTWILSON MTWILSON 556
+ziti MACH_ZITI ZITI 557
+grandfather MACH_GRANDFATHER GRANDFATHER 558
+tengine MACH_TENGINE TENGINE 559
+s3c2460 MACH_S3C2460 S3C2460 560
+pdm MACH_PDM PDM 561
+h4700 MACH_H4700 H4700 562
+h6300 MACH_H6300 H6300 563
+rz1700 MACH_RZ1700 RZ1700 564
+a716 MACH_A716 A716 565
+estk2440a MACH_ESTK2440A ESTK2440A 566
+atwixp425 MACH_ATWIXP425 ATWIXP425 567
+csb336 MACH_CSB336 CSB336 568
+rirm2 MACH_RIRM2 RIRM2 569
+cx23518 MACH_CX23518 CX23518 570
+cx2351x MACH_CX2351X CX2351X 571
+computime MACH_COMPUTIME COMPUTIME 572
+izarus MACH_IZARUS IZARUS 573
+pxa_rts MACH_RTS RTS 574
+netgate5100 MACH_NETGATE5100 NETGATE5100 575
+s3c2510 MACH_S3C2510 S3C2510 576
+csb437tl MACH_CSB437TL CSB437TL 577
+slauson MACH_SLAUSON SLAUSON 578