diff --git a/[refs] b/[refs]
index 3796d5fdfea9..1f3de53ceda8 100644
--- a/[refs]
+++ b/[refs]
@@ -1,2 +1,2 @@
---
-refs/heads/master: 78c2644feccf78ecab8e9413d2fac83cda091bae
+refs/heads/master: dcda7e4ba1adec80089ec784964b32f9fd653237
diff --git a/trunk/Documentation/arm/Samsung-S3C24XX/DMA.txt b/trunk/Documentation/arm/Samsung-S3C24XX/DMA.txt
deleted file mode 100644
index 37f4edcc5d87..000000000000
--- a/trunk/Documentation/arm/Samsung-S3C24XX/DMA.txt
+++ /dev/null
@@ -1,46 +0,0 @@
- S3C2410 DMA
- ===========
-
-Introduction
-------------
-
- The kernel provides an interface to manage DMA transfers
- using the DMA channels in the cpu, so that the central
- duty of managing channel mappings, and programming the
- channel generators is in one place.
-
-
-DMA Channel Ordering
---------------------
-
- Many of the range do not have connections for the DMA
- channels to all sources, which means that some devices
- have a restricted number of channels that can be used.
-
- To allow flexibilty for each cpu type and board, the
- dma code can be given an dma ordering structure which
- allows the order of channel search to be specified, as
- well as allowing the prohibition of certain claims.
-
- struct s3c24xx_dma_order has a list of channels, and
- each channel within has a slot for a list of dma
- channel numbers. The slots are searched in order, for
- the presence of a dma channel number with DMA_CH_VALID
- orred in.
-
- If the order has the flag DMA_CH_NEVER set, then after
- checking the channel list, the system will return no
- found channel, thus denying the request.
-
- A board support file can call s3c24xx_dma_order_set()
- to register an complete ordering set. The routine will
- copy the data, so the original can be discared with
- __initdata.
-
-
-Authour
--------
-
-Ben Dooks,
-Copyright (c) 2007 Ben Dooks, Simtec Electronics
-Licensed under the GPL v2
diff --git a/trunk/Documentation/arm/Samsung-S3C24XX/Overview.txt b/trunk/Documentation/arm/Samsung-S3C24XX/Overview.txt
index c31b76fa66c4..28d014714ab8 100644
--- a/trunk/Documentation/arm/Samsung-S3C24XX/Overview.txt
+++ b/trunk/Documentation/arm/Samsung-S3C24XX/Overview.txt
@@ -8,10 +8,13 @@ Introduction
The Samsung S3C24XX range of ARM9 System-on-Chip CPUs are supported
by the 's3c2410' architecture of ARM Linux. Currently the S3C2410,
- S3C2412, S3C2413, S3C2440 and S3C2442 devices are supported.
+ S3C2440 and S3C2442 devices are supported.
Support for the S3C2400 series is in progress.
+ Support for the S3C2412 and S3C2413 CPUs is being merged.
+
+
Configuration
-------------
@@ -23,22 +26,6 @@ Configuration
please check the machine specific documentation.
-Layout
-------
-
- The core support files are located in the platform code contained in
- arch/arm/plat-s3c24xx with headers in include/asm-arm/plat-s3c24xx.
- This directory should be kept to items shared between the platform
- code (arch/arm/plat-s3c24xx) and the arch/arm/mach-s3c24* code.
-
- Each cpu has a directory with the support files for it, and the
- machines that carry the device. For example S3C2410 is contained
- in arch/arm/mach-s3c2410 and S3C2440 in arch/arm/mach-s3c2440
-
- Register, kernel and platform data definitions are held in the
- include/asm-arm/arch-s3c2410 directory.
-
-
Machines
--------
diff --git a/trunk/arch/arm/Kconfig b/trunk/arch/arm/Kconfig
index 0f711c4394a9..6783c2e5512d 100644
--- a/trunk/arch/arm/Kconfig
+++ b/trunk/arch/arm/Kconfig
@@ -303,7 +303,7 @@ config ARCH_SA1100
Support for StrongARM 11x0 based boards.
config ARCH_S3C2410
- bool "Samsung S3C2410, S3C2412, S3C2413, S3C2440, S3C2442, S3C2443"
+ bool "Samsung S3C2410, S3C2412, S3C2413, S3C2440, S3C2442"
help
Samsung S3C2410X CPU based systems, such as the Simtec Electronics
BAST (), the IPAQ 1940 or
@@ -363,16 +363,7 @@ source "arch/arm/mach-omap1/Kconfig"
source "arch/arm/mach-omap2/Kconfig"
-source "arch/arm/plat-s3c24xx/Kconfig"
-
-if ARCH_S3C2410
-source "arch/arm/mach-s3c2400/Kconfig"
source "arch/arm/mach-s3c2410/Kconfig"
-source "arch/arm/mach-s3c2412/Kconfig"
-source "arch/arm/mach-s3c2440/Kconfig"
-source "arch/arm/mach-s3c2442/Kconfig"
-source "arch/arm/mach-s3c2443/Kconfig"
-endif
source "arch/arm/mach-lh7a40x/Kconfig"
diff --git a/trunk/arch/arm/Makefile b/trunk/arch/arm/Makefile
index 93e474726725..000f1100b553 100644
--- a/trunk/arch/arm/Makefile
+++ b/trunk/arch/arm/Makefile
@@ -149,7 +149,7 @@ MACHINE := arch/arm/mach-$(machine-y)/
else
MACHINE :=
endif
-
+
export TEXT_OFFSET GZFLAGS MMUEXT
# Do we have FASTFPE?
@@ -161,11 +161,6 @@ endif
# If we have a machine-specific directory, then include it in the build.
core-y += arch/arm/kernel/ arch/arm/mm/ arch/arm/common/
core-y += $(MACHINE)
-core-$(CONFIG_ARCH_S3C2410) += arch/arm/mach-s3c2400/
-core-$(CONFIG_ARCH_S3C2410) += arch/arm/mach-s3c2412/
-core-$(CONFIG_ARCH_S3C2410) += arch/arm/mach-s3c2440/
-core-$(CONFIG_ARCH_S3C2410) += arch/arm/mach-s3c2442/
-core-$(CONFIG_ARCH_S3C2410) += arch/arm/mach-s3c2443/
core-$(CONFIG_FPE_NWFPE) += arch/arm/nwfpe/
core-$(CONFIG_FPE_FASTFPE) += $(FASTFPE_OBJ)
core-$(CONFIG_VFP) += arch/arm/vfp/
@@ -173,7 +168,6 @@ core-$(CONFIG_VFP) += arch/arm/vfp/
# If we have a common platform directory, then include it in the build.
core-$(CONFIG_PLAT_IOP) += arch/arm/plat-iop/
core-$(CONFIG_ARCH_OMAP) += arch/arm/plat-omap/
-core-$(CONFIG_PLAT_S3C24XX) += arch/arm/plat-s3c24xx/
drivers-$(CONFIG_OPROFILE) += arch/arm/oprofile/
drivers-$(CONFIG_ARCH_CLPS7500) += drivers/acorn/char/
diff --git a/trunk/arch/arm/configs/s3c2410_defconfig b/trunk/arch/arm/configs/s3c2410_defconfig
index df19e3632038..3b31a33d0080 100644
--- a/trunk/arch/arm/configs/s3c2410_defconfig
+++ b/trunk/arch/arm/configs/s3c2410_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.20
-# Thu Feb 15 11:26:24 2007
+# Linux kernel version: 2.6.19-rc4
+# Fri Nov 3 17:41:31 2006
#
CONFIG_ARM=y
# CONFIG_GENERIC_TIME is not set
@@ -11,8 +11,6 @@ CONFIG_TRACE_IRQFLAGS_SUPPORT=y
CONFIG_HARDIRQS_SW_RESEND=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_ARCH_HAS_ILOG2_U32 is not set
-# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_VECTORS_BASE=0xffff0000
@@ -39,14 +37,13 @@ CONFIG_SYSVIPC=y
# CONFIG_UTS_NS is not set
# CONFIG_AUDIT is not set
# CONFIG_IKCONFIG is not set
-CONFIG_SYSFS_DEPRECATED=y
# CONFIG_RELAY is not set
CONFIG_INITRAMFS_SOURCE=""
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
# CONFIG_EMBEDDED is not set
CONFIG_UID16=y
-CONFIG_SYSCTL_SYSCALL=y
+# CONFIG_SYSCTL_SYSCALL is not set
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_ALL is not set
# CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -79,9 +76,7 @@ CONFIG_KMOD=y
# Block layer
#
CONFIG_BLOCK=y
-# CONFIG_LBD is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_LSF is not set
#
# IO Schedulers
@@ -115,7 +110,6 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
# CONFIG_ARCH_IMX is not set
# CONFIG_ARCH_IOP32X is not set
# CONFIG_ARCH_IOP33X is not set
-# CONFIG_ARCH_IOP13XX is not set
# CONFIG_ARCH_IXP4XX is not set
# CONFIG_ARCH_IXP2000 is not set
# CONFIG_ARCH_IXP23XX is not set
@@ -128,73 +122,54 @@ CONFIG_ARCH_S3C2410=y
# CONFIG_ARCH_SHARK is not set
# CONFIG_ARCH_LH7A40X is not set
# CONFIG_ARCH_OMAP is not set
-CONFIG_PLAT_S3C24XX=y
-CONFIG_CPU_S3C244X=y
-CONFIG_PM_SIMTEC=y
-# CONFIG_S3C2410_BOOT_WATCHDOG is not set
-# CONFIG_S3C2410_BOOT_ERROR_RESET is not set
-# CONFIG_S3C2410_PM_DEBUG is not set
-# CONFIG_S3C2410_PM_CHECK is not set
-CONFIG_S3C2410_LOWLEVEL_UART_PORT=0
-CONFIG_S3C2410_DMA=y
-# CONFIG_S3C2410_DMA_DEBUG is not set
-CONFIG_MACH_SMDK=y
#
-# S3C2400 Machines
+# S3C24XX Implementations
#
-CONFIG_CPU_S3C2410=y
-CONFIG_CPU_S3C2410_DMA=y
-CONFIG_S3C2410_PM=y
-CONFIG_S3C2410_GPIO=y
-CONFIG_S3C2410_CLOCK=y
-
-#
-# S3C2410 Machines
-#
-CONFIG_ARCH_SMDK2410=y
-CONFIG_ARCH_H1940=y
-CONFIG_PM_H1940=y
-CONFIG_MACH_N30=y
+# CONFIG_MACH_AML_M5900 is not set
+CONFIG_MACH_ANUBIS=y
+CONFIG_MACH_OSIRIS=y
CONFIG_ARCH_BAST=y
-CONFIG_MACH_OTOM=y
-CONFIG_MACH_AML_M5900=y
CONFIG_BAST_PC104_IRQ=y
-CONFIG_MACH_VR1000=y
-CONFIG_CPU_S3C2412=y
-CONFIG_S3C2412_DMA=y
-CONFIG_S3C2412_PM=y
-
-#
-# S3C2412 Machines
-#
-CONFIG_MACH_SMDK2413=y
+CONFIG_ARCH_H1940=y
+CONFIG_MACH_N30=y
+CONFIG_MACH_SMDK=y
+CONFIG_ARCH_SMDK2410=y
+CONFIG_ARCH_S3C2440=y
+CONFIG_SMDK2440_CPU2440=y
+CONFIG_SMDK2440_CPU2442=y
CONFIG_MACH_S3C2413=y
-CONFIG_MACH_VSTMS=y
-CONFIG_CPU_S3C2440=y
-CONFIG_S3C2440_DMA=y
-
-#
-# S3C2440 Machines
-#
-CONFIG_MACH_ANUBIS=y
-CONFIG_MACH_OSIRIS=y
+CONFIG_MACH_SMDK2413=y
+CONFIG_MACH_VR1000=y
CONFIG_MACH_RX3715=y
-CONFIG_ARCH_S3C2440=y
+CONFIG_MACH_OTOM=y
CONFIG_MACH_NEXCODER_2440=y
-CONFIG_SMDK2440_CPU2440=y
+CONFIG_MACH_VSTMS=y
+CONFIG_S3C2410_CLOCK=y
+CONFIG_S3C2410_PM=y
+CONFIG_CPU_S3C2410_DMA=y
+CONFIG_CPU_S3C2410=y
+CONFIG_S3C2412_PM=y
+CONFIG_CPU_S3C2412=y
+CONFIG_CPU_S3C244X=y
+CONFIG_CPU_S3C2440=y
CONFIG_CPU_S3C2442=y
#
-# S3C2442 Machines
+# S3C2410 Boot
#
-CONFIG_SMDK2440_CPU2442=y
-CONFIG_CPU_S3C2443=y
+# CONFIG_S3C2410_BOOT_WATCHDOG is not set
+# CONFIG_S3C2410_BOOT_ERROR_RESET is not set
#
-# S3C2443 Machines
+# S3C2410 Setup
#
-CONFIG_MACH_SMDK2443=y
+CONFIG_S3C2410_DMA=y
+# CONFIG_S3C2410_DMA_DEBUG is not set
+# CONFIG_S3C2410_PM_DEBUG is not set
+# CONFIG_S3C2410_PM_CHECK is not set
+CONFIG_PM_SIMTEC=y
+CONFIG_S3C2410_LOWLEVEL_UART_PORT=0
#
# Processor Type
@@ -221,7 +196,6 @@ CONFIG_CPU_CP15_MMU=y
# CONFIG_CPU_DCACHE_DISABLE is not set
# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
-# CONFIG_OUTER_CACHE is not set
#
# Bus support
@@ -329,7 +303,6 @@ CONFIG_INET_TCP_DIAG=y
# CONFIG_TCP_CONG_ADVANCED is not set
CONFIG_TCP_CONG_CUBIC=y
CONFIG_DEFAULT_TCP_CONG="cubic"
-# CONFIG_TCP_MD5SIG is not set
# CONFIG_IPV6 is not set
# CONFIG_INET6_XFRM_TUNNEL is not set
# CONFIG_INET6_TUNNEL is not set
@@ -412,7 +385,6 @@ CONFIG_MTD_CMDLINE_PARTS=y
# User Modules And Translation Layers
#
CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLKDEVS=y
CONFIG_MTD_BLOCK=y
# CONFIG_FTL is not set
# CONFIG_NFTL is not set
@@ -558,11 +530,6 @@ CONFIG_BLK_DEV_IDE_BAST=y
# CONFIG_SCSI is not set
# CONFIG_SCSI_NETLINK is not set
-#
-# Serial ATA (prod) and Parallel ATA (experimental) drivers
-#
-# CONFIG_ATA is not set
-
#
# Multi-device support (RAID and LVM)
#
@@ -715,7 +682,7 @@ CONFIG_SERIAL_NONSTANDARD=y
# CONFIG_DIGIEPCA is not set
# CONFIG_MOXA_INTELLIO is not set
# CONFIG_MOXA_SMARTIO is not set
-# CONFIG_MOXA_SMARTIO_NEW is not set
+# CONFIG_ISI is not set
# CONFIG_SYNCLINKMP is not set
# CONFIG_N_HDLC is not set
# CONFIG_RISCOM8 is not set
@@ -733,14 +700,13 @@ CONFIG_SERIAL_8250_NR_UARTS=8
CONFIG_SERIAL_8250_RUNTIME_UARTS=4
CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_MANY_PORTS=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_RSA is not set
# CONFIG_SERIAL_8250_FOURPORT is not set
# CONFIG_SERIAL_8250_ACCENT is not set
# CONFIG_SERIAL_8250_BOCA is not set
-# CONFIG_SERIAL_8250_EXAR_ST16C554 is not set
# CONFIG_SERIAL_8250_HUB6 is not set
-CONFIG_SERIAL_8250_SHARE_IRQ=y
-# CONFIG_SERIAL_8250_DETECT_IRQ is not set
-# CONFIG_SERIAL_8250_RSA is not set
#
# Non-8250 serial port support
@@ -789,6 +755,10 @@ CONFIG_HW_RANDOM=y
# CONFIG_NVRAM is not set
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
+
+#
+# Ftape, the floppy tape device driver
+#
# CONFIG_RAW_DRIVER is not set
#
@@ -893,7 +863,6 @@ CONFIG_SENSORS_LM85=m
# CONFIG_SENSORS_LM92 is not set
# CONFIG_SENSORS_MAX1619 is not set
# CONFIG_SENSORS_PC87360 is not set
-# CONFIG_SENSORS_PC87427 is not set
# CONFIG_SENSORS_SMSC47M1 is not set
# CONFIG_SENSORS_SMSC47M192 is not set
# CONFIG_SENSORS_SMSC47B397 is not set
@@ -901,7 +870,6 @@ CONFIG_SENSORS_LM85=m
# CONFIG_SENSORS_W83781D is not set
# CONFIG_SENSORS_W83791D is not set
# CONFIG_SENSORS_W83792D is not set
-# CONFIG_SENSORS_W83793 is not set
# CONFIG_SENSORS_W83L785TS is not set
# CONFIG_SENSORS_W83627HF is not set
# CONFIG_SENSORS_W83627EHF is not set
@@ -983,11 +951,6 @@ CONFIG_FONT_8x16=y
#
# CONFIG_SOUND is not set
-#
-# HID Devices
-#
-CONFIG_HID=y
-
#
# USB support
#
@@ -1065,7 +1028,6 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
# CONFIG_USB_KAWETH is not set
# CONFIG_USB_PEGASUS is not set
# CONFIG_USB_RTL8150 is not set
-# CONFIG_USB_USBNET_MII is not set
# CONFIG_USB_USBNET is not set
CONFIG_USB_MON=y
@@ -1217,6 +1179,9 @@ CONFIG_RAMFS=y
# CONFIG_BEFS_FS is not set
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
+CONFIG_JFFS_FS=y
+CONFIG_JFFS_FS_VERBOSE=0
+# CONFIG_JFFS_PROC_FS is not set
CONFIG_JFFS2_FS=y
CONFIG_JFFS2_FS_DEBUG=0
CONFIG_JFFS2_FS_WRITEBUFFER=y
@@ -1226,7 +1191,7 @@ CONFIG_JFFS2_FS_WRITEBUFFER=y
CONFIG_JFFS2_ZLIB=y
CONFIG_JFFS2_RTIME=y
# CONFIG_JFFS2_RUBIN is not set
-CONFIG_CRAMFS=y
+# CONFIG_CRAMFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_HPFS_FS is not set
# CONFIG_QNX4FS_FS is not set
@@ -1319,11 +1284,6 @@ CONFIG_NLS_DEFAULT="iso8859-1"
# CONFIG_NLS_KOI8_U is not set
# CONFIG_NLS_UTF8 is not set
-#
-# Distributed Lock Manager
-#
-# CONFIG_DLM is not set
-
#
# Profiling support
#
@@ -1336,8 +1296,6 @@ CONFIG_NLS_DEFAULT="iso8859-1"
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_MAGIC_SYSRQ=y
# CONFIG_UNUSED_SYMBOLS is not set
-# CONFIG_DEBUG_FS is not set
-# CONFIG_HEADERS_CHECK is not set
CONFIG_DEBUG_KERNEL=y
CONFIG_LOG_BUF_SHIFT=16
CONFIG_DETECT_SOFTLOCKUP=y
@@ -1353,10 +1311,12 @@ CONFIG_DEBUG_MUTEXES=y
# CONFIG_DEBUG_KOBJECT is not set
CONFIG_DEBUG_BUGVERBOSE=y
CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_FS is not set
# CONFIG_DEBUG_VM is not set
# CONFIG_DEBUG_LIST is not set
CONFIG_FRAME_POINTER=y
CONFIG_FORCED_INLINING=y
+# CONFIG_HEADERS_CHECK is not set
# CONFIG_RCU_TORTURE_TEST is not set
CONFIG_DEBUG_USER=y
# CONFIG_DEBUG_ERRORS is not set
@@ -1379,7 +1339,6 @@ CONFIG_DEBUG_S3C2410_UART=0
#
# Library routines
#
-CONFIG_BITREVERSE=y
# CONFIG_CRC_CCITT is not set
# CONFIG_CRC16 is not set
CONFIG_CRC32=y
@@ -1387,4 +1346,3 @@ CONFIG_CRC32=y
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
CONFIG_PLIST=y
-CONFIG_IOMAP_COPY=y
diff --git a/trunk/arch/arm/mach-s3c2400/Kconfig b/trunk/arch/arm/mach-s3c2400/Kconfig
deleted file mode 100644
index deab0722836e..000000000000
--- a/trunk/arch/arm/mach-s3c2400/Kconfig
+++ /dev/null
@@ -1,13 +0,0 @@
-# arch/arm/mach-s3c2400/Kconfig
-#
-# Copyright 2007 Simtec Electronics
-#
-# Licensed under GPLv2
-
-
-
-menu "S3C2400 Machines"
-
-
-endmenu
-
diff --git a/trunk/arch/arm/mach-s3c2400/Makefile b/trunk/arch/arm/mach-s3c2400/Makefile
deleted file mode 100644
index 7e23f4e13766..000000000000
--- a/trunk/arch/arm/mach-s3c2400/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-# arch/arm/mach-s3c2400/Makefile
-#
-# Copyright 2007 Simtec Electronics
-#
-# Licensed under GPLv2
-
-obj-y :=
-obj-m :=
-obj-n :=
-obj- :=
-
-obj-$(CONFIG_CPU_S3C2400) += gpio.o
-
-# Machine support
-
diff --git a/trunk/arch/arm/mach-s3c2410/Kconfig b/trunk/arch/arm/mach-s3c2410/Kconfig
index d4b013b283c3..eb4ec411312b 100644
--- a/trunk/arch/arm/mach-s3c2410/Kconfig
+++ b/trunk/arch/arm/mach-s3c2410/Kconfig
@@ -1,51 +1,54 @@
-# arch/arm/mach-s3c2410/Kconfig
-#
-# Copyright 2007 Simtec Electronics
-#
-# Licensed under GPLv2
+if ARCH_S3C2410
-config CPU_S3C2410
- bool
- depends on ARCH_S3C2410
- select S3C2410_CLOCK
- select S3C2410_GPIO
- select S3C2410_PM if PM
- help
- Support for S3C2410 and S3C2410A family from the S3C24XX line
- of Samsung Mobile CPUs.
+menu "S3C24XX Implementations"
-config CPU_S3C2410_DMA
- bool
- depends on S3C2410_DMA && (CPU_S3C2410 || CPU_S3C2442)
- default y if CPU_S3C2410 || CPU_S3C2442
+config MACH_AML_M5900
+ bool "AML M5900 Series"
+ select CPU_S3C2410
+ select PM_SIMTEC if PM
help
- DMA device selection for S3C2410 and compatible CPUs
+ Say Y here if you are using the American Microsystems M5900 Series
+
-config S3C2410_PM
- bool
+config MACH_ANUBIS
+ bool "Simtec Electronics ANUBIS"
+ select CPU_S3C2440
+ select PM_SIMTEC if PM
help
- Power Management code common to S3C2410 and better
+ Say Y here if you are using the Simtec Electronics ANUBIS
+ development system
-config S3C2410_GPIO
- bool
+config MACH_OSIRIS
+ bool "Simtec IM2440D20 (OSIRIS) module"
+ select CPU_S3C2440
+ select PM_SIMTEC if PM
help
- GPIO code for S3C2410 and similar processors
+ Say Y here if you are using the Simtec IM2440D20 module, also
+ known as the Osiris.
-config S3C2410_CLOCK
- bool
+config ARCH_BAST
+ bool "Simtec Electronics BAST (EB2410ITX)"
+ select CPU_S3C2410
+ select PM_SIMTEC if PM
+ select ISA
help
- Clock code for the S3C2410, and similar processors
+ Say Y here if you are using the Simtec Electronics EB2410ITX
+ development board (also known as BAST)
+ Product page: .
-menu "S3C2410 Machines"
+config BAST_PC104_IRQ
+ bool "BAST PC104 IRQ support"
+ depends on ARCH_BAST
+ default y
+ help
+ Say Y here to enable the PC104 IRQ routing on the
+ Simtec BAST (EB2410ITX)
-config ARCH_SMDK2410
- bool "SMDK2410/A9M2410"
- select CPU_S3C2410
- select MACH_SMDK
+config PM_H1940
+ bool
help
- Say Y here if you are using the SMDK2410 or the derived module A9M2410
-
+ Internal node for H1940 and related PM
config ARCH_H1940
bool "IPAQ H1940"
@@ -54,10 +57,7 @@ config ARCH_H1940
help
Say Y here if you are using the HP IPAQ H1940
-config PM_H1940
- bool
- help
- Internal node for H1940 and related PM
+ .
config MACH_N30
bool "Acer N30"
@@ -65,36 +65,53 @@ config MACH_N30
help
Say Y here if you are using the Acer N30
-config ARCH_BAST
- bool "Simtec Electronics BAST (EB2410ITX)"
+ .
+
+config MACH_SMDK
+ bool
+ help
+ Common machine code for SMDK2410 and SMDK2440
+
+config ARCH_SMDK2410
+ bool "SMDK2410/A9M2410"
select CPU_S3C2410
- select PM_SIMTEC if PM
- select ISA
+ select MACH_SMDK
help
- Say Y here if you are using the Simtec Electronics EB2410ITX
- development board (also known as BAST)
+ Say Y here if you are using the SMDK2410 or the derived module A9M2410
+
-config MACH_OTOM
- bool "NexVision OTOM Board"
- select CPU_S3C2410
+config ARCH_S3C2440
+ bool "SMDK2440"
+ select CPU_S3C2440
+ select MACH_SMDK
help
- Say Y here if you are using the Nex Vision OTOM board
+ Say Y here if you are using the SMDK2440.
-config MACH_AML_M5900
- bool "AML M5900 Series"
- select CPU_S3C2410
- select PM_SIMTEC if PM
+config SMDK2440_CPU2440
+ bool "SMDK2440 with S3C2440 CPU module"
+ depends on ARCH_S3C2440
+ default y if ARCH_S3C2440
+ select CPU_S3C2440
+
+config SMDK2440_CPU2442
+ bool "SMDM2440 with S3C2442 CPU module"
+ depends on ARCH_S3C2440
+ select CPU_S3C2442
+
+config MACH_S3C2413
+ bool
help
- Say Y here if you are using the American Microsystems M5900 Series
-
+ Internal node for S3C2413 version of SMDK2413, so that
+ machine_is_s3c2413() will work when MACH_SMDK2413 is
+ selected
-config BAST_PC104_IRQ
- bool "BAST PC104 IRQ support"
- depends on ARCH_BAST
- default y
+config MACH_SMDK2413
+ bool "SMDK2413"
+ select CPU_S3C2412
+ select MACH_S3C2413
+ select MACH_SMDK
help
- Say Y here to enable the PC104 IRQ routing on the
- Simtec BAST (EB2410ITX)
+ Say Y here if you are using an SMDK2413
config MACH_VR1000
bool "Thorcom VR1000"
@@ -103,11 +120,202 @@ config MACH_VR1000
help
Say Y here if you are using the Thorcom VR1000 board.
-config MACH_QT2410
- bool "QT2410"
- select CPU_S3C2410
+ This linux port is currently being maintained by Simtec, on behalf
+ of Thorcom. Any queries, please contact Thorcom first.
+
+config MACH_RX3715
+ bool "HP iPAQ rx3715"
+ select CPU_S3C2440
+ select PM_H1940 if PM
+ help
+ Say Y here if you are using the HP iPAQ rx3715.
+
+ See for more
+ information on this project
+
+config MACH_OTOM
+ bool "NexVision OTOM Board"
+ select CPU_S3C2410
+ help
+ Say Y here if you are using the Nex Vision OTOM board
+
+config MACH_NEXCODER_2440
+ bool "NexVision NEXCODER 2440 Light Board"
+ select CPU_S3C2440
help
- Say Y here if you are using the Armzone QT2410
+ Say Y here if you are using the Nex Vision NEXCODER 2440 Light Board
+
+config MACH_VSTMS
+ bool "VMSTMS"
+ select CPU_S3C2412
+ help
+ Say Y here if you are using an VSTMS board
endmenu
+config S3C2410_CLOCK
+ bool
+ help
+ Clock code for the S3C2410, and similar processors
+
+config S3C2410_PM
+ bool
+ help
+ Power Management code common to S3C2410 and better
+
+config CPU_S3C2410_DMA
+ bool
+ depends on S3C2410_DMA && (CPU_S3C2410 || CPU_S3C2442)
+ default y if CPU_S3C2410 || CPU_S3C2442
+ help
+ DMA device selection for S3C2410 and compatible CPUs
+
+config CPU_S3C2410
+ bool
+ depends on ARCH_S3C2410
+ select S3C2410_CLOCK
+ select S3C2410_PM if PM
+ help
+ Support for S3C2410 and S3C2410A family from the S3C24XX line
+ of Samsung Mobile CPUs.
+
+# internal node to signify if we are only dealing with an S3C2412
+
+config CPU_S3C2412_ONLY
+ bool
+ depends on ARCH_S3C2410 && !CPU_S3C2400 && !CPU_S3C2410 && \
+ !CPU_S3C2440 && !CPU_S3C2442 && CPU_S3C2412
+ default y if CPU_S3C2412
+
+config S3C2412_PM
+ bool
+ help
+ Internal config node to apply S3C2412 power management
+
+config CPU_S3C2412
+ bool
+ depends on ARCH_S3C2410
+ select S3C2412_PM if PM
+ help
+ Support for the S3C2412 and S3C2413 SoCs from the S3C24XX line
+
+config CPU_S3C244X
+ bool
+ depends on ARCH_S3C2410 && (CPU_S3C2440 || CPU_S3C2442)
+ help
+ Support for S3C2440 and S3C2442 Samsung Mobile CPU based systems.
+
+config CPU_S3C2440
+ bool
+ depends on ARCH_S3C2410
+ select S3C2410_CLOCK
+ select S3C2410_PM if PM
+ select CPU_S3C244X
+ help
+ Support for S3C2440 Samsung Mobile CPU based systems.
+
+config CPU_S3C2442
+ bool
+ depends on ARCH_S3C2420
+ select S3C2410_CLOCK
+ select S3C2410_PM if PM
+ select CPU_S3C244X
+ help
+ Support for S3C2442 Samsung Mobile CPU based systems.
+
+comment "S3C2410 Boot"
+
+config S3C2410_BOOT_WATCHDOG
+ bool "S3C2410 Initialisation watchdog"
+ depends on ARCH_S3C2410 && S3C2410_WATCHDOG
+ help
+ Say y to enable the watchdog during the kernel decompression
+ stage. If the kernel fails to uncompress, then the watchdog
+ will trigger a reset and the system should restart.
+
+ Although this uses the same hardware unit as the kernel watchdog
+ driver, it is not a replacement for it. If you use this option,
+ you will have to use the watchdg driver to either stop the timeout
+ or restart it. If you do not, then your kernel will reboot after
+ startup.
+
+ The driver uses a fixed timeout value, so the exact time till the
+ system resets depends on the value of PCLK. The timeout on an
+ 200MHz s3c2410 should be about 30 seconds.
+
+config S3C2410_BOOT_ERROR_RESET
+ bool "S3C2410 Reboot on decompression error"
+ depends on ARCH_S3C2410
+ help
+ Say y here to use the watchdog to reset the system if the
+ kernel decompressor detects an error during decompression.
+
+
+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 percentage of
+ the CPU time doing so.
+
+
+config S3C2410_PM_DEBUG
+ bool "S3C2410 PM Suspend debug"
+ depends on ARCH_S3C2410 && PM
+ help
+ Say Y here if you want verbose debugging from the PM Suspend and
+ Resume code. See
+ for more information.
+
+config S3C2410_PM_CHECK
+ bool "S3C2410 PM Suspend Memory CRC"
+ depends on ARCH_S3C2410 && PM && CRC32
+ help
+ Enable the PM code's memory area checksum over sleep. This option
+ will generate CRCs of all blocks of memory, and store them before
+ going to sleep. The blocks are then checked on resume for any
+ errors.
+
+config S3C2410_PM_CHECK_CHUNKSIZE
+ int "S3C2410 PM Suspend CRC Chunksize (KiB)"
+ depends on ARCH_S3C2410 && PM && S3C2410_PM_CHECK
+ default 64
+ help
+ Set the chunksize in Kilobytes of the CRC for checking memory
+ corruption over suspend and resume. A smaller value will mean that
+ the CRC data block will take more memory, but wil identify any
+ faults with better precision.
+
+config PM_SIMTEC
+ bool
+ help
+ Common power management code for systems that are
+ compatible with the Simtec style of power management
+
+config S3C2410_LOWLEVEL_UART_PORT
+ int "S3C2410 UART to use for low-level messages"
+ default 0
+ help
+ Choice of which UART port to use for the low-level messages,
+ such as the `Uncompressing...` at start time. The value of
+ this configuration should be between zero and two. The port
+ must have been initialised by the boot-loader before use.
+
+ Note, this does not affect the port used by the debug messages,
+ which is a separate configuration.
+
+endif
diff --git a/trunk/arch/arm/mach-s3c2410/Makefile b/trunk/arch/arm/mach-s3c2410/Makefile
index 9a3d3d24c084..27663e28cc88 100644
--- a/trunk/arch/arm/mach-s3c2410/Makefile
+++ b/trunk/arch/arm/mach-s3c2410/Makefile
@@ -1,31 +1,92 @@
-# arch/arm/mach-s3c2410/Makefile
+
#
-# Copyright 2007 Simtec Electronics
+# Makefile for the linux kernel.
#
-# Licensed under GPLv2
-obj-y :=
-obj-m :=
-obj-n :=
-obj- :=
+# Object file lists.
+
+obj-y := cpu.o irq.o time.o gpio.o clock.o devs.o
+obj-m :=
+obj-n :=
+obj- :=
+obj-dma-y :=
+obj-dma-n :=
+
+# DMA
+obj-$(CONFIG_S3C2410_DMA) += dma.o
+
+# S3C2400 support files
+obj-$(CONFIG_CPU_S3C2400) += s3c2400-gpio.o
+
+# S3C2410 support files
obj-$(CONFIG_CPU_S3C2410) += s3c2410.o
-obj-$(CONFIG_CPU_S3C2410) += irq.o
-obj-$(CONFIG_CPU_S3C2410_DMA) += dma.o
-obj-$(CONFIG_CPU_S3C2410_DMA) += dma.o
-obj-$(CONFIG_S3C2410_PM) += pm.o sleep.o
-obj-$(CONFIG_S3C2410_GPIO) += gpio.o
-obj-$(CONFIG_S3C2410_CLOCK) += clock.o
+obj-$(CONFIG_CPU_S3C2410) += s3c2410-gpio.o
+obj-$(CONFIG_CPU_S3C2410) += s3c2410-irq.o
-# Machine support
+obj-$(CONFIG_S3C2410_PM) += s3c2410-pm.o s3c2410-sleep.o
+obj-$(CONFIG_CPU_S3C2410_DMA) += s3c2410-dma.o
-obj-$(CONFIG_ARCH_SMDK2410) += mach-smdk2410.o
-obj-$(CONFIG_ARCH_H1940) += mach-h1940.o
+# Power Management support
+
+obj-$(CONFIG_PM) += pm.o sleep.o
+obj-$(CONFIG_PM_SIMTEC) += pm-simtec.o
obj-$(CONFIG_PM_H1940) += pm-h1940.o
-obj-$(CONFIG_MACH_N30) += mach-n30.o
-obj-$(CONFIG_ARCH_BAST) += mach-bast.o usb-simtec.o
-obj-$(CONFIG_MACH_OTOM) += mach-otom.o
-obj-$(CONFIG_MACH_AML_M5900) += mach-amlm5900.o
+
+# S3C2412 support
+obj-$(CONFIG_CPU_S3C2412) += s3c2412.o
+obj-$(CONFIG_CPU_S3C2412) += s3c2412-irq.o
+obj-$(CONFIG_CPU_S3C2412) += s3c2412-clock.o
+obj-dma-$(CONFIG_CPU_S3C2412) += s3c2412-dma.o
+
+obj-$(CONFIG_S3C2412_PM) += s3c2412-pm.o
+
+#
+# S3C244X support
+
+obj-$(CONFIG_CPU_S3C244X) += s3c244x.o
+obj-$(CONFIG_CPU_S3C244X) += s3c244x-irq.o
+
+# Clock control
+
+obj-$(CONFIG_S3C2410_CLOCK) += s3c2410-clock.o
+
+# S3C2440 support
+
+obj-$(CONFIG_CPU_S3C2440) += s3c2440.o s3c2440-dsc.o
+obj-$(CONFIG_CPU_S3C2440) += s3c2440-irq.o
+obj-$(CONFIG_CPU_S3C2440) += s3c2440-clock.o
+obj-$(CONFIG_CPU_S3C2440) += s3c2410-gpio.o
+obj-dma-$(CONFIG_CPU_S3C2440) += s3c2440-dma.o
+
+# S3C2442 support
+
+obj-$(CONFIG_CPU_S3C2442) += s3c2442.o
+obj-$(CONFIG_CPU_S3C2442) += s3c2442-clock.o
+
+# bast extras
+
obj-$(CONFIG_BAST_PC104_IRQ) += bast-irq.o
+
+# merge in dma objects
+
+obj-y += $(obj-dma-y)
+
+# machine specific support
+
+obj-$(CONFIG_MACH_AML_M5900) += mach-amlm5900.o
+obj-$(CONFIG_MACH_ANUBIS) += mach-anubis.o
+obj-$(CONFIG_MACH_OSIRIS) += mach-osiris.o
+obj-$(CONFIG_ARCH_BAST) += mach-bast.o usb-simtec.o
+obj-$(CONFIG_ARCH_H1940) += mach-h1940.o
+obj-$(CONFIG_MACH_N30) += mach-n30.o
+obj-$(CONFIG_ARCH_SMDK2410) += mach-smdk2410.o
+obj-$(CONFIG_MACH_SMDK2413) += mach-smdk2413.o
+obj-$(CONFIG_ARCH_S3C2440) += mach-smdk2440.o
obj-$(CONFIG_MACH_VR1000) += mach-vr1000.o usb-simtec.o
-obj-$(CONFIG_MACH_QT2410) += mach-qt2410.o
+obj-$(CONFIG_MACH_RX3715) += mach-rx3715.o
+obj-$(CONFIG_MACH_OTOM) += mach-otom.o
+obj-$(CONFIG_MACH_NEXCODER_2440) += mach-nexcoder.o
+obj-$(CONFIG_MACH_VSTMS) += mach-vstms.o
+
+obj-$(CONFIG_MACH_SMDK) += common-smdk.o
\ No newline at end of file
diff --git a/trunk/arch/arm/mach-s3c2410/bast-irq.c b/trunk/arch/arm/mach-s3c2410/bast-irq.c
index daeba427d781..379efe70778c 100644
--- a/trunk/arch/arm/mach-s3c2410/bast-irq.c
+++ b/trunk/arch/arm/mach-s3c2410/bast-irq.c
@@ -39,7 +39,7 @@
#include
#include
-#include
+#include "irq.h"
#if 0
#include
diff --git a/trunk/arch/arm/mach-s3c2410/bast.h b/trunk/arch/arm/mach-s3c2410/bast.h
index e98543742eb9..e5d03311752c 100644
--- a/trunk/arch/arm/mach-s3c2410/bast.h
+++ b/trunk/arch/arm/mach-s3c2410/bast.h
@@ -1,2 +1,2 @@
-/* linux/arch/arm/mach-s3c2410/bast.h
+
extern void bast_init_irq(void);
diff --git a/trunk/arch/arm/mach-s3c2410/clock.c b/trunk/arch/arm/mach-s3c2410/clock.c
index 5b4831c4c1d8..e13fb6778890 100644
--- a/trunk/arch/arm/mach-s3c2410/clock.c
+++ b/trunk/arch/arm/mach-s3c2410/clock.c
@@ -1,9 +1,15 @@
/* linux/arch/arm/mach-s3c2410/clock.c
*
- * Copyright (c) 2006 Simtec Electronics
+ * Copyright (c) 2004-2005 Simtec Electronics
* Ben Dooks
*
- * S3C2410,S3C2440,S3C2442 Clock control support
+ * S3C24XX Core 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
@@ -26,251 +32,418 @@
#include
#include
#include
+#include
#include
+#include
+#include
#include
#include
#include
-#include
-
-#include
#include
+#include
#include
-#include
#include
#include
-#include
-#include
-#include
+#include "clock.h"
+#include "cpu.h"
+
+/* clock information */
-int s3c2410_clkcon_enable(struct clk *clk, int enable)
+static LIST_HEAD(clocks);
+
+DEFINE_MUTEX(clocks_mutex);
+
+/* enable and disable calls for use with the clk struct */
+
+static int clk_null_enable(struct clk *clk, int enable)
{
- unsigned int clocks = clk->ctrlbit;
- unsigned long clkcon;
+ return 0;
+}
- clkcon = __raw_readl(S3C2410_CLKCON);
+/* Clock API calls */
- if (enable)
- clkcon |= clocks;
+struct clk *clk_get(struct device *dev, const char *id)
+{
+ struct clk *p;
+ struct clk *clk = ERR_PTR(-ENOENT);
+ int idno;
+
+ if (dev == NULL || dev->bus != &platform_bus_type)
+ idno = -1;
else
- clkcon &= ~clocks;
+ idno = to_platform_device(dev)->id;
+
+ mutex_lock(&clocks_mutex);
+
+ list_for_each_entry(p, &clocks, list) {
+ if (p->id == idno &&
+ strcmp(id, p->name) == 0 &&
+ try_module_get(p->owner)) {
+ clk = p;
+ break;
+ }
+ }
+
+ /* check for the case where a device was supplied, but the
+ * clock that was being searched for is not device specific */
+
+ if (IS_ERR(clk)) {
+ list_for_each_entry(p, &clocks, list) {
+ if (p->id == -1 && strcmp(id, p->name) == 0 &&
+ try_module_get(p->owner)) {
+ clk = p;
+ break;
+ }
+ }
+ }
- /* ensure none of the special function bits set */
- clkcon &= ~(S3C2410_CLKCON_IDLE|S3C2410_CLKCON_POWER);
+ mutex_unlock(&clocks_mutex);
+ return clk;
+}
- __raw_writel(clkcon, S3C2410_CLKCON);
+void clk_put(struct clk *clk)
+{
+ module_put(clk->owner);
+}
+int clk_enable(struct clk *clk)
+{
+ if (IS_ERR(clk) || clk == NULL)
+ return -EINVAL;
+
+ clk_enable(clk->parent);
+
+ mutex_lock(&clocks_mutex);
+
+ if ((clk->usage++) == 0)
+ (clk->enable)(clk, 1);
+
+ mutex_unlock(&clocks_mutex);
return 0;
}
-static int s3c2410_upll_enable(struct clk *clk, int enable)
+void clk_disable(struct clk *clk)
+{
+ if (IS_ERR(clk) || clk == NULL)
+ return;
+
+ mutex_lock(&clocks_mutex);
+
+ if ((--clk->usage) == 0)
+ (clk->enable)(clk, 0);
+
+ mutex_unlock(&clocks_mutex);
+ clk_disable(clk->parent);
+}
+
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+ if (IS_ERR(clk))
+ return 0;
+
+ if (clk->rate != 0)
+ return clk->rate;
+
+ if (clk->get_rate != NULL)
+ return (clk->get_rate)(clk);
+
+ if (clk->parent != NULL)
+ return clk_get_rate(clk->parent);
+
+ return clk->rate;
+}
+
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+ if (!IS_ERR(clk) && clk->round_rate)
+ return (clk->round_rate)(clk, rate);
+
+ return rate;
+}
+
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+ int ret;
+
+ if (IS_ERR(clk))
+ return -EINVAL;
+
+ mutex_lock(&clocks_mutex);
+ ret = (clk->set_rate)(clk, rate);
+ mutex_unlock(&clocks_mutex);
+
+ return ret;
+}
+
+struct clk *clk_get_parent(struct clk *clk)
{
- unsigned long clkslow = __raw_readl(S3C2410_CLKSLOW);
- unsigned long orig = clkslow;
+ return clk->parent;
+}
+
+int clk_set_parent(struct clk *clk, struct clk *parent)
+{
+ int ret = 0;
+
+ if (IS_ERR(clk))
+ return -EINVAL;
+
+ mutex_lock(&clocks_mutex);
+
+ if (clk->set_parent)
+ ret = (clk->set_parent)(clk, parent);
+
+ mutex_unlock(&clocks_mutex);
+
+ return ret;
+}
+
+EXPORT_SYMBOL(clk_get);
+EXPORT_SYMBOL(clk_put);
+EXPORT_SYMBOL(clk_enable);
+EXPORT_SYMBOL(clk_disable);
+EXPORT_SYMBOL(clk_get_rate);
+EXPORT_SYMBOL(clk_round_rate);
+EXPORT_SYMBOL(clk_set_rate);
+EXPORT_SYMBOL(clk_get_parent);
+EXPORT_SYMBOL(clk_set_parent);
+
+/* base clocks */
+
+struct clk clk_xtal = {
+ .name = "xtal",
+ .id = -1,
+ .rate = 0,
+ .parent = NULL,
+ .ctrlbit = 0,
+};
+
+struct clk clk_mpll = {
+ .name = "mpll",
+ .id = -1,
+};
+
+struct clk clk_upll = {
+ .name = "upll",
+ .id = -1,
+ .parent = NULL,
+ .ctrlbit = 0,
+};
+
+struct clk clk_f = {
+ .name = "fclk",
+ .id = -1,
+ .rate = 0,
+ .parent = &clk_mpll,
+ .ctrlbit = 0,
+};
+
+struct clk clk_h = {
+ .name = "hclk",
+ .id = -1,
+ .rate = 0,
+ .parent = NULL,
+ .ctrlbit = 0,
+};
+
+struct clk clk_p = {
+ .name = "pclk",
+ .id = -1,
+ .rate = 0,
+ .parent = NULL,
+ .ctrlbit = 0,
+};
+
+struct clk clk_usb_bus = {
+ .name = "usb-bus",
+ .id = -1,
+ .rate = 0,
+ .parent = &clk_upll,
+};
+
+/* clocks that could be registered by external code */
+
+static int s3c24xx_dclk_enable(struct clk *clk, int enable)
+{
+ unsigned long dclkcon = __raw_readl(S3C24XX_DCLKCON);
if (enable)
- clkslow &= ~S3C2410_CLKSLOW_UCLK_OFF;
+ dclkcon |= clk->ctrlbit;
else
- clkslow |= S3C2410_CLKSLOW_UCLK_OFF;
+ dclkcon &= ~clk->ctrlbit;
- __raw_writel(clkslow, S3C2410_CLKSLOW);
+ __raw_writel(dclkcon, S3C24XX_DCLKCON);
- /* if we started the UPLL, then allow to settle */
+ return 0;
+}
- if (enable && (orig & S3C2410_CLKSLOW_UCLK_OFF))
- udelay(200);
+static int s3c24xx_dclk_setparent(struct clk *clk, struct clk *parent)
+{
+ unsigned long dclkcon;
+ unsigned int uclk;
+
+ if (parent == &clk_upll)
+ uclk = 1;
+ else if (parent == &clk_p)
+ uclk = 0;
+ else
+ return -EINVAL;
+
+ clk->parent = parent;
+
+ dclkcon = __raw_readl(S3C24XX_DCLKCON);
+
+ if (clk->ctrlbit == S3C2410_DCLKCON_DCLK0EN) {
+ if (uclk)
+ dclkcon |= S3C2410_DCLKCON_DCLK0_UCLK;
+ else
+ dclkcon &= ~S3C2410_DCLKCON_DCLK0_UCLK;
+ } else {
+ if (uclk)
+ dclkcon |= S3C2410_DCLKCON_DCLK1_UCLK;
+ else
+ dclkcon &= ~S3C2410_DCLKCON_DCLK1_UCLK;
+ }
+
+ __raw_writel(dclkcon, S3C24XX_DCLKCON);
return 0;
}
-/* standard clock definitions */
-
-static struct clk init_clocks_disable[] = {
- {
- .name = "nand",
- .id = -1,
- .parent = &clk_h,
- .enable = s3c2410_clkcon_enable,
- .ctrlbit = S3C2410_CLKCON_NAND,
- }, {
- .name = "sdi",
- .id = -1,
- .parent = &clk_p,
- .enable = s3c2410_clkcon_enable,
- .ctrlbit = S3C2410_CLKCON_SDI,
- }, {
- .name = "adc",
- .id = -1,
- .parent = &clk_p,
- .enable = s3c2410_clkcon_enable,
- .ctrlbit = S3C2410_CLKCON_ADC,
- }, {
- .name = "i2c",
- .id = -1,
- .parent = &clk_p,
- .enable = s3c2410_clkcon_enable,
- .ctrlbit = S3C2410_CLKCON_IIC,
- }, {
- .name = "iis",
- .id = -1,
- .parent = &clk_p,
- .enable = s3c2410_clkcon_enable,
- .ctrlbit = S3C2410_CLKCON_IIS,
- }, {
- .name = "spi",
- .id = -1,
- .parent = &clk_p,
- .enable = s3c2410_clkcon_enable,
- .ctrlbit = S3C2410_CLKCON_SPI,
+
+static int s3c24xx_clkout_setparent(struct clk *clk, struct clk *parent)
+{
+ unsigned long mask;
+ unsigned long source;
+
+ /* calculate the MISCCR setting for the clock */
+
+ if (parent == &clk_xtal)
+ source = S3C2410_MISCCR_CLK0_MPLL;
+ else if (parent == &clk_upll)
+ source = S3C2410_MISCCR_CLK0_UPLL;
+ else if (parent == &clk_f)
+ source = S3C2410_MISCCR_CLK0_FCLK;
+ else if (parent == &clk_h)
+ source = S3C2410_MISCCR_CLK0_HCLK;
+ else if (parent == &clk_p)
+ source = S3C2410_MISCCR_CLK0_PCLK;
+ else if (clk == &s3c24xx_clkout0 && parent == &s3c24xx_dclk0)
+ source = S3C2410_MISCCR_CLK0_DCLK0;
+ else if (clk == &s3c24xx_clkout1 && parent == &s3c24xx_dclk1)
+ source = S3C2410_MISCCR_CLK0_DCLK0;
+ else
+ return -EINVAL;
+
+ clk->parent = parent;
+
+ if (clk == &s3c24xx_dclk0)
+ mask = S3C2410_MISCCR_CLK0_MASK;
+ else {
+ source <<= 4;
+ mask = S3C2410_MISCCR_CLK1_MASK;
}
+
+ s3c2410_modify_misccr(mask, source);
+ return 0;
+}
+
+/* external clock definitions */
+
+struct clk s3c24xx_dclk0 = {
+ .name = "dclk0",
+ .id = -1,
+ .ctrlbit = S3C2410_DCLKCON_DCLK0EN,
+ .enable = s3c24xx_dclk_enable,
+ .set_parent = s3c24xx_dclk_setparent,
};
-static struct clk init_clocks[] = {
- {
- .name = "lcd",
- .id = -1,
- .parent = &clk_h,
- .enable = s3c2410_clkcon_enable,
- .ctrlbit = S3C2410_CLKCON_LCDC,
- }, {
- .name = "gpio",
- .id = -1,
- .parent = &clk_p,
- .enable = s3c2410_clkcon_enable,
- .ctrlbit = S3C2410_CLKCON_GPIO,
- }, {
- .name = "usb-host",
- .id = -1,
- .parent = &clk_h,
- .enable = s3c2410_clkcon_enable,
- .ctrlbit = S3C2410_CLKCON_USBH,
- }, {
- .name = "usb-device",
- .id = -1,
- .parent = &clk_h,
- .enable = s3c2410_clkcon_enable,
- .ctrlbit = S3C2410_CLKCON_USBD,
- }, {
- .name = "timers",
- .id = -1,
- .parent = &clk_p,
- .enable = s3c2410_clkcon_enable,
- .ctrlbit = S3C2410_CLKCON_PWMT,
- }, {
- .name = "uart",
- .id = 0,
- .parent = &clk_p,
- .enable = s3c2410_clkcon_enable,
- .ctrlbit = S3C2410_CLKCON_UART0,
- }, {
- .name = "uart",
- .id = 1,
- .parent = &clk_p,
- .enable = s3c2410_clkcon_enable,
- .ctrlbit = S3C2410_CLKCON_UART1,
- }, {
- .name = "uart",
- .id = 2,
- .parent = &clk_p,
- .enable = s3c2410_clkcon_enable,
- .ctrlbit = S3C2410_CLKCON_UART2,
- }, {
- .name = "rtc",
- .id = -1,
- .parent = &clk_p,
- .enable = s3c2410_clkcon_enable,
- .ctrlbit = S3C2410_CLKCON_RTC,
- }, {
- .name = "watchdog",
- .id = -1,
- .parent = &clk_p,
- .ctrlbit = 0,
- }, {
- .name = "usb-bus-host",
- .id = -1,
- .parent = &clk_usb_bus,
- }, {
- .name = "usb-bus-gadget",
- .id = -1,
- .parent = &clk_usb_bus,
- },
+struct clk s3c24xx_dclk1 = {
+ .name = "dclk1",
+ .id = -1,
+ .ctrlbit = S3C2410_DCLKCON_DCLK0EN,
+ .enable = s3c24xx_dclk_enable,
+ .set_parent = s3c24xx_dclk_setparent,
};
-/* s3c2410_baseclk_add()
- *
- * Add all the clocks used by the s3c2410 or compatible CPUs
- * such as the S3C2440 and S3C2442.
- *
- * We cannot use a system device as we are needed before any
- * of the init-calls that initialise the devices are actually
- * done.
-*/
+struct clk s3c24xx_clkout0 = {
+ .name = "clkout0",
+ .id = -1,
+ .set_parent = s3c24xx_clkout_setparent,
+};
+
+struct clk s3c24xx_clkout1 = {
+ .name = "clkout1",
+ .id = -1,
+ .set_parent = s3c24xx_clkout_setparent,
+};
+
+struct clk s3c24xx_uclk = {
+ .name = "uclk",
+ .id = -1,
+};
+
+/* initialise the clock system */
-int __init s3c2410_baseclk_add(void)
+int s3c24xx_register_clock(struct clk *clk)
{
- unsigned long clkslow = __raw_readl(S3C2410_CLKSLOW);
- unsigned long clkcon = __raw_readl(S3C2410_CLKCON);
- struct clk *clkp;
- struct clk *xtal;
- int ret;
- int ptr;
+ clk->owner = THIS_MODULE;
- clk_upll.enable = s3c2410_upll_enable;
+ if (clk->enable == NULL)
+ clk->enable = clk_null_enable;
- if (s3c24xx_register_clock(&clk_usb_bus) < 0)
- printk(KERN_ERR "failed to register usb bus clock\n");
+ /* add to the list of available clocks */
- /* register clocks from clock array */
+ mutex_lock(&clocks_mutex);
+ list_add(&clk->list, &clocks);
+ mutex_unlock(&clocks_mutex);
- clkp = init_clocks;
- for (ptr = 0; ptr < ARRAY_SIZE(init_clocks); ptr++, clkp++) {
- /* ensure that we note the clock state */
+ return 0;
+}
- clkp->usage = clkcon & clkp->ctrlbit ? 1 : 0;
+/* initalise all the clocks */
- ret = s3c24xx_register_clock(clkp);
- if (ret < 0) {
- printk(KERN_ERR "Failed to register clock %s (%d)\n",
- clkp->name, ret);
- }
- }
+int __init s3c24xx_setup_clocks(unsigned long xtal,
+ unsigned long fclk,
+ unsigned long hclk,
+ unsigned long pclk)
+{
+ printk(KERN_INFO "S3C24XX Clocks, (c) 2004 Simtec Electronics\n");
- /* We must be careful disabling the clocks we are not intending to
- * be using at boot time, as subsytems such as the LCD which do
- * their own DMA requests to the bus can cause the system to lockup
- * if they where in the middle of requesting bus access.
- *
- * Disabling the LCD clock if the LCD is active is very dangerous,
- * and therefore the bootloader should be careful to not enable
- * the LCD clock if it is not needed.
- */
-
- /* install (and disable) the clocks we do not need immediately */
-
- clkp = init_clocks_disable;
- for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) {
-
- ret = s3c24xx_register_clock(clkp);
- if (ret < 0) {
- printk(KERN_ERR "Failed to register clock %s (%d)\n",
- clkp->name, ret);
- }
+ /* initialise the main system clocks */
- s3c2410_clkcon_enable(clkp, 0);
- }
+ clk_xtal.rate = xtal;
+ clk_upll.rate = s3c2410_get_pll(__raw_readl(S3C2410_UPLLCON), xtal);
+
+ clk_mpll.rate = fclk;
+ clk_h.rate = hclk;
+ clk_p.rate = pclk;
+ clk_f.rate = fclk;
+
+ /* assume uart clocks are correctly setup */
+
+ /* register our clocks */
+
+ if (s3c24xx_register_clock(&clk_xtal) < 0)
+ printk(KERN_ERR "failed to register master xtal\n");
+
+ if (s3c24xx_register_clock(&clk_mpll) < 0)
+ printk(KERN_ERR "failed to register mpll clock\n");
+
+ if (s3c24xx_register_clock(&clk_upll) < 0)
+ printk(KERN_ERR "failed to register upll clock\n");
- /* show the clock-slow value */
+ if (s3c24xx_register_clock(&clk_f) < 0)
+ printk(KERN_ERR "failed to register cpu fclk\n");
- xtal = clk_get(NULL, "xtal");
+ if (s3c24xx_register_clock(&clk_h) < 0)
+ printk(KERN_ERR "failed to register cpu hclk\n");
- printk("CLOCK: Slow mode (%ld.%ld MHz), %s, MPLL %s, UPLL %s\n",
- print_mhz(clk_get_rate(xtal) /
- ( 2 * S3C2410_CLKSLOW_GET_SLOWVAL(clkslow))),
- (clkslow & S3C2410_CLKSLOW_SLOW) ? "slow" : "fast",
- (clkslow & S3C2410_CLKSLOW_MPLL_OFF) ? "off" : "on",
- (clkslow & S3C2410_CLKSLOW_UCLK_OFF) ? "off" : "on");
+ if (s3c24xx_register_clock(&clk_p) < 0)
+ printk(KERN_ERR "failed to register cpu pclk\n");
return 0;
}
diff --git a/trunk/include/asm-arm/plat-s3c24xx/clock.h b/trunk/arch/arm/mach-s3c2410/clock.h
similarity index 97%
rename from trunk/include/asm-arm/plat-s3c24xx/clock.h
rename to trunk/arch/arm/mach-s3c2410/clock.h
index f6135dbb9fa9..7f0ea03e1d49 100644
--- a/trunk/include/asm-arm/plat-s3c24xx/clock.h
+++ b/trunk/arch/arm/mach-s3c2410/clock.h
@@ -1,4 +1,4 @@
-/* linux/include/asm-arm/plat-s3c24xx/clock.h
+/*
* linux/arch/arm/mach-s3c2410/clock.h
*
* Copyright (c) 2004-2005 Simtec Electronics
diff --git a/trunk/arch/arm/plat-s3c24xx/common-smdk.c b/trunk/arch/arm/mach-s3c2410/common-smdk.c
similarity index 96%
rename from trunk/arch/arm/plat-s3c24xx/common-smdk.c
rename to trunk/arch/arm/mach-s3c2410/common-smdk.c
index 908efa7d745f..a40eaa656177 100644
--- a/trunk/arch/arm/plat-s3c24xx/common-smdk.c
+++ b/trunk/arch/arm/mach-s3c2410/common-smdk.c
@@ -1,4 +1,4 @@
-/* linux/arch/arm/plat-s3c24xx/common-smdk.c
+/* linux/arch/arm/mach-s3c2410/common-smdk.c
*
* Copyright (c) 2006 Simtec Electronics
* Ben Dooks
@@ -38,9 +38,9 @@
#include
-#include
-#include
-#include
+#include "common-smdk.h"
+#include "devs.h"
+#include "pm.h"
/* LED devices */
diff --git a/trunk/include/asm-arm/plat-s3c24xx/common-smdk.h b/trunk/arch/arm/mach-s3c2410/common-smdk.h
similarity index 88%
rename from trunk/include/asm-arm/plat-s3c24xx/common-smdk.h
rename to trunk/arch/arm/mach-s3c2410/common-smdk.h
index 58d9094c935c..0e3a3be330a3 100644
--- a/trunk/include/asm-arm/plat-s3c24xx/common-smdk.h
+++ b/trunk/arch/arm/mach-s3c2410/common-smdk.h
@@ -1,4 +1,4 @@
-/* linux/include/asm-arm/plat-s3c24xx/common-smdk.h
+/* linux/arch/arm/mach-s3c2410/common-smdk.h
*
* Copyright (c) 2006 Simtec Electronics
* Ben Dooks
diff --git a/trunk/arch/arm/plat-s3c24xx/cpu.c b/trunk/arch/arm/mach-s3c2410/cpu.c
similarity index 92%
rename from trunk/arch/arm/plat-s3c24xx/cpu.c
rename to trunk/arch/arm/mach-s3c2410/cpu.c
index 6a2d1070e5a0..ae1f5bb63f7a 100644
--- a/trunk/arch/arm/plat-s3c24xx/cpu.c
+++ b/trunk/arch/arm/mach-s3c2410/cpu.c
@@ -1,4 +1,4 @@
-/* linux/arch/arm/plat-s3c24xx/cpu.c
+/* linux/arch/arm/mach-s3c2410/cpu.c
*
* Copyright (c) 2004-2005 Simtec Electronics
* http://www.simtec.co.uk/products/SWLINUX/
@@ -40,16 +40,15 @@
#include
#include
-#include
-#include
-#include
-#include
-#include
-#include
+#include "cpu.h"
+#include "devs.h"
+#include "clock.h"
+#include "s3c2400.h"
+#include "s3c2410.h"
+#include "s3c2412.h"
#include "s3c244x.h"
-#include
-#include
-#include
+#include "s3c2440.h"
+#include "s3c2442.h"
struct cpu_table {
unsigned long idcode;
@@ -68,7 +67,6 @@ static const char name_s3c2410[] = "S3C2410";
static const char name_s3c2412[] = "S3C2412";
static const char name_s3c2440[] = "S3C2440";
static const char name_s3c2442[] = "S3C2442";
-static const char name_s3c2443[] = "S3C2443";
static const char name_s3c2410a[] = "S3C2410A";
static const char name_s3c2440a[] = "S3C2440A";
@@ -136,15 +134,6 @@ static struct cpu_table cpu_ids[] __initdata = {
.init = s3c2412_init,
.name = name_s3c2412,
},
- {
- .idcode = 0x32443001,
- .idmask = 0xffffffff,
- .map_io = s3c2443_map_io,
- .init_clocks = s3c2443_init_clocks,
- .init_uarts = s3c2443_init_uarts,
- .init = s3c2443_init,
- .name = name_s3c2443,
- },
{
.idcode = 0x0, /* S3C2400 doesn't have an idcode */
.idmask = 0xffffffff,
diff --git a/trunk/include/asm-arm/plat-s3c24xx/cpu.h b/trunk/arch/arm/mach-s3c2410/cpu.h
similarity index 95%
rename from trunk/include/asm-arm/plat-s3c24xx/cpu.h
rename to trunk/arch/arm/mach-s3c2410/cpu.h
index 15dd18810905..be42e4032a6d 100644
--- a/trunk/include/asm-arm/plat-s3c24xx/cpu.h
+++ b/trunk/arch/arm/mach-s3c2410/cpu.h
@@ -1,4 +1,4 @@
-/* linux/include/asm-arm/plat-s3c24xx/cpu.h
+/* arch/arm/mach-s3c2410/cpu.h
*
* Copyright (c) 2004-2005 Simtec Electronics
* Ben Dooks
@@ -67,4 +67,3 @@ extern struct sysdev_class s3c2410_sysclass;
extern struct sysdev_class s3c2412_sysclass;
extern struct sysdev_class s3c2440_sysclass;
extern struct sysdev_class s3c2442_sysclass;
-extern struct sysdev_class s3c2443_sysclass;
diff --git a/trunk/arch/arm/plat-s3c24xx/devs.c b/trunk/arch/arm/mach-s3c2410/devs.c
similarity index 96%
rename from trunk/arch/arm/plat-s3c24xx/devs.c
rename to trunk/arch/arm/mach-s3c2410/devs.c
index 0fe53b39cb2f..faccde2092d2 100644
--- a/trunk/arch/arm/plat-s3c24xx/devs.c
+++ b/trunk/arch/arm/mach-s3c2410/devs.c
@@ -1,4 +1,4 @@
-/* linux/arch/arm/plat-s3c24xx/devs.c
+/* linux/arch/arm/mach-s3c2410/devs.c
*
* Copyright (c) 2004 Simtec Electronics
* Ben Dooks
@@ -29,10 +29,9 @@
#include
#include
-#include
-#include
-#include
+#include "devs.h"
+#include "cpu.h"
/* Serial port registrations */
@@ -231,20 +230,6 @@ struct platform_device s3c_device_usbgadget = {
EXPORT_SYMBOL(s3c_device_usbgadget);
-void __init s3c24xx_udc_set_platdata(struct s3c2410_udc_mach_info *pd)
-{
- struct s3c2410_udc_mach_info *npd;
-
- npd = kmalloc(sizeof(*npd), GFP_KERNEL);
- if (npd) {
- memcpy(npd, pd, sizeof(*npd));
- s3c_device_usbgadget.dev.platform_data = npd;
- } else {
- printk(KERN_ERR "no memory for udc platform data\n");
- }
-}
-
-
/* Watchdog */
static struct resource s3c_wdt_resource[] = {
diff --git a/trunk/include/asm-arm/plat-s3c24xx/devs.h b/trunk/arch/arm/mach-s3c2410/devs.h
similarity index 97%
rename from trunk/include/asm-arm/plat-s3c24xx/devs.h
rename to trunk/arch/arm/mach-s3c2410/devs.h
index dddf485fc067..14fb0bade716 100644
--- a/trunk/include/asm-arm/plat-s3c24xx/devs.h
+++ b/trunk/arch/arm/mach-s3c2410/devs.h
@@ -1,4 +1,4 @@
-/* linux/include/asm-arm/plat-s3c24xx/devs.h
+/* arch/arm/mach-s3c2410/devs.h
*
* Copyright (c) 2004 Simtec Electronics
* Ben Dooks
diff --git a/trunk/arch/arm/mach-s3c2410/dma.c b/trunk/arch/arm/mach-s3c2410/dma.c
index 67d1ad363973..fa860e716b4f 100644
--- a/trunk/arch/arm/mach-s3c2410/dma.c
+++ b/trunk/arch/arm/mach-s3c2410/dma.c
@@ -1,9 +1,9 @@
/* linux/arch/arm/mach-s3c2410/dma.c
*
- * Copyright (c) 2006 Simtec Electronics
+ * Copyright (c) 2003-2005,2006 Simtec Electronics
* Ben Dooks
*
- * S3C2410 DMA selection
+ * S3C2410 DMA core
*
* http://armlinux.simtec.co.uk/
*
@@ -12,170 +12,1430 @@
* published by the Free Software Foundation.
*/
-#include
+
+#ifdef CONFIG_S3C2410_DMA_DEBUG
+#define DEBUG
+#endif
+
+#include
#include
+#include
+#include
+#include
#include
-#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
#include
-#include
-
-#include
-#include
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-static struct s3c24xx_dma_map __initdata s3c2410_dma_mappings[] = {
- [DMACH_XD0] = {
- .name = "xdreq0",
- .channels[0] = S3C2410_DCON_CH0_XDREQ0 | DMA_CH_VALID,
- },
- [DMACH_XD1] = {
- .name = "xdreq1",
- .channels[1] = S3C2410_DCON_CH1_XDREQ1 | DMA_CH_VALID,
- },
- [DMACH_SDI] = {
- .name = "sdi",
- .channels[0] = S3C2410_DCON_CH0_SDI | DMA_CH_VALID,
- .channels[2] = S3C2410_DCON_CH2_SDI | DMA_CH_VALID,
- .channels[3] = S3C2410_DCON_CH3_SDI | DMA_CH_VALID,
- .hw_addr.to = S3C2410_PA_IIS + S3C2410_IISFIFO,
- .hw_addr.from = S3C2410_PA_IIS + S3C2410_IISFIFO,
- },
- [DMACH_SPI0] = {
- .name = "spi0",
- .channels[1] = S3C2410_DCON_CH1_SPI | DMA_CH_VALID,
- .hw_addr.to = S3C2410_PA_SPI + S3C2410_SPTDAT,
- .hw_addr.from = S3C2410_PA_SPI + S3C2410_SPRDAT,
- },
- [DMACH_SPI1] = {
- .name = "spi1",
- .channels[3] = S3C2410_DCON_CH3_SPI | DMA_CH_VALID,
- .hw_addr.to = S3C2410_PA_SPI + 0x20 + S3C2410_SPTDAT,
- .hw_addr.from = S3C2410_PA_SPI + 0x20 + S3C2410_SPRDAT,
- },
- [DMACH_UART0] = {
- .name = "uart0",
- .channels[0] = S3C2410_DCON_CH0_UART0 | DMA_CH_VALID,
- .hw_addr.to = S3C2410_PA_UART0 + S3C2410_UTXH,
- .hw_addr.from = S3C2410_PA_UART0 + S3C2410_URXH,
- },
- [DMACH_UART1] = {
- .name = "uart1",
- .channels[1] = S3C2410_DCON_CH1_UART1 | DMA_CH_VALID,
- .hw_addr.to = S3C2410_PA_UART1 + S3C2410_UTXH,
- .hw_addr.from = S3C2410_PA_UART1 + S3C2410_URXH,
- },
- [DMACH_UART2] = {
- .name = "uart2",
- .channels[3] = S3C2410_DCON_CH3_UART2 | DMA_CH_VALID,
- .hw_addr.to = S3C2410_PA_UART2 + S3C2410_UTXH,
- .hw_addr.from = S3C2410_PA_UART2 + S3C2410_URXH,
- },
- [DMACH_TIMER] = {
- .name = "timer",
- .channels[0] = S3C2410_DCON_CH0_TIMER | DMA_CH_VALID,
- .channels[2] = S3C2410_DCON_CH2_TIMER | DMA_CH_VALID,
- .channels[3] = S3C2410_DCON_CH3_TIMER | DMA_CH_VALID,
- },
- [DMACH_I2S_IN] = {
- .name = "i2s-sdi",
- .channels[1] = S3C2410_DCON_CH1_I2SSDI | DMA_CH_VALID,
- .channels[2] = S3C2410_DCON_CH2_I2SSDI | DMA_CH_VALID,
- .hw_addr.from = S3C2410_PA_IIS + S3C2410_IISFIFO,
- },
- [DMACH_I2S_OUT] = {
- .name = "i2s-sdo",
- .channels[2] = S3C2410_DCON_CH2_I2SSDO | DMA_CH_VALID,
- .hw_addr.to = S3C2410_PA_IIS + S3C2410_IISFIFO,
- },
- [DMACH_USB_EP1] = {
- .name = "usb-ep1",
- .channels[0] = S3C2410_DCON_CH0_USBEP1 | DMA_CH_VALID,
- },
- [DMACH_USB_EP2] = {
- .name = "usb-ep2",
- .channels[1] = S3C2410_DCON_CH1_USBEP2 | DMA_CH_VALID,
- },
- [DMACH_USB_EP3] = {
- .name = "usb-ep3",
- .channels[2] = S3C2410_DCON_CH2_USBEP3 | DMA_CH_VALID,
- },
- [DMACH_USB_EP4] = {
- .name = "usb-ep4",
- .channels[3] =S3C2410_DCON_CH3_USBEP4 | DMA_CH_VALID,
- },
-};
-static void s3c2410_dma_select(struct s3c2410_dma_chan *chan,
- struct s3c24xx_dma_map *map)
+#include
+#include
+
+#include "dma.h"
+
+/* io map for dma */
+static void __iomem *dma_base;
+static struct kmem_cache *dma_kmem;
+
+struct s3c24xx_dma_selection dma_sel;
+
+/* dma channel state information */
+struct s3c2410_dma_chan 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(struct s3c2410_dma_chan *chan, int reg, unsigned long val)
{
- chan->dcon = map->channels[chan->number] & ~DMA_CH_VALID;
+ pr_debug("writing %08x to register %08x\n",(unsigned int)val,reg);
+ writel(val, dma_regaddr(chan, reg));
}
+#endif
-static struct s3c24xx_dma_selection __initdata s3c2410_dma_sel = {
- .select = s3c2410_dma_select,
- .dcon_mask = 7 << 24,
- .map = s3c2410_dma_mappings,
- .map_size = ARRAY_SIZE(s3c2410_dma_mappings),
-};
+#define dma_rdreg(chan, reg) readl((chan)->regs + (reg))
-static struct s3c24xx_dma_order __initdata s3c2410_dma_order = {
- .channels = {
- [DMACH_SDI] = {
- .list = {
- [0] = 3 | DMA_CH_VALID,
- [1] = 2 | DMA_CH_VALID,
- [2] = 0 | DMA_CH_VALID,
- },
- },
- [DMACH_I2S_IN] = {
- .list = {
- [0] = 1 | DMA_CH_VALID,
- [1] = 2 | DMA_CH_VALID,
- },
- },
- },
+/* captured register state for debug */
+
+struct s3c2410_dma_regstate {
+ unsigned long dcsrc;
+ unsigned long disrc;
+ unsigned long dstat;
+ unsigned long dcon;
+ unsigned long dmsktrig;
};
-static int s3c2410_dma_add(struct sys_device *sysdev)
+#ifdef CONFIG_S3C2410_DMA_DEBUG
+
+/* dmadbg_showregs
+ *
+ * simple debug routine to print the current state of the dma registers
+*/
+
+static void
+dmadbg_capture(struct s3c2410_dma_chan *chan, struct s3c2410_dma_regstate *regs)
{
- s3c2410_dma_init();
- s3c24xx_dma_order_set(&s3c2410_dma_order);
- return s3c24xx_dma_init_map(&s3c2410_dma_sel);
+ 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);
}
-#if defined(CONFIG_CPU_S3C2410)
-static struct sysdev_driver s3c2410_dma_driver = {
- .add = s3c2410_dma_add,
-};
+static void
+dmadbg_dumpregs(const char *fname, int line, struct s3c2410_dma_chan *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, struct s3c2410_dma_chan *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_dumpregs(fname, line, chan, &state);
+}
+
+static void
+dmadbg_showregs(const char *fname, int line, struct s3c2410_dma_chan *chan)
+{
+ struct s3c2410_dma_regstate state;
+
+ dmadbg_capture(chan, &state);
+ dmadbg_dumpregs(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 */
+
+static struct s3c2410_dma_chan *dma_chan_map[DMACH_MAX];
+
+/* lookup_dma_channel
+ *
+ * change the dma channel number given into a real dma channel id
+*/
-static int __init s3c2410_dma_drvinit(void)
+static struct s3c2410_dma_chan *lookup_dma_channel(unsigned int channel)
{
- return sysdev_driver_register(&s3c2410_sysclass, &s3c2410_dma_driver);
+ if (channel & DMACH_LOW_LEVEL)
+ return &s3c2410_chans[channel & ~DMACH_LOW_LEVEL];
+ else
+ return dma_chan_map[channel];
+}
+
+/* s3c2410_dma_stats_timeout
+ *
+ * Update DMA stats from timeout info
+*/
+
+static void
+s3c2410_dma_stats_timeout(struct s3c2410_dma_stats *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;
}
-arch_initcall(s3c2410_dma_drvinit);
+/* s3c2410_dma_waitforload
+ *
+ * wait for the DMA engine to load a buffer, and update the state accordingly
+*/
+
+static int
+s3c2410_dma_waitforload(struct s3c2410_dma_chan *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(struct s3c2410_dma_chan *chan,
+ struct s3c2410_dma_buf *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;
+ }
+
+ if ((buf->data & 0xf0000000) != 0x30000000) {
+ dmawarn("dmaload: buffer is %p\n", (void *)buf->data);
+ }
+
+ 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(struct s3c2410_dma_chan *chan, enum s3c2410_chan_op 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(struct s3c2410_dma_chan *chan, struct s3c2410_dma_buf *buf,
+ enum s3c2410_dma_buffresult result)
+{
+#if 0
+ pr_debug("callback_fn=%p, buf=%p, id=%p, size=%d, result=%d\n",
+ chan->callback_fn, buf, buf->id, buf->size, result);
#endif
-#if defined(CONFIG_CPU_S3C2442)
-/* S3C2442 DMA contains the same selection table as the S3C2410 */
-static struct sysdev_driver s3c2442_dma_driver = {
- .add = s3c2410_dma_add,
-};
+ if (chan->callback_fn != NULL) {
+ (chan->callback_fn)(chan, buf->id, buf->size, result);
+ }
+}
-static int __init s3c2442_dma_drvinit(void)
+/* s3c2410_dma_start
+ *
+ * start a dma channel going
+*/
+
+static int s3c2410_dma_start(struct s3c2410_dma_chan *chan)
{
- return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_dma_driver);
+ 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("dma%d: %08lx to DMASKTRIG\n", chan->number, 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);
+
+ /* if we've only loaded one buffer onto the channel, then chec
+ * to see if we have another, and if so, try and load it so when
+ * the first buffer is finished, the new one will be loaded onto
+ * the channel */
+
+ if (chan->next != NULL) {
+ if (chan->load_state == S3C2410_DMALOAD_1LOADED) {
+
+ if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {
+ pr_debug("%s: buff not yet loaded, no more todo\n",
+ __FUNCTION__);
+ } else {
+ chan->load_state = S3C2410_DMALOAD_1RUNNING;
+ s3c2410_dma_loadbuffer(chan, chan->next);
+ }
+
+ } else if (chan->load_state == S3C2410_DMALOAD_1RUNNING) {
+ s3c2410_dma_loadbuffer(chan, chan->next);
+ }
+ }
+
+
+ local_irq_restore(flags);
+
+ return 0;
}
-arch_initcall(s3c2442_dma_drvinit);
+/* s3c2410_dma_canload
+ *
+ * work out if we can queue another buffer into the DMA engine
+*/
+
+static int
+s3c2410_dma_canload(struct s3c2410_dma_chan *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)
+{
+ struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
+ struct s3c2410_dma_buf *buf;
+ unsigned long flags;
+
+ if (chan == NULL)
+ return -EINVAL;
+
+ pr_debug("%s: id=%p, data=%08x, size=%d\n",
+ __FUNCTION__, id, (unsigned int)data, size);
+
+ buf = kmem_cache_alloc(dma_kmem, GFP_ATOMIC);
+ if (buf == NULL) {
+ pr_debug("%s: out of memory (%ld alloc)\n",
+ __FUNCTION__, (long)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);
+ }
+ }
+
+ local_irq_restore(flags);
+ return 0;
+}
+
+EXPORT_SYMBOL(s3c2410_dma_enqueue);
+
+static inline void
+s3c2410_dma_freebuf(struct s3c2410_dma_buf *buf)
+{
+ int magicok = (buf->magic == BUF_MAGIC);
+
+ buf->magic = -1;
+
+ if (magicok) {
+ kmem_cache_free(dma_kmem, 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(struct s3c2410_dma_chan *chan)
+{
+#if 0
+ pr_debug("dma%d: s3c2410_dma_lastxfer: load_state %d\n",
+ chan->number, chan->load_state);
#endif
+ 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 (%s)\n",
+ chan->number, __FUNCTION__);
+ return;
+ }
+ break;
+
+ case S3C2410_DMALOAD_1LOADED_1RUNNING:
+ /* I belive in this case we do not have anything to do
+ * until the next buffer comes along, and we turn off the
+ * reload */
+ return;
+
+ default:
+ pr_debug("dma%d: lastxfer: unhandled load_state %d with no next\n",
+ 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 s3c2410_dma_chan *chan = (struct s3c2410_dma_chan *)devpw;
+ struct s3c2410_dma_buf *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 {
+ }
+
+ /* only reload if the channel is still running... our buffer done
+ * routine may have altered the state by requesting the dma channel
+ * to stop or shutdown... */
+
+ /* todo: check that when the channel is shut-down from inside this
+ * function, we cope with unsetting reload, etc */
+
+ if (chan->next != NULL && chan->state != S3C2410_DMA_IDLE) {
+ 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 (%s)\n",
+ chan->number, __FUNCTION__);
+ return IRQ_HANDLED;
+ }
+
+ break;
+
+ case S3C2410_DMALOAD_1LOADED_1RUNNING:
+ goto no_load;
+
+ 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 | DMACH_LOW_LEVEL,
+ S3C2410_DMAOP_STOP);
+ }
+ }
+
+ no_load:
+ return IRQ_HANDLED;
+}
+
+static struct s3c2410_dma_chan *s3c2410_dma_map_channel(int channel);
+
+/* s3c2410_request_dma
+ *
+ * get control of an dma channel
+*/
+
+int s3c2410_dma_request(unsigned int channel,
+ struct s3c2410_dma_client *client,
+ void *dev)
+{
+ struct s3c2410_dma_chan *chan;
+ unsigned long flags;
+ int err;
+
+ pr_debug("dma%d: s3c2410_request_dma: client=%s, dev=%p\n",
+ channel, client->name, dev);
+
+ local_irq_save(flags);
+
+ chan = s3c2410_dma_map_channel(channel);
+ if (chan == NULL) {
+ local_irq_restore(flags);
+ return -EBUSY;
+ }
+
+ dbg_showchan(chan);
+
+ chan->client = client;
+ chan->in_use = 1;
+
+ if (!chan->irq_claimed) {
+ pr_debug("dma%d: %s : requesting irq %d\n",
+ channel, __FUNCTION__, chan->irq);
+
+ chan->irq_claimed = 1;
+ local_irq_restore(flags);
+
+ err = request_irq(chan->irq, s3c2410_dma_irq, IRQF_DISABLED,
+ client->name, (void *)chan);
+
+ local_irq_save(flags);
+
+ if (err) {
+ chan->in_use = 0;
+ chan->irq_claimed = 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_enabled = 1;
+ }
+
+ local_irq_restore(flags);
+
+ /* need to setup */
+
+ pr_debug("%s: channel initialised, %p\n", __FUNCTION__, chan);
+
+ return 0;
+}
+
+EXPORT_SYMBOL(s3c2410_dma_request);
+
+/* 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, struct s3c2410_dma_client *client)
+{
+ struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
+ unsigned long flags;
+
+ if (chan == NULL)
+ return -EINVAL;
+
+ 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;
+
+ if (chan->irq_claimed)
+ free_irq(chan->irq, (void *)chan);
+
+ chan->irq_claimed = 0;
+
+ if (!(channel & DMACH_LOW_LEVEL))
+ dma_chan_map[channel] = NULL;
+
+ local_irq_restore(flags);
+
+ return 0;
+}
+
+EXPORT_SYMBOL(s3c2410_dma_free);
+
+static int s3c2410_dma_dostop(struct s3c2410_dma_chan *chan)
+{
+ unsigned long flags;
+ unsigned long tmp;
+
+ 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;
+ //tmp &= ~S3C2410_DMASKTRIG_ON;
+ 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
+
+ /* should stop do this, or should we wait for flush? */
+ chan->state = S3C2410_DMA_IDLE;
+ chan->load_state = S3C2410_DMALOAD_NONE;
+
+ local_irq_restore(flags);
+
+ return 0;
+}
+
+void s3c2410_dma_waitforstop(struct s3c2410_dma_chan *chan)
+{
+ unsigned long tmp;
+ unsigned int timeout = 0x10000;
+
+ while (timeout-- > 0) {
+ tmp = dma_rdreg(chan, S3C2410_DMA_DMASKTRIG);
+
+ if (!(tmp & S3C2410_DMASKTRIG_ON))
+ return;
+ }
+
+ pr_debug("dma%d: failed to stop?\n", chan->number);
+}
+
+
+/* s3c2410_dma_flush
+ *
+ * stop the channel, and remove all current and pending transfers
+*/
+
+static int s3c2410_dma_flush(struct s3c2410_dma_chan *chan)
+{
+ struct s3c2410_dma_buf *buf, *next;
+ unsigned long flags;
+
+ pr_debug("%s: chan %p (%d)\n", __FUNCTION__, chan, chan->number);
+
+ dbg_showchan(chan);
+
+ 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);
+ }
+ }
+
+ dbg_showregs(chan);
+
+ s3c2410_dma_waitforstop(chan);
+
+#if 0
+ /* should also clear interrupts, according to WinCE BSP */
+ {
+ unsigned long tmp;
+
+ tmp = dma_rdreg(chan, S3C2410_DMA_DCON);
+ tmp |= S3C2410_DCON_NORELOAD;
+ dma_wrreg(chan, S3C2410_DMA_DCON, tmp);
+ }
+#endif
+
+ dbg_showregs(chan);
+
+ local_irq_restore(flags);
+
+ return 0;
+}
+
+int
+s3c2410_dma_started(struct s3c2410_dma_chan *chan)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+
+ dbg_showchan(chan);
+
+ /* if we've only loaded one buffer onto the channel, then chec
+ * to see if we have another, and if so, try and load it so when
+ * the first buffer is finished, the new one will be loaded onto
+ * the channel */
+
+ if (chan->next != NULL) {
+ if (chan->load_state == S3C2410_DMALOAD_1LOADED) {
+
+ if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {
+ pr_debug("%s: buff not yet loaded, no more todo\n",
+ __FUNCTION__);
+ } else {
+ chan->load_state = S3C2410_DMALOAD_1RUNNING;
+ s3c2410_dma_loadbuffer(chan, chan->next);
+ }
+
+ } else if (chan->load_state == S3C2410_DMALOAD_1RUNNING) {
+ s3c2410_dma_loadbuffer(chan, chan->next);
+ }
+ }
+
+
+ local_irq_restore(flags);
+
+ return 0;
+
+}
+
+int
+s3c2410_dma_ctrl(dmach_t channel, enum s3c2410_chan_op op)
+{
+ struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
+
+ if (chan == NULL)
+ return -EINVAL;
+
+ switch (op) {
+ case S3C2410_DMAOP_START:
+ return s3c2410_dma_start(chan);
+
+ case S3C2410_DMAOP_STOP:
+ return s3c2410_dma_dostop(chan);
+
+ case S3C2410_DMAOP_PAUSE:
+ case S3C2410_DMAOP_RESUME:
+ return -ENOENT;
+
+ case S3C2410_DMAOP_FLUSH:
+ return s3c2410_dma_flush(chan);
+
+ case S3C2410_DMAOP_STARTED:
+ return s3c2410_dma_started(chan);
+
+ case S3C2410_DMAOP_TIMEOUT:
+ return 0;
+
+ }
+
+ return -ENOENT; /* unknown, don't bother */
+}
+
+EXPORT_SYMBOL(s3c2410_dma_ctrl);
+
+/* 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)
+{
+ struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
+
+ pr_debug("%s: chan=%d, xfer_unit=%d, dcon=%08x\n",
+ __FUNCTION__, channel, xferunit, dcon);
+
+ if (chan == NULL)
+ return -EINVAL;
+
+ pr_debug("%s: Initial dcon is %08x\n", __FUNCTION__, dcon);
+
+ dcon |= chan->dcon & dma_sel.dcon_mask;
+
+ pr_debug("%s: New dcon is %08x\n", __FUNCTION__, dcon);
+
+ 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;
+}
+
+EXPORT_SYMBOL(s3c2410_dma_config);
+
+int s3c2410_dma_setflags(dmach_t channel, unsigned int flags)
+{
+ struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
+
+ if (chan == NULL)
+ return -EINVAL;
+
+ pr_debug("%s: chan=%p, flags=%08x\n", __FUNCTION__, chan, flags);
+
+ chan->flags = flags;
+
+ return 0;
+}
+
+EXPORT_SYMBOL(s3c2410_dma_setflags);
+
+
+/* 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)
+{
+ struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
+
+ if (chan == NULL)
+ return -EINVAL;
+
+ pr_debug("%s: chan=%p, op rtn=%p\n", __FUNCTION__, chan, rtn);
+
+ chan->op_fn = rtn;
+
+ return 0;
+}
+
+EXPORT_SYMBOL(s3c2410_dma_set_opfn);
+
+int s3c2410_dma_set_buffdone_fn(dmach_t channel, s3c2410_dma_cbfn_t rtn)
+{
+ struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
+
+ if (chan == NULL)
+ return -EINVAL;
+
+ pr_debug("%s: chan=%p, callback rtn=%p\n", __FUNCTION__, chan, rtn);
+
+ chan->callback_fn = rtn;
+
+ return 0;
+}
+
+EXPORT_SYMBOL(s3c2410_dma_set_buffdone_fn);
+
+/* 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,
+ enum s3c2410_dmasrc source,
+ int hwcfg,
+ unsigned long devaddr)
+{
+ struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
+
+ if (chan == NULL)
+ return -EINVAL;
+
+ 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;
+}
+
+EXPORT_SYMBOL(s3c2410_dma_devconfig);
+
+/* s3c2410_dma_getposition
+ *
+ * returns the current transfer points for the dma source and destination
+*/
+
+int s3c2410_dma_getposition(dmach_t channel, dma_addr_t *src, dma_addr_t *dst)
+{
+ struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
+
+ if (chan == NULL)
+ return -EINVAL;
+
+ if (src != NULL)
+ *src = dma_rdreg(chan, S3C2410_DMA_DCSRC);
+
+ if (dst != NULL)
+ *dst = dma_rdreg(chan, S3C2410_DMA_DCDST);
+
+ return 0;
+}
+
+EXPORT_SYMBOL(s3c2410_dma_getposition);
+
+
+/* system device class */
+
+#ifdef CONFIG_PM
+
+static int s3c2410_dma_suspend(struct sys_device *dev, pm_message_t state)
+{
+ struct s3c2410_dma_chan *cp = container_of(dev, struct s3c2410_dma_chan, dev);
+
+ printk(KERN_DEBUG "suspending dma channel %d\n", cp->number);
+
+ if (dma_rdreg(cp, S3C2410_DMA_DMASKTRIG) & S3C2410_DMASKTRIG_ON) {
+ /* the dma channel is still working, which is probably
+ * a bad thing to do over suspend/resume. We stop the
+ * channel and assume that the client is either going to
+ * retry after resume, or that it is broken.
+ */
+
+ printk(KERN_INFO "dma: stopping channel %d due to suspend\n",
+ cp->number);
+
+ s3c2410_dma_dostop(cp);
+ }
+
+ return 0;
+}
+
+static int s3c2410_dma_resume(struct sys_device *dev)
+{
+ return 0;
+}
+
+#else
+#define s3c2410_dma_suspend NULL
+#define s3c2410_dma_resume NULL
+#endif /* CONFIG_PM */
+
+struct sysdev_class dma_sysclass = {
+ set_kset_name("s3c24xx-dma"),
+ .suspend = s3c2410_dma_suspend,
+ .resume = s3c2410_dma_resume,
+};
+
+/* kmem cache implementation */
+
+static void s3c2410_dma_cache_ctor(void *p, struct kmem_cache *c, unsigned long f)
+{
+ memset(p, 0, sizeof(struct s3c2410_dma_buf));
+}
+
+/* initialisation code */
+
+static int __init s3c2410_init_dma(void)
+{
+ struct s3c2410_dma_chan *cp;
+ int channel;
+ int ret;
+
+ printk("S3C24XX DMA Driver, (c) 2003-2004,2006 Simtec Electronics\n");
+
+ dma_base = ioremap(S3C24XX_PA_DMA, 0x200);
+ if (dma_base == NULL) {
+ printk(KERN_ERR "dma failed to remap register block\n");
+ return -ENOMEM;
+ }
+
+ printk("Registering sysclass\n");
+
+ ret = sysdev_class_register(&dma_sysclass);
+ if (ret != 0) {
+ printk(KERN_ERR "dma sysclass registration failed\n");
+ goto err;
+ }
+
+ dma_kmem = kmem_cache_create("dma_desc", sizeof(struct s3c2410_dma_buf), 0,
+ SLAB_HWCACHE_ALIGN,
+ s3c2410_dma_cache_ctor, NULL);
+
+ if (dma_kmem == NULL) {
+ printk(KERN_ERR "dma failed to make kmem cache\n");
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ for (channel = 0; channel < S3C2410_DMA_CHANNELS; channel++) {
+ cp = &s3c2410_chans[channel];
+
+ memset(cp, 0, sizeof(struct s3c2410_dma_chan));
+
+ /* dma channel irqs are in order.. */
+ cp->number = channel;
+ cp->irq = channel + IRQ_DMA0;
+ cp->regs = 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;
+
+ /* register system device */
+
+ cp->dev.cls = &dma_sysclass;
+ cp->dev.id = channel;
+ ret = sysdev_register(&cp->dev);
+
+ printk("DMA channel %d at %p, irq %d\n",
+ cp->number, cp->regs, cp->irq);
+ }
+
+ return 0;
+
+ err:
+ kmem_cache_destroy(dma_kmem);
+ iounmap(dma_base);
+ dma_base = NULL;
+ return ret;
+}
+
+core_initcall(s3c2410_init_dma);
+
+static inline int is_channel_valid(unsigned int channel)
+{
+ return (channel & DMA_CH_VALID);
+}
+
+/* s3c2410_dma_map_channel()
+ *
+ * turn the virtual channel number into a real, and un-used hardware
+ * channel.
+ *
+ * currently this code uses first-free channel from the specified harware
+ * map, not taking into account anything that the board setup code may
+ * have to say about the likely peripheral set to be in use.
+*/
+
+struct s3c2410_dma_chan *s3c2410_dma_map_channel(int channel)
+{
+ struct s3c24xx_dma_map *ch_map;
+ struct s3c2410_dma_chan *dmach;
+ int ch;
+
+ if (dma_sel.map == NULL || channel > dma_sel.map_size)
+ return NULL;
+
+ ch_map = dma_sel.map + channel;
+
+ for (ch = 0; ch < S3C2410_DMA_CHANNELS; ch++) {
+ if (!is_channel_valid(ch_map->channels[ch]))
+ continue;
+
+ if (s3c2410_chans[ch].in_use == 0) {
+ printk("mapped channel %d to %d\n", channel, ch);
+ break;
+ }
+ }
+
+ if (ch >= S3C2410_DMA_CHANNELS)
+ return NULL;
+
+ /* update our channel mapping */
+
+ dmach = &s3c2410_chans[ch];
+ dma_chan_map[channel] = dmach;
+
+ /* select the channel */
+
+ (dma_sel.select)(dmach, ch_map);
+
+ return dmach;
+}
+
+static void s3c24xx_dma_show_ch(struct s3c24xx_dma_map *map, int ch)
+{
+ /* show the channel configuration */
+
+ printk("%2d: %20s, channels %c%c%c%c\n", ch, map->name,
+ (is_channel_valid(map->channels[0]) ? '0' : '-'),
+ (is_channel_valid(map->channels[1]) ? '1' : '-'),
+ (is_channel_valid(map->channels[2]) ? '2' : '-'),
+ (is_channel_valid(map->channels[3]) ? '3' : '-'));
+}
+
+static int s3c24xx_dma_check_entry(struct s3c24xx_dma_map *map, int ch)
+{
+ if (1)
+ s3c24xx_dma_show_ch(map, ch);
+
+ return 0;
+}
+
+int __init s3c24xx_dma_init_map(struct s3c24xx_dma_selection *sel)
+{
+ struct s3c24xx_dma_map *nmap;
+ size_t map_sz = sizeof(*nmap) * sel->map_size;
+ int ptr;
+
+ nmap = kmalloc(map_sz, GFP_KERNEL);
+ if (nmap == NULL)
+ return -ENOMEM;
+
+ memcpy(nmap, sel->map, map_sz);
+ memcpy(&dma_sel, sel, sizeof(*sel));
+
+ dma_sel.map = nmap;
+
+ for (ptr = 0; ptr < sel->map_size; ptr++)
+ s3c24xx_dma_check_entry(nmap+ptr, ptr);
+
+ return 0;
+}
diff --git a/trunk/include/asm-arm/plat-s3c24xx/dma.h b/trunk/arch/arm/mach-s3c2410/dma.h
similarity index 53%
rename from trunk/include/asm-arm/plat-s3c24xx/dma.h
rename to trunk/arch/arm/mach-s3c2410/dma.h
index 2c59406435e5..0ebfe0aab80b 100644
--- a/trunk/include/asm-arm/plat-s3c24xx/dma.h
+++ b/trunk/arch/arm/mach-s3c2410/dma.h
@@ -1,4 +1,4 @@
-/* linux/include/asm-arm/plat-s3c24xx/dma.h
+/* arch/arm/mach-s3c2410/dma.h
*
* Copyright (C) 2006 Simtec Electronics
* Ben Dooks
@@ -14,7 +14,6 @@ extern struct sysdev_class dma_sysclass;
extern struct s3c2410_dma_chan s3c2410_chans[S3C2410_DMA_CHANNELS];
#define DMA_CH_VALID (1<<31)
-#define DMA_CH_NEVER (1<<30)
struct s3c24xx_dma_addr {
unsigned long from;
@@ -44,34 +43,3 @@ struct s3c24xx_dma_selection {
};
extern int s3c24xx_dma_init_map(struct s3c24xx_dma_selection *sel);
-
-/* struct s3c24xx_dma_order_ch
- *
- * channel map for one of the `enum dma_ch` dma channels. the list
- * entry contains a set of low-level channel numbers, orred with
- * DMA_CH_VALID, which are checked in the order in the array.
-*/
-
-struct s3c24xx_dma_order_ch {
- unsigned int list[S3C2410_DMA_CHANNELS]; /* list of channels */
- unsigned int flags; /* flags */
-};
-
-/* struct s3c24xx_dma_order
- *
- * information provided by either the core or the board to give the
- * dma system a hint on how to allocate channels
-*/
-
-struct s3c24xx_dma_order {
- struct s3c24xx_dma_order_ch channels[DMACH_MAX];
-};
-
-extern int s3c24xx_dma_order_set(struct s3c24xx_dma_order *map);
-
-/* DMA init code, called from the cpu support code */
-
-extern int s3c2410_dma_init(void);
-
-extern int s3c24xx_dma_init(unsigned int channels, unsigned int irq,
- unsigned int stride);
diff --git a/trunk/arch/arm/mach-s3c2410/gpio.c b/trunk/arch/arm/mach-s3c2410/gpio.c
index 01e795d1146e..f6fb215bb48c 100644
--- a/trunk/arch/arm/mach-s3c2410/gpio.c
+++ b/trunk/arch/arm/mach-s3c2410/gpio.c
@@ -1,9 +1,9 @@
/* linux/arch/arm/mach-s3c2410/gpio.c
*
- * Copyright (c) 2004-2006 Simtec Electronics
+ * Copyright (c) 2004-2005 Simtec Electronics
* Ben Dooks
*
- * S3C2410 GPIO support
+ * S3C24XX GPIO support
*
* 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
@@ -18,7 +18,8 @@
* 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
#include
@@ -32,40 +33,156 @@
#include
-int s3c2410_gpio_irqfilter(unsigned int pin, unsigned int on,
- unsigned int config)
+void s3c2410_gpio_cfgpin(unsigned int pin, unsigned int function)
+{
+ void __iomem *base = S3C24XX_GPIO_BASE(pin);
+ unsigned long mask;
+ unsigned long con;
+ unsigned long flags;
+
+ if (pin < S3C2410_GPIO_BANKB) {
+ mask = 1 << S3C2410_GPIO_OFFSET(pin);
+ } else {
+ mask = 3 << S3C2410_GPIO_OFFSET(pin)*2;
+ }
+
+ switch (function) {
+ case S3C2410_GPIO_LEAVE:
+ mask = 0;
+ function = 0;
+ break;
+
+ case S3C2410_GPIO_INPUT:
+ case S3C2410_GPIO_OUTPUT:
+ case S3C2410_GPIO_SFN2:
+ case S3C2410_GPIO_SFN3:
+ if (pin < S3C2410_GPIO_BANKB) {
+ function -= 1;
+ function &= 1;
+ function <<= S3C2410_GPIO_OFFSET(pin);
+ } else {
+ function &= 3;
+ function <<= S3C2410_GPIO_OFFSET(pin)*2;
+ }
+ }
+
+ /* modify the specified register wwith IRQs off */
+
+ local_irq_save(flags);
+
+ con = __raw_readl(base + 0x00);
+ con &= ~mask;
+ con |= function;
+
+ __raw_writel(con, base + 0x00);
+
+ local_irq_restore(flags);
+}
+
+EXPORT_SYMBOL(s3c2410_gpio_cfgpin);
+
+unsigned int s3c2410_gpio_getcfg(unsigned int pin)
+{
+ void __iomem *base = S3C24XX_GPIO_BASE(pin);
+ unsigned long val = __raw_readl(base);
+
+ if (pin < S3C2410_GPIO_BANKB) {
+ val >>= S3C2410_GPIO_OFFSET(pin);
+ val &= 1;
+ val += 1;
+ } else {
+ val >>= S3C2410_GPIO_OFFSET(pin)*2;
+ val &= 3;
+ }
+
+ return val | S3C2410_GPIO_INPUT;
+}
+
+EXPORT_SYMBOL(s3c2410_gpio_getcfg);
+
+void s3c2410_gpio_pullup(unsigned int pin, unsigned int to)
{
- void __iomem *reg = S3C24XX_EINFLT0;
+ void __iomem *base = S3C24XX_GPIO_BASE(pin);
+ unsigned long offs = S3C2410_GPIO_OFFSET(pin);
unsigned long flags;
- unsigned long val;
+ unsigned long up;
+
+ if (pin < S3C2410_GPIO_BANKB)
+ return;
+
+ local_irq_save(flags);
+
+ up = __raw_readl(base + 0x08);
+ up &= ~(1L << offs);
+ up |= to << offs;
+ __raw_writel(up, base + 0x08);
- if (pin < S3C2410_GPG8 || pin > S3C2410_GPG15)
- return -1;
+ local_irq_restore(flags);
+}
- config &= 0xff;
+EXPORT_SYMBOL(s3c2410_gpio_pullup);
- pin -= S3C2410_GPG8;
- reg += pin & ~3;
+void s3c2410_gpio_setpin(unsigned int pin, unsigned int to)
+{
+ void __iomem *base = S3C24XX_GPIO_BASE(pin);
+ unsigned long offs = S3C2410_GPIO_OFFSET(pin);
+ unsigned long flags;
+ unsigned long dat;
local_irq_save(flags);
- /* update filter width and clock source */
+ dat = __raw_readl(base + 0x04);
+ dat &= ~(1 << offs);
+ dat |= to << offs;
+ __raw_writel(dat, base + 0x04);
+
+ local_irq_restore(flags);
+}
+
+EXPORT_SYMBOL(s3c2410_gpio_setpin);
+
+unsigned int s3c2410_gpio_getpin(unsigned int pin)
+{
+ void __iomem *base = S3C24XX_GPIO_BASE(pin);
+ unsigned long offs = S3C2410_GPIO_OFFSET(pin);
- val = __raw_readl(reg);
- val &= ~(0xff << ((pin & 3) * 8));
- val |= config << ((pin & 3) * 8);
- __raw_writel(val, reg);
+ return __raw_readl(base + 0x04) & (1<< offs);
+}
- /* update filter enable */
+EXPORT_SYMBOL(s3c2410_gpio_getpin);
- val = __raw_readl(S3C24XX_EXTINT2);
- val &= ~(1 << ((pin * 4) + 3));
- val |= on << ((pin * 4) + 3);
- __raw_writel(val, S3C24XX_EXTINT2);
+unsigned int s3c2410_modify_misccr(unsigned int clear, unsigned int change)
+{
+ unsigned long flags;
+ unsigned long misccr;
+ local_irq_save(flags);
+ misccr = __raw_readl(S3C24XX_MISCCR);
+ misccr &= ~clear;
+ misccr ^= change;
+ __raw_writel(misccr, S3C24XX_MISCCR);
local_irq_restore(flags);
- return 0;
+ return misccr;
+}
+
+EXPORT_SYMBOL(s3c2410_modify_misccr);
+
+int s3c2410_gpio_getirq(unsigned int pin)
+{
+ if (pin < S3C2410_GPF0 || pin > S3C2410_GPG15)
+ return -1; /* not valid interrupts */
+
+ if (pin < S3C2410_GPG0 && pin > S3C2410_GPF7)
+ return -1; /* not valid pin */
+
+ if (pin < S3C2410_GPF4)
+ return (pin - S3C2410_GPF0) + IRQ_EINT0;
+
+ if (pin < S3C2410_GPG0)
+ return (pin - S3C2410_GPF4) + IRQ_EINT4;
+
+ return (pin - S3C2410_GPG0) + IRQ_EINT8;
}
-EXPORT_SYMBOL(s3c2410_gpio_irqfilter);
+EXPORT_SYMBOL(s3c2410_gpio_getirq);
diff --git a/trunk/arch/arm/mach-s3c2410/irq.c b/trunk/arch/arm/mach-s3c2410/irq.c
index 53cbdaa43ac6..3c0ed7871c55 100644
--- a/trunk/arch/arm/mach-s3c2410/irq.c
+++ b/trunk/arch/arm/mach-s3c2410/irq.c
@@ -1,6 +1,6 @@
/* linux/arch/arm/mach-s3c2410/irq.c
*
- * Copyright (c) 2006 Simtec Electronics
+ * Copyright (c) 2003,2004 Simtec Electronics
* Ben Dooks
*
* This program is free software; you can redistribute it and/or modify
@@ -17,6 +17,37 @@
* 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
+ * Fixed compile warnings
+ *
+ * 22-Jul-2004 Roc Wu
+ * Fixed s3c_extirq_type
+ *
+ * 21-Jul-2004 Arnaud Patard (Rtp)
+ * Addition of ADC/TC demux
+ *
+ * 04-Oct-2004 Klaus Fetscher
+ * Fix for set_irq_type() on low EINT numbers
+ *
+ * 05-Oct-2004 Ben Dooks
+ * Tidy up KF's patch and sort out new release
+ *
+ * 05-Oct-2004 Ben Dooks
+ * Add support for power management controls
+ *
+ * 04-Nov-2004 Ben Dooks
+ * Fix standard IRQ wake for EINT0..4 and RTC
+ *
+ * 22-Feb-2005 Ben Dooks
+ * Fixed edge-triggering on ADC IRQ
+ *
+ * 28-Jun-2005 Ben Dooks
+ * Mark IRQ_LCD valid
+ *
+ * 25-Jul-2005 Ben Dooks
+ * Split the S3C2440 IRQ code to seperate file
*/
#include
@@ -26,23 +57,745 @@
#include
#include
-#include
-#include
+#include
+#include
+#include
+
+#include
+
+#include
+#include
+
+#include "cpu.h"
+#include "pm.h"
+#include "irq.h"
+
+/* wakeup irq control */
+
+#ifdef CONFIG_PM
+
+/* state for IRQs over sleep */
+
+/* default is to allow for EINT0..EINT15, and IRQ_RTC as wakeup sources
+ *
+ * set bit to 1 in allow bitfield to enable the wakeup settings on it
+*/
+
+unsigned long s3c_irqwake_intallow = 1L << (IRQ_RTC - IRQ_EINT0) | 0xfL;
+unsigned long s3c_irqwake_intmask = 0xffffffffL;
+unsigned long s3c_irqwake_eintallow = 0x0000fff0L;
+unsigned long s3c_irqwake_eintmask = 0xffffffffL;
+
+int
+s3c_irq_wake(unsigned int irqno, unsigned int state)
+{
+ unsigned long irqbit = 1 << (irqno - IRQ_EINT0);
+
+ if (!(s3c_irqwake_intallow & irqbit))
+ return -ENOENT;
+
+ printk(KERN_INFO "wake %s for irq %d\n",
+ state ? "enabled" : "disabled", irqno);
+
+ if (!state)
+ s3c_irqwake_intmask |= irqbit;
+ else
+ s3c_irqwake_intmask &= ~irqbit;
+
+ return 0;
+}
+
+static int
+s3c_irqext_wake(unsigned int irqno, unsigned int state)
+{
+ unsigned long bit = 1L << (irqno - EXTINT_OFF);
+
+ if (!(s3c_irqwake_eintallow & bit))
+ return -ENOENT;
+
+ printk(KERN_INFO "wake %s for irq %d\n",
+ state ? "enabled" : "disabled", irqno);
+
+ if (!state)
+ s3c_irqwake_eintmask |= bit;
+ else
+ s3c_irqwake_eintmask &= ~bit;
+
+ return 0;
+}
+
+#else
+#define s3c_irqext_wake NULL
+#define s3c_irq_wake NULL
+#endif
+
+
+static void
+s3c_irq_mask(unsigned int irqno)
+{
+ unsigned long mask;
+
+ irqno -= IRQ_EINT0;
+
+ mask = __raw_readl(S3C2410_INTMSK);
+ mask |= 1UL << irqno;
+ __raw_writel(mask, S3C2410_INTMSK);
+}
+
+static inline void
+s3c_irq_ack(unsigned int irqno)
+{
+ unsigned long bitval = 1UL << (irqno - IRQ_EINT0);
+
+ __raw_writel(bitval, S3C2410_SRCPND);
+ __raw_writel(bitval, S3C2410_INTPND);
+}
+
+static inline void
+s3c_irq_maskack(unsigned int irqno)
+{
+ unsigned long bitval = 1UL << (irqno - IRQ_EINT0);
+ unsigned long mask;
+
+ mask = __raw_readl(S3C2410_INTMSK);
+ __raw_writel(mask|bitval, S3C2410_INTMSK);
+
+ __raw_writel(bitval, S3C2410_SRCPND);
+ __raw_writel(bitval, S3C2410_INTPND);
+}
+
+
+static void
+s3c_irq_unmask(unsigned int irqno)
+{
+ unsigned long mask;
+
+ if (irqno != IRQ_TIMER4 && irqno != IRQ_EINT8t23)
+ irqdbf2("s3c_irq_unmask %d\n", irqno);
+
+ irqno -= IRQ_EINT0;
+
+ mask = __raw_readl(S3C2410_INTMSK);
+ mask &= ~(1UL << irqno);
+ __raw_writel(mask, S3C2410_INTMSK);
+}
+
+struct irq_chip s3c_irq_level_chip = {
+ .name = "s3c-level",
+ .ack = s3c_irq_maskack,
+ .mask = s3c_irq_mask,
+ .unmask = s3c_irq_unmask,
+ .set_wake = s3c_irq_wake
+};
+
+static struct irq_chip s3c_irq_chip = {
+ .name = "s3c",
+ .ack = s3c_irq_ack,
+ .mask = s3c_irq_mask,
+ .unmask = s3c_irq_unmask,
+ .set_wake = s3c_irq_wake
+};
+
+static void
+s3c_irqext_mask(unsigned int irqno)
+{
+ unsigned long mask;
+
+ irqno -= EXTINT_OFF;
+
+ mask = __raw_readl(S3C24XX_EINTMASK);
+ mask |= ( 1UL << irqno);
+ __raw_writel(mask, S3C24XX_EINTMASK);
+}
+
+static void
+s3c_irqext_ack(unsigned int irqno)
+{
+ unsigned long req;
+ unsigned long bit;
+ unsigned long mask;
-static int s3c2410_irq_add(struct sys_device *sysdev)
+ bit = 1UL << (irqno - EXTINT_OFF);
+
+ mask = __raw_readl(S3C24XX_EINTMASK);
+
+ __raw_writel(bit, S3C24XX_EINTPEND);
+
+ req = __raw_readl(S3C24XX_EINTPEND);
+ req &= ~mask;
+
+ /* not sure if we should be acking the parent irq... */
+
+ if (irqno <= IRQ_EINT7 ) {
+ if ((req & 0xf0) == 0)
+ s3c_irq_ack(IRQ_EINT4t7);
+ } else {
+ if ((req >> 8) == 0)
+ s3c_irq_ack(IRQ_EINT8t23);
+ }
+}
+
+static void
+s3c_irqext_unmask(unsigned int irqno)
{
+ unsigned long mask;
+
+ irqno -= EXTINT_OFF;
+
+ mask = __raw_readl(S3C24XX_EINTMASK);
+ mask &= ~( 1UL << irqno);
+ __raw_writel(mask, S3C24XX_EINTMASK);
+}
+
+int
+s3c_irqext_type(unsigned int irq, unsigned int type)
+{
+ void __iomem *extint_reg;
+ void __iomem *gpcon_reg;
+ unsigned long gpcon_offset, extint_offset;
+ unsigned long newvalue = 0, value;
+
+ if ((irq >= IRQ_EINT0) && (irq <= IRQ_EINT3))
+ {
+ gpcon_reg = S3C2410_GPFCON;
+ extint_reg = S3C24XX_EXTINT0;
+ gpcon_offset = (irq - IRQ_EINT0) * 2;
+ extint_offset = (irq - IRQ_EINT0) * 4;
+ }
+ else if ((irq >= IRQ_EINT4) && (irq <= IRQ_EINT7))
+ {
+ gpcon_reg = S3C2410_GPFCON;
+ extint_reg = S3C24XX_EXTINT0;
+ gpcon_offset = (irq - (EXTINT_OFF)) * 2;
+ extint_offset = (irq - (EXTINT_OFF)) * 4;
+ }
+ else if ((irq >= IRQ_EINT8) && (irq <= IRQ_EINT15))
+ {
+ gpcon_reg = S3C2410_GPGCON;
+ extint_reg = S3C24XX_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 = S3C24XX_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;
}
-static struct sysdev_driver s3c2410_irq_driver = {
- .add = s3c2410_irq_add,
- .suspend = s3c24xx_irq_suspend,
- .resume = s3c24xx_irq_resume,
+static struct irq_chip s3c_irqext_chip = {
+ .name = "s3c-ext",
+ .mask = s3c_irqext_mask,
+ .unmask = s3c_irqext_unmask,
+ .ack = s3c_irqext_ack,
+ .set_type = s3c_irqext_type,
+ .set_wake = s3c_irqext_wake
+};
+
+static struct irq_chip s3c_irq_eint0t4 = {
+ .name = "s3c-ext0",
+ .ack = s3c_irq_ack,
+ .mask = s3c_irq_mask,
+ .unmask = s3c_irq_unmask,
+ .set_wake = s3c_irq_wake,
+ .set_type = s3c_irqext_type,
+};
+
+/* mask values for the parent registers for each of the interrupt types */
+
+#define INTMSK_UART0 (1UL << (IRQ_UART0 - IRQ_EINT0))
+#define INTMSK_UART1 (1UL << (IRQ_UART1 - IRQ_EINT0))
+#define INTMSK_UART2 (1UL << (IRQ_UART2 - IRQ_EINT0))
+#define INTMSK_ADCPARENT (1UL << (IRQ_ADCPARENT - IRQ_EINT0))
+
+
+/* UART0 */
+
+static void
+s3c_irq_uart0_mask(unsigned int irqno)
+{
+ s3c_irqsub_mask(irqno, INTMSK_UART0, 7);
+}
+
+static void
+s3c_irq_uart0_unmask(unsigned int irqno)
+{
+ s3c_irqsub_unmask(irqno, INTMSK_UART0);
+}
+
+static void
+s3c_irq_uart0_ack(unsigned int irqno)
+{
+ s3c_irqsub_maskack(irqno, INTMSK_UART0, 7);
+}
+
+static struct irq_chip s3c_irq_uart0 = {
+ .name = "s3c-uart0",
+ .mask = s3c_irq_uart0_mask,
+ .unmask = s3c_irq_uart0_unmask,
+ .ack = s3c_irq_uart0_ack,
+};
+
+/* UART1 */
+
+static void
+s3c_irq_uart1_mask(unsigned int irqno)
+{
+ s3c_irqsub_mask(irqno, INTMSK_UART1, 7 << 3);
+}
+
+static void
+s3c_irq_uart1_unmask(unsigned int irqno)
+{
+ s3c_irqsub_unmask(irqno, INTMSK_UART1);
+}
+
+static void
+s3c_irq_uart1_ack(unsigned int irqno)
+{
+ s3c_irqsub_maskack(irqno, INTMSK_UART1, 7 << 3);
+}
+
+static struct irq_chip s3c_irq_uart1 = {
+ .name = "s3c-uart1",
+ .mask = s3c_irq_uart1_mask,
+ .unmask = s3c_irq_uart1_unmask,
+ .ack = s3c_irq_uart1_ack,
+};
+
+/* UART2 */
+
+static void
+s3c_irq_uart2_mask(unsigned int irqno)
+{
+ s3c_irqsub_mask(irqno, INTMSK_UART2, 7 << 6);
+}
+
+static void
+s3c_irq_uart2_unmask(unsigned int irqno)
+{
+ s3c_irqsub_unmask(irqno, INTMSK_UART2);
+}
+
+static void
+s3c_irq_uart2_ack(unsigned int irqno)
+{
+ s3c_irqsub_maskack(irqno, INTMSK_UART2, 7 << 6);
+}
+
+static struct irq_chip s3c_irq_uart2 = {
+ .name = "s3c-uart2",
+ .mask = s3c_irq_uart2_mask,
+ .unmask = s3c_irq_uart2_unmask,
+ .ack = s3c_irq_uart2_ack,
+};
+
+/* ADC and Touchscreen */
+
+static void
+s3c_irq_adc_mask(unsigned int irqno)
+{
+ s3c_irqsub_mask(irqno, INTMSK_ADCPARENT, 3 << 9);
+}
+
+static void
+s3c_irq_adc_unmask(unsigned int irqno)
+{
+ s3c_irqsub_unmask(irqno, INTMSK_ADCPARENT);
+}
+
+static void
+s3c_irq_adc_ack(unsigned int irqno)
+{
+ s3c_irqsub_ack(irqno, INTMSK_ADCPARENT, 3 << 9);
+}
+
+static struct irq_chip s3c_irq_adc = {
+ .name = "s3c-adc",
+ .mask = s3c_irq_adc_mask,
+ .unmask = s3c_irq_adc_unmask,
+ .ack = s3c_irq_adc_ack,
+};
+
+/* irq demux for adc */
+static void s3c_irq_demux_adc(unsigned int irq,
+ struct irq_desc *desc)
+{
+ unsigned int subsrc, submsk;
+ unsigned int offset = 9;
+ struct irq_desc *mydesc;
+
+ /* read the current pending interrupts, and the mask
+ * for what it is available */
+
+ subsrc = __raw_readl(S3C2410_SUBSRCPND);
+ submsk = __raw_readl(S3C2410_INTSUBMSK);
+
+ subsrc &= ~submsk;
+ subsrc >>= offset;
+ subsrc &= 3;
+
+ if (subsrc != 0) {
+ if (subsrc & 1) {
+ mydesc = irq_desc + IRQ_TC;
+ desc_handle_irq(IRQ_TC, mydesc);
+ }
+ if (subsrc & 2) {
+ mydesc = irq_desc + IRQ_ADC;
+ desc_handle_irq(IRQ_ADC, mydesc);
+ }
+ }
+}
+
+static void s3c_irq_demux_uart(unsigned int start)
+{
+ unsigned int subsrc, submsk;
+ unsigned int offset = start - IRQ_S3CUART_RX0;
+ struct irq_desc *desc;
+
+ /* read the current pending interrupts, and the mask
+ * for what it is available */
+
+ subsrc = __raw_readl(S3C2410_SUBSRCPND);
+ submsk = __raw_readl(S3C2410_INTSUBMSK);
+
+ irqdbf2("s3c_irq_demux_uart: start=%d (%d), subsrc=0x%08x,0x%08x\n",
+ start, offset, subsrc, submsk);
+
+ subsrc &= ~submsk;
+ subsrc >>= offset;
+ subsrc &= 7;
+
+ if (subsrc != 0) {
+ desc = irq_desc + start;
+
+ if (subsrc & 1)
+ desc_handle_irq(start, desc);
+
+ desc++;
+
+ if (subsrc & 2)
+ desc_handle_irq(start+1, desc);
+
+ desc++;
+
+ if (subsrc & 4)
+ desc_handle_irq(start+2, desc);
+ }
+}
+
+/* uart demux entry points */
+
+static void
+s3c_irq_demux_uart0(unsigned int irq,
+ struct irq_desc *desc)
+{
+ irq = irq;
+ s3c_irq_demux_uart(IRQ_S3CUART_RX0);
+}
+
+static void
+s3c_irq_demux_uart1(unsigned int irq,
+ struct irq_desc *desc)
+{
+ irq = irq;
+ s3c_irq_demux_uart(IRQ_S3CUART_RX1);
+}
+
+static void
+s3c_irq_demux_uart2(unsigned int irq,
+ struct irq_desc *desc)
+{
+ irq = irq;
+ s3c_irq_demux_uart(IRQ_S3CUART_RX2);
+}
+
+static void
+s3c_irq_demux_extint8(unsigned int irq,
+ struct irq_desc *desc)
+{
+ unsigned long eintpnd = __raw_readl(S3C24XX_EINTPEND);
+ unsigned long eintmsk = __raw_readl(S3C24XX_EINTMASK);
+
+ eintpnd &= ~eintmsk;
+ eintpnd &= ~0xff; /* ignore lower irqs */
+
+ /* we may as well handle all the pending IRQs here */
+
+ while (eintpnd) {
+ irq = __ffs(eintpnd);
+ eintpnd &= ~(1<
diff --git a/trunk/arch/arm/mach-s3c2410/mach-amlm5900.c b/trunk/arch/arm/mach-s3c2410/mach-amlm5900.c
index 72f2cc4fcd03..817e2c684410 100644
--- a/trunk/arch/arm/mach-s3c2410/mach-amlm5900.c
+++ b/trunk/arch/arm/mach-s3c2410/mach-amlm5900.c
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-s3c2410/mach-amlm5900.c
+/***********************************************************************
*
* linux/arch/arm/mach-s3c2410/mach-amlm5900.c
*
@@ -35,7 +35,7 @@
#include
#include
#include
-#include
+
#include
#include
@@ -52,8 +52,8 @@
#include
#include
-#include
-#include
+#include "devs.h"
+#include "cpu.h"
#ifdef CONFIG_MTD_PARTITIONS
@@ -113,6 +113,12 @@ static struct platform_device amlm5900_device_nor = {
#endif
static struct map_desc amlm5900_iodesc[] __initdata = {
+ {
+ .virtual = (u32)S3C24XX_VA_SPI,
+ .pfn = __phys_to_pfn(S3C2410_PA_SPI),
+ .length = SZ_1M,
+ .type = MT_DEVICE
+ }
};
#define UCON S3C2410_UCON_DEFAULT
diff --git a/trunk/arch/arm/mach-s3c2440/mach-anubis.c b/trunk/arch/arm/mach-s3c2410/mach-anubis.c
similarity index 98%
rename from trunk/arch/arm/mach-s3c2440/mach-anubis.c
rename to trunk/arch/arm/mach-s3c2410/mach-anubis.c
index 3f0288eb1ed5..0fad0c2fe07b 100644
--- a/trunk/arch/arm/mach-s3c2440/mach-anubis.c
+++ b/trunk/arch/arm/mach-s3c2410/mach-anubis.c
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-s3c2440/mach-anubis.c
+/* linux/arch/arm/mach-s3c2410/mach-anubis.c
*
* Copyright (c) 2003-2005 Simtec Electronics
* http://armlinux.simtec.co.uk/
@@ -42,9 +42,9 @@
#include
#include
-#include
-#include
-#include
+#include "clock.h"
+#include "devs.h"
+#include "cpu.h"
#define COPYRIGHT ", (c) 2005 Simtec Electronics"
diff --git a/trunk/arch/arm/mach-s3c2410/mach-bast.c b/trunk/arch/arm/mach-s3c2410/mach-bast.c
index 7b81296427eb..b8b76757ec54 100644
--- a/trunk/arch/arm/mach-s3c2410/mach-bast.c
+++ b/trunk/arch/arm/mach-s3c2410/mach-bast.c
@@ -50,9 +50,9 @@
#include
-#include
-#include
-#include
+#include "clock.h"
+#include "devs.h"
+#include "cpu.h"
#include "usb-simtec.h"
#define COPYRIGHT ", (c) 2004-2005 Simtec Electronics"
diff --git a/trunk/arch/arm/mach-s3c2410/mach-h1940.c b/trunk/arch/arm/mach-s3c2410/mach-h1940.c
index 01c60d0923cd..15b625eae499 100644
--- a/trunk/arch/arm/mach-s3c2410/mach-h1940.c
+++ b/trunk/arch/arm/mach-s3c2410/mach-h1940.c
@@ -25,24 +25,23 @@
#include
#include
+#include
#include
#include
#include
+
#include
#include
-#include
-#include
#include
#include
#include
-#include
-#include
-#include
-#include
-#include
+#include "clock.h"
+#include "devs.h"
+#include "cpu.h"
+#include "pm.h"
static struct map_desc h1940_iodesc[] __initdata = {
[0] = {
@@ -103,32 +102,6 @@ void h1940_latch_control(unsigned int clear, unsigned int set)
EXPORT_SYMBOL_GPL(h1940_latch_control);
-static void h1940_udc_pullup(enum s3c2410_udc_cmd_e cmd)
-{
- printk(KERN_DEBUG "udc: pullup(%d)\n",cmd);
-
- switch (cmd)
- {
- case S3C2410_UDC_P_ENABLE :
- h1940_latch_control(0, H1940_LATCH_USB_DP);
- break;
- case S3C2410_UDC_P_DISABLE :
- h1940_latch_control(H1940_LATCH_USB_DP, 0);
- break;
- case S3C2410_UDC_P_RESET :
- break;
- default:
- break;
- }
-}
-
-static struct s3c2410_udc_mach_info h1940_udc_cfg __initdata = {
- .udc_command = h1940_udc_pullup,
- .vbus_pin = S3C2410_GPG5,
- .vbus_pin_inverted = 1,
-};
-
-
/**
* Set lcd on or off
@@ -173,19 +146,12 @@ static struct s3c2410fb_mach_info h1940_lcdcfg __initdata = {
.bpp= {16,16,16},
};
-static struct platform_device s3c_device_leds = {
- .name = "h1940-leds",
- .id = -1,
-};
-
static struct platform_device *h1940_devices[] __initdata = {
&s3c_device_usb,
&s3c_device_lcd,
&s3c_device_wdt,
&s3c_device_i2c,
&s3c_device_iis,
- &s3c_device_usbgadget,
- &s3c_device_leds,
};
static struct s3c24xx_board h1940_board __initdata = {
@@ -213,23 +179,7 @@ static void __init h1940_init_irq(void)
static void __init h1940_init(void)
{
- u32 tmp;
-
s3c24xx_fb_set_platdata(&h1940_lcdcfg);
- s3c24xx_udc_set_platdata(&h1940_udc_cfg);
-
- /* Turn off suspend on both USB ports, and switch the
- * selectable USB port to USB device mode. */
-
- s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST |
- S3C2410_MISCCR_USBSUSPND0 |
- S3C2410_MISCCR_USBSUSPND1, 0x0);
-
- tmp = (
- 0x78 << S3C2410_PLLCON_MDIVSHIFT)
- | (0x02 << S3C2410_PLLCON_PDIVSHIFT)
- | (0x03 << S3C2410_PLLCON_SDIVSHIFT);
- writel(tmp, S3C2410_UPLLCON);
}
MACHINE_START(H1940, "IPAQ-H1940")
@@ -239,6 +189,6 @@ MACHINE_START(H1940, "IPAQ-H1940")
.boot_params = S3C2410_SDRAM_PA + 0x100,
.map_io = h1940_map_io,
.init_irq = h1940_init_irq,
- .init_machine = h1940_init,
+ .init_machine = h1940_init,
.timer = &s3c24xx_timer,
MACHINE_END
diff --git a/trunk/arch/arm/mach-s3c2410/mach-n30.c b/trunk/arch/arm/mach-s3c2410/mach-n30.c
index 261aa4cc0770..0411e9adb54d 100644
--- a/trunk/arch/arm/mach-s3c2410/mach-n30.c
+++ b/trunk/arch/arm/mach-s3c2410/mach-n30.c
@@ -29,6 +29,7 @@
#include
#include
+#include
#include
#include
#include
@@ -37,10 +38,10 @@
#include
#include
-#include
-#include
-#include
-#include
+#include "s3c2410.h"
+#include "clock.h"
+#include "devs.h"
+#include "cpu.h"
static struct map_desc n30_iodesc[] __initdata = {
/* nothing here yet */
diff --git a/trunk/arch/arm/mach-s3c2440/mach-nexcoder.c b/trunk/arch/arm/mach-s3c2410/mach-nexcoder.c
similarity index 94%
rename from trunk/arch/arm/mach-s3c2440/mach-nexcoder.c
rename to trunk/arch/arm/mach-s3c2410/mach-nexcoder.c
index 6d551d88330b..d6dfdad8c90b 100644
--- a/trunk/arch/arm/mach-s3c2440/mach-nexcoder.c
+++ b/trunk/arch/arm/mach-s3c2410/mach-nexcoder.c
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-s3c2440/mach-nexcoder.c
+/* linux/arch/arm/mach-s3c2410/mach-nexcoder.c
*
* Copyright (c) 2004 Nex Vision
* Guillaume GOURAT
@@ -38,11 +38,11 @@
#include
#include
-#include
-#include
-#include
-#include
-#include
+#include "s3c2410.h"
+#include "s3c2440.h"
+#include "clock.h"
+#include "devs.h"
+#include "cpu.h"
static struct map_desc nexcoder_iodesc[] __initdata = {
/* nothing here yet */
diff --git a/trunk/arch/arm/mach-s3c2440/mach-osiris.c b/trunk/arch/arm/mach-s3c2410/mach-osiris.c
similarity index 97%
rename from trunk/arch/arm/mach-s3c2440/mach-osiris.c
rename to trunk/arch/arm/mach-s3c2410/mach-osiris.c
index 2ed8e51f20c8..37b40850c9b9 100644
--- a/trunk/arch/arm/mach-s3c2440/mach-osiris.c
+++ b/trunk/arch/arm/mach-s3c2410/mach-osiris.c
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-s3c2440/mach-osiris.c
+/* linux/arch/arm/mach-s3c2410/mach-osiris.c
*
* Copyright (c) 2005 Simtec Electronics
* http://armlinux.simtec.co.uk/
@@ -41,9 +41,9 @@
#include
#include
-#include
-#include
-#include
+#include "clock.h"
+#include "devs.h"
+#include "cpu.h"
/* onboard perihpheral map */
diff --git a/trunk/arch/arm/mach-s3c2410/mach-otom.c b/trunk/arch/arm/mach-s3c2410/mach-otom.c
index c78ab75b44f3..2c738b375e4d 100644
--- a/trunk/arch/arm/mach-s3c2410/mach-otom.c
+++ b/trunk/arch/arm/mach-s3c2410/mach-otom.c
@@ -32,10 +32,10 @@
#include
#include
-#include
-#include
-#include
-#include
+#include "s3c2410.h"
+#include "clock.h"
+#include "devs.h"
+#include "cpu.h"
static struct map_desc otom11_iodesc[] __initdata = {
/* Device area */
diff --git a/trunk/arch/arm/mach-s3c2410/mach-qt2410.c b/trunk/arch/arm/mach-s3c2410/mach-qt2410.c
deleted file mode 100644
index c6a41593de21..000000000000
--- a/trunk/arch/arm/mach-s3c2410/mach-qt2410.c
+++ /dev/null
@@ -1,448 +0,0 @@
-/* linux/arch/arm/mach-s3c2410/mach-qt2410.c
- *
- * Copyright (C) 2006 by OpenMoko, Inc.
- * Author: Harald Welte
- * All rights reserved.
- *
- * 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
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-#include
-#include
-#include
-
-#include
-#include
-#include
-
-#include
-#include
-#include
-#include
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-#include
-#include
-#include
-
-static struct map_desc qt2410_iodesc[] __initdata = {
- { 0xe0000000, __phys_to_pfn(S3C2410_CS3+0x01000000), SZ_1M, MT_DEVICE }
-};
-
-#define UCON S3C2410_UCON_DEFAULT
-#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
-#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
-
-static struct s3c2410_uartcfg smdk2410_uartcfgs[] = {
- [0] = {
- .hwport = 0,
- .flags = 0,
- .ucon = UCON,
- .ulcon = ULCON,
- .ufcon = UFCON,
- },
- [1] = {
- .hwport = 1,
- .flags = 0,
- .ucon = UCON,
- .ulcon = ULCON,
- .ufcon = UFCON,
- },
- [2] = {
- .hwport = 2,
- .flags = 0,
- .ucon = UCON,
- .ulcon = ULCON,
- .ufcon = UFCON,
- }
-};
-
-/* LCD driver info */
-
-/* Configuration for 640x480 SHARP LQ080V3DG01 */
-static struct s3c2410fb_mach_info qt2410_biglcd_cfg __initdata = {
- .regs = {
-
- .lcdcon1 = S3C2410_LCDCON1_TFT16BPP |
- S3C2410_LCDCON1_TFT |
- S3C2410_LCDCON1_CLKVAL(0x01), /* HCLK/4 */
-
- .lcdcon2 = S3C2410_LCDCON2_VBPD(18) | /* 19 */
- S3C2410_LCDCON2_LINEVAL(479) |
- S3C2410_LCDCON2_VFPD(10) | /* 11 */
- S3C2410_LCDCON2_VSPW(14), /* 15 */
-
- .lcdcon3 = S3C2410_LCDCON3_HBPD(43) | /* 44 */
- S3C2410_LCDCON3_HOZVAL(639) | /* 640 */
- S3C2410_LCDCON3_HFPD(115), /* 116 */
-
- .lcdcon4 = S3C2410_LCDCON4_MVAL(0) |
- S3C2410_LCDCON4_HSPW(95), /* 96 */
-
- .lcdcon5 = S3C2410_LCDCON5_FRM565 |
- S3C2410_LCDCON5_INVVLINE |
- S3C2410_LCDCON5_INVVFRAME |
- S3C2410_LCDCON5_PWREN |
- S3C2410_LCDCON5_HWSWP,
- },
-
- .lpcsel = ((0xCE6) & ~7) | 1<<4,
-
- .width = 640,
- .height = 480,
-
- .xres = {
- .min = 640,
- .max = 640,
- .defval = 640,
- },
-
- .yres = {
- .min = 480,
- .max = 480,
- .defval = 480,
- },
-
- .bpp = {
- .min = 16,
- .max = 16,
- .defval = 16,
- },
-};
-
-/* Configuration for 480x640 toppoly TD028TTEC1 */
-static struct s3c2410fb_mach_info qt2410_prodlcd_cfg __initdata = {
- .regs = {
-
- .lcdcon1 = S3C2410_LCDCON1_TFT16BPP |
- S3C2410_LCDCON1_TFT |
- S3C2410_LCDCON1_CLKVAL(0x01), /* HCLK/4 */
-
- .lcdcon2 = S3C2410_LCDCON2_VBPD(1) | /* 2 */
- S3C2410_LCDCON2_LINEVAL(639) |/* 640 */
- S3C2410_LCDCON2_VFPD(3) | /* 4 */
- S3C2410_LCDCON2_VSPW(1), /* 2 */
-
- .lcdcon3 = S3C2410_LCDCON3_HBPD(7) | /* 8 */
- S3C2410_LCDCON3_HOZVAL(479) | /* 479 */
- S3C2410_LCDCON3_HFPD(23), /* 24 */
-
- .lcdcon4 = S3C2410_LCDCON4_MVAL(0) |
- S3C2410_LCDCON4_HSPW(7), /* 8 */
-
- .lcdcon5 = S3C2410_LCDCON5_FRM565 |
- S3C2410_LCDCON5_INVVLINE |
- S3C2410_LCDCON5_INVVFRAME |
- S3C2410_LCDCON5_PWREN |
- S3C2410_LCDCON5_HWSWP,
- },
-
- .lpcsel = ((0xCE6) & ~7) | 1<<4,
-
- .width = 480,
- .height = 640,
-
- .xres = {
- .min = 480,
- .max = 480,
- .defval = 480,
- },
-
- .yres = {
- .min = 640,
- .max = 640,
- .defval = 640,
- },
-
- .bpp = {
- .min = 16,
- .max = 16,
- .defval = 16,
- },
-};
-
-/* Config for 240x320 LCD */
-static struct s3c2410fb_mach_info qt2410_lcd_cfg __initdata = {
- .regs = {
-
- .lcdcon1 = S3C2410_LCDCON1_TFT16BPP |
- S3C2410_LCDCON1_TFT |
- S3C2410_LCDCON1_CLKVAL(0x04),
-
- .lcdcon2 = S3C2410_LCDCON2_VBPD(1) |
- S3C2410_LCDCON2_LINEVAL(319) |
- S3C2410_LCDCON2_VFPD(6) |
- S3C2410_LCDCON2_VSPW(3),
-
- .lcdcon3 = S3C2410_LCDCON3_HBPD(12) |
- S3C2410_LCDCON3_HOZVAL(239) |
- S3C2410_LCDCON3_HFPD(7),
-
- .lcdcon4 = S3C2410_LCDCON4_MVAL(0) |
- S3C2410_LCDCON4_HSPW(3),
-
- .lcdcon5 = S3C2410_LCDCON5_FRM565 |
- S3C2410_LCDCON5_INVVLINE |
- S3C2410_LCDCON5_INVVFRAME |
- S3C2410_LCDCON5_PWREN |
- S3C2410_LCDCON5_HWSWP,
- },
-
- .lpcsel = ((0xCE6) & ~7) | 1<<4,
-
- .width = 240,
- .height = 320,
-
- .xres = {
- .min = 240,
- .max = 240,
- .defval = 240,
- },
-
- .yres = {
- .min = 320,
- .max = 320,
- .defval = 320,
- },
-
- .bpp = {
- .min = 16,
- .max = 16,
- .defval = 16,
- },
-};
-
-/* CS8900 */
-
-static struct resource qt2410_cs89x0_resources[] = {
- [0] = {
- .start = 0x19000000,
- .end = 0x19000000 + 16,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = IRQ_EINT9,
- .end = IRQ_EINT9,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct platform_device qt2410_cs89x0 = {
- .name = "cirrus-cs89x0",
- .num_resources = ARRAY_SIZE(qt2410_cs89x0_resources),
- .resource = qt2410_cs89x0_resources,
-};
-
-/* LED */
-
-static struct s3c24xx_led_platdata qt2410_pdata_led = {
- .gpio = S3C2410_GPB0,
- .flags = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE,
- .name = "led",
- .def_trigger = "timer",
-};
-
-static struct platform_device qt2410_led = {
- .name = "s3c24xx_led",
- .id = 0,
- .dev = {
- .platform_data = &qt2410_pdata_led,
- },
-};
-
-/* SPI */
-
-static void spi_gpio_cs(struct s3c2410_spigpio_info *spi, int cs)
-{
- switch (cs) {
- case BITBANG_CS_ACTIVE:
- s3c2410_gpio_setpin(S3C2410_GPB5, 0);
- break;
- case BITBANG_CS_INACTIVE:
- s3c2410_gpio_setpin(S3C2410_GPB5, 1);
- break;
- }
-}
-
-static struct s3c2410_spigpio_info spi_gpio_cfg = {
- .pin_clk = S3C2410_GPG7,
- .pin_mosi = S3C2410_GPG6,
- .pin_miso = S3C2410_GPG5,
- .chip_select = &spi_gpio_cs,
-};
-
-
-static struct platform_device qt2410_spi = {
- .name = "s3c24xx-spi-gpio",
- .id = 1,
- .dev = {
- .platform_data = &spi_gpio_cfg,
- },
-};
-
-/* Board devices */
-
-static struct platform_device *qt2410_devices[] __initdata = {
- &s3c_device_usb,
- &s3c_device_lcd,
- &s3c_device_wdt,
- &s3c_device_i2c,
- &s3c_device_iis,
- &s3c_device_sdi,
- &s3c_device_usbgadget,
- &qt2410_spi,
- &qt2410_cs89x0,
- &qt2410_led,
-};
-
-static struct s3c24xx_board qt2410_board __initdata = {
- .devices = qt2410_devices,
- .devices_count = ARRAY_SIZE(qt2410_devices)
-};
-
-static struct mtd_partition qt2410_nand_part[] = {
- [0] = {
- .name = "U-Boot",
- .size = 0x30000,
- .offset = 0,
- },
- [1] = {
- .name = "U-Boot environment",
- .offset = 0x30000,
- .size = 0x4000,
- },
- [2] = {
- .name = "kernel",
- .offset = 0x34000,
- .size = SZ_2M,
- },
- [3] = {
- .name = "initrd",
- .offset = 0x234000,
- .size = SZ_4M,
- },
- [4] = {
- .name = "jffs2",
- .offset = 0x634000,
- .size = 0x39cc000,
- },
-};
-
-static struct s3c2410_nand_set qt2410_nand_sets[] = {
- [0] = {
- .name = "NAND",
- .nr_chips = 1,
- .nr_partitions = ARRAY_SIZE(qt2410_nand_part),
- .partitions = qt2410_nand_part,
- },
-};
-
-/* choose a set of timings which should suit most 512Mbit
- * chips and beyond.
- */
-
-static struct s3c2410_platform_nand qt2410_nand_info = {
- .tacls = 20,
- .twrph0 = 60,
- .twrph1 = 20,
- .nr_sets = ARRAY_SIZE(qt2410_nand_sets),
- .sets = qt2410_nand_sets,
-};
-
-/* UDC */
-
-static struct s3c2410_udc_mach_info qt2410_udc_cfg = {
-};
-
-static char tft_type = 's';
-
-static int __init qt2410_tft_setup(char *str)
-{
- tft_type = str[0];
- return 1;
-}
-
-__setup("tft=", qt2410_tft_setup);
-
-static void __init qt2410_map_io(void)
-{
- s3c24xx_init_io(qt2410_iodesc, ARRAY_SIZE(qt2410_iodesc));
- s3c24xx_init_clocks(12*1000*1000);
- s3c24xx_init_uarts(smdk2410_uartcfgs, ARRAY_SIZE(smdk2410_uartcfgs));
- s3c24xx_set_board(&qt2410_board);
-}
-
-static void __init qt2410_machine_init(void)
-{
- s3c_device_nand.dev.platform_data = &qt2410_nand_info;
-
- switch (tft_type) {
- case 'p': /* production */
- s3c24xx_fb_set_platdata(&qt2410_prodlcd_cfg);
- break;
- case 'b': /* big */
- s3c24xx_fb_set_platdata(&qt2410_biglcd_cfg);
- break;
- case 's': /* small */
- default:
- s3c24xx_fb_set_platdata(&qt2410_lcd_cfg);
- break;
- }
-
- s3c2410_gpio_cfgpin(S3C2410_GPB0, S3C2410_GPIO_OUTPUT);
- s3c2410_gpio_setpin(S3C2410_GPB0, 1);
-
- s3c24xx_udc_set_platdata(&qt2410_udc_cfg);
-
- s3c2410_gpio_cfgpin(S3C2410_GPB5, S3C2410_GPIO_OUTPUT);
-
- s3c2410_pm_init();
-}
-
-MACHINE_START(QT2410, "QT2410")
- .phys_io = S3C2410_PA_UART,
- .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
- .boot_params = S3C2410_SDRAM_PA + 0x100,
- .map_io = qt2410_map_io,
- .init_irq = s3c24xx_init_irq,
- .init_machine = qt2410_machine_init,
- .timer = &s3c24xx_timer,
-MACHINE_END
-
-
diff --git a/trunk/arch/arm/mach-s3c2440/mach-rx3715.c b/trunk/arch/arm/mach-s3c2410/mach-rx3715.c
similarity index 96%
rename from trunk/arch/arm/mach-s3c2440/mach-rx3715.c
rename to trunk/arch/arm/mach-s3c2410/mach-rx3715.c
index 480ccde63fb4..ecbcdf79d739 100644
--- a/trunk/arch/arm/mach-s3c2440/mach-rx3715.c
+++ b/trunk/arch/arm/mach-s3c2410/mach-rx3715.c
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-s3c2440/mach-rx3715.c
+/* linux/arch/arm/mach-s3c2410/mach-rx3715.c
*
* Copyright (c) 2003,2004 Simtec Electronics
* Ben Dooks
@@ -33,6 +33,7 @@
#include
#include
+#include
#include
#include
#include
@@ -45,10 +46,10 @@
#include
#include
-#include
-#include
-#include
-#include
+#include "clock.h"
+#include "devs.h"
+#include "cpu.h"
+#include "pm.h"
static struct map_desc rx3715_iodesc[] __initdata = {
/* dump ISA space somewhere unused */
diff --git a/trunk/arch/arm/mach-s3c2410/mach-smdk2410.c b/trunk/arch/arm/mach-s3c2410/mach-smdk2410.c
index 57b8a80f33d0..01c0c986d827 100644
--- a/trunk/arch/arm/mach-s3c2410/mach-smdk2410.c
+++ b/trunk/arch/arm/mach-s3c2410/mach-smdk2410.c
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-s3c2410/mach-smdk2410.c
+/***********************************************************************
*
* linux/arch/arm/mach-s3c2410/mach-smdk2410.c
*
@@ -49,10 +49,10 @@
#include
-#include
-#include
+#include "devs.h"
+#include "cpu.h"
-#include
+#include "common-smdk.h"
static struct map_desc smdk2410_iodesc[] __initdata = {
/* nothing here yet */
diff --git a/trunk/arch/arm/mach-s3c2412/mach-smdk2413.c b/trunk/arch/arm/mach-s3c2410/mach-smdk2413.c
similarity index 67%
rename from trunk/arch/arm/mach-s3c2412/mach-smdk2413.c
rename to trunk/arch/arm/mach-s3c2410/mach-smdk2413.c
index b5befce6c8d3..4f89abd7a6df 100644
--- a/trunk/arch/arm/mach-s3c2412/mach-smdk2413.c
+++ b/trunk/arch/arm/mach-s3c2410/mach-smdk2413.c
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-s3c2412/mach-smdk2413.c
+/* linux/arch/arm/mach-s3c2410/mach-smdk2413.c
*
* Copyright (c) 2006 Simtec Electronics
* Ben Dooks
@@ -37,16 +37,15 @@
#include
#include
-#include
#include
-#include
-#include
-#include
-#include
-#include
+#include "s3c2410.h"
+#include "s3c2412.h"
+#include "clock.h"
+#include "devs.h"
+#include "cpu.h"
-#include
+#include "common-smdk.h"
static struct map_desc smdk2413_iodesc[] __initdata = {
};
@@ -76,38 +75,12 @@ static struct s3c2410_uartcfg smdk2413_uartcfgs[] __initdata = {
}
};
-static void smdk2413_udc_pullup(enum s3c2410_udc_cmd_e cmd)
-{
- printk(KERN_DEBUG "udc: pullup(%d)\n",cmd);
-
- switch (cmd)
- {
- case S3C2410_UDC_P_ENABLE :
- s3c2410_gpio_setpin(S3C2410_GPF2, 1);
- break;
- case S3C2410_UDC_P_DISABLE :
- s3c2410_gpio_setpin(S3C2410_GPF2, 0);
- break;
- case S3C2410_UDC_P_RESET :
- break;
- default:
- break;
- }
-}
-
-
-static struct s3c2410_udc_mach_info smdk2413_udc_cfg __initdata = {
- .udc_command = smdk2413_udc_pullup,
-};
-
-
static struct platform_device *smdk2413_devices[] __initdata = {
&s3c_device_usb,
//&s3c_device_lcd,
&s3c_device_wdt,
&s3c_device_i2c,
&s3c_device_iis,
- &s3c_device_usbgadget,
};
static struct s3c24xx_board smdk2413_board __initdata = {
@@ -136,19 +109,7 @@ static void __init smdk2413_map_io(void)
}
static void __init smdk2413_machine_init(void)
-{ /* Turn off suspend on both USB ports, and switch the
- * selectable USB port to USB device mode. */
-
- s3c2410_gpio_setpin(S3C2410_GPF2, 0);
- s3c2410_gpio_cfgpin(S3C2410_GPF2, S3C2410_GPIO_OUTPUT);
-
- s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST |
- S3C2410_MISCCR_USBSUSPND0 |
- S3C2410_MISCCR_USBSUSPND1, 0x0);
-
-
- s3c24xx_udc_set_platdata(&smdk2413_udc_cfg);
-
+{
smdk_machine_init();
}
@@ -165,19 +126,6 @@ MACHINE_START(S3C2413, "S3C2413")
.timer = &s3c24xx_timer,
MACHINE_END
-MACHINE_START(SMDK2412, "SMDK2412")
- /* Maintainer: Ben Dooks */
- .phys_io = S3C2410_PA_UART,
- .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
- .boot_params = S3C2410_SDRAM_PA + 0x100,
-
- .fixup = smdk2413_fixup,
- .init_irq = s3c24xx_init_irq,
- .map_io = smdk2413_map_io,
- .init_machine = smdk2413_machine_init,
- .timer = &s3c24xx_timer,
-MACHINE_END
-
MACHINE_START(SMDK2413, "SMDK2413")
/* Maintainer: Ben Dooks */
.phys_io = S3C2410_PA_UART,
diff --git a/trunk/arch/arm/mach-s3c2440/mach-smdk2440.c b/trunk/arch/arm/mach-s3c2410/mach-smdk2440.c
similarity index 93%
rename from trunk/arch/arm/mach-s3c2440/mach-smdk2440.c
rename to trunk/arch/arm/mach-s3c2410/mach-smdk2440.c
index c17eb5b1f6b4..2b61f4ed1da4 100644
--- a/trunk/arch/arm/mach-s3c2440/mach-smdk2440.c
+++ b/trunk/arch/arm/mach-s3c2410/mach-smdk2440.c
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-s3c2440/mach-smdk2440.c
+/* linux/arch/arm/mach-s3c2410/mach-smdk2440.c
*
* Copyright (c) 2004,2005 Simtec Electronics
* Ben Dooks
@@ -27,10 +27,12 @@
#include
#include
+#include
#include
#include
#include
+//#include
#include