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 #include #include @@ -38,13 +40,13 @@ #include #include -#include -#include -#include -#include -#include +#include "s3c2410.h" +#include "s3c2440.h" +#include "clock.h" +#include "devs.h" +#include "cpu.h" -#include +#include "common-smdk.h" static struct map_desc smdk2440_iodesc[] __initdata = { /* ISA IO Space map (memory space selected by A24) */ @@ -142,7 +144,6 @@ static struct s3c2410fb_mach_info smdk2440_lcd_cfg __initdata = { #endif .lpcsel = ((0xCE6) & ~7) | 1<<4, - .type = S3C2410_LCDCON1_TFT16BPP, .width = 240, .height = 320, diff --git a/trunk/arch/arm/mach-s3c2410/mach-vr1000.c b/trunk/arch/arm/mach-s3c2410/mach-vr1000.c index c947c75bcbf0..a382fc095110 100644 --- a/trunk/arch/arm/mach-s3c2410/mach-vr1000.c +++ b/trunk/arch/arm/mach-s3c2410/mach-vr1000.c @@ -43,9 +43,9 @@ #include #include -#include -#include -#include +#include "clock.h" +#include "devs.h" +#include "cpu.h" #include "usb-simtec.h" /* macros for virtual address mods for the io space entries */ diff --git a/trunk/arch/arm/mach-s3c2412/mach-vstms.c b/trunk/arch/arm/mach-s3c2410/mach-vstms.c similarity index 93% rename from trunk/arch/arm/mach-s3c2412/mach-vstms.c rename to trunk/arch/arm/mach-s3c2410/mach-vstms.c index 4231b549d797..0360e1055bcd 100644 --- a/trunk/arch/arm/mach-s3c2412/mach-vstms.c +++ b/trunk/arch/arm/mach-s3c2410/mach-vstms.c @@ -1,4 +1,4 @@ -/* linux/arch/arm/mach-s3c2412/mach-vstms.c +/* linux/arch/arm/mach-s3c2410/mach-vstms.c * * (C) 2006 Thomas Gleixner * @@ -28,6 +28,7 @@ #include #include +#include #include #include #include @@ -42,11 +43,11 @@ #include -#include -#include -#include -#include -#include +#include "s3c2410.h" +#include "s3c2412.h" +#include "clock.h" +#include "devs.h" +#include "cpu.h" static struct map_desc vstms_iodesc[] __initdata = { diff --git a/trunk/arch/arm/plat-s3c24xx/pm-simtec.c b/trunk/arch/arm/mach-s3c2410/pm-simtec.c similarity index 95% rename from trunk/arch/arm/plat-s3c24xx/pm-simtec.c rename to trunk/arch/arm/mach-s3c2410/pm-simtec.c index bd965f2feeca..619133eb7168 100644 --- a/trunk/arch/arm/plat-s3c24xx/pm-simtec.c +++ b/trunk/arch/arm/mach-s3c2410/pm-simtec.c @@ -1,4 +1,4 @@ -/* linux/arch/arm/plat-s3c24xx/pm-simtec.c +/* linux/arch/arm/mach-s3c2410/pm-simtec.c * * Copyright (c) 2004 Simtec Electronics * Ben Dooks @@ -32,7 +32,7 @@ #include -#include +#include "pm.h" #define COPYRIGHT ", (c) 2005 Simtec Electronics" diff --git a/trunk/arch/arm/mach-s3c2410/pm.c b/trunk/arch/arm/mach-s3c2410/pm.c index 3b3a7db4e0dd..ebf294dd31da 100644 --- a/trunk/arch/arm/mach-s3c2410/pm.c +++ b/trunk/arch/arm/mach-s3c2410/pm.c @@ -1,9 +1,11 @@ /* linux/arch/arm/mach-s3c2410/pm.c * - * Copyright (c) 2006 Simtec Electronics + * Copyright (c) 2004,2006 Simtec Electronics * Ben Dooks * - * S3C2410 (and compatible) Power Manager (Suspend-To-RAM) support + * S3C24XX Power Manager (Suspend-To-RAM) support + * + * See Documentation/arm/Samsung-S3C24XX/Suspend.txt for more information * * 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,139 +20,640 @@ * 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 + * + * Parts based on arch/arm/mach-pxa/pm.c + * + * Thanks to Dimitry Andric for debugging */ #include #include #include #include -#include +#include +#include +#include +#include +#include +#include #include #include -#include - +#include +#include #include -#include +#include +#include + +#include + +#include "pm.h" + +/* for external use */ + +unsigned long s3c_pm_flags; + +#define PFX "s3c24xx-pm: " + +static struct sleep_save core_save[] = { + SAVE_ITEM(S3C2410_LOCKTIME), + SAVE_ITEM(S3C2410_CLKCON), + + /* we restore the timings here, with the proviso that the board + * brings the system up in an slower, or equal frequency setting + * to the original system. + * + * if we cannot guarantee this, then things are going to go very + * wrong here, as we modify the refresh and both pll settings. + */ + + SAVE_ITEM(S3C2410_BWSCON), + SAVE_ITEM(S3C2410_BANKCON0), + SAVE_ITEM(S3C2410_BANKCON1), + SAVE_ITEM(S3C2410_BANKCON2), + SAVE_ITEM(S3C2410_BANKCON3), + SAVE_ITEM(S3C2410_BANKCON4), + SAVE_ITEM(S3C2410_BANKCON5), + + SAVE_ITEM(S3C2410_CLKDIVN), + SAVE_ITEM(S3C2410_MPLLCON), + SAVE_ITEM(S3C2410_UPLLCON), + SAVE_ITEM(S3C2410_CLKSLOW), + SAVE_ITEM(S3C2410_REFRESH), +}; + +static struct sleep_save gpio_save[] = { + SAVE_ITEM(S3C2410_GPACON), + SAVE_ITEM(S3C2410_GPADAT), + + SAVE_ITEM(S3C2410_GPBCON), + SAVE_ITEM(S3C2410_GPBDAT), + SAVE_ITEM(S3C2410_GPBUP), + + SAVE_ITEM(S3C2410_GPCCON), + SAVE_ITEM(S3C2410_GPCDAT), + SAVE_ITEM(S3C2410_GPCUP), + + SAVE_ITEM(S3C2410_GPDCON), + SAVE_ITEM(S3C2410_GPDDAT), + SAVE_ITEM(S3C2410_GPDUP), + + SAVE_ITEM(S3C2410_GPECON), + SAVE_ITEM(S3C2410_GPEDAT), + SAVE_ITEM(S3C2410_GPEUP), + + SAVE_ITEM(S3C2410_GPFCON), + SAVE_ITEM(S3C2410_GPFDAT), + SAVE_ITEM(S3C2410_GPFUP), -#include -#include + SAVE_ITEM(S3C2410_GPGCON), + SAVE_ITEM(S3C2410_GPGDAT), + SAVE_ITEM(S3C2410_GPGUP), + + SAVE_ITEM(S3C2410_GPHCON), + SAVE_ITEM(S3C2410_GPHDAT), + SAVE_ITEM(S3C2410_GPHUP), + + SAVE_ITEM(S3C2410_DCLKCON), +}; #ifdef CONFIG_S3C2410_PM_DEBUG -extern void pm_dbg(const char *fmt, ...); + +#define SAVE_UART(va) \ + SAVE_ITEM((va) + S3C2410_ULCON), \ + SAVE_ITEM((va) + S3C2410_UCON), \ + SAVE_ITEM((va) + S3C2410_UFCON), \ + SAVE_ITEM((va) + S3C2410_UMCON), \ + SAVE_ITEM((va) + S3C2410_UBRDIV) + +static struct sleep_save uart_save[] = { + SAVE_UART(S3C24XX_VA_UART0), + SAVE_UART(S3C24XX_VA_UART1), +#ifndef CONFIG_CPU_S3C2400 + SAVE_UART(S3C24XX_VA_UART2), +#endif +}; + +/* debug + * + * we send the debug to printascii() to allow it to be seen if the + * system never wakes up from the sleep +*/ + +extern void printascii(const char *); + +void pm_dbg(const char *fmt, ...) +{ + va_list va; + char buff[256]; + + va_start(va, fmt); + vsprintf(buff, fmt, va); + va_end(va); + + printascii(buff); +} + +static void s3c2410_pm_debug_init(void) +{ + unsigned long tmp = __raw_readl(S3C2410_CLKCON); + + /* re-start uart clocks */ + tmp |= S3C2410_CLKCON_UART0; + tmp |= S3C2410_CLKCON_UART1; + tmp |= S3C2410_CLKCON_UART2; + + __raw_writel(tmp, S3C2410_CLKCON); + udelay(10); +} + #define DBG(fmt...) pm_dbg(fmt) #else #define DBG(fmt...) printk(KERN_DEBUG fmt) + +#define s3c2410_pm_debug_init() do { } while(0) + +static struct sleep_save uart_save[] = {}; #endif -static void s3c2410_pm_prepare(void) +#if defined(CONFIG_S3C2410_PM_CHECK) && CONFIG_S3C2410_PM_CHECK_CHUNKSIZE != 0 + +/* suspend checking code... + * + * this next area does a set of crc checks over all the installed + * memory, so the system can verify if the resume was ok. + * + * CONFIG_S3C2410_PM_CHECK_CHUNKSIZE defines the block-size for the CRC, + * increasing it will mean that the area corrupted will be less easy to spot, + * and reducing the size will cause the CRC save area to grow +*/ + +#define CHECK_CHUNKSIZE (CONFIG_S3C2410_PM_CHECK_CHUNKSIZE * 1024) + +static u32 crc_size; /* size needed for the crc block */ +static u32 *crcs; /* allocated over suspend/resume */ + +typedef u32 *(run_fn_t)(struct resource *ptr, u32 *arg); + +/* s3c2410_pm_run_res + * + * go thorugh the given resource list, and look for system ram +*/ + +static void s3c2410_pm_run_res(struct resource *ptr, run_fn_t fn, u32 *arg) +{ + while (ptr != NULL) { + if (ptr->child != NULL) + s3c2410_pm_run_res(ptr->child, fn, arg); + + if ((ptr->flags & IORESOURCE_MEM) && + strcmp(ptr->name, "System RAM") == 0) { + DBG("Found system RAM at %08lx..%08lx\n", + ptr->start, ptr->end); + arg = (fn)(ptr, arg); + } + + ptr = ptr->sibling; + } +} + +static void s3c2410_pm_run_sysram(run_fn_t fn, u32 *arg) +{ + s3c2410_pm_run_res(&iomem_resource, fn, arg); +} + +static u32 *s3c2410_pm_countram(struct resource *res, u32 *val) +{ + u32 size = (u32)(res->end - res->start)+1; + + size += CHECK_CHUNKSIZE-1; + size /= CHECK_CHUNKSIZE; + + DBG("Area %08lx..%08lx, %d blocks\n", res->start, res->end, size); + + *val += size * sizeof(u32); + return val; +} + +/* s3c2410_pm_prepare_check + * + * prepare the necessary information for creating the CRCs. This + * must be done before the final save, as it will require memory + * allocating, and thus touching bits of the kernel we do not + * know about. +*/ + +static void s3c2410_pm_check_prepare(void) { - /* ensure at least GSTATUS3 has the resume address */ + crc_size = 0; - __raw_writel(virt_to_phys(s3c2410_cpu_resume), S3C2410_GSTATUS3); + s3c2410_pm_run_sysram(s3c2410_pm_countram, &crc_size); - DBG("GSTATUS3 0x%08x\n", __raw_readl(S3C2410_GSTATUS3)); - DBG("GSTATUS4 0x%08x\n", __raw_readl(S3C2410_GSTATUS4)); + DBG("s3c2410_pm_prepare_check: %u checks needed\n", crc_size); - if (machine_is_h1940()) { - void *base = phys_to_virt(H1940_SUSPEND_CHECK); - unsigned long ptr; - unsigned long calc = 0; + crcs = kmalloc(crc_size+4, GFP_KERNEL); + if (crcs == NULL) + printk(KERN_ERR "Cannot allocated CRC save area\n"); +} - /* generate check for the bootloader to check on resume */ +static u32 *s3c2410_pm_makecheck(struct resource *res, u32 *val) +{ + unsigned long addr, left; - for (ptr = 0; ptr < 0x40000; ptr += 0x400) - calc += __raw_readl(base+ptr); + for (addr = res->start; addr < res->end; + addr += CHECK_CHUNKSIZE) { + left = res->end - addr; - __raw_writel(calc, phys_to_virt(H1940_SUSPEND_CHECKSUM)); + if (left > CHECK_CHUNKSIZE) + left = CHECK_CHUNKSIZE; + + *val = crc32_le(~0, phys_to_virt(addr), left); + val++; } - /* the RX3715 uses similar code and the same H1940 and the - * same offsets for resume and checksum pointers */ + return val; +} + +/* s3c2410_pm_check_store + * + * compute the CRC values for the memory blocks before the final + * sleep. +*/ + +static void s3c2410_pm_check_store(void) +{ + if (crcs != NULL) + s3c2410_pm_run_sysram(s3c2410_pm_makecheck, crcs); +} + +/* in_region + * + * return TRUE if the area defined by ptr..ptr+size contatins the + * what..what+whatsz +*/ + +static inline int in_region(void *ptr, int size, void *what, size_t whatsz) +{ + if ((what+whatsz) < ptr) + return 0; + + if (what > (ptr+size)) + return 0; + + return 1; +} + +static u32 *s3c2410_pm_runcheck(struct resource *res, u32 *val) +{ + void *save_at = phys_to_virt(s3c2410_sleep_save_phys); + unsigned long addr; + unsigned long left; + void *ptr; + u32 calc; + + for (addr = res->start; addr < res->end; + addr += CHECK_CHUNKSIZE) { + left = res->end - addr; - if (machine_is_rx3715()) { - void *base = phys_to_virt(H1940_SUSPEND_CHECK); - unsigned long ptr; - unsigned long calc = 0; + if (left > CHECK_CHUNKSIZE) + left = CHECK_CHUNKSIZE; - /* generate check for the bootloader to check on resume */ + ptr = phys_to_virt(addr); - for (ptr = 0; ptr < 0x40000; ptr += 0x4) - calc += __raw_readl(base+ptr); + if (in_region(ptr, left, crcs, crc_size)) { + DBG("skipping %08lx, has crc block in\n", addr); + goto skip_check; + } - __raw_writel(calc, phys_to_virt(H1940_SUSPEND_CHECKSUM)); + if (in_region(ptr, left, save_at, 32*4 )) { + DBG("skipping %08lx, has save block in\n", addr); + goto skip_check; + } + + /* calculate and check the checksum */ + + calc = crc32_le(~0, ptr, left); + if (calc != *val) { + printk(KERN_ERR PFX "Restore CRC error at " + "%08lx (%08x vs %08x)\n", addr, calc, *val); + + DBG("Restore CRC error at %08lx (%08x vs %08x)\n", + addr, calc, *val); + } + + skip_check: + val++; } - if ( machine_is_aml_m5900() ) - s3c2410_gpio_setpin(S3C2410_GPF2, 1); + return val; +} +/* s3c2410_pm_check_restore + * + * check the CRCs after the restore event and free the memory used + * to hold them +*/ + +static void s3c2410_pm_check_restore(void) +{ + if (crcs != NULL) { + s3c2410_pm_run_sysram(s3c2410_pm_runcheck, crcs); + kfree(crcs); + crcs = NULL; + } } -static int s3c2410_pm_resume(struct sys_device *dev) +#else + +#define s3c2410_pm_check_prepare() do { } while(0) +#define s3c2410_pm_check_restore() do { } while(0) +#define s3c2410_pm_check_store() do { } while(0) +#endif + +/* helper functions to save and restore register state */ + +void s3c2410_pm_do_save(struct sleep_save *ptr, int count) { - unsigned long tmp; + for (; count > 0; count--, ptr++) { + ptr->val = __raw_readl(ptr->reg); + DBG("saved %p value %08lx\n", ptr->reg, ptr->val); + } +} - /* unset the return-from-sleep flag, to ensure reset */ +/* s3c2410_pm_do_restore + * + * restore the system from the given list of saved registers + * + * Note, we do not use DBG() in here, as the system may not have + * restore the UARTs state yet +*/ - tmp = __raw_readl(S3C2410_GSTATUS2); - tmp &= S3C2410_GSTATUS2_OFFRESET; - __raw_writel(tmp, S3C2410_GSTATUS2); +void s3c2410_pm_do_restore(struct sleep_save *ptr, int count) +{ + for (; count > 0; count--, ptr++) { + printk(KERN_DEBUG "restore %p (restore %08lx, was %08x)\n", + ptr->reg, ptr->val, __raw_readl(ptr->reg)); - if ( machine_is_aml_m5900() ) - s3c2410_gpio_setpin(S3C2410_GPF2, 0); + __raw_writel(ptr->val, ptr->reg); + } +} - return 0; +/* s3c2410_pm_do_restore_core + * + * similar to s3c2410_pm_do_restore_core + * + * WARNING: Do not put any debug in here that may effect memory or use + * peripherals, as things may be changing! +*/ + +static void s3c2410_pm_do_restore_core(struct sleep_save *ptr, int count) +{ + for (; count > 0; count--, ptr++) { + __raw_writel(ptr->val, ptr->reg); + } } -static int s3c2410_pm_add(struct sys_device *dev) +/* s3c2410_pm_show_resume_irqs + * + * print any IRQs asserted at resume time (ie, we woke from) +*/ + +static void s3c2410_pm_show_resume_irqs(int start, unsigned long which, + unsigned long mask) { - pm_cpu_prep = s3c2410_pm_prepare; - pm_cpu_sleep = s3c2410_cpu_suspend; + int i; - return 0; + which &= ~mask; + + for (i = 0; i <= 31; i++) { + if ((which) & (1L< diff --git a/trunk/arch/arm/mach-s3c2400/gpio.c b/trunk/arch/arm/mach-s3c2410/s3c2400-gpio.c similarity index 96% rename from trunk/arch/arm/mach-s3c2400/gpio.c rename to trunk/arch/arm/mach-s3c2410/s3c2400-gpio.c index 758e160410e9..1576d01d5f82 100644 --- a/trunk/arch/arm/mach-s3c2400/gpio.c +++ b/trunk/arch/arm/mach-s3c2410/s3c2400-gpio.c @@ -1,4 +1,4 @@ -/* linux/arch/arm/mach-s3c2400/gpio.c +/* linux/arch/arm/mach-s3c2410/s3c2400-gpio.c * * Copyright (c) 2006 Lucas Correia Villa Real * diff --git a/trunk/include/asm-arm/plat-s3c24xx/s3c2400.h b/trunk/arch/arm/mach-s3c2410/s3c2400.h similarity index 94% rename from trunk/include/asm-arm/plat-s3c24xx/s3c2400.h rename to trunk/arch/arm/mach-s3c2410/s3c2400.h index 3a5a16821af8..8b2394e1ed40 100644 --- a/trunk/include/asm-arm/plat-s3c24xx/s3c2400.h +++ b/trunk/arch/arm/mach-s3c2410/s3c2400.h @@ -1,4 +1,4 @@ -/* linux/include/asm-arm/plat-s3c24xx/s3c2400.h +/* arch/arm/mach-s3c2410/s3c2400.h * * Copyright (c) 2004 Simtec Electronics * Ben Dooks diff --git a/trunk/arch/arm/mach-s3c2410/s3c2410-clock.c b/trunk/arch/arm/mach-s3c2410/s3c2410-clock.c new file mode 100644 index 000000000000..992cc6af230e --- /dev/null +++ b/trunk/arch/arm/mach-s3c2410/s3c2410-clock.c @@ -0,0 +1,276 @@ +/* linux/arch/arm/mach-s3c2410/s3c2410-clock.c + * + * Copyright (c) 2006 Simtec Electronics + * Ben Dooks + * + * S3C2410,S3C2440,S3C2442 Clock control 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 + * 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 "s3c2410.h" +#include "clock.h" +#include "cpu.h" + +int s3c2410_clkcon_enable(struct clk *clk, int enable) +{ + unsigned int clocks = clk->ctrlbit; + unsigned long clkcon; + + clkcon = __raw_readl(S3C2410_CLKCON); + + if (enable) + clkcon |= clocks; + else + clkcon &= ~clocks; + + /* ensure none of the special function bits set */ + clkcon &= ~(S3C2410_CLKCON_IDLE|S3C2410_CLKCON_POWER); + + __raw_writel(clkcon, S3C2410_CLKCON); + + return 0; +} + +static int s3c2410_upll_enable(struct clk *clk, int enable) +{ + unsigned long clkslow = __raw_readl(S3C2410_CLKSLOW); + unsigned long orig = clkslow; + + if (enable) + clkslow &= ~S3C2410_CLKSLOW_UCLK_OFF; + else + clkslow |= S3C2410_CLKSLOW_UCLK_OFF; + + __raw_writel(clkslow, S3C2410_CLKSLOW); + + /* if we started the UPLL, then allow to settle */ + + if (enable && (orig & S3C2410_CLKSLOW_UCLK_OFF)) + udelay(200); + + 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 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, + }, +}; + +/* 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. +*/ + +int __init s3c2410_baseclk_add(void) +{ + 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_upll.enable = s3c2410_upll_enable; + + if (s3c24xx_register_clock(&clk_usb_bus) < 0) + printk(KERN_ERR "failed to register usb bus clock\n"); + + /* register clocks from clock array */ + + clkp = init_clocks; + for (ptr = 0; ptr < ARRAY_SIZE(init_clocks); ptr++, clkp++) { + /* ensure that we note the clock state */ + + clkp->usage = clkcon & clkp->ctrlbit ? 1 : 0; + + ret = s3c24xx_register_clock(clkp); + if (ret < 0) { + printk(KERN_ERR "Failed to register clock %s (%d)\n", + clkp->name, ret); + } + } + + /* 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); + } + + s3c2410_clkcon_enable(clkp, 0); + } + + /* show the clock-slow value */ + + xtal = clk_get(NULL, "xtal"); + + 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"); + + return 0; +} diff --git a/trunk/arch/arm/mach-s3c2410/s3c2410-dma.c b/trunk/arch/arm/mach-s3c2410/s3c2410-dma.c new file mode 100644 index 000000000000..e67ba3911f11 --- /dev/null +++ b/trunk/arch/arm/mach-s3c2410/s3c2410-dma.c @@ -0,0 +1,161 @@ +/* linux/arch/arm/mach-s3c2410/s3c2410-dma.c + * + * Copyright (c) 2006 Simtec Electronics + * Ben Dooks + * + * S3C2410 DMA selection + * + * http://armlinux.simtec.co.uk/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#include +#include +#include +#include + +#include +#include +#include "dma.h" + +#include "cpu.h" + +#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) +{ + chan->dcon = map->channels[chan->number] & ~DMA_CH_VALID; +} + +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), +}; + +static int s3c2410_dma_add(struct sys_device *sysdev) +{ + return s3c24xx_dma_init_map(&s3c2410_dma_sel); +} + +#if defined(CONFIG_CPU_S3C2410) +static struct sysdev_driver s3c2410_dma_driver = { + .add = s3c2410_dma_add, +}; + +static int __init s3c2410_dma_init(void) +{ + return sysdev_driver_register(&s3c2410_sysclass, &s3c2410_dma_driver); +} + +arch_initcall(s3c2410_dma_init); +#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, +}; + +static int __init s3c2442_dma_init(void) +{ + return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_dma_driver); +} + +arch_initcall(s3c2442_dma_init); +#endif + diff --git a/trunk/arch/arm/mach-s3c2410/s3c2410-gpio.c b/trunk/arch/arm/mach-s3c2410/s3c2410-gpio.c new file mode 100644 index 000000000000..ec3a276cc3cf --- /dev/null +++ b/trunk/arch/arm/mach-s3c2410/s3c2410-gpio.c @@ -0,0 +1,71 @@ +/* linux/arch/arm/mach-s3c2410/s3c2410-gpio.c + * + * Copyright (c) 2004-2006 Simtec Electronics + * Ben Dooks + * + * S3C2410 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 + * 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 + +int s3c2410_gpio_irqfilter(unsigned int pin, unsigned int on, + unsigned int config) +{ + void __iomem *reg = S3C24XX_EINFLT0; + unsigned long flags; + unsigned long val; + + if (pin < S3C2410_GPG8 || pin > S3C2410_GPG15) + return -1; + + config &= 0xff; + + pin -= S3C2410_GPG8; + reg += pin & ~3; + + local_irq_save(flags); + + /* update filter width and clock source */ + + val = __raw_readl(reg); + val &= ~(0xff << ((pin & 3) * 8)); + val |= config << ((pin & 3) * 8); + __raw_writel(val, reg); + + /* update filter enable */ + + val = __raw_readl(S3C24XX_EXTINT2); + val &= ~(1 << ((pin * 4) + 3)); + val |= on << ((pin * 4) + 3); + __raw_writel(val, S3C24XX_EXTINT2); + + local_irq_restore(flags); + + return 0; +} + +EXPORT_SYMBOL(s3c2410_gpio_irqfilter); diff --git a/trunk/arch/arm/mach-s3c2410/s3c2410-irq.c b/trunk/arch/arm/mach-s3c2410/s3c2410-irq.c new file mode 100644 index 000000000000..c796c9c76e78 --- /dev/null +++ b/trunk/arch/arm/mach-s3c2410/s3c2410-irq.c @@ -0,0 +1,48 @@ +/* linux/arch/arm/mach-s3c2410/s3c2410-irq.c + * + * Copyright (c) 2006 Simtec Electronics + * Ben Dooks + * + * 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 "cpu.h" +#include "pm.h" + +static int s3c2410_irq_add(struct sys_device *sysdev) +{ + return 0; +} + +static struct sysdev_driver s3c2410_irq_driver = { + .add = s3c2410_irq_add, + .suspend = s3c24xx_irq_suspend, + .resume = s3c24xx_irq_resume, +}; + +static int s3c2410_irq_init(void) +{ + return sysdev_driver_register(&s3c2410_sysclass, &s3c2410_irq_driver); +} + +arch_initcall(s3c2410_irq_init); diff --git a/trunk/arch/arm/mach-s3c2410/s3c2410-pm.c b/trunk/arch/arm/mach-s3c2410/s3c2410-pm.c new file mode 100644 index 000000000000..8bb6e5e21f59 --- /dev/null +++ b/trunk/arch/arm/mach-s3c2410/s3c2410-pm.c @@ -0,0 +1,156 @@ +/* linux/arch/arm/mach-s3c2410/s3c2410-pm.c + * + * Copyright (c) 2006 Simtec Electronics + * Ben Dooks + * + * S3C2410 (and compatible) Power Manager (Suspend-To-RAM) 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 + * 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 "cpu.h" +#include "pm.h" + +#ifdef CONFIG_S3C2410_PM_DEBUG +extern void pm_dbg(const char *fmt, ...); +#define DBG(fmt...) pm_dbg(fmt) +#else +#define DBG(fmt...) printk(KERN_DEBUG fmt) +#endif + +static void s3c2410_pm_prepare(void) +{ + /* ensure at least GSTATUS3 has the resume address */ + + __raw_writel(virt_to_phys(s3c2410_cpu_resume), S3C2410_GSTATUS3); + + DBG("GSTATUS3 0x%08x\n", __raw_readl(S3C2410_GSTATUS3)); + DBG("GSTATUS4 0x%08x\n", __raw_readl(S3C2410_GSTATUS4)); + + if (machine_is_h1940()) { + void *base = phys_to_virt(H1940_SUSPEND_CHECK); + unsigned long ptr; + unsigned long calc = 0; + + /* generate check for the bootloader to check on resume */ + + for (ptr = 0; ptr < 0x40000; ptr += 0x400) + calc += __raw_readl(base+ptr); + + __raw_writel(calc, phys_to_virt(H1940_SUSPEND_CHECKSUM)); + } + + /* the RX3715 uses similar code and the same H1940 and the + * same offsets for resume and checksum pointers */ + + if (machine_is_rx3715()) { + void *base = phys_to_virt(H1940_SUSPEND_CHECK); + unsigned long ptr; + unsigned long calc = 0; + + /* generate check for the bootloader to check on resume */ + + for (ptr = 0; ptr < 0x40000; ptr += 0x4) + calc += __raw_readl(base+ptr); + + __raw_writel(calc, phys_to_virt(H1940_SUSPEND_CHECKSUM)); + } + + if ( machine_is_aml_m5900() ) + s3c2410_gpio_setpin(S3C2410_GPF2, 1); + +} + +static int s3c2410_pm_resume(struct sys_device *dev) +{ + unsigned long tmp; + + /* unset the return-from-sleep flag, to ensure reset */ + + tmp = __raw_readl(S3C2410_GSTATUS2); + tmp &= S3C2410_GSTATUS2_OFFRESET; + __raw_writel(tmp, S3C2410_GSTATUS2); + + if ( machine_is_aml_m5900() ) + s3c2410_gpio_setpin(S3C2410_GPF2, 0); + + return 0; +} + +static int s3c2410_pm_add(struct sys_device *dev) +{ + pm_cpu_prep = s3c2410_pm_prepare; + pm_cpu_sleep = s3c2410_cpu_suspend; + + return 0; +} + +#if defined(CONFIG_CPU_S3C2410) +static struct sysdev_driver s3c2410_pm_driver = { + .add = s3c2410_pm_add, + .resume = s3c2410_pm_resume, +}; + +/* register ourselves */ + +static int __init s3c2410_pm_drvinit(void) +{ + return sysdev_driver_register(&s3c2410_sysclass, &s3c2410_pm_driver); +} + +arch_initcall(s3c2410_pm_drvinit); +#endif + +#if defined(CONFIG_CPU_S3C2440) +static struct sysdev_driver s3c2440_pm_driver = { + .add = s3c2410_pm_add, + .resume = s3c2410_pm_resume, +}; + +static int __init s3c2440_pm_drvinit(void) +{ + return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_pm_driver); +} + +arch_initcall(s3c2440_pm_drvinit); +#endif + +#if defined(CONFIG_CPU_S3C2442) +static struct sysdev_driver s3c2442_pm_driver = { + .add = s3c2410_pm_add, + .resume = s3c2410_pm_resume, +}; + +static int __init s3c2442_pm_drvinit(void) +{ + return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_pm_driver); +} + +arch_initcall(s3c2442_pm_drvinit); +#endif diff --git a/trunk/arch/arm/mach-s3c2410/s3c2410-sleep.S b/trunk/arch/arm/mach-s3c2410/s3c2410-sleep.S new file mode 100644 index 000000000000..9179a1024588 --- /dev/null +++ b/trunk/arch/arm/mach-s3c2410/s3c2410-sleep.S @@ -0,0 +1,68 @@ +/* linux/arch/arm/mach-s3c2410/s3c2410-sleep.S + * + * Copyright (c) 2004 Simtec Electronics + * Ben Dooks + * + * S3C2410 Power Manager (Suspend-To-RAM) support + * + * Based on PXA/SA1100 sleep code by: + * Nicolas Pitre, (c) 2002 Monta Vista Software Inc + * Cliff Brake, (c) 2001 + * + * 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 + + /* s3c2410_cpu_suspend + * + * put the cpu into sleep mode + */ + +ENTRY(s3c2410_cpu_suspend) + @@ prepare cpu to sleep + + ldr r4, =S3C2410_REFRESH + ldr r5, =S3C24XX_MISCCR + ldr r6, =S3C2410_CLKCON + ldr r7, [ r4 ] @ get REFRESH (and ensure in TLB) + ldr r8, [ r5 ] @ get MISCCR (and ensure in TLB) + ldr r9, [ r6 ] @ get CLKCON (and ensure in TLB) + + orr r7, r7, #S3C2410_REFRESH_SELF @ SDRAM sleep command + orr r8, r8, #S3C2410_MISCCR_SDSLEEP @ SDRAM power-down signals + orr r9, r9, #S3C2410_CLKCON_POWER @ power down command + + teq pc, #0 @ first as a trial-run to load cache + bl s3c2410_do_sleep + teq r0, r0 @ now do it for real + b s3c2410_do_sleep @ + + @@ align next bit of code to cache line + .align 8 +s3c2410_do_sleep: + streq r7, [ r4 ] @ SDRAM sleep command + streq r8, [ r5 ] @ SDRAM power-down config + streq r9, [ r6 ] @ CPU sleep +1: beq 1b + mov pc, r14 diff --git a/trunk/arch/arm/mach-s3c2410/s3c2410.c b/trunk/arch/arm/mach-s3c2410/s3c2410.c index 1a86a9803753..4cdc0d70c19f 100644 --- a/trunk/arch/arm/mach-s3c2410/s3c2410.c +++ b/trunk/arch/arm/mach-s3c2410/s3c2410.c @@ -31,10 +31,10 @@ #include #include -#include -#include -#include -#include +#include "s3c2410.h" +#include "cpu.h" +#include "devs.h" +#include "clock.h" /* Initial IO mappings */ @@ -110,7 +110,7 @@ static struct sys_device s3c2410_sysdev = { /* need to register class before we actually register the device, and * we also need to ensure that it has been initialised before any of the - * drivers even try to use it (even if not on an s3c2410 based system) + * drivers even try to use it (even if not on an s3c2440 based system) * as a driver which may support both 2410 and 2440 may try and use it. */ diff --git a/trunk/include/asm-arm/plat-s3c24xx/s3c2410.h b/trunk/arch/arm/mach-s3c2410/s3c2410.h similarity index 93% rename from trunk/include/asm-arm/plat-s3c24xx/s3c2410.h rename to trunk/arch/arm/mach-s3c2410/s3c2410.h index 36de0b835873..fbed084f26d0 100644 --- a/trunk/include/asm-arm/plat-s3c24xx/s3c2410.h +++ b/trunk/arch/arm/mach-s3c2410/s3c2410.h @@ -1,4 +1,4 @@ -/* linux/include/asm-arm/plat-s3c24xx/s3c2410.h +/* arch/arm/mach-s3c2410/s3c2410.h * * Copyright (c) 2004 Simtec Electronics * Ben Dooks diff --git a/trunk/arch/arm/mach-s3c2412/clock.c b/trunk/arch/arm/mach-s3c2410/s3c2412-clock.c similarity index 99% rename from trunk/arch/arm/mach-s3c2412/clock.c rename to trunk/arch/arm/mach-s3c2410/s3c2412-clock.c index 6a8e4448770b..8f94ad83901d 100644 --- a/trunk/arch/arm/mach-s3c2412/clock.c +++ b/trunk/arch/arm/mach-s3c2410/s3c2412-clock.c @@ -1,4 +1,4 @@ -/* linux/arch/arm/mach-s3c2412/clock.c +/* linux/arch/arm/mach-s3c2410/s3c2412-clock.c * * Copyright (c) 2006 Simtec Electronics * Ben Dooks @@ -41,9 +41,9 @@ #include #include -#include -#include -#include +#include "s3c2412.h" +#include "clock.h" +#include "cpu.h" /* We currently have to assume that the system is running * from the XTPll input, and that all ***REFCLKs are being diff --git a/trunk/arch/arm/mach-s3c2412/dma.c b/trunk/arch/arm/mach-s3c2410/s3c2412-dma.c similarity index 97% rename from trunk/arch/arm/mach-s3c2412/dma.c rename to trunk/arch/arm/mach-s3c2410/s3c2412-dma.c index d0f4695c09d9..138f726ac6bf 100644 --- a/trunk/arch/arm/mach-s3c2412/dma.c +++ b/trunk/arch/arm/mach-s3c2410/s3c2412-dma.c @@ -1,4 +1,4 @@ -/* linux/arch/arm/mach-s3c2412/dma.c +/* linux/arch/arm/mach-s3c2410/s3c2412-dma.c * * Copyright (c) 2006 Simtec Electronics * Ben Dooks @@ -21,8 +21,8 @@ #include #include -#include -#include +#include "dma.h" +#include "cpu.h" #include #include @@ -146,7 +146,6 @@ static struct s3c24xx_dma_selection __initdata s3c2412_dma_sel = { static int s3c2412_dma_add(struct sys_device *sysdev) { - s3c2410_dma_init(); return s3c24xx_dma_init_map(&s3c2412_dma_sel); } diff --git a/trunk/arch/arm/mach-s3c2412/irq.c b/trunk/arch/arm/mach-s3c2410/s3c2412-irq.c similarity index 96% rename from trunk/arch/arm/mach-s3c2412/irq.c rename to trunk/arch/arm/mach-s3c2410/s3c2412-irq.c index e89dbdcb1b7b..ffcc30b23a80 100644 --- a/trunk/arch/arm/mach-s3c2412/irq.c +++ b/trunk/arch/arm/mach-s3c2410/s3c2412-irq.c @@ -1,4 +1,4 @@ -/* linux/arch/arm/mach-s3c2412/irq.c +/* linux/arch/arm/mach-s3c2412/s3c2412-irq.c * * Copyright (c) 2006 Simtec Electronics * Ben Dooks @@ -35,9 +35,9 @@ #include #include -#include -#include -#include +#include "cpu.h" +#include "irq.h" +#include "pm.h" /* the s3c2412 changes the behaviour of IRQ_EINT0 through IRQ_EINT3 by * having them turn up in both the INT* and the EINT* registers. Whilst diff --git a/trunk/arch/arm/mach-s3c2412/pm.c b/trunk/arch/arm/mach-s3c2410/s3c2412-pm.c similarity index 95% rename from trunk/arch/arm/mach-s3c2412/pm.c rename to trunk/arch/arm/mach-s3c2410/s3c2412-pm.c index 8988dac388a9..19b63322d259 100644 --- a/trunk/arch/arm/mach-s3c2412/pm.c +++ b/trunk/arch/arm/mach-s3c2410/s3c2412-pm.c @@ -1,4 +1,4 @@ -/* linux/arch/arm/mach-s3c2412/pm.c +/* linux/arch/arm/mach-s3c2410/s3c2412-pm.c * * Copyright (c) 2006 Simtec Electronics * Ben Dooks @@ -28,10 +28,10 @@ #include #include -#include -#include +#include "cpu.h" +#include "pm.h" -#include +#include "s3c2412.h" static void s3c2412_cpu_suspend(void) { diff --git a/trunk/arch/arm/mach-s3c2412/s3c2412.c b/trunk/arch/arm/mach-s3c2410/s3c2412.c similarity index 95% rename from trunk/arch/arm/mach-s3c2412/s3c2412.c rename to trunk/arch/arm/mach-s3c2410/s3c2412.c index aafe0bc593f1..2f651a811ecd 100644 --- a/trunk/arch/arm/mach-s3c2412/s3c2412.c +++ b/trunk/arch/arm/mach-s3c2410/s3c2412.c @@ -1,4 +1,4 @@ -/* linux/arch/arm/mach-s3c2412/s3c2412.c +/* linux/arch/arm/mach-s3c2410/s3c2412.c * * Copyright (c) 2006 Simtec Electronics * Ben Dooks @@ -38,11 +38,11 @@ #include #include -#include -#include -#include -#include -#include +#include "s3c2412.h" +#include "cpu.h" +#include "devs.h" +#include "clock.h" +#include "pm.h" #ifndef CONFIG_CPU_S3C2412_ONLY void __iomem *s3c24xx_va_gpio2 = S3C24XX_VA_GPIO; diff --git a/trunk/include/asm-arm/plat-s3c24xx/s3c2412.h b/trunk/arch/arm/mach-s3c2410/s3c2412.h similarity index 93% rename from trunk/include/asm-arm/plat-s3c24xx/s3c2412.h rename to trunk/arch/arm/mach-s3c2410/s3c2412.h index 3ec97685e781..c6e56032a6e7 100644 --- a/trunk/include/asm-arm/plat-s3c24xx/s3c2412.h +++ b/trunk/arch/arm/mach-s3c2410/s3c2412.h @@ -1,4 +1,4 @@ -/* linux/include/asm-arm/plat-s3c24xx/s3c2412.h +/* arch/arm/mach-s3c2410/s3c2412.h * * Copyright (c) 2006 Simtec Electronics * Ben Dooks diff --git a/trunk/arch/arm/mach-s3c2440/clock.c b/trunk/arch/arm/mach-s3c2410/s3c2440-clock.c similarity index 97% rename from trunk/arch/arm/mach-s3c2440/clock.c rename to trunk/arch/arm/mach-s3c2410/s3c2440-clock.c index 79e2ea4adaf3..ba13c1d079d1 100644 --- a/trunk/arch/arm/mach-s3c2440/clock.c +++ b/trunk/arch/arm/mach-s3c2410/s3c2440-clock.c @@ -1,4 +1,4 @@ -/* linux/arch/arm/mach-s3c2440/clock.c +/* linux/arch/arm/mach-s3c2410/s3c2440-clock.c * * Copyright (c) 2004-2005 Simtec Electronics * http://armlinux.simtec.co.uk/ @@ -41,8 +41,8 @@ #include -#include -#include +#include "clock.h" +#include "cpu.h" /* S3C2440 extended clock support */ diff --git a/trunk/arch/arm/mach-s3c2440/dma.c b/trunk/arch/arm/mach-s3c2410/s3c2440-dma.c similarity index 83% rename from trunk/arch/arm/mach-s3c2440/dma.c rename to trunk/arch/arm/mach-s3c2410/s3c2440-dma.c index cd035a3ec878..47b861b9443d 100644 --- a/trunk/arch/arm/mach-s3c2440/dma.c +++ b/trunk/arch/arm/mach-s3c2410/s3c2440-dma.c @@ -1,4 +1,4 @@ -/* linux/arch/arm/mach-s3c2440/dma.c +/* linux/arch/arm/mach-s3c2410/s3c2440-dma.c * * Copyright (c) 2006 Simtec Electronics * Ben Dooks @@ -19,9 +19,9 @@ #include #include +#include "dma.h" -#include -#include +#include "cpu.h" #include #include @@ -147,53 +147,8 @@ static struct s3c24xx_dma_selection __initdata s3c2440_dma_sel = { .map_size = ARRAY_SIZE(s3c2440_dma_mappings), }; -static struct s3c24xx_dma_order __initdata s3c2440_dma_order = { - .channels = { - [DMACH_SDI] = { - .list = { - [0] = 3 | DMA_CH_VALID, - [1] = 2 | DMA_CH_VALID, - [2] = 1 | DMA_CH_VALID, - [3] = 0 | DMA_CH_VALID, - }, - }, - [DMACH_I2S_IN] = { - .list = { - [0] = 1 | DMA_CH_VALID, - [1] = 2 | DMA_CH_VALID, - }, - }, - [DMACH_I2S_OUT] = { - .list = { - [0] = 2 | DMA_CH_VALID, - [1] = 1 | DMA_CH_VALID, - }, - }, - [DMACH_PCM_IN] = { - .list = { - [0] = 2 | DMA_CH_VALID, - [1] = 1 | DMA_CH_VALID, - }, - }, - [DMACH_PCM_OUT] = { - .list = { - [0] = 1 | DMA_CH_VALID, - [1] = 3 | DMA_CH_VALID, - }, - }, - [DMACH_MIC_IN] = { - .list = { - [0] = 3 | DMA_CH_VALID, - [1] = 2 | DMA_CH_VALID, - }, - }, - }, -}; - static int s3c2440_dma_add(struct sys_device *sysdev) { - s3c2410_dma_init(); - s3c24xx_dma_order_set(&s3c2440_dma_order); return s3c24xx_dma_init_map(&s3c2440_dma_sel); } diff --git a/trunk/arch/arm/mach-s3c2440/dsc.c b/trunk/arch/arm/mach-s3c2410/s3c2440-dsc.c similarity index 91% rename from trunk/arch/arm/mach-s3c2440/dsc.c rename to trunk/arch/arm/mach-s3c2410/s3c2440-dsc.c index 2995ff5681bb..c92ea66ba45e 100644 --- a/trunk/arch/arm/mach-s3c2440/dsc.c +++ b/trunk/arch/arm/mach-s3c2410/s3c2440-dsc.c @@ -1,4 +1,4 @@ -/* linux/arch/arm/mach-s3c2440/dsc.c +/* linux/arch/arm/mach-s3c2410/s3c2440-dsc.c * * Copyright (c) 2004-2005 Simtec Electronics * Ben Dooks @@ -27,8 +27,8 @@ #include #include -#include -#include +#include "cpu.h" +#include "s3c2440.h" int s3c2440_set_dsc(unsigned int pin, unsigned int value) { diff --git a/trunk/arch/arm/mach-s3c2440/irq.c b/trunk/arch/arm/mach-s3c2410/s3c2440-irq.c similarity index 95% rename from trunk/arch/arm/mach-s3c2440/irq.c rename to trunk/arch/arm/mach-s3c2410/s3c2440-irq.c index 1069d13d8c57..1ba19b27ab05 100644 --- a/trunk/arch/arm/mach-s3c2440/irq.c +++ b/trunk/arch/arm/mach-s3c2410/s3c2440-irq.c @@ -1,4 +1,4 @@ -/* linux/arch/arm/mach-s3c2440/irq.c +/* linux/arch/arm/mach-s3c2410/s3c2440-irq.c * * Copyright (c) 2003,2004 Simtec Electronics * Ben Dooks @@ -35,9 +35,9 @@ #include #include -#include -#include -#include +#include "cpu.h" +#include "pm.h" +#include "irq.h" /* WDT/AC97 */ diff --git a/trunk/arch/arm/mach-s3c2440/s3c2440.c b/trunk/arch/arm/mach-s3c2410/s3c2440.c similarity index 88% rename from trunk/arch/arm/mach-s3c2440/s3c2440.c rename to trunk/arch/arm/mach-s3c2410/s3c2440.c index 90e1da61fbc3..344eb27cca48 100644 --- a/trunk/arch/arm/mach-s3c2440/s3c2440.c +++ b/trunk/arch/arm/mach-s3c2410/s3c2440.c @@ -1,4 +1,4 @@ -/* linux/arch/arm/mach-s3c2440/s3c2440.c +/* linux/arch/arm/mach-s3c2410/s3c2440.c * * Copyright (c) 2004-2006 Simtec Electronics * Ben Dooks @@ -29,9 +29,9 @@ #include #include -#include -#include -#include +#include "s3c2440.h" +#include "devs.h" +#include "cpu.h" static struct sys_device s3c2440_sysdev = { .cls = &s3c2440_sysclass, diff --git a/trunk/include/asm-arm/plat-s3c24xx/s3c2440.h b/trunk/arch/arm/mach-s3c2410/s3c2440.h similarity index 89% rename from trunk/include/asm-arm/plat-s3c24xx/s3c2440.h rename to trunk/arch/arm/mach-s3c2410/s3c2440.h index 107853bf9481..dcd316076c59 100644 --- a/trunk/include/asm-arm/plat-s3c24xx/s3c2440.h +++ b/trunk/arch/arm/mach-s3c2410/s3c2440.h @@ -1,4 +1,4 @@ -/* linux/include/asm-arm/plat-s3c24xx/s3c2440.h +/* arch/arm/mach-s3c2410/s3c2440.h * * Copyright (c) 2004-2005 Simtec Electronics * Ben Dooks diff --git a/trunk/arch/arm/mach-s3c2442/clock.c b/trunk/arch/arm/mach-s3c2410/s3c2442-clock.c similarity index 97% rename from trunk/arch/arm/mach-s3c2442/clock.c rename to trunk/arch/arm/mach-s3c2410/s3c2442-clock.c index 5b9e830ac4d3..4e292ca7c9be 100644 --- a/trunk/arch/arm/mach-s3c2442/clock.c +++ b/trunk/arch/arm/mach-s3c2410/s3c2442-clock.c @@ -1,4 +1,4 @@ -/* linux/arch/arm/mach-s3c2442/clock.c +/* linux/arch/arm/mach-s3c2410/s3c2442-clock.c * * Copyright (c) 2004-2005 Simtec Electronics * http://armlinux.simtec.co.uk/ @@ -41,8 +41,8 @@ #include -#include -#include +#include "clock.h" +#include "cpu.h" /* S3C2442 extended clock support */ diff --git a/trunk/arch/arm/mach-s3c2442/s3c2442.c b/trunk/arch/arm/mach-s3c2410/s3c2442.c similarity index 86% rename from trunk/arch/arm/mach-s3c2442/s3c2442.c rename to trunk/arch/arm/mach-s3c2410/s3c2442.c index fbf8264249da..428732ee68c4 100644 --- a/trunk/arch/arm/mach-s3c2442/s3c2442.c +++ b/trunk/arch/arm/mach-s3c2410/s3c2442.c @@ -1,4 +1,4 @@ -/* linux/arch/arm/mach-s3c2442/s3c2442.c +/* linux/arch/arm/mach-s3c2410/s3c2442.c * * Copyright (c) 2006 Simtec Electronics * Ben Dooks @@ -19,8 +19,8 @@ #include #include -#include -#include +#include "s3c2442.h" +#include "cpu.h" static struct sys_device s3c2442_sysdev = { .cls = &s3c2442_sysclass, diff --git a/trunk/include/asm-arm/plat-s3c24xx/s3c2442.h b/trunk/arch/arm/mach-s3c2410/s3c2442.h similarity index 89% rename from trunk/include/asm-arm/plat-s3c24xx/s3c2442.h rename to trunk/arch/arm/mach-s3c2410/s3c2442.h index 451a23a2092a..0ae37d24866c 100644 --- a/trunk/include/asm-arm/plat-s3c24xx/s3c2442.h +++ b/trunk/arch/arm/mach-s3c2410/s3c2442.h @@ -1,4 +1,4 @@ -/* linux/include/asm-arm/plat-s3c24xx/s3c2442.h +/* arch/arm/mach-s3c2410/s3c2442.h * * Copyright (c) 2006 Simtec Electronics * Ben Dooks diff --git a/trunk/arch/arm/plat-s3c24xx/s3c244x-irq.c b/trunk/arch/arm/mach-s3c2410/s3c244x-irq.c similarity index 95% rename from trunk/arch/arm/plat-s3c24xx/s3c244x-irq.c rename to trunk/arch/arm/mach-s3c2410/s3c244x-irq.c index a0e39d894014..ede94636a72a 100644 --- a/trunk/arch/arm/plat-s3c24xx/s3c244x-irq.c +++ b/trunk/arch/arm/mach-s3c2410/s3c244x-irq.c @@ -1,4 +1,4 @@ -/* linux/arch/arm/plat-s3c24xx/s3c244x-irq.c +/* linux/arch/arm/mach-s3c2410/s3c244x-irq.c * * Copyright (c) 2003,2004 Simtec Electronics * Ben Dooks @@ -35,9 +35,9 @@ #include #include -#include -#include -#include +#include "cpu.h" +#include "pm.h" +#include "irq.h" /* camera irq */ diff --git a/trunk/arch/arm/plat-s3c24xx/s3c244x.c b/trunk/arch/arm/mach-s3c2410/s3c244x.c similarity index 93% rename from trunk/arch/arm/plat-s3c24xx/s3c244x.c rename to trunk/arch/arm/mach-s3c2410/s3c244x.c index 767f2e9a3a55..23c7494ad10d 100644 --- a/trunk/arch/arm/plat-s3c24xx/s3c244x.c +++ b/trunk/arch/arm/mach-s3c2410/s3c244x.c @@ -1,9 +1,9 @@ -/* linux/arch/arm/plat-s3c24xx/s3c244x.c +/* linux/arch/arm/mach-s3c2410/s3c244x.c * * Copyright (c) 2004-2006 Simtec Electronics * Ben Dooks * - * Samsung S3C2440 and S3C2442 Mobile CPU support (not S3C2443) + * Samsung S3C2440 and S3C2442 Mobile CPU support * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -35,13 +35,13 @@ #include #include -#include -#include +#include "s3c2410.h" +#include "s3c2440.h" #include "s3c244x.h" -#include -#include -#include -#include +#include "clock.h" +#include "devs.h" +#include "cpu.h" +#include "pm.h" static struct map_desc s3c244x_iodesc[] __initdata = { IODESC_ENT(CLKPWR), diff --git a/trunk/arch/arm/plat-s3c24xx/s3c244x.h b/trunk/arch/arm/mach-s3c2410/s3c244x.h similarity index 94% rename from trunk/arch/arm/plat-s3c24xx/s3c244x.h rename to trunk/arch/arm/mach-s3c2410/s3c244x.h index f8ed17676a35..1488c1eb37e6 100644 --- a/trunk/arch/arm/plat-s3c24xx/s3c244x.h +++ b/trunk/arch/arm/mach-s3c2410/s3c244x.h @@ -1,4 +1,4 @@ -/* linux/arch/arm/plat-s3c24xx/s3c244x.h +/* arch/arm/mach-s3c2410/s3c244x.h * * Copyright (c) 2004-2005 Simtec Electronics * Ben Dooks diff --git a/trunk/arch/arm/mach-s3c2410/sleep.S b/trunk/arch/arm/mach-s3c2410/sleep.S index 637aaba65390..2018c2e1dcc5 100644 --- a/trunk/arch/arm/mach-s3c2410/sleep.S +++ b/trunk/arch/arm/mach-s3c2410/sleep.S @@ -1,4 +1,4 @@ -/* linux/arch/arm/mach-s3c2410/s3c2410-sleep.S +/* linux/arch/arm/mach-s3c2410/sleep.S * * Copyright (c) 2004 Simtec Electronics * Ben Dooks @@ -34,35 +34,126 @@ #include #include - /* s3c2410_cpu_suspend +/* CONFIG_DEBUG_RESUME is dangerous if your bootloader does not + * reset the UART configuration, only enable if you really need this! +*/ +//#define CONFIG_DEBUG_RESUME + + .text + + /* s3c2410_cpu_save + * + * save enough of the CPU state to allow us to re-start + * pm.c code. as we store items like the sp/lr, we will + * end up returning from this function when the cpu resumes + * so the return value is set to mark this. + * + * This arangement means we avoid having to flush the cache + * from this code. + * + * entry: + * r0 = pointer to save block + * + * exit: + * r0 = 0 => we stored everything + * 1 => resumed from sleep + */ + +ENTRY(s3c2410_cpu_save) + stmfd sp!, { r4 - r12, lr } + + @@ store co-processor registers + + mrc p15, 0, r4, c15, c1, 0 @ CP access register + mrc p15, 0, r5, c13, c0, 0 @ PID + mrc p15, 0, r6, c3, c0, 0 @ Domain ID + mrc p15, 0, r7, c2, c0, 0 @ translation table base address + mrc p15, 0, r8, c1, c0, 0 @ control register + + stmia r0, { r4 - r13 } + + mov r0, #0 + ldmfd sp, { r4 - r12, pc } + + @@ return to the caller, after having the MMU + @@ turned on, this restores the last bits from the + @@ stack +resume_with_mmu: + mov r0, #1 + ldmfd sp!, { r4 - r12, pc } + + .ltorg + + @@ the next bits sit in the .data segment, even though they + @@ happen to be code... the s3c2410_sleep_save_phys needs to be + @@ accessed by the resume code before it can restore the MMU. + @@ This means that the variable has to be close enough for the + @@ code to read it... since the .text segment needs to be RO, + @@ the data segment can be the only place to put this code. + + .data + + .global s3c2410_sleep_save_phys +s3c2410_sleep_save_phys: + .word 0 + + /* s3c2410_cpu_resume * - * put the cpu into sleep mode + * resume code entry for bootloader to call + * + * we must put this code here in the data segment as we have no + * other way of restoring the stack pointer after sleep, and we + * must not write to the code segment (code is read-only) */ -ENTRY(s3c2410_cpu_suspend) - @@ prepare cpu to sleep - - ldr r4, =S3C2410_REFRESH - ldr r5, =S3C24XX_MISCCR - ldr r6, =S3C2410_CLKCON - ldr r7, [ r4 ] @ get REFRESH (and ensure in TLB) - ldr r8, [ r5 ] @ get MISCCR (and ensure in TLB) - ldr r9, [ r6 ] @ get CLKCON (and ensure in TLB) - - orr r7, r7, #S3C2410_REFRESH_SELF @ SDRAM sleep command - orr r8, r8, #S3C2410_MISCCR_SDSLEEP @ SDRAM power-down signals - orr r9, r9, #S3C2410_CLKCON_POWER @ power down command - - teq pc, #0 @ first as a trial-run to load cache - bl s3c2410_do_sleep - teq r0, r0 @ now do it for real - b s3c2410_do_sleep @ - - @@ align next bit of code to cache line - .align 5 -s3c2410_do_sleep: - streq r7, [ r4 ] @ SDRAM sleep command - streq r8, [ r5 ] @ SDRAM power-down config - streq r9, [ r6 ] @ CPU sleep -1: beq 1b - mov pc, r14 +ENTRY(s3c2410_cpu_resume) + mov r0, #PSR_I_BIT | PSR_F_BIT | SVC_MODE + msr cpsr_c, r0 + + @@ load UART to allow us to print the two characters for + @@ resume debug + + mov r2, #S3C24XX_PA_UART & 0xff000000 + orr r2, r2, #S3C24XX_PA_UART & 0xff000 + +#if 0 + /* SMDK2440 LED set */ + mov r14, #S3C24XX_PA_GPIO + ldr r12, [ r14, #0x54 ] + bic r12, r12, #3<<4 + orr r12, r12, #1<<7 + str r12, [ r14, #0x54 ] +#endif + +#ifdef CONFIG_DEBUG_RESUME + mov r3, #'L' + strb r3, [ r2, #S3C2410_UTXH ] +1001: + ldrb r14, [ r3, #S3C2410_UTRSTAT ] + tst r14, #S3C2410_UTRSTAT_TXE + beq 1001b +#endif /* CONFIG_DEBUG_RESUME */ + + mov r1, #0 + mcr p15, 0, r1, c8, c7, 0 @@ invalidate I & D TLBs + mcr p15, 0, r1, c7, c7, 0 @@ invalidate I & D caches + + ldr r0, s3c2410_sleep_save_phys @ address of restore block + ldmia r0, { r4 - r13 } + + mcr p15, 0, r4, c15, c1, 0 @ CP access register + mcr p15, 0, r5, c13, c0, 0 @ PID + mcr p15, 0, r6, c3, c0, 0 @ Domain ID + mcr p15, 0, r7, c2, c0, 0 @ translation table base + +#ifdef CONFIG_DEBUG_RESUME + mov r3, #'R' + strb r3, [ r2, #S3C2410_UTXH ] +#endif + + ldr r2, =resume_with_mmu + mcr p15, 0, r8, c1, c0, 0 @ turn on MMU, etc + nop @ second-to-last before mmu + mov pc, r2 @ go back to virtual address + + .ltorg diff --git a/trunk/arch/arm/plat-s3c24xx/time.c b/trunk/arch/arm/mach-s3c2410/time.c similarity index 98% rename from trunk/arch/arm/plat-s3c24xx/time.c rename to trunk/arch/arm/mach-s3c2410/time.c index c523d1c9cce5..9910bf0f2cea 100644 --- a/trunk/arch/arm/plat-s3c24xx/time.c +++ b/trunk/arch/arm/mach-s3c2410/time.c @@ -1,4 +1,4 @@ -/* linux/arch/arm/plat-s3c24xx/time.c +/* linux/arch/arm/mach-s3c2410/time.c * * Copyright (C) 2003-2005 Simtec Electronics * Ben Dooks, @@ -37,8 +37,8 @@ #include #include -#include -#include +#include "clock.h" +#include "cpu.h" static unsigned long timer_startval; static unsigned long timer_usec_ticks; diff --git a/trunk/arch/arm/mach-s3c2410/usb-simtec.c b/trunk/arch/arm/mach-s3c2410/usb-simtec.c index bcd562ac1d3d..22b0e1cdd4bf 100644 --- a/trunk/arch/arm/mach-s3c2410/usb-simtec.c +++ b/trunk/arch/arm/mach-s3c2410/usb-simtec.c @@ -35,7 +35,7 @@ #include #include -#include +#include "devs.h" #include "usb-simtec.h" /* control power and monitor over-current events on various Simtec diff --git a/trunk/arch/arm/mach-s3c2412/Kconfig b/trunk/arch/arm/mach-s3c2412/Kconfig deleted file mode 100644 index befc5fdbb613..000000000000 --- a/trunk/arch/arm/mach-s3c2412/Kconfig +++ /dev/null @@ -1,58 +0,0 @@ -# arch/arm/mach-s3c2412/Kconfig -# -# Copyright 2007 Simtec Electronics -# -# Licensed under GPLv2 - -config CPU_S3C2412 - bool - depends on ARCH_S3C2410 - select S3C2412_PM if PM - select S3C2412_DMA if S3C2410_DMA - help - Support for the S3C2412 and S3C2413 SoCs from the S3C24XX line - -config CPU_S3C2412_ONLY - bool - depends on ARCH_S3C2410 && !CPU_S3C2400 && !CPU_S3C2410 && \ - !CPU_S3C2440 && !CPU_S3C2442 && !CPU_S3C2443 && CPU_S3C2412 - default y if CPU_S3C2412 - -config S3C2412_DMA - bool - depends on CPU_S3C2412 - help - Internal config node for S3C2412 DMA support - -config S3C2412_PM - bool - help - Internal config node to apply S3C2412 power management - - -menu "S3C2412 Machines" - -config MACH_SMDK2413 - bool "SMDK2413" - select CPU_S3C2412 - select MACH_S3C2413 - select MACH_SMDK - help - Say Y here if you are using an SMDK2413 - -config MACH_S3C2413 - bool - help - Internal node for S3C2413 version of SMDK2413, so that - machine_is_s3c2413() will work when MACH_SMDK2413 is - selected - -config MACH_VSTMS - bool "VMSTMS" - select CPU_S3C2412 - help - Say Y here if you are using an VSTMS board - - -endmenu - diff --git a/trunk/arch/arm/mach-s3c2412/Makefile b/trunk/arch/arm/mach-s3c2412/Makefile deleted file mode 100644 index f8e011691b31..000000000000 --- a/trunk/arch/arm/mach-s3c2412/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -# arch/arm/mach-s3c2412/Makefile -# -# Copyright 2007 Simtec Electronics -# -# Licensed under GPLv2 - -obj-y := -obj-m := -obj-n := -obj- := - -obj-$(CONFIG_CPU_S3C2412) += s3c2412.o -obj-$(CONFIG_CPU_S3C2412) += irq.o -obj-$(CONFIG_CPU_S3C2412) += clock.o -obj-$(CONFIG_S3C2412_DMA) += dma.o -obj-$(CONFIG_S3C2412_PM) += pm.o - -# Machine support - -obj-$(CONFIG_MACH_SMDK2413) += mach-smdk2413.o -obj-$(CONFIG_MACH_VSTMS) += mach-vstms.o diff --git a/trunk/arch/arm/mach-s3c2440/Kconfig b/trunk/arch/arm/mach-s3c2440/Kconfig deleted file mode 100644 index e3bfda098c0f..000000000000 --- a/trunk/arch/arm/mach-s3c2440/Kconfig +++ /dev/null @@ -1,71 +0,0 @@ -# arch/arm/mach-s3c2440/Kconfig -# -# Copyright 2007 Simtec Electronics -# -# Licensed under GPLv2 - -config CPU_S3C2440 - bool - depends on ARCH_S3C2410 - select S3C2410_CLOCK - select S3C2410_PM if PM - select S3C2410_GPIO - select S3C2440_DMA if S3C2410_DMA - select CPU_S3C244X - help - Support for S3C2440 Samsung Mobile CPU based systems. - -config S3C2440_DMA - bool - depends on ARCH_S3C2410 && CPU_S3C24405B - help - Support for S3C2440 specific DMA code5A - - -menu "S3C2440 Machines" - -config MACH_ANUBIS - bool "Simtec Electronics ANUBIS" - select CPU_S3C2440 - select PM_SIMTEC if PM - help - Say Y here if you are using the Simtec Electronics ANUBIS - development system - -config MACH_OSIRIS - bool "Simtec IM2440D20 (OSIRIS) module" - select CPU_S3C2440 - select PM_SIMTEC if PM - help - Say Y here if you are using the Simtec IM2440D20 module, also - known as the Osiris. - -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. - -config ARCH_S3C2440 - bool "SMDK2440" - select CPU_S3C2440 - select MACH_SMDK - help - Say Y here if you are using the SMDK2440. - -config MACH_NEXCODER_2440 - bool "NexVision NEXCODER 2440 Light Board" - select CPU_S3C2440 - help - Say Y here if you are using the Nex Vision NEXCODER 2440 Light Board - -config SMDK2440_CPU2440 - bool "SMDK2440 with S3C2440 CPU module" - depends on ARCH_S3C2440 - default y if ARCH_S3C2440 - select CPU_S3C2440 - - -endmenu - diff --git a/trunk/arch/arm/mach-s3c2440/Makefile b/trunk/arch/arm/mach-s3c2440/Makefile deleted file mode 100644 index c81ed6248dcb..000000000000 --- a/trunk/arch/arm/mach-s3c2440/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -# arch/arm/mach-s3c2440/Makefile -# -# Copyright 2007 Simtec Electronics -# -# Licensed under GPLv2 - -obj-y := -obj-m := -obj-n := -obj- := - -obj-$(CONFIG_CPU_S3C2440) += s3c2440.o dsc.o -obj-$(CONFIG_CPU_S3C2440) += irq.o -obj-$(CONFIG_CPU_S3C2440) += clock.o -obj-$(CONFIG_S3C2440_DMA) += dma.o - -# Machine support - -obj-$(CONFIG_MACH_ANUBIS) += mach-anubis.o -obj-$(CONFIG_MACH_OSIRIS) += mach-osiris.o -obj-$(CONFIG_MACH_RX3715) += mach-rx3715.o -obj-$(CONFIG_ARCH_S3C2440) += mach-smdk2440.o -obj-$(CONFIG_MACH_NEXCODER_2440) += mach-nexcoder.o diff --git a/trunk/arch/arm/mach-s3c2442/Kconfig b/trunk/arch/arm/mach-s3c2442/Kconfig deleted file mode 100644 index bf8d87abfab3..000000000000 --- a/trunk/arch/arm/mach-s3c2442/Kconfig +++ /dev/null @@ -1,27 +0,0 @@ -# arch/arm/mach-s3c2442/Kconfig -# -# Copyright 2007 Simtec Electronics -# -# Licensed under GPLv2 - -config CPU_S3C2442 - bool - depends on ARCH_S3C2420 - select S3C2410_CLOCK - select S3C2410_GPIO - select S3C2410_PM if PM - select CPU_S3C244X - help - Support for S3C2442 Samsung Mobile CPU based systems. - - -menu "S3C2442 Machines" - -config SMDK2440_CPU2442 - bool "SMDM2440 with S3C2442 CPU module" - depends on ARCH_S3C2440 - select CPU_S3C2442 - - -endmenu - diff --git a/trunk/arch/arm/mach-s3c2442/Makefile b/trunk/arch/arm/mach-s3c2442/Makefile deleted file mode 100644 index 2a909c6c5798..000000000000 --- a/trunk/arch/arm/mach-s3c2442/Makefile +++ /dev/null @@ -1,16 +0,0 @@ -# arch/arm/mach-s3c2442/Makefile -# -# Copyright 2007 Simtec Electronics -# -# Licensed under GPLv2 - -obj-y := -obj-m := -obj-n := -obj- := - -obj-$(CONFIG_CPU_S3C2442) += s3c2442.o -obj-$(CONFIG_CPU_S3C2442) += clock.o - -# Machine support - diff --git a/trunk/arch/arm/mach-s3c2443/Kconfig b/trunk/arch/arm/mach-s3c2443/Kconfig deleted file mode 100644 index c649bb2e7ce8..000000000000 --- a/trunk/arch/arm/mach-s3c2443/Kconfig +++ /dev/null @@ -1,29 +0,0 @@ -# arch/arm/mach-s3c2443/Kconfig -# -# Copyright 2007 Simtec Electronics -# -# Licensed under GPLv2 - -config CPU_S3C2443 - bool - depends on ARCH_S3C2410 - select S3C2443_DMA if S3C2410_DMA - help - Support for the S3C2443 SoC from the S3C24XX line - -config S3C2443_DMA - bool - depends on CPU_S3C2443 - help - Internal config node for S3C2443 DMA support - -menu "S3C2443 Machines" - -config MACH_SMDK2443 - bool "SMDK2443" - select CPU_S3C2443 - select MACH_SMDK - help - Say Y here if you are using an SMDK2443 - -endmenu diff --git a/trunk/arch/arm/mach-s3c2443/Makefile b/trunk/arch/arm/mach-s3c2443/Makefile deleted file mode 100644 index d1843c9eb8bd..000000000000 --- a/trunk/arch/arm/mach-s3c2443/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# arch/arm/mach-s3c2443/Makefile -# -# Copyright 2007 Simtec Electronics -# -# Licensed under GPLv2 - -obj-y := -obj-m := -obj-n := -obj- := - -obj-$(CONFIG_CPU_S3C2443) += s3c2443.o -obj-$(CONFIG_CPU_S3C2443) += irq.o -obj-$(CONFIG_CPU_S3C2443) += clock.o - -obj-$(CONFIG_S3C2443_DMA) += dma.o - -# Machine support - -obj-$(CONFIG_MACH_SMDK2443) += mach-smdk2443.o diff --git a/trunk/arch/arm/mach-s3c2443/clock.c b/trunk/arch/arm/mach-s3c2443/clock.c deleted file mode 100644 index dd2272fb1131..000000000000 --- a/trunk/arch/arm/mach-s3c2443/clock.c +++ /dev/null @@ -1,1007 +0,0 @@ -/* linux/arch/arm/mach-s3c2443/clock.c - * - * Copyright (c) 2007 Simtec Electronics - * Ben Dooks - * - * S3C2443 Clock control 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 - * 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 - -/* We currently have to assume that the system is running - * from the XTPll input, and that all ***REFCLKs are being - * fed from it, as we cannot read the state of OM[4] from - * software. - * - * It would be possible for each board initialisation to - * set the correct muxing at initialisation -*/ - -static int s3c2443_clkcon_enable_h(struct clk *clk, int enable) -{ - unsigned int clocks = clk->ctrlbit; - unsigned long clkcon; - - clkcon = __raw_readl(S3C2443_HCLKCON); - - if (enable) - clkcon |= clocks; - else - clkcon &= ~clocks; - - __raw_writel(clkcon, S3C2443_HCLKCON); - - return 0; -} - -static int s3c2443_clkcon_enable_p(struct clk *clk, int enable) -{ - unsigned int clocks = clk->ctrlbit; - unsigned long clkcon; - - clkcon = __raw_readl(S3C2443_PCLKCON); - - if (enable) - clkcon |= clocks; - else - clkcon &= ~clocks; - - __raw_writel(clkcon, S3C2443_HCLKCON); - - return 0; -} - -static int s3c2443_clkcon_enable_s(struct clk *clk, int enable) -{ - unsigned int clocks = clk->ctrlbit; - unsigned long clkcon; - - clkcon = __raw_readl(S3C2443_SCLKCON); - - if (enable) - clkcon |= clocks; - else - clkcon &= ~clocks; - - __raw_writel(clkcon, S3C2443_SCLKCON); - - return 0; -} - -static unsigned long s3c2443_roundrate_clksrc(struct clk *clk, - unsigned long rate, - unsigned int max) -{ - unsigned long parent_rate = clk_get_rate(clk->parent); - int div; - - if (rate > parent_rate) - return parent_rate; - - /* note, we remove the +/- 1 calculations as they cancel out */ - - div = (rate / parent_rate); - - if (div < 1) - div = 1; - else if (div > max) - div = max; - - return parent_rate / div; -} - -static unsigned long s3c2443_roundrate_clksrc4(struct clk *clk, - unsigned long rate) -{ - return s3c2443_roundrate_clksrc(clk, rate, 4); -} - -static unsigned long s3c2443_roundrate_clksrc16(struct clk *clk, - unsigned long rate) -{ - return s3c2443_roundrate_clksrc(clk, rate, 16); -} - -static unsigned long s3c2443_roundrate_clksrc256(struct clk *clk, - unsigned long rate) -{ - return s3c2443_roundrate_clksrc(clk, rate, 256); -} - -/* clock selections */ - -/* CPU EXTCLK input */ -static struct clk clk_ext = { - .name = "ext", - .id = -1, -}; - -static struct clk clk_mpllref = { - .name = "mpllref", - .parent = &clk_xtal, - .id = -1, -}; - -#if 0 -static struct clk clk_mpll = { - .name = "mpll", - .parent = &clk_mpllref, - .id = -1, -}; -#endif - -static struct clk clk_epllref; - -static struct clk clk_epll = { - .name = "epll", - .parent = &clk_epllref, - .id = -1, -}; - -static struct clk clk_i2s_ext = { - .name = "i2s-ext", - .id = -1, -}; - -static int s3c2443_setparent_epllref(struct clk *clk, struct clk *parent) -{ - unsigned long clksrc = __raw_readl(S3C2443_CLKSRC); - - clksrc &= ~S3C2443_CLKSRC_EPLLREF_MASK; - - if (parent == &clk_xtal) - clksrc |= S3C2443_CLKSRC_EPLLREF_XTAL; - else if (parent == &clk_ext) - clksrc |= S3C2443_CLKSRC_EPLLREF_EXTCLK; - else if (parent != &clk_mpllref) - return -EINVAL; - - __raw_writel(clksrc, S3C2443_CLKSRC); - clk->parent = parent; - - return 0; -} - -static struct clk clk_epllref = { - .name = "epllref", - .id = -1, - .set_parent = s3c2443_setparent_epllref, -}; - -static unsigned long s3c2443_getrate_mdivclk(struct clk *clk) -{ - unsigned long parent_rate = clk_get_rate(clk->parent); - unsigned long div = __raw_readl(S3C2443_CLKDIV0); - - div &= S3C2443_CLKDIV0_EXTDIV_MASK; - div >>= (S3C2443_CLKDIV0_EXTDIV_SHIFT-1); /* x2 */ - - return parent_rate / (div + 1); -} - -static struct clk clk_mdivclk = { - .name = "mdivclk", - .parent = &clk_mpllref, - .id = -1, - .get_rate = s3c2443_getrate_mdivclk, -}; - - -static int s3c2443_setparent_msysclk(struct clk *clk, struct clk *parent) -{ - unsigned long clksrc = __raw_readl(S3C2443_CLKSRC); - - clksrc &= ~(S3C2443_CLKSRC_MSYSCLK_MPLL | - S3C2443_CLKSRC_EXTCLK_DIV); - - if (parent == &clk_mpll) - clksrc |= S3C2443_CLKSRC_MSYSCLK_MPLL; - else if (parent == &clk_mdivclk) - clksrc |= S3C2443_CLKSRC_EXTCLK_DIV; - else if (parent != &clk_mpllref) - return -EINVAL; - - __raw_writel(clksrc, S3C2443_CLKSRC); - clk->parent = parent; - - return 0; -} - -static struct clk clk_msysclk = { - .name = "msysclk", - .parent = &clk_xtal, - .id = -1, - .set_parent = s3c2443_setparent_msysclk, -}; - - -/* esysclk - * - * this is sourced from either the EPLL or the EPLLref clock -*/ - -static int s3c2443_setparent_esysclk(struct clk *clk, struct clk *parent) -{ - unsigned long clksrc = __raw_readl(S3C2443_CLKSRC); - - if (parent == &clk_epll) - clksrc |= S3C2443_CLKSRC_ESYSCLK_EPLL; - else if (parent == &clk_epllref) - clksrc &= ~S3C2443_CLKSRC_ESYSCLK_EPLL; - else - return -EINVAL; - - __raw_writel(clksrc, S3C2443_CLKSRC); - clk->parent = parent; - - return 0; -} - -static struct clk clk_esysclk = { - .name = "esysclk", - .parent = &clk_epll, - .id = -1, - .set_parent = s3c2443_setparent_esysclk, -}; - -/* uartclk - * - * UART baud-rate clock sourced from esysclk via a divisor -*/ - -static unsigned long s3c2443_getrate_uart(struct clk *clk) -{ - unsigned long parent_rate = clk_get_rate(clk->parent); - unsigned long div = __raw_readl(S3C2443_CLKDIV1); - - div &= S3C2443_CLKDIV1_UARTDIV_MASK; - div >>= S3C2443_CLKDIV1_UARTDIV_SHIFT; - - return parent_rate / (div + 1); -} - - -static int s3c2443_setrate_uart(struct clk *clk, unsigned long rate) -{ - unsigned long parent_rate = clk_get_rate(clk->parent); - unsigned long clkdivn = __raw_readl(S3C2443_CLKDIV1); - - rate = s3c2443_roundrate_clksrc16(clk, rate); - rate = parent_rate / rate; - - clkdivn &= ~S3C2443_CLKDIV1_UARTDIV_MASK; - clkdivn |= (rate - 1) << S3C2443_CLKDIV1_UARTDIV_SHIFT; - - __raw_writel(clkdivn, S3C2443_CLKDIV1); - return 0; -} - -static struct clk clk_uart = { - .name = "uartclk", - .id = -1, - .parent = &clk_esysclk, - .get_rate = s3c2443_getrate_uart, - .set_rate = s3c2443_setrate_uart, - .round_rate = s3c2443_roundrate_clksrc16, -}; - -/* hsspi - * - * high-speed spi clock, sourced from esysclk -*/ - -static unsigned long s3c2443_getrate_hsspi(struct clk *clk) -{ - unsigned long parent_rate = clk_get_rate(clk->parent); - unsigned long div = __raw_readl(S3C2443_CLKDIV1); - - div &= S3C2443_CLKDIV1_HSSPIDIV_MASK; - div >>= S3C2443_CLKDIV1_HSSPIDIV_SHIFT; - - return parent_rate / (div + 1); -} - - -static int s3c2443_setrate_hsspi(struct clk *clk, unsigned long rate) -{ - unsigned long parent_rate = clk_get_rate(clk->parent); - unsigned long clkdivn = __raw_readl(S3C2443_CLKDIV1); - - rate = s3c2443_roundrate_clksrc4(clk, rate); - rate = parent_rate / rate; - - clkdivn &= ~S3C2443_CLKDIV1_HSSPIDIV_MASK; - clkdivn |= (rate - 1) << S3C2443_CLKDIV1_HSSPIDIV_SHIFT; - - __raw_writel(clkdivn, S3C2443_CLKDIV1); - return 0; -} - -static struct clk clk_hsspi = { - .name = "hsspi", - .id = -1, - .parent = &clk_esysclk, - .ctrlbit = S3C2443_SCLKCON_HSSPICLK, - .enable = s3c2443_clkcon_enable_s, - .get_rate = s3c2443_getrate_hsspi, - .set_rate = s3c2443_setrate_hsspi, - .round_rate = s3c2443_roundrate_clksrc4, -}; - -/* usbhost - * - * usb host bus-clock, usually 48MHz to provide USB bus clock timing -*/ - -static unsigned long s3c2443_getrate_usbhost(struct clk *clk) -{ - unsigned long parent_rate = clk_get_rate(clk->parent); - unsigned long div = __raw_readl(S3C2443_CLKDIV1); - - div &= S3C2443_CLKDIV1_USBHOSTDIV_MASK; - div >>= S3C2443_CLKDIV1_USBHOSTDIV_SHIFT; - - return parent_rate / (div + 1); -} - -static int s3c2443_setrate_usbhost(struct clk *clk, unsigned long rate) -{ - unsigned long parent_rate = clk_get_rate(clk->parent); - unsigned long clkdivn = __raw_readl(S3C2443_CLKDIV1); - - rate = s3c2443_roundrate_clksrc4(clk, rate); - rate = parent_rate / rate; - - clkdivn &= ~S3C2443_CLKDIV1_USBHOSTDIV_MASK; - clkdivn |= (rate - 1) << S3C2443_CLKDIV1_USBHOSTDIV_SHIFT; - - __raw_writel(clkdivn, S3C2443_CLKDIV1); - return 0; -} - -struct clk clk_usb_bus_host = { - .name = "usb-bus-host-parent", - .id = -1, - .parent = &clk_esysclk, - .ctrlbit = S3C2443_SCLKCON_USBHOST, - .enable = s3c2443_clkcon_enable_s, - .get_rate = s3c2443_getrate_usbhost, - .set_rate = s3c2443_setrate_usbhost, - .round_rate = s3c2443_roundrate_clksrc4, -}; - -/* clk_hsmcc_div - * - * this clock is sourced from epll, and is fed through a divider, - * to a mux controlled by sclkcon where either it or a extclk can - * be fed to the hsmmc block -*/ - -static unsigned long s3c2443_getrate_hsmmc_div(struct clk *clk) -{ - unsigned long parent_rate = clk_get_rate(clk->parent); - unsigned long div = __raw_readl(S3C2443_CLKDIV1); - - div &= S3C2443_CLKDIV1_HSMMCDIV_MASK; - div >>= S3C2443_CLKDIV1_HSMMCDIV_SHIFT; - - return parent_rate / (div + 1); -} - -static int s3c2443_setrate_hsmmc_div(struct clk *clk, unsigned long rate) -{ - unsigned long parent_rate = clk_get_rate(clk->parent); - unsigned long clkdivn = __raw_readl(S3C2443_CLKDIV1); - - rate = s3c2443_roundrate_clksrc4(clk, rate); - rate = parent_rate / rate; - - clkdivn &= ~S3C2443_CLKDIV1_HSMMCDIV_MASK; - clkdivn |= (rate - 1) << S3C2443_CLKDIV1_HSMMCDIV_SHIFT; - - __raw_writel(clkdivn, S3C2443_CLKDIV1); - return 0; -} - -static struct clk clk_hsmmc_div = { - .name = "hsmmc-div", - .id = -1, - .parent = &clk_esysclk, - .get_rate = s3c2443_getrate_hsmmc_div, - .set_rate = s3c2443_setrate_hsmmc_div, - .round_rate = s3c2443_roundrate_clksrc4, -}; - -static int s3c2443_setparent_hsmmc(struct clk *clk, struct clk *parent) -{ - unsigned long clksrc = __raw_readl(S3C2443_SCLKCON); - - clksrc &= ~(S3C2443_SCLKCON_HSMMCCLK_EXT | - S3C2443_SCLKCON_HSMMCCLK_EPLL); - - if (parent == &clk_epll) - clksrc |= S3C2443_SCLKCON_HSMMCCLK_EPLL; - else if (parent == &clk_ext) - clksrc |= S3C2443_SCLKCON_HSMMCCLK_EXT; - else - return -EINVAL; - - if (clk->usage > 0) { - __raw_writel(clksrc, S3C2443_SCLKCON); - } - - clk->parent = parent; - return 0; -} - -static int s3c2443_enable_hsmmc(struct clk *clk, int enable) -{ - return s3c2443_setparent_hsmmc(clk, clk->parent); -} - -static struct clk clk_hsmmc = { - .name = "hsmmc-if", - .id = -1, - .parent = &clk_hsmmc_div, - .enable = s3c2443_enable_hsmmc, - .set_parent = s3c2443_setparent_hsmmc, -}; - -/* i2s_eplldiv - * - * this clock is the output from the i2s divisor of esysclk -*/ - -static unsigned long s3c2443_getrate_i2s_eplldiv(struct clk *clk) -{ - unsigned long parent_rate = clk_get_rate(clk->parent); - unsigned long div = __raw_readl(S3C2443_CLKDIV1); - - div &= S3C2443_CLKDIV1_I2SDIV_MASK; - div >>= S3C2443_CLKDIV1_I2SDIV_SHIFT; - - return parent_rate / (div + 1); -} - -static int s3c2443_setrate_i2s_eplldiv(struct clk *clk, unsigned long rate) -{ - unsigned long parent_rate = clk_get_rate(clk->parent); - unsigned long clkdivn = __raw_readl(S3C2443_CLKDIV1); - - rate = s3c2443_roundrate_clksrc16(clk, rate); - rate = parent_rate / rate; - - clkdivn &= ~S3C2443_CLKDIV1_I2SDIV_MASK; - clkdivn |= (rate - 1) << S3C2443_CLKDIV1_I2SDIV_SHIFT; - - __raw_writel(clkdivn, S3C2443_CLKDIV1); - return 0; -} - -static struct clk clk_i2s_eplldiv = { - .name = "i2s-eplldiv", - .id = -1, - .parent = &clk_esysclk, - .get_rate = s3c2443_getrate_i2s_eplldiv, - .set_rate = s3c2443_setrate_i2s_eplldiv, - .round_rate = s3c2443_roundrate_clksrc16, -}; - -/* i2s-ref - * - * i2s bus reference clock, selectable from external, esysclk or epllref -*/ - -static int s3c2443_setparent_i2s(struct clk *clk, struct clk *parent) -{ - unsigned long clksrc = __raw_readl(S3C2443_CLKSRC); - - clksrc &= ~S3C2443_CLKSRC_I2S_MASK; - - if (parent == &clk_epllref) - clksrc |= S3C2443_CLKSRC_I2S_EPLLREF; - else if (parent == &clk_i2s_ext) - clksrc |= S3C2443_CLKSRC_I2S_EXT; - else if (parent != &clk_i2s_eplldiv) - return -EINVAL; - - clk->parent = parent; - __raw_writel(clksrc, S3C2443_CLKSRC); - - return 0; -} - -static struct clk clk_i2s = { - .name = "i2s-if", - .id = -1, - .parent = &clk_i2s_eplldiv, - .ctrlbit = S3C2443_SCLKCON_I2SCLK, - .enable = s3c2443_clkcon_enable_s, - .set_parent = s3c2443_setparent_i2s, -}; - -/* cam-if - * - * camera interface bus-clock, divided down from esysclk -*/ - -static unsigned long s3c2443_getrate_cam(struct clk *clk) -{ - unsigned long parent_rate = clk_get_rate(clk->parent); - unsigned long div = __raw_readl(S3C2443_CLKDIV1); - - div &= S3C2443_CLKDIV1_CAMDIV_MASK; - div >>= S3C2443_CLKDIV1_CAMDIV_SHIFT; - - return parent_rate / (div + 1); -} - -static int s3c2443_setrate_cam(struct clk *clk, unsigned long rate) -{ - unsigned long parent_rate = clk_get_rate(clk->parent); - unsigned long clkdiv1 = __raw_readl(S3C2443_CLKDIV1); - - rate = s3c2443_roundrate_clksrc16(clk, rate); - rate = parent_rate / rate; - - clkdiv1 &= ~S3C2443_CLKDIV1_CAMDIV_MASK; - clkdiv1 |= (rate - 1) << S3C2443_CLKDIV1_CAMDIV_SHIFT; - - __raw_writel(clkdiv1, S3C2443_CLKDIV1); - return 0; -} - -static struct clk clk_cam = { - .name = "camif-upll", /* same as 2440 name */ - .id = -1, - .parent = &clk_esysclk, - .ctrlbit = S3C2443_SCLKCON_CAMCLK, - .enable = s3c2443_clkcon_enable_s, - .get_rate = s3c2443_getrate_cam, - .set_rate = s3c2443_setrate_cam, - .round_rate = s3c2443_roundrate_clksrc16, -}; - -/* display-if - * - * display interface clock, divided from esysclk -*/ - -static unsigned long s3c2443_getrate_display(struct clk *clk) -{ - unsigned long parent_rate = clk_get_rate(clk->parent); - unsigned long div = __raw_readl(S3C2443_CLKDIV1); - - div &= S3C2443_CLKDIV1_DISPDIV_MASK; - div >>= S3C2443_CLKDIV1_DISPDIV_SHIFT; - - return parent_rate / (div + 1); -} - -static int s3c2443_setrate_display(struct clk *clk, unsigned long rate) -{ - unsigned long parent_rate = clk_get_rate(clk->parent); - unsigned long clkdivn = __raw_readl(S3C2443_CLKDIV1); - - rate = s3c2443_roundrate_clksrc256(clk, rate); - rate = parent_rate / rate; - - clkdivn &= ~S3C2443_CLKDIV1_UARTDIV_MASK; - clkdivn |= (rate - 1) << S3C2443_CLKDIV1_UARTDIV_SHIFT; - - __raw_writel(clkdivn, S3C2443_CLKDIV1); - return 0; -} - -static struct clk clk_display = { - .name = "display-if", - .id = -1, - .parent = &clk_esysclk, - .ctrlbit = S3C2443_SCLKCON_DISPCLK, - .enable = s3c2443_clkcon_enable_s, - .get_rate = s3c2443_getrate_display, - .set_rate = s3c2443_setrate_display, - .round_rate = s3c2443_roundrate_clksrc256, -}; - -/* standard clock definitions */ - -static struct clk init_clocks_disable[] = { - { - .name = "nand", - .id = -1, - .parent = &clk_h, - }, { - .name = "sdi", - .id = -1, - .parent = &clk_p, - .enable = s3c2443_clkcon_enable_p, - .ctrlbit = S3C2443_PCLKCON_SDI, - }, { - .name = "adc", - .id = -1, - .parent = &clk_p, - .enable = s3c2443_clkcon_enable_p, - .ctrlbit = S3C2443_PCLKCON_ADC, - }, { - .name = "i2c", - .id = -1, - .parent = &clk_p, - .enable = s3c2443_clkcon_enable_p, - .ctrlbit = S3C2443_PCLKCON_IIC, - }, { - .name = "iis", - .id = -1, - .parent = &clk_p, - .enable = s3c2443_clkcon_enable_p, - .ctrlbit = S3C2443_PCLKCON_IIS, - }, { - .name = "spi", - .id = 0, - .parent = &clk_p, - .enable = s3c2443_clkcon_enable_p, - .ctrlbit = S3C2443_PCLKCON_SPI0, - }, { - .name = "spi", - .id = 1, - .parent = &clk_p, - .enable = s3c2443_clkcon_enable_p, - .ctrlbit = S3C2443_PCLKCON_SPI1, - } -}; - -static struct clk init_clocks[] = { - { - .name = "dma", - .id = 0, - .parent = &clk_h, - .enable = s3c2443_clkcon_enable_h, - .ctrlbit = S3C2443_HCLKCON_DMA0, - }, { - .name = "dma", - .id = 1, - .parent = &clk_h, - .enable = s3c2443_clkcon_enable_h, - .ctrlbit = S3C2443_HCLKCON_DMA1, - }, { - .name = "dma", - .id = 2, - .parent = &clk_h, - .enable = s3c2443_clkcon_enable_h, - .ctrlbit = S3C2443_HCLKCON_DMA2, - }, { - .name = "dma", - .id = 3, - .parent = &clk_h, - .enable = s3c2443_clkcon_enable_h, - .ctrlbit = S3C2443_HCLKCON_DMA3, - }, { - .name = "dma", - .id = 4, - .parent = &clk_h, - .enable = s3c2443_clkcon_enable_h, - .ctrlbit = S3C2443_HCLKCON_DMA4, - }, { - .name = "dma", - .id = 5, - .parent = &clk_h, - .enable = s3c2443_clkcon_enable_h, - .ctrlbit = S3C2443_HCLKCON_DMA5, - }, { - .name = "lcd", - .id = -1, - .parent = &clk_h, - .enable = s3c2443_clkcon_enable_h, - .ctrlbit = S3C2443_HCLKCON_LCDC, - }, { - .name = "gpio", - .id = -1, - .parent = &clk_p, - .enable = s3c2443_clkcon_enable_p, - .ctrlbit = S3C2443_PCLKCON_GPIO, - }, { - .name = "usb-host", - .id = -1, - .parent = &clk_h, - .enable = s3c2443_clkcon_enable_h, - .ctrlbit = S3C2443_HCLKCON_USBH, - }, { - .name = "usb-device", - .id = -1, - .parent = &clk_h, - .enable = s3c2443_clkcon_enable_h, - .ctrlbit = S3C2443_HCLKCON_USBD, - }, { - .name = "timers", - .id = -1, - .parent = &clk_p, - .enable = s3c2443_clkcon_enable_p, - .ctrlbit = S3C2443_PCLKCON_PWMT, - }, { - .name = "uart", - .id = 0, - .parent = &clk_p, - .enable = s3c2443_clkcon_enable_p, - .ctrlbit = S3C2443_PCLKCON_UART0, - }, { - .name = "uart", - .id = 1, - .parent = &clk_p, - .enable = s3c2443_clkcon_enable_p, - .ctrlbit = S3C2443_PCLKCON_UART1, - }, { - .name = "uart", - .id = 2, - .parent = &clk_p, - .enable = s3c2443_clkcon_enable_p, - .ctrlbit = S3C2443_PCLKCON_UART2, - }, { - .name = "uart", - .id = 3, - .parent = &clk_p, - .enable = s3c2443_clkcon_enable_p, - .ctrlbit = S3C2443_PCLKCON_UART3, - }, { - .name = "rtc", - .id = -1, - .parent = &clk_p, - .enable = s3c2443_clkcon_enable_p, - .ctrlbit = S3C2443_PCLKCON_RTC, - }, { - .name = "watchdog", - .id = -1, - .parent = &clk_p, - .ctrlbit = S3C2443_PCLKCON_WDT, - }, { - .name = "usb-bus-host", - .id = -1, - .parent = &clk_usb_bus_host, - } -}; - -/* clocks to add where we need to check their parentage */ - -/* s3c2443_clk_initparents - * - * Initialise the parents for the clocks that we get at start-time -*/ - -static int __init clk_init_set_parent(struct clk *clk, struct clk *parent) -{ - printk(KERN_DEBUG "clock %s: parent %s\n", clk->name, parent->name); - return clk_set_parent(clk, parent); -} - -static void __init s3c2443_clk_initparents(void) -{ - unsigned long clksrc = __raw_readl(S3C2443_CLKSRC); - struct clk *parent; - - switch (clksrc & S3C2443_CLKSRC_EPLLREF_MASK) { - case S3C2443_CLKSRC_EPLLREF_EXTCLK: - parent = &clk_ext; - break; - - case S3C2443_CLKSRC_EPLLREF_XTAL: - default: - parent = &clk_xtal; - break; - - case S3C2443_CLKSRC_EPLLREF_MPLLREF: - case S3C2443_CLKSRC_EPLLREF_MPLLREF2: - parent = &clk_mpllref; - break; - } - - clk_init_set_parent(&clk_epllref, parent); - - switch (clksrc & S3C2443_CLKSRC_I2S_MASK) { - case S3C2443_CLKSRC_I2S_EXT: - parent = &clk_i2s_ext; - break; - - case S3C2443_CLKSRC_I2S_EPLLDIV: - default: - parent = &clk_i2s_eplldiv; - break; - - case S3C2443_CLKSRC_I2S_EPLLREF: - case S3C2443_CLKSRC_I2S_EPLLREF3: - parent = &clk_epllref; - } - - clk_init_set_parent(&clk_i2s, &clk_epllref); - - /* esysclk source */ - - parent = (clksrc & S3C2443_CLKSRC_ESYSCLK_EPLL) ? - &clk_epll : &clk_epllref; - - clk_init_set_parent(&clk_esysclk, parent); - - /* msysclk source */ - - if (clksrc & S3C2443_CLKSRC_MSYSCLK_MPLL) { - parent = &clk_mpll; - } else { - parent = (clksrc & S3C2443_CLKSRC_EXTCLK_DIV) ? - &clk_mdivclk : &clk_mpllref; - } - - clk_init_set_parent(&clk_msysclk, parent); -} - -/* armdiv divisor table */ - -static unsigned int armdiv[16] = { - [S3C2443_CLKDIV0_ARMDIV_1 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 1, - [S3C2443_CLKDIV0_ARMDIV_2 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 2, - [S3C2443_CLKDIV0_ARMDIV_3 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 3, - [S3C2443_CLKDIV0_ARMDIV_4 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 4, - [S3C2443_CLKDIV0_ARMDIV_6 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 6, - [S3C2443_CLKDIV0_ARMDIV_8 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 8, - [S3C2443_CLKDIV0_ARMDIV_12 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 12, - [S3C2443_CLKDIV0_ARMDIV_16 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 16, -}; - -static inline unsigned int s3c2443_fclk_div(unsigned long clkcon0) -{ - clkcon0 &= S3C2443_CLKDIV0_ARMDIV_MASK; - - return armdiv[clkcon0 >> S3C2443_CLKDIV0_ARMDIV_SHIFT]; -} - -static inline unsigned long s3c2443_get_prediv(unsigned long clkcon0) -{ - clkcon0 &= S3C2443_CLKDIV0_PREDIV_MASK; - clkcon0 >>= S3C2443_CLKDIV0_PREDIV_SHIFT; - - return clkcon0 + 1; -} - -/* clocks to add straight away */ - -static struct clk *clks[] __initdata = { - &clk_ext, - &clk_epll, - &clk_usb_bus_host, - &clk_usb_bus, - &clk_esysclk, - &clk_epllref, - &clk_mpllref, - &clk_msysclk, - &clk_uart, - &clk_display, - &clk_cam, - &clk_i2s_eplldiv, - &clk_i2s, - &clk_hsspi, - &clk_hsmmc_div, - &clk_hsmmc, -}; - -void __init s3c2443_init_clocks(int xtal) -{ - unsigned long epllcon = __raw_readl(S3C2443_EPLLCON); - unsigned long mpllcon = __raw_readl(S3C2443_MPLLCON); - unsigned long clkdiv0 = __raw_readl(S3C2443_CLKDIV0); - unsigned long pll; - unsigned long fclk; - unsigned long hclk; - unsigned long pclk; - struct clk *clkp; - int ret; - int ptr; - - pll = s3c2443_get_mpll(mpllcon, xtal); - - fclk = pll / s3c2443_fclk_div(clkdiv0); - hclk = fclk / s3c2443_get_prediv(clkdiv0); - hclk = hclk / ((clkdiv0 & S3C2443_CLKDIV0_HALF_HCLK) ? 2 : 1); - pclk = hclk / ((clkdiv0 & S3C2443_CLKDIV0_HALF_PCLK) ? 2 : 1); - - s3c24xx_setup_clocks(xtal, fclk, hclk, pclk); - - printk("S3C2443: mpll %s %ld.%03ld MHz, cpu %ld.%03ld MHz, mem %ld.%03ld MHz, pclk %ld.%03ld MHz\n", - (mpllcon & S3C2443_PLLCON_OFF) ? "off":"on", - print_mhz(pll), print_mhz(fclk), - print_mhz(hclk), print_mhz(pclk)); - - s3c2443_clk_initparents(); - - for (ptr = 0; ptr < ARRAY_SIZE(clks); ptr++) { - clkp = clks[ptr]; - - ret = s3c24xx_register_clock(clkp); - if (ret < 0) { - printk(KERN_ERR "Failed to register clock %s (%d)\n", - clkp->name, ret); - } - } - - clk_epll.rate = s3c2443_get_epll(epllcon, xtal); - - clk_usb_bus.parent = &clk_usb_bus_host; - - /* ensure usb bus clock is within correct rate of 48MHz */ - - if (clk_get_rate(&clk_usb_bus_host) != (48 * 1000 * 1000)) { - printk(KERN_INFO "Warning: USB host bus not at 48MHz\n"); - clk_set_rate(&clk_usb_bus_host, 48*1000*1000); - } - - printk("S3C2443: epll %s %ld.%03ld MHz, usb-bus %ld.%03ld MHz\n", - (epllcon & S3C2443_PLLCON_OFF) ? "off":"on", - print_mhz(clk_get_rate(&clk_epll)), - print_mhz(clk_get_rate(&clk_usb_bus))); - - /* register clocks from clock array */ - - clkp = init_clocks; - for (ptr = 0; ptr < ARRAY_SIZE(init_clocks); ptr++, clkp++) { - ret = s3c24xx_register_clock(clkp); - if (ret < 0) { - printk(KERN_ERR "Failed to register clock %s (%d)\n", - clkp->name, ret); - } - } - - /* 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); - } - - (clkp->enable)(clkp, 0); - } -} diff --git a/trunk/arch/arm/mach-s3c2443/dma.c b/trunk/arch/arm/mach-s3c2443/dma.c deleted file mode 100644 index f70e8ccffc3d..000000000000 --- a/trunk/arch/arm/mach-s3c2443/dma.c +++ /dev/null @@ -1,180 +0,0 @@ -/* linux/arch/arm/mach-s3c2443/dma.c - * - * Copyright (c) 2007 Simtec Electronics - * Ben Dooks - * - * S3C2443 DMA selection - * - * http://armlinux.simtec.co.uk/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#define MAP(x) { \ - [0] = (x) | DMA_CH_VALID, \ - [1] = (x) | DMA_CH_VALID, \ - [2] = (x) | DMA_CH_VALID, \ - [3] = (x) | DMA_CH_VALID, \ - [4] = (x) | DMA_CH_VALID, \ - [5] = (x) | DMA_CH_VALID, \ - } - -static struct s3c24xx_dma_map __initdata s3c2443_dma_mappings[] = { - [DMACH_XD0] = { - .name = "xdreq0", - .channels = MAP(S3C2443_DMAREQSEL_XDREQ0), - }, - [DMACH_XD1] = { - .name = "xdreq1", - .channels = MAP(S3C2443_DMAREQSEL_XDREQ1), - }, - [DMACH_SDI] = { - .name = "sdi", - .channels = MAP(S3C2443_DMAREQSEL_SDI), - .hw_addr.to = S3C2410_PA_IIS + S3C2410_IISFIFO, - .hw_addr.from = S3C2410_PA_IIS + S3C2410_IISFIFO, - }, - [DMACH_SPI0] = { - .name = "spi0", - .channels = MAP(S3C2443_DMAREQSEL_SPI0TX), - .hw_addr.to = S3C2410_PA_SPI + S3C2410_SPTDAT, - .hw_addr.from = S3C2410_PA_SPI + S3C2410_SPRDAT, - }, - [DMACH_SPI1] = { - .name = "spi1", - .channels = MAP(S3C2443_DMAREQSEL_SPI1TX), - .hw_addr.to = S3C2410_PA_SPI + 0x20 + S3C2410_SPTDAT, - .hw_addr.from = S3C2410_PA_SPI + 0x20 + S3C2410_SPRDAT, - }, - [DMACH_UART0] = { - .name = "uart0", - .channels = MAP(S3C2443_DMAREQSEL_UART0_0), - .hw_addr.to = S3C2410_PA_UART0 + S3C2410_UTXH, - .hw_addr.from = S3C2410_PA_UART0 + S3C2410_URXH, - }, - [DMACH_UART1] = { - .name = "uart1", - .channels = MAP(S3C2443_DMAREQSEL_UART1_0), - .hw_addr.to = S3C2410_PA_UART1 + S3C2410_UTXH, - .hw_addr.from = S3C2410_PA_UART1 + S3C2410_URXH, - }, - [DMACH_UART2] = { - .name = "uart2", - .channels = MAP(S3C2443_DMAREQSEL_UART2_0), - .hw_addr.to = S3C2410_PA_UART2 + S3C2410_UTXH, - .hw_addr.from = S3C2410_PA_UART2 + S3C2410_URXH, - }, - [DMACH_UART3] = { - .name = "uart3", - .channels = MAP(S3C2443_DMAREQSEL_UART3_0), - .hw_addr.to = S3C2443_PA_UART3 + S3C2410_UTXH, - .hw_addr.from = S3C2443_PA_UART3 + S3C2410_URXH, - }, - [DMACH_UART0_SRC2] = { - .name = "uart0", - .channels = MAP(S3C2443_DMAREQSEL_UART0_1), - .hw_addr.to = S3C2410_PA_UART0 + S3C2410_UTXH, - .hw_addr.from = S3C2410_PA_UART0 + S3C2410_URXH, - }, - [DMACH_UART1_SRC2] = { - .name = "uart1", - .channels = MAP(S3C2443_DMAREQSEL_UART1_1), - .hw_addr.to = S3C2410_PA_UART1 + S3C2410_UTXH, - .hw_addr.from = S3C2410_PA_UART1 + S3C2410_URXH, - }, - [DMACH_UART2_SRC2] = { - .name = "uart2", - .channels = MAP(S3C2443_DMAREQSEL_UART2_1), - .hw_addr.to = S3C2410_PA_UART2 + S3C2410_UTXH, - .hw_addr.from = S3C2410_PA_UART2 + S3C2410_URXH, - }, - [DMACH_UART3_SRC2] = { - .name = "uart3", - .channels = MAP(S3C2443_DMAREQSEL_UART3_1), - .hw_addr.to = S3C2443_PA_UART3 + S3C2410_UTXH, - .hw_addr.from = S3C2443_PA_UART3 + S3C2410_URXH, - }, - [DMACH_TIMER] = { - .name = "timer", - .channels = MAP(S3C2443_DMAREQSEL_TIMER), - }, - [DMACH_I2S_IN] = { - .name = "i2s-sdi", - .channels = MAP(S3C2443_DMAREQSEL_I2SRX), - .hw_addr.from = S3C2410_PA_IIS + S3C2410_IISFIFO, - }, - [DMACH_I2S_OUT] = { - .name = "i2s-sdo", - .channels = MAP(S3C2443_DMAREQSEL_I2STX), - .hw_addr.to = S3C2410_PA_IIS + S3C2410_IISFIFO, - }, - [DMACH_PCM_IN] = { - .name = "pcm-in", - .channels = MAP(S3C2443_DMAREQSEL_PCMIN), - .hw_addr.from = S3C2440_PA_AC97 + S3C_AC97_PCM_DATA, - }, - [DMACH_PCM_OUT] = { - .name = "pcm-out", - .channels = MAP(S3C2443_DMAREQSEL_PCMOUT), - .hw_addr.to = S3C2440_PA_AC97 + S3C_AC97_PCM_DATA, - }, - [DMACH_MIC_IN] = { - .name = "mic-in", - .channels = MAP(S3C2443_DMAREQSEL_MICIN), - .hw_addr.from = S3C2440_PA_AC97 + S3C_AC97_MIC_DATA, - }, -}; - -static void s3c2443_dma_select(struct s3c2410_dma_chan *chan, - struct s3c24xx_dma_map *map) -{ - writel(map->channels[0] | S3C2443_DMAREQSEL_HW, - chan->regs + S3C2443_DMA_DMAREQSEL); -} - -static struct s3c24xx_dma_selection __initdata s3c2443_dma_sel = { - .select = s3c2443_dma_select, - .dcon_mask = 0, - .map = s3c2443_dma_mappings, - .map_size = ARRAY_SIZE(s3c2443_dma_mappings), -}; - -static int s3c2443_dma_add(struct sys_device *sysdev) -{ - s3c24xx_dma_init(6, IRQ_S3C2443_DMA0, 0x100); - return s3c24xx_dma_init_map(&s3c2443_dma_sel); -} - -static struct sysdev_driver s3c2443_dma_driver = { - .add = s3c2443_dma_add, -}; - -static int __init s3c2443_dma_init(void) -{ - return sysdev_driver_register(&s3c2443_sysclass, &s3c2443_dma_driver); -} - -arch_initcall(s3c2443_dma_init); diff --git a/trunk/arch/arm/mach-s3c2443/irq.c b/trunk/arch/arm/mach-s3c2443/irq.c deleted file mode 100644 index 7a45b6dcb73e..000000000000 --- a/trunk/arch/arm/mach-s3c2443/irq.c +++ /dev/null @@ -1,290 +0,0 @@ -/* linux/arch/arm/mach-s3c2443/irq.c - * - * Copyright (c) 2007 Simtec Electronics - * Ben Dooks - * - * 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 - -#define INTMSK(start, end) ((1 << ((end) + 1 - (start))) - 1) - -static inline void s3c2443_irq_demux(unsigned int irq, unsigned int len) -{ - unsigned int subsrc, submsk; - unsigned int end; - 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 >>= (irq - S3C2410_IRQSUB(0)); - subsrc &= (1 << len)-1; - - end = len + irq; - mydesc = irq_desc + irq; - - for (; irq < end && subsrc; irq++) { - if (subsrc & 1) - desc_handle_irq(irq, mydesc); - - mydesc++; - subsrc >>= 1; - } -} - -/* WDT/AC97 sub interrupts */ - -static void s3c2443_irq_demux_wdtac97(unsigned int irq, struct irq_desc *desc) -{ - s3c2443_irq_demux(IRQ_S3C2443_WDT, 4); -} - -#define INTMSK_WDTAC97 (1UL << (IRQ_WDT - IRQ_EINT0)) -#define SUBMSK_WDTAC97 INTMSK(IRQ_S3C2443_WDT, IRQ_S3C2443_AC97) - -static void s3c2443_irq_wdtac97_mask(unsigned int irqno) -{ - s3c_irqsub_mask(irqno, INTMSK_WDTAC97, SUBMSK_WDTAC97); -} - -static void s3c2443_irq_wdtac97_unmask(unsigned int irqno) -{ - s3c_irqsub_unmask(irqno, INTMSK_WDTAC97); -} - -static void s3c2443_irq_wdtac97_ack(unsigned int irqno) -{ - s3c_irqsub_maskack(irqno, INTMSK_WDTAC97, SUBMSK_WDTAC97); -} - -static struct irq_chip s3c2443_irq_wdtac97 = { - .mask = s3c2443_irq_wdtac97_mask, - .unmask = s3c2443_irq_wdtac97_unmask, - .ack = s3c2443_irq_wdtac97_ack, -}; - - -/* LCD sub interrupts */ - -static void s3c2443_irq_demux_lcd(unsigned int irq, struct irq_desc *desc) -{ - s3c2443_irq_demux(IRQ_S3C2443_LCD1, 4); -} - -#define INTMSK_LCD (1UL << (IRQ_LCD - IRQ_EINT0)) -#define SUBMSK_LCD INTMSK(IRQ_S3C2443_LCD1, IRQ_S3C2443_LCD4) - -static void s3c2443_irq_lcd_mask(unsigned int irqno) -{ - s3c_irqsub_mask(irqno, INTMSK_LCD, SUBMSK_LCD); -} - -static void s3c2443_irq_lcd_unmask(unsigned int irqno) -{ - s3c_irqsub_unmask(irqno, INTMSK_LCD); -} - -static void s3c2443_irq_lcd_ack(unsigned int irqno) -{ - s3c_irqsub_maskack(irqno, INTMSK_LCD, SUBMSK_LCD); -} - -static struct irq_chip s3c2443_irq_lcd = { - .mask = s3c2443_irq_lcd_mask, - .unmask = s3c2443_irq_lcd_unmask, - .ack = s3c2443_irq_lcd_ack, -}; - - -/* DMA sub interrupts */ - -static void s3c2443_irq_demux_dma(unsigned int irq, struct irq_desc *desc) -{ - s3c2443_irq_demux(IRQ_S3C2443_DMA1, 6); -} - -#define INTMSK_DMA (1UL << (IRQ_S3C2443_DMA - IRQ_EINT0)) -#define SUBMSK_DMA INTMSK(IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5) - - -static void s3c2443_irq_dma_mask(unsigned int irqno) -{ - s3c_irqsub_mask(irqno, INTMSK_DMA, SUBMSK_DMA); -} - -static void s3c2443_irq_dma_unmask(unsigned int irqno) -{ - s3c_irqsub_unmask(irqno, INTMSK_DMA); -} - -static void s3c2443_irq_dma_ack(unsigned int irqno) -{ - s3c_irqsub_maskack(irqno, INTMSK_DMA, SUBMSK_DMA); -} - -static struct irq_chip s3c2443_irq_dma = { - .mask = s3c2443_irq_dma_mask, - .unmask = s3c2443_irq_dma_unmask, - .ack = s3c2443_irq_dma_ack, -}; - - -/* UART3 sub interrupts */ - -static void s3c2443_irq_demux_uart3(unsigned int irq, struct irq_desc *desc) -{ - s3c2443_irq_demux(IRQ_S3C2443_UART3, 3); -} - -#define INTMSK_UART3 (1UL << (IRQ_S3C2443_UART3 - IRQ_EINT0)) -#define SUBMSK_UART3 (0xf << (IRQ_S3C2443_RX3 - S3C2410_IRQSUB(0))) - - -static void s3c2443_irq_uart3_mask(unsigned int irqno) -{ - s3c_irqsub_mask(irqno, INTMSK_UART3, SUBMSK_UART3); -} - -static void s3c2443_irq_uart3_unmask(unsigned int irqno) -{ - s3c_irqsub_unmask(irqno, INTMSK_UART3); -} - -static void s3c2443_irq_uart3_ack(unsigned int irqno) -{ - s3c_irqsub_maskack(irqno, INTMSK_UART3, SUBMSK_UART3); -} - -static struct irq_chip s3c2443_irq_uart3 = { - .mask = s3c2443_irq_uart3_mask, - .unmask = s3c2443_irq_uart3_unmask, - .ack = s3c2443_irq_uart3_ack, -}; - - -/* CAM sub interrupts */ - -static void s3c2443_irq_demux_cam(unsigned int irq, struct irq_desc *desc) -{ - s3c2443_irq_demux(IRQ_S3C2440_CAM_C, 4); -} - -#define INTMSK_CAM (1UL << (IRQ_CAM - IRQ_EINT0)) -#define SUBMSK_CAM INTMSK(IRQ_S3C2440_CAM_C, IRQ_S3C2440_CAM_P) - -static void s3c2443_irq_cam_mask(unsigned int irqno) -{ - s3c_irqsub_mask(irqno, INTMSK_CAM, SUBMSK_CAM); -} - -static void s3c2443_irq_cam_unmask(unsigned int irqno) -{ - s3c_irqsub_unmask(irqno, INTMSK_CAM); -} - -static void s3c2443_irq_cam_ack(unsigned int irqno) -{ - s3c_irqsub_maskack(irqno, INTMSK_CAM, SUBMSK_CAM); -} - -static struct irq_chip s3c2443_irq_cam = { - .mask = s3c2443_irq_cam_mask, - .unmask = s3c2443_irq_cam_unmask, - .ack = s3c2443_irq_cam_ack, -}; - -/* IRQ initialisation code */ - -static int __init s3c2443_add_sub(unsigned int base, - void (*demux)(unsigned int, - struct irq_desc *), - struct irq_chip *chip, - unsigned int start, unsigned int end) -{ - unsigned int irqno; - - set_irq_chip(base, &s3c_irq_level_chip); - set_irq_handler(base, handle_level_irq); - set_irq_chained_handler(base, demux); - - for (irqno = start; irqno <= end; irqno++) { - set_irq_chip(irqno, chip); - set_irq_handler(irqno, handle_level_irq); - set_irq_flags(irqno, IRQF_VALID); - } - - return 0; -} - -static int s3c2443_irq_add(struct sys_device *sysdev) -{ - printk("S3C2443: IRQ Support\n"); - - s3c2443_add_sub(IRQ_CAM, s3c2443_irq_demux_cam, &s3c2443_irq_cam, - IRQ_S3C2440_CAM_C, IRQ_S3C2440_CAM_P); - - s3c2443_add_sub(IRQ_LCD, s3c2443_irq_demux_lcd, &s3c2443_irq_lcd, - IRQ_S3C2443_LCD1, IRQ_S3C2443_LCD4); - - s3c2443_add_sub(IRQ_S3C2443_DMA, s3c2443_irq_demux_dma, - &s3c2443_irq_dma, IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5); - - s3c2443_add_sub(IRQ_S3C2443_UART3, s3c2443_irq_demux_uart3, - &s3c2443_irq_uart3, - IRQ_S3C2443_RX3, IRQ_S3C2443_ERR3); - - s3c2443_add_sub(IRQ_WDT, s3c2443_irq_demux_wdtac97, - &s3c2443_irq_wdtac97, - IRQ_S3C2443_WDT, IRQ_S3C2443_AC97); - - return 0; -} - -static struct sysdev_driver s3c2443_irq_driver = { - .add = s3c2443_irq_add, -}; - -static int s3c2443_irq_init(void) -{ - return sysdev_driver_register(&s3c2443_sysclass, &s3c2443_irq_driver); -} - -arch_initcall(s3c2443_irq_init); - diff --git a/trunk/arch/arm/mach-s3c2443/mach-smdk2443.c b/trunk/arch/arm/mach-s3c2443/mach-smdk2443.c deleted file mode 100644 index e82aaff7dee4..000000000000 --- a/trunk/arch/arm/mach-s3c2443/mach-smdk2443.c +++ /dev/null @@ -1,137 +0,0 @@ -/* linux/arch/arm/mach-s3c2443/mach-smdk2443.c - * - * Copyright (c) 2007 Simtec Electronics - * Ben Dooks - * - * http://www.fluff.org/ben/smdk2443/ - * - * Thanks to Samsung for the loan of an SMDK2443 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * -*/ - -#include -#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 smdk2443_iodesc[] __initdata = { - /* ISA IO Space map (memory space selected by A24) */ - - { - .virtual = (u32)S3C24XX_VA_ISA_WORD, - .pfn = __phys_to_pfn(S3C2410_CS2), - .length = 0x10000, - .type = MT_DEVICE, - }, { - .virtual = (u32)S3C24XX_VA_ISA_WORD + 0x10000, - .pfn = __phys_to_pfn(S3C2410_CS2 + (1<<24)), - .length = SZ_4M, - .type = MT_DEVICE, - }, { - .virtual = (u32)S3C24XX_VA_ISA_BYTE, - .pfn = __phys_to_pfn(S3C2410_CS2), - .length = 0x10000, - .type = MT_DEVICE, - }, { - .virtual = (u32)S3C24XX_VA_ISA_BYTE + 0x10000, - .pfn = __phys_to_pfn(S3C2410_CS2 + (1<<24)), - .length = SZ_4M, - .type = MT_DEVICE, - } -}; - -#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK -#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB -#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE - -static struct s3c2410_uartcfg smdk2443_uartcfgs[] __initdata = { - [0] = { - .hwport = 0, - .flags = 0, - .ucon = 0x3c5, - .ulcon = 0x03, - .ufcon = 0x51, - }, - [1] = { - .hwport = 1, - .flags = 0, - .ucon = 0x3c5, - .ulcon = 0x03, - .ufcon = 0x51, - }, - /* IR port */ - [2] = { - .hwport = 2, - .flags = 0, - .ucon = 0x3c5, - .ulcon = 0x43, - .ufcon = 0x51, - } -}; - -static struct platform_device *smdk2443_devices[] __initdata = { - &s3c_device_wdt, - &s3c_device_i2c, -}; - -static struct s3c24xx_board smdk2443_board __initdata = { - .devices = smdk2443_devices, - .devices_count = ARRAY_SIZE(smdk2443_devices) -}; - -static void __init smdk2443_map_io(void) -{ - s3c24xx_init_io(smdk2443_iodesc, ARRAY_SIZE(smdk2443_iodesc)); - s3c24xx_init_clocks(12000000); - s3c24xx_init_uarts(smdk2443_uartcfgs, ARRAY_SIZE(smdk2443_uartcfgs)); - s3c24xx_set_board(&smdk2443_board); -} - -static void __init smdk2443_machine_init(void) -{ - smdk_machine_init(); -} - -MACHINE_START(SMDK2443, "SMDK2443") - /* Maintainer: Ben Dooks */ - .phys_io = S3C2410_PA_UART, - .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, - .boot_params = S3C2410_SDRAM_PA + 0x100, - - .init_irq = s3c24xx_init_irq, - .map_io = smdk2443_map_io, - .init_machine = smdk2443_machine_init, - .timer = &s3c24xx_timer, -MACHINE_END diff --git a/trunk/arch/arm/mach-s3c2443/s3c2443.c b/trunk/arch/arm/mach-s3c2443/s3c2443.c deleted file mode 100644 index 11b1d0b310c3..000000000000 --- a/trunk/arch/arm/mach-s3c2443/s3c2443.c +++ /dev/null @@ -1,97 +0,0 @@ -/* linux/arch/arm/mach-s3c2443/s3c2443.c - * - * Copyright (c) 2007 Simtec Electronics - * Ben Dooks - * - * Samsung S3C2443 Mobile CPU support - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include - -#include -#include - -#include -#include -#include - -static struct map_desc s3c2443_iodesc[] __initdata = { - IODESC_ENT(WATCHDOG), - IODESC_ENT(CLKPWR), - IODESC_ENT(TIMER), -}; - -struct sysdev_class s3c2443_sysclass = { - set_kset_name("s3c2443-core"), -}; - -static struct sys_device s3c2443_sysdev = { - .cls = &s3c2443_sysclass, -}; - -static void s3c2443_hard_reset(void) -{ - __raw_writel(S3C2443_SWRST_RESET, S3C2443_SWRST); -} - -int __init s3c2443_init(void) -{ - printk("S3C2443: Initialising architecture\n"); - - s3c24xx_reset_hook = s3c2443_hard_reset; - - s3c_device_nand.name = "s3c2412-nand"; - - return sysdev_register(&s3c2443_sysdev); -} - -void __init s3c2443_init_uarts(struct s3c2410_uartcfg *cfg, int no) -{ - s3c24xx_init_uartdevs("s3c2440-uart", s3c2410_uart_resources, cfg, no); -} - -/* s3c2443_map_io - * - * register the standard cpu IO areas, and any passed in from the - * machine specific initialisation. - */ - -void __init s3c2443_map_io(struct map_desc *mach_desc, int mach_size) -{ - iotable_init(s3c2443_iodesc, ARRAY_SIZE(s3c2443_iodesc)); - iotable_init(mach_desc, mach_size); -} - -/* need to register class before we actually register the device, and - * we also need to ensure that it has been initialised before any of the - * drivers even try to use it (even if not on an s3c2443 based system) - * as a driver which may support both 2443 and 2440 may try and use it. -*/ - -static int __init s3c2443_core_init(void) -{ - return sysdev_class_register(&s3c2443_sysclass); -} - -core_initcall(s3c2443_core_init); diff --git a/trunk/arch/arm/plat-s3c24xx/Kconfig b/trunk/arch/arm/plat-s3c24xx/Kconfig deleted file mode 100644 index e22343160634..000000000000 --- a/trunk/arch/arm/plat-s3c24xx/Kconfig +++ /dev/null @@ -1,99 +0,0 @@ -# arch/arm/plat-s3c24xx/Kconfig -# -# Copyright 2007 Simtec Electronics -# -# Licensed under GPLv2 - -config PLAT_S3C24XX - bool - depends on ARCH_S3C2410 - default y if ARCH_S3C2410 - help - Base platform code for any Samsung S3C device - -if PLAT_S3C24XX - -config CPU_S3C244X - bool - depends on ARCH_S3C2410 && (CPU_S3C2440 || CPU_S3C2442) - help - Support for S3C2440 and S3C2442 Samsung Mobile CPU based systems. - -config PM_SIMTEC - bool - help - Common power management code for systems that are - compatible with the Simtec style of power management - -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. - -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. - -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 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. - -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. - -config MACH_SMDK - bool - help - Common machine code for SMDK2410 and SMDK2440 - -endif diff --git a/trunk/arch/arm/plat-s3c24xx/Makefile b/trunk/arch/arm/plat-s3c24xx/Makefile deleted file mode 100644 index 8e5ccaa1f03c..000000000000 --- a/trunk/arch/arm/plat-s3c24xx/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -# arch/arm/plat-s3c24xx/Makefile -# -# Copyright 2007 Simtec Electronics -# -# Licensed under GPLv2 - -obj-y := -obj-m := -obj-n := -obj- := - - -# Core files - -obj-y += cpu.o -obj-y += irq.o -obj-y += devs.o -obj-y += gpio.o -obj-y += time.o -obj-y += clock.o - -# Architecture dependant builds - -obj-$(CONFIG_CPU_S3C244X) += s3c244x.o -obj-$(CONFIG_CPU_S3C244X) += s3c244x-irq.o -obj-$(CONFIG_PM_SIMTEC) += pm-simtec.o -obj-$(CONFIG_PM) += pm.o -obj-$(CONFIG_PM) += sleep.o -obj-$(CONFIG_S3C2410_DMA) += dma.o -obj-$(CONFIG_MACH_SMDK) += common-smdk.o diff --git a/trunk/arch/arm/plat-s3c24xx/clock.c b/trunk/arch/arm/plat-s3c24xx/clock.c deleted file mode 100644 index d3dc03a7383a..000000000000 --- a/trunk/arch/arm/plat-s3c24xx/clock.c +++ /dev/null @@ -1,449 +0,0 @@ -/* linux/arch/arm/plat-s3c24xx/clock.c - * - * Copyright (c) 2004-2005 Simtec Electronics - * Ben Dooks - * - * 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 - * 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 - -/* clock information */ - -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) -{ - return 0; -} - -/* Clock API calls */ - -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 - 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; - } - } - } - - mutex_unlock(&clocks_mutex); - return clk; -} - -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; -} - -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) -{ - 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) - dclkcon |= clk->ctrlbit; - else - dclkcon &= ~clk->ctrlbit; - - __raw_writel(dclkcon, S3C24XX_DCLKCON); - - return 0; -} - -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; -} - - -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, -}; - -struct clk s3c24xx_dclk1 = { - .name = "dclk1", - .id = -1, - .ctrlbit = S3C2410_DCLKCON_DCLK0EN, - .enable = s3c24xx_dclk_enable, - .set_parent = s3c24xx_dclk_setparent, -}; - -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 s3c24xx_register_clock(struct clk *clk) -{ - clk->owner = THIS_MODULE; - - if (clk->enable == NULL) - clk->enable = clk_null_enable; - - /* add to the list of available clocks */ - - mutex_lock(&clocks_mutex); - list_add(&clk->list, &clocks); - mutex_unlock(&clocks_mutex); - - return 0; -} - -/* initalise all the clocks */ - -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"); - - /* initialise the main system clocks */ - - 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"); - - if (s3c24xx_register_clock(&clk_f) < 0) - printk(KERN_ERR "failed to register cpu fclk\n"); - - if (s3c24xx_register_clock(&clk_h) < 0) - printk(KERN_ERR "failed to register cpu hclk\n"); - - if (s3c24xx_register_clock(&clk_p) < 0) - printk(KERN_ERR "failed to register cpu pclk\n"); - - return 0; -} diff --git a/trunk/arch/arm/plat-s3c24xx/dma.c b/trunk/arch/arm/plat-s3c24xx/dma.c deleted file mode 100644 index 4540a806f522..000000000000 --- a/trunk/arch/arm/plat-s3c24xx/dma.c +++ /dev/null @@ -1,1499 +0,0 @@ -/* linux/arch/arm/plat-s3c24xx/dma.c - * - * Copyright (c) 2003-2005,2006 Simtec Electronics - * Ben Dooks - * - * S3C2410 DMA core - * - * http://armlinux.simtec.co.uk/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - - -#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 - -/* io map for dma */ -static void __iomem *dma_base; -static struct kmem_cache *dma_kmem; - -static int dma_channels; - -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) -{ - pr_debug("writing %08x to register %08x\n",(unsigned int)val,reg); - writel(val, dma_regaddr(chan, reg)); -} -#endif - -#define dma_rdreg(chan, reg) readl((chan)->regs + (reg)) - -/* captured register state for debug */ - -struct s3c2410_dma_regstate { - unsigned long dcsrc; - unsigned long disrc; - unsigned long dstat; - unsigned long dcon; - unsigned long dmsktrig; -}; - -#ifdef CONFIG_S3C2410_DMA_DEBUG - -/* dmadbg_showregs - * - * simple debug routine to print the current state of the dma registers -*/ - -static void -dmadbg_capture(struct s3c2410_dma_chan *chan, struct s3c2410_dma_regstate *regs) -{ - regs->dcsrc = dma_rdreg(chan, S3C2410_DMA_DCSRC); - regs->disrc = dma_rdreg(chan, S3C2410_DMA_DISRC); - regs->dstat = dma_rdreg(chan, S3C2410_DMA_DSTAT); - regs->dcon = dma_rdreg(chan, S3C2410_DMA_DCON); - regs->dmsktrig = dma_rdreg(chan, S3C2410_DMA_DMASKTRIG); -} - -static void -dmadbg_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 struct s3c2410_dma_chan *lookup_dma_channel(unsigned int channel) -{ - 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; -} - -/* 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 (chan->callback_fn != NULL) { - (chan->callback_fn)(chan, buf->id, buf->size, result); - } -} - -/* s3c2410_dma_start - * - * start a dma channel going -*/ - -static int s3c2410_dma_start(struct s3c2410_dma_chan *chan) -{ - unsigned long tmp; - unsigned long flags; - - pr_debug("s3c2410_start_dma: channel=%d\n", chan->number); - - local_irq_save(flags); - - if (chan->state == S3C2410_DMA_RUNNING) { - pr_debug("s3c2410_start_dma: already running (%d)\n", chan->state); - local_irq_restore(flags); - return 0; - } - - chan->state = S3C2410_DMA_RUNNING; - - /* check wether there is anything to load, and if not, see - * if we can find anything to load - */ - - if (chan->load_state == S3C2410_DMALOAD_NONE) { - if (chan->next == NULL) { - printk(KERN_ERR "dma%d: channel has nothing loaded\n", - chan->number); - chan->state = S3C2410_DMA_IDLE; - local_irq_restore(flags); - return -EINVAL; - } - - s3c2410_dma_loadbuffer(chan, chan->next); - } - - dbg_showchan(chan); - - /* enable the channel */ - - if (!chan->irq_enabled) { - enable_irq(chan->irq); - chan->irq_enabled = 1; - } - - /* start the channel going */ - - tmp = dma_rdreg(chan, S3C2410_DMA_DMASKTRIG); - tmp &= ~S3C2410_DMASKTRIG_STOP; - tmp |= S3C2410_DMASKTRIG_ON; - dma_wrreg(chan, S3C2410_DMA_DMASKTRIG, tmp); - - pr_debug("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; -} - -/* 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 */ - -int __init s3c24xx_dma_sysclass_init(void) -{ - int ret = sysdev_class_register(&dma_sysclass); - - if (ret != 0) - printk(KERN_ERR "dma sysclass registration failed\n"); - - return ret; -} - -core_initcall(s3c24xx_dma_sysclass_init); - -int __init s3c24xx_dma_sysdev_register(void) -{ - struct s3c2410_dma_chan *cp = s3c2410_chans; - int channel, ret; - - for (channel = 0; channel < dma_channels; cp++, channel++) { - cp->dev.cls = &dma_sysclass; - cp->dev.id = channel; - ret = sysdev_register(&cp->dev); - - if (ret) { - printk(KERN_ERR "error registering dev for dma %d\n", - channel); - return ret; - } - } - - return 0; -} - -late_initcall(s3c24xx_dma_sysdev_register); - -int __init s3c24xx_dma_init(unsigned int channels, unsigned int irq, - unsigned int stride) -{ - struct s3c2410_dma_chan *cp; - int channel; - int ret; - - printk("S3C24XX DMA Driver, (c) 2003-2004,2006 Simtec Electronics\n"); - - dma_channels = channels; - - dma_base = ioremap(S3C24XX_PA_DMA, stride * channels); - if (dma_base == NULL) { - printk(KERN_ERR "dma failed to remap register block\n"); - return -ENOMEM; - } - - 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 < 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; - cp->regs = dma_base + (channel * stride); - - /* point current stats somewhere */ - cp->stats = &cp->stats_store; - cp->stats_store.timeout_shortest = LONG_MAX; - - /* basic channel configuration */ - - cp->load_timeout = 1<<18; - - printk("DMA channel %d at %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; -} - -int s3c2410_dma_init(void) -{ - return s3c24xx_dma_init(4, IRQ_DMA0, 0x40); -} - -static inline int is_channel_valid(unsigned int channel) -{ - return (channel & DMA_CH_VALID); -} - -static struct s3c24xx_dma_order *dma_order; - - -/* s3c2410_dma_map_channel() - * - * turn the virtual channel number into a real, and un-used hardware - * channel. - * - * first, try the dma ordering given to us by either the relevant - * dma code, or the board. Then just find the first usable free - * channel -*/ - -struct s3c2410_dma_chan *s3c2410_dma_map_channel(int channel) -{ - struct s3c24xx_dma_order_ch *ord = NULL; - 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; - - /* first, try the board mapping */ - - if (dma_order) { - ord = &dma_order->channels[channel]; - - for (ch = 0; ch < dma_channels; ch++) { - if (!is_channel_valid(ord->list[ch])) - continue; - - if (s3c2410_chans[ord->list[ch]].in_use == 0) { - ch = ord->list[ch] & ~DMA_CH_VALID; - goto found; - } - } - - if (ord->flags & DMA_CH_NEVER) - return NULL; - } - - /* second, search the channel map for first free */ - - for (ch = 0; ch < 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 >= dma_channels) - return NULL; - - /* update our channel mapping */ - - found: - dmach = &s3c2410_chans[ch]; - dma_chan_map[channel] = dmach; - - /* select the channel */ - - (dma_sel.select)(dmach, ch_map); - - return dmach; -} - -static int s3c24xx_dma_check_entry(struct s3c24xx_dma_map *map, int 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; -} - -int __init s3c24xx_dma_order_set(struct s3c24xx_dma_order *ord) -{ - struct s3c24xx_dma_order *nord = dma_order; - - if (nord == NULL) - nord = kmalloc(sizeof(struct s3c24xx_dma_order), GFP_KERNEL); - - if (nord == NULL) { - printk(KERN_ERR "no memory to store dma channel order\n"); - return -ENOMEM; - } - - dma_order = nord; - memcpy(nord, ord, sizeof(struct s3c24xx_dma_order)); - return 0; -} diff --git a/trunk/arch/arm/plat-s3c24xx/gpio.c b/trunk/arch/arm/plat-s3c24xx/gpio.c deleted file mode 100644 index ec3a09c4d181..000000000000 --- a/trunk/arch/arm/plat-s3c24xx/gpio.c +++ /dev/null @@ -1,188 +0,0 @@ -/* linux/arch/arm/plat-s3c24xx/gpio.c - * - * Copyright (c) 2004-2005 Simtec Electronics - * Ben Dooks - * - * 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 - * 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 - -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 *base = S3C24XX_GPIO_BASE(pin); - unsigned long offs = S3C2410_GPIO_OFFSET(pin); - unsigned long flags; - 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); - - local_irq_restore(flags); -} - -EXPORT_SYMBOL(s3c2410_gpio_pullup); - -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); - - 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); - - return __raw_readl(base + 0x04) & (1<< offs); -} - -EXPORT_SYMBOL(s3c2410_gpio_getpin); - -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 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_getirq); diff --git a/trunk/arch/arm/plat-s3c24xx/irq.c b/trunk/arch/arm/plat-s3c24xx/irq.c deleted file mode 100644 index ce186398e3fd..000000000000 --- a/trunk/arch/arm/plat-s3c24xx/irq.c +++ /dev/null @@ -1,801 +0,0 @@ -/* linux/arch/arm/plat-s3c24xx/irq.c - * - * Copyright (c) 2003,2004 Simtec Electronics - * Ben Dooks - * - * 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 - * - * 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 -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -#include -#include - -#include -#include -#include - -/* 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; - - 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 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< - * - * S3C24XX Power Manager (Suspend-To-RAM) support - * - * See Documentation/arm/Samsung-S3C24XX/Suspend.txt for more information - * - * 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 - * - * Parts based on arch/arm/mach-pxa/pm.c - * - * Thanks to Dimitry Andric for debugging -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include - -#include - -#include - -/* for external use */ - -unsigned long s3c_pm_flags; - -#define PFX "s3c24xx-pm: " - -static struct sleep_save core_save[] = { - SAVE_ITEM(S3C2410_LOCKTIME), - SAVE_ITEM(S3C2410_CLKCON), - - /* we restore the timings here, with the proviso that the board - * brings the system up in an slower, or equal frequency setting - * to the original system. - * - * if we cannot guarantee this, then things are going to go very - * wrong here, as we modify the refresh and both pll settings. - */ - - SAVE_ITEM(S3C2410_BWSCON), - SAVE_ITEM(S3C2410_BANKCON0), - SAVE_ITEM(S3C2410_BANKCON1), - SAVE_ITEM(S3C2410_BANKCON2), - SAVE_ITEM(S3C2410_BANKCON3), - SAVE_ITEM(S3C2410_BANKCON4), - SAVE_ITEM(S3C2410_BANKCON5), - - SAVE_ITEM(S3C2410_CLKDIVN), - SAVE_ITEM(S3C2410_MPLLCON), - SAVE_ITEM(S3C2410_UPLLCON), - SAVE_ITEM(S3C2410_CLKSLOW), - SAVE_ITEM(S3C2410_REFRESH), -}; - -static struct sleep_save gpio_save[] = { - SAVE_ITEM(S3C2410_GPACON), - SAVE_ITEM(S3C2410_GPADAT), - - SAVE_ITEM(S3C2410_GPBCON), - SAVE_ITEM(S3C2410_GPBDAT), - SAVE_ITEM(S3C2410_GPBUP), - - SAVE_ITEM(S3C2410_GPCCON), - SAVE_ITEM(S3C2410_GPCDAT), - SAVE_ITEM(S3C2410_GPCUP), - - SAVE_ITEM(S3C2410_GPDCON), - SAVE_ITEM(S3C2410_GPDDAT), - SAVE_ITEM(S3C2410_GPDUP), - - SAVE_ITEM(S3C2410_GPECON), - SAVE_ITEM(S3C2410_GPEDAT), - SAVE_ITEM(S3C2410_GPEUP), - - SAVE_ITEM(S3C2410_GPFCON), - SAVE_ITEM(S3C2410_GPFDAT), - SAVE_ITEM(S3C2410_GPFUP), - - SAVE_ITEM(S3C2410_GPGCON), - SAVE_ITEM(S3C2410_GPGDAT), - SAVE_ITEM(S3C2410_GPGUP), - - SAVE_ITEM(S3C2410_GPHCON), - SAVE_ITEM(S3C2410_GPHDAT), - SAVE_ITEM(S3C2410_GPHUP), - - SAVE_ITEM(S3C2410_DCLKCON), -}; - -#ifdef CONFIG_S3C2410_PM_DEBUG - -#define SAVE_UART(va) \ - SAVE_ITEM((va) + S3C2410_ULCON), \ - SAVE_ITEM((va) + S3C2410_UCON), \ - SAVE_ITEM((va) + S3C2410_UFCON), \ - SAVE_ITEM((va) + S3C2410_UMCON), \ - SAVE_ITEM((va) + S3C2410_UBRDIV) - -static struct sleep_save uart_save[] = { - SAVE_UART(S3C24XX_VA_UART0), - SAVE_UART(S3C24XX_VA_UART1), -#ifndef CONFIG_CPU_S3C2400 - SAVE_UART(S3C24XX_VA_UART2), -#endif -}; - -/* debug - * - * we send the debug to printascii() to allow it to be seen if the - * system never wakes up from the sleep -*/ - -extern void printascii(const char *); - -void pm_dbg(const char *fmt, ...) -{ - va_list va; - char buff[256]; - - va_start(va, fmt); - vsprintf(buff, fmt, va); - va_end(va); - - printascii(buff); -} - -static void s3c2410_pm_debug_init(void) -{ - unsigned long tmp = __raw_readl(S3C2410_CLKCON); - - /* re-start uart clocks */ - tmp |= S3C2410_CLKCON_UART0; - tmp |= S3C2410_CLKCON_UART1; - tmp |= S3C2410_CLKCON_UART2; - - __raw_writel(tmp, S3C2410_CLKCON); - udelay(10); -} - -#define DBG(fmt...) pm_dbg(fmt) -#else -#define DBG(fmt...) printk(KERN_DEBUG fmt) - -#define s3c2410_pm_debug_init() do { } while(0) - -static struct sleep_save uart_save[] = {}; -#endif - -#if defined(CONFIG_S3C2410_PM_CHECK) && CONFIG_S3C2410_PM_CHECK_CHUNKSIZE != 0 - -/* suspend checking code... - * - * this next area does a set of crc checks over all the installed - * memory, so the system can verify if the resume was ok. - * - * CONFIG_S3C2410_PM_CHECK_CHUNKSIZE defines the block-size for the CRC, - * increasing it will mean that the area corrupted will be less easy to spot, - * and reducing the size will cause the CRC save area to grow -*/ - -#define CHECK_CHUNKSIZE (CONFIG_S3C2410_PM_CHECK_CHUNKSIZE * 1024) - -static u32 crc_size; /* size needed for the crc block */ -static u32 *crcs; /* allocated over suspend/resume */ - -typedef u32 *(run_fn_t)(struct resource *ptr, u32 *arg); - -/* s3c2410_pm_run_res - * - * go thorugh the given resource list, and look for system ram -*/ - -static void s3c2410_pm_run_res(struct resource *ptr, run_fn_t fn, u32 *arg) -{ - while (ptr != NULL) { - if (ptr->child != NULL) - s3c2410_pm_run_res(ptr->child, fn, arg); - - if ((ptr->flags & IORESOURCE_MEM) && - strcmp(ptr->name, "System RAM") == 0) { - DBG("Found system RAM at %08lx..%08lx\n", - ptr->start, ptr->end); - arg = (fn)(ptr, arg); - } - - ptr = ptr->sibling; - } -} - -static void s3c2410_pm_run_sysram(run_fn_t fn, u32 *arg) -{ - s3c2410_pm_run_res(&iomem_resource, fn, arg); -} - -static u32 *s3c2410_pm_countram(struct resource *res, u32 *val) -{ - u32 size = (u32)(res->end - res->start)+1; - - size += CHECK_CHUNKSIZE-1; - size /= CHECK_CHUNKSIZE; - - DBG("Area %08lx..%08lx, %d blocks\n", res->start, res->end, size); - - *val += size * sizeof(u32); - return val; -} - -/* s3c2410_pm_prepare_check - * - * prepare the necessary information for creating the CRCs. This - * must be done before the final save, as it will require memory - * allocating, and thus touching bits of the kernel we do not - * know about. -*/ - -static void s3c2410_pm_check_prepare(void) -{ - crc_size = 0; - - s3c2410_pm_run_sysram(s3c2410_pm_countram, &crc_size); - - DBG("s3c2410_pm_prepare_check: %u checks needed\n", crc_size); - - crcs = kmalloc(crc_size+4, GFP_KERNEL); - if (crcs == NULL) - printk(KERN_ERR "Cannot allocated CRC save area\n"); -} - -static u32 *s3c2410_pm_makecheck(struct resource *res, u32 *val) -{ - unsigned long addr, left; - - for (addr = res->start; addr < res->end; - addr += CHECK_CHUNKSIZE) { - left = res->end - addr; - - if (left > CHECK_CHUNKSIZE) - left = CHECK_CHUNKSIZE; - - *val = crc32_le(~0, phys_to_virt(addr), left); - val++; - } - - return val; -} - -/* s3c2410_pm_check_store - * - * compute the CRC values for the memory blocks before the final - * sleep. -*/ - -static void s3c2410_pm_check_store(void) -{ - if (crcs != NULL) - s3c2410_pm_run_sysram(s3c2410_pm_makecheck, crcs); -} - -/* in_region - * - * return TRUE if the area defined by ptr..ptr+size contatins the - * what..what+whatsz -*/ - -static inline int in_region(void *ptr, int size, void *what, size_t whatsz) -{ - if ((what+whatsz) < ptr) - return 0; - - if (what > (ptr+size)) - return 0; - - return 1; -} - -static u32 *s3c2410_pm_runcheck(struct resource *res, u32 *val) -{ - void *save_at = phys_to_virt(s3c2410_sleep_save_phys); - unsigned long addr; - unsigned long left; - void *ptr; - u32 calc; - - for (addr = res->start; addr < res->end; - addr += CHECK_CHUNKSIZE) { - left = res->end - addr; - - if (left > CHECK_CHUNKSIZE) - left = CHECK_CHUNKSIZE; - - ptr = phys_to_virt(addr); - - if (in_region(ptr, left, crcs, crc_size)) { - DBG("skipping %08lx, has crc block in\n", addr); - goto skip_check; - } - - if (in_region(ptr, left, save_at, 32*4 )) { - DBG("skipping %08lx, has save block in\n", addr); - goto skip_check; - } - - /* calculate and check the checksum */ - - calc = crc32_le(~0, ptr, left); - if (calc != *val) { - printk(KERN_ERR PFX "Restore CRC error at " - "%08lx (%08x vs %08x)\n", addr, calc, *val); - - DBG("Restore CRC error at %08lx (%08x vs %08x)\n", - addr, calc, *val); - } - - skip_check: - val++; - } - - return val; -} - -/* s3c2410_pm_check_restore - * - * check the CRCs after the restore event and free the memory used - * to hold them -*/ - -static void s3c2410_pm_check_restore(void) -{ - if (crcs != NULL) { - s3c2410_pm_run_sysram(s3c2410_pm_runcheck, crcs); - kfree(crcs); - crcs = NULL; - } -} - -#else - -#define s3c2410_pm_check_prepare() do { } while(0) -#define s3c2410_pm_check_restore() do { } while(0) -#define s3c2410_pm_check_store() do { } while(0) -#endif - -/* helper functions to save and restore register state */ - -void s3c2410_pm_do_save(struct sleep_save *ptr, int count) -{ - for (; count > 0; count--, ptr++) { - ptr->val = __raw_readl(ptr->reg); - DBG("saved %p value %08lx\n", ptr->reg, ptr->val); - } -} - -/* s3c2410_pm_do_restore - * - * restore the system from the given list of saved registers - * - * Note, we do not use DBG() in here, as the system may not have - * restore the UARTs state yet -*/ - -void s3c2410_pm_do_restore(struct sleep_save *ptr, int count) -{ - for (; count > 0; count--, ptr++) { - printk(KERN_DEBUG "restore %p (restore %08lx, was %08x)\n", - ptr->reg, ptr->val, __raw_readl(ptr->reg)); - - __raw_writel(ptr->val, ptr->reg); - } -} - -/* s3c2410_pm_do_restore_core - * - * similar to s3c2410_pm_do_restore_core - * - * WARNING: Do not put any debug in here that may effect memory or use - * peripherals, as things may be changing! -*/ - -static void s3c2410_pm_do_restore_core(struct sleep_save *ptr, int count) -{ - for (; count > 0; count--, ptr++) { - __raw_writel(ptr->val, ptr->reg); - } -} - -/* s3c2410_pm_show_resume_irqs - * - * print any IRQs asserted at resume time (ie, we woke from) -*/ - -static void s3c2410_pm_show_resume_irqs(int start, unsigned long which, - unsigned long mask) -{ - int i; - - which &= ~mask; - - for (i = 0; i <= 31; i++) { - if ((which) & (1L< - * - * S3C2410 Power Manager (Suspend-To-RAM) support - * - * Based on PXA/SA1100 sleep code by: - * Nicolas Pitre, (c) 2002 Monta Vista Software Inc - * Cliff Brake, (c) 2001 - * - * 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 - -/* CONFIG_DEBUG_RESUME is dangerous if your bootloader does not - * reset the UART configuration, only enable if you really need this! -*/ -//#define CONFIG_DEBUG_RESUME - - .text - - /* s3c2410_cpu_save - * - * save enough of the CPU state to allow us to re-start - * pm.c code. as we store items like the sp/lr, we will - * end up returning from this function when the cpu resumes - * so the return value is set to mark this. - * - * This arangement means we avoid having to flush the cache - * from this code. - * - * entry: - * r0 = pointer to save block - * - * exit: - * r0 = 0 => we stored everything - * 1 => resumed from sleep - */ - -ENTRY(s3c2410_cpu_save) - stmfd sp!, { r4 - r12, lr } - - @@ store co-processor registers - - mrc p15, 0, r4, c13, c0, 0 @ PID - mrc p15, 0, r5, c3, c0, 0 @ Domain ID - mrc p15, 0, r6, c2, c0, 0 @ translation table base address - mrc p15, 0, r7, c1, c0, 0 @ control register - - stmia r0, { r4 - r13 } - - mov r0, #0 - ldmfd sp, { r4 - r12, pc } - - @@ return to the caller, after having the MMU - @@ turned on, this restores the last bits from the - @@ stack -resume_with_mmu: - mov r0, #1 - ldmfd sp!, { r4 - r12, pc } - - .ltorg - - @@ the next bits sit in the .data segment, even though they - @@ happen to be code... the s3c2410_sleep_save_phys needs to be - @@ accessed by the resume code before it can restore the MMU. - @@ This means that the variable has to be close enough for the - @@ code to read it... since the .text segment needs to be RO, - @@ the data segment can be the only place to put this code. - - .data - - .global s3c2410_sleep_save_phys -s3c2410_sleep_save_phys: - .word 0 - - /* s3c2410_cpu_resume - * - * resume code entry for bootloader to call - * - * we must put this code here in the data segment as we have no - * other way of restoring the stack pointer after sleep, and we - * must not write to the code segment (code is read-only) - */ - -ENTRY(s3c2410_cpu_resume) - mov r0, #PSR_I_BIT | PSR_F_BIT | SVC_MODE - msr cpsr_c, r0 - - @@ load UART to allow us to print the two characters for - @@ resume debug - - mov r2, #S3C24XX_PA_UART & 0xff000000 - orr r2, r2, #S3C24XX_PA_UART & 0xff000 - -#if 0 - /* SMDK2440 LED set */ - mov r14, #S3C24XX_PA_GPIO - ldr r12, [ r14, #0x54 ] - bic r12, r12, #3<<4 - orr r12, r12, #1<<7 - str r12, [ r14, #0x54 ] -#endif - -#ifdef CONFIG_DEBUG_RESUME - mov r3, #'L' - strb r3, [ r2, #S3C2410_UTXH ] -1001: - ldrb r14, [ r3, #S3C2410_UTRSTAT ] - tst r14, #S3C2410_UTRSTAT_TXE - beq 1001b -#endif /* CONFIG_DEBUG_RESUME */ - - mov r1, #0 - mcr p15, 0, r1, c8, c7, 0 @@ invalidate I & D TLBs - mcr p15, 0, r1, c7, c7, 0 @@ invalidate I & D caches - - ldr r0, s3c2410_sleep_save_phys @ address of restore block - ldmia r0, { r4 - r13 } - - mcr p15, 0, r4, c13, c0, 0 @ PID - mcr p15, 0, r5, c3, c0, 0 @ Domain ID - mcr p15, 0, r6, c2, c0, 0 @ translation table base - -#ifdef CONFIG_DEBUG_RESUME - mov r3, #'R' - strb r3, [ r2, #S3C2410_UTXH ] -#endif - - ldr r2, =resume_with_mmu - mcr p15, 0, r7, c1, c0, 0 @ turn on MMU, etc - nop @ second-to-last before mmu - mov pc, r2 @ go back to virtual address - - .ltorg diff --git a/trunk/include/asm-arm/arch-s3c2410/dma.h b/trunk/include/asm-arm/arch-s3c2410/dma.h index c6e8d8f64938..58ffa7ba3c88 100644 --- a/trunk/include/asm-arm/arch-s3c2410/dma.h +++ b/trunk/include/asm-arm/arch-s3c2410/dma.h @@ -51,19 +51,13 @@ enum dma_ch { DMACH_UART0_SRC2, /* s3c2412 second uart sources */ DMACH_UART1_SRC2, DMACH_UART2_SRC2, - DMACH_UART3, /* s3c2443 has extra uart */ - DMACH_UART3_SRC2, DMACH_MAX, /* the end entry */ }; #define DMACH_LOW_LEVEL (1<<28) /* use this to specifiy hardware ch no */ /* we have 4 dma channels */ -#ifndef CONFIG_CPU_S3C2443 -#define S3C2410_DMA_CHANNELS (4) -#else -#define S3C2410_DMA_CHANNELS (6) -#endif +#define S3C2410_DMA_CHANNELS (4) /* types */ @@ -327,7 +321,6 @@ extern int s3c2410_dma_set_buffdone_fn(dmach_t, s3c2410_dma_cbfn_t rtn); #define S3C2410_DMA_DCDST (0x1C) #define S3C2410_DMA_DMASKTRIG (0x20) #define S3C2412_DMA_DMAREQSEL (0x24) -#define S3C2443_DMA_DMAREQSEL (0x24) #define S3C2410_DISRCC_INC (1<<0) #define S3C2410_DISRCC_APB (1<<1) @@ -422,31 +415,4 @@ extern int s3c2410_dma_set_buffdone_fn(dmach_t, s3c2410_dma_cbfn_t rtn); #define S3C2412_DMAREQSEL_UART2_1 S3C2412_DMAREQSEL_SRC(24) #endif - -#define S3C2443_DMAREQSEL_SRC(x) ((x)<<1) - -#define S3C2443_DMAREQSEL_HW (1) - -#define S3C2443_DMAREQSEL_SPI0TX S3C2443_DMAREQSEL_SRC(0) -#define S3C2443_DMAREQSEL_SPI0RX S3C2443_DMAREQSEL_SRC(1) -#define S3C2443_DMAREQSEL_SPI1TX S3C2443_DMAREQSEL_SRC(2) -#define S3C2443_DMAREQSEL_SPI1RX S3C2443_DMAREQSEL_SRC(3) -#define S3C2443_DMAREQSEL_I2STX S3C2443_DMAREQSEL_SRC(4) -#define S3C2443_DMAREQSEL_I2SRX S3C2443_DMAREQSEL_SRC(5) -#define S3C2443_DMAREQSEL_TIMER S3C2443_DMAREQSEL_SRC(9) -#define S3C2443_DMAREQSEL_SDI S3C2443_DMAREQSEL_SRC(10) -#define S3C2443_DMAREQSEL_XDREQ0 S3C2443_DMAREQSEL_SRC(17) -#define S3C2443_DMAREQSEL_XDREQ1 S3C2443_DMAREQSEL_SRC(18) -#define S3C2443_DMAREQSEL_UART0_0 S3C2443_DMAREQSEL_SRC(19) -#define S3C2443_DMAREQSEL_UART0_1 S3C2443_DMAREQSEL_SRC(20) -#define S3C2443_DMAREQSEL_UART1_0 S3C2443_DMAREQSEL_SRC(21) -#define S3C2443_DMAREQSEL_UART1_1 S3C2443_DMAREQSEL_SRC(22) -#define S3C2443_DMAREQSEL_UART2_0 S3C2443_DMAREQSEL_SRC(23) -#define S3C2443_DMAREQSEL_UART2_1 S3C2443_DMAREQSEL_SRC(24) -#define S3C2443_DMAREQSEL_UART3_0 S3C2443_DMAREQSEL_SRC(25) -#define S3C2443_DMAREQSEL_UART3_1 S3C2443_DMAREQSEL_SRC(26) -#define S3C2443_DMAREQSEL_PCMOUT S3C2443_DMAREQSEL_SRC(27) -#define S3C2443_DMAREQSEL_PCMIN S3C2443_DMAREQSEL_SRC(28) -#define S3C2443_DMAREQSEL_MICIN S3C2443_DMAREQSEL_SRC(29) - #endif /* __ASM_ARCH_DMA_H */ diff --git a/trunk/include/asm-arm/arch-s3c2410/irqs.h b/trunk/include/asm-arm/arch-s3c2410/irqs.h index c79cb1819913..4b7cff456c4e 100644 --- a/trunk/include/asm-arm/arch-s3c2410/irqs.h +++ b/trunk/include/asm-arm/arch-s3c2410/irqs.h @@ -34,10 +34,10 @@ #define IRQ_EINT4t7 S3C2410_IRQ(4) /* 20 */ #define IRQ_EINT8t23 S3C2410_IRQ(5) #define IRQ_RESERVED6 S3C2410_IRQ(6) /* for s3c2410 */ -#define IRQ_CAM S3C2410_IRQ(6) /* for s3c2440,s3c2443 */ +#define IRQ_CAM S3C2410_IRQ(6) /* for s3c2440 */ #define IRQ_BATT_FLT S3C2410_IRQ(7) #define IRQ_TICK S3C2410_IRQ(8) /* 24 */ -#define IRQ_WDT S3C2410_IRQ(9) /* WDT/AC97 for s3c2443 */ +#define IRQ_WDT S3C2410_IRQ(9) #define IRQ_TIMER0 S3C2410_IRQ(10) #define IRQ_TIMER1 S3C2410_IRQ(11) #define IRQ_TIMER2 S3C2410_IRQ(12) @@ -45,7 +45,7 @@ #define IRQ_TIMER4 S3C2410_IRQ(14) #define IRQ_UART2 S3C2410_IRQ(15) #define IRQ_LCD S3C2410_IRQ(16) /* 32 */ -#define IRQ_DMA0 S3C2410_IRQ(17) /* IRQ_DMA for s3c2443 */ +#define IRQ_DMA0 S3C2410_IRQ(17) #define IRQ_DMA1 S3C2410_IRQ(18) #define IRQ_DMA2 S3C2410_IRQ(19) #define IRQ_DMA3 S3C2410_IRQ(20) @@ -94,63 +94,29 @@ * these need to be ordered in number of appearance in the * SUBSRC mask register */ +#define IRQ_S3CUART_RX0 S3C2410_IRQ(54) /* 70 */ +#define IRQ_S3CUART_TX0 S3C2410_IRQ(55) /* 71 */ +#define IRQ_S3CUART_ERR0 S3C2410_IRQ(56) -#define S3C2410_IRQSUB(x) S3C2410_IRQ((x)+54) +#define IRQ_S3CUART_RX1 S3C2410_IRQ(57) +#define IRQ_S3CUART_TX1 S3C2410_IRQ(58) +#define IRQ_S3CUART_ERR1 S3C2410_IRQ(59) -#define IRQ_S3CUART_RX0 S3C2410_IRQSUB(0) /* 70 */ -#define IRQ_S3CUART_TX0 S3C2410_IRQSUB(1) -#define IRQ_S3CUART_ERR0 S3C2410_IRQSUB(2) +#define IRQ_S3CUART_RX2 S3C2410_IRQ(60) +#define IRQ_S3CUART_TX2 S3C2410_IRQ(61) +#define IRQ_S3CUART_ERR2 S3C2410_IRQ(62) -#define IRQ_S3CUART_RX1 S3C2410_IRQSUB(3) /* 73 */ -#define IRQ_S3CUART_TX1 S3C2410_IRQSUB(4) -#define IRQ_S3CUART_ERR1 S3C2410_IRQSUB(5) - -#define IRQ_S3CUART_RX2 S3C2410_IRQSUB(6) /* 76 */ -#define IRQ_S3CUART_TX2 S3C2410_IRQSUB(7) -#define IRQ_S3CUART_ERR2 S3C2410_IRQSUB(8) - -#define IRQ_TC S3C2410_IRQSUB(9) -#define IRQ_ADC S3C2410_IRQSUB(10) +#define IRQ_TC S3C2410_IRQ(63) +#define IRQ_ADC S3C2410_IRQ(64) /* extra irqs for s3c2440 */ -#define IRQ_S3C2440_CAM_C S3C2410_IRQSUB(11) /* S3C2443 too */ -#define IRQ_S3C2440_CAM_P S3C2410_IRQSUB(12) /* S3C2443 too */ -#define IRQ_S3C2440_WDT S3C2410_IRQSUB(13) -#define IRQ_S3C2440_AC97 S3C2410_IRQSUB(14) - -/* irqs for s3c2443 */ - -#define IRQ_S3C2443_DMA S3C2410_IRQ(17) /* IRQ_DMA1 */ -#define IRQ_S3C2443_UART3 S3C2410_IRQ(18) /* IRQ_DMA2 */ -#define IRQ_S3C2443_CFCON S3C2410_IRQ(19) /* IRQ_DMA3 */ -#define IRQ_S3C2443_SDI1 S3C2410_IRQ(20) /* IRQ_SDI */ -#define IRQ_S3C2443_NAND S3C2410_IRQ(24) /* reserved */ - -#define IRQ_S3C2443_LCD1 S3C2410_IRQSUB(14) -#define IRQ_S3C2443_LCD2 S3C2410_IRQSUB(15) -#define IRQ_S3C2443_LCD3 S3C2410_IRQSUB(16) -#define IRQ_S3C2443_LCD4 S3C2410_IRQSUB(17) - -#define IRQ_S3C2443_DMA0 S3C2410_IRQSUB(18) -#define IRQ_S3C2443_DMA1 S3C2410_IRQSUB(19) -#define IRQ_S3C2443_DMA2 S3C2410_IRQSUB(20) -#define IRQ_S3C2443_DMA3 S3C2410_IRQSUB(21) -#define IRQ_S3C2443_DMA4 S3C2410_IRQSUB(22) -#define IRQ_S3C2443_DMA5 S3C2410_IRQSUB(23) - -/* UART3 */ -#define IRQ_S3C2443_RX3 S3C2410_IRQSUB(24) -#define IRQ_S3C2443_TX3 S3C2410_IRQSUB(25) -#define IRQ_S3C2443_ERR3 S3C2410_IRQSUB(26) - -#define IRQ_S3C2443_WDT S3C2410_IRQSUB(27) -#define IRQ_S3C2443_AC97 S3C2410_IRQSUB(28) - -#ifdef CONFIG_CPU_S3C2443 -#define NR_IRQS (IRQ_S3C2443_AC97+1) -#else +#define IRQ_S3C2440_CAM_C S3C2410_IRQ(65) +#define IRQ_S3C2440_CAM_P S3C2410_IRQ(66) +#define IRQ_S3C2440_WDT S3C2410_IRQ(67) +#define IRQ_S3C2440_AC97 S3C2410_IRQ(68) + #define NR_IRQS (IRQ_S3C2440_AC97+1) -#endif + #endif /* __ASM_ARCH_IRQ_H */ diff --git a/trunk/include/asm-arm/arch-s3c2410/regs-adc.h b/trunk/include/asm-arm/arch-s3c2410/regs-adc.h index c7f231963e76..3196a2849e8a 100644 --- a/trunk/include/asm-arm/arch-s3c2410/regs-adc.h +++ b/trunk/include/asm-arm/arch-s3c2410/regs-adc.h @@ -41,7 +41,7 @@ #define S3C2410_ADCTSC_XP_SEN (1<<4) #define S3C2410_ADCTSC_PULL_UP_DISABLE (1<<3) #define S3C2410_ADCTSC_AUTO_PST (1<<2) -#define S3C2410_ADCTSC_XY_PST(x) (((x)&0x3)<<0) +#define S3C2410_ADCTSC_XY_PST (0x3<<0) /* ADCDAT0 Bits */ #define S3C2410_ADCDAT0_UPDOWN (1<<15) diff --git a/trunk/include/asm-arm/arch-s3c2410/regs-gpio.h b/trunk/include/asm-arm/arch-s3c2410/regs-gpio.h index dea578b8f7f6..eae91694edcd 100644 --- a/trunk/include/asm-arm/arch-s3c2410/regs-gpio.h +++ b/trunk/include/asm-arm/arch-s3c2410/regs-gpio.h @@ -201,7 +201,7 @@ #define S3C2400_GPBDAT S3C2410_GPIOREG(0x0C) #define S3C2400_GPBUP S3C2410_GPIOREG(0x10) -/* no i/o pin in port b can have value 3 (unless it is a s3c2443) ! */ +/* no i/o pin in port b can have value 3! */ #define S3C2410_GPB0 S3C2410_GPIONO(S3C2410_GPIO_BANKB, 0) #define S3C2410_GPB0_INP (0x00 << 0) @@ -242,7 +242,6 @@ #define S3C2410_GPB5_INP (0x00 << 10) #define S3C2410_GPB5_OUTP (0x01 << 10) #define S3C2410_GPB5_nXBACK (0x02 << 10) -#define S3C2443_GPB5_XBACK (0x03 << 10) #define S3C2400_GPB5_DATA21 (0x02 << 10) #define S3C2400_GPB5_nCTS1 (0x03 << 10) @@ -250,7 +249,6 @@ #define S3C2410_GPB6_INP (0x00 << 12) #define S3C2410_GPB6_OUTP (0x01 << 12) #define S3C2410_GPB6_nXBREQ (0x02 << 12) -#define S3C2443_GPB6_XBREQ (0x03 << 12) #define S3C2400_GPB6_DATA22 (0x02 << 12) #define S3C2400_GPB6_nRTS1 (0x03 << 12) @@ -258,7 +256,6 @@ #define S3C2410_GPB7_INP (0x00 << 14) #define S3C2410_GPB7_OUTP (0x01 << 14) #define S3C2410_GPB7_nXDACK1 (0x02 << 14) -#define S3C2443_GPB7_XDACK1 (0x03 << 14) #define S3C2400_GPB7_DATA23 (0x02 << 14) #define S3C2410_GPB8 S3C2410_GPIONO(S3C2410_GPIO_BANKB, 8) @@ -271,7 +268,6 @@ #define S3C2410_GPB9_INP (0x00 << 18) #define S3C2410_GPB9_OUTP (0x01 << 18) #define S3C2410_GPB9_nXDACK0 (0x02 << 18) -#define S3C2443_GPB9_XDACK0 (0x03 << 18) #define S3C2400_GPB9_DATA25 (0x02 << 18) #define S3C2400_GPB9_I2SSDI (0x03 << 18) @@ -279,7 +275,6 @@ #define S3C2410_GPB10_INP (0x00 << 20) #define S3C2410_GPB10_OUTP (0x01 << 20) #define S3C2410_GPB10_nXDRE0 (0x02 << 20) -#define S3C2443_GPB10_XDREQ0 (0x03 << 20) #define S3C2400_GPB10_DATA26 (0x02 << 20) #define S3C2400_GPB10_nSS (0x03 << 20) @@ -561,7 +556,6 @@ #define S3C2410_GPE0_INP (0x00 << 0) #define S3C2410_GPE0_OUTP (0x01 << 0) #define S3C2410_GPE0_I2SLRCK (0x02 << 0) -#define S3C2443_GPE0_AC_nRESET (0x03 << 0) #define S3C2400_GPE0_EINT0 (0x02 << 0) #define S3C2410_GPE0_MASK (0x03 << 0) @@ -569,7 +563,6 @@ #define S3C2410_GPE1_INP (0x00 << 2) #define S3C2410_GPE1_OUTP (0x01 << 2) #define S3C2410_GPE1_I2SSCLK (0x02 << 2) -#define S3C2443_GPE1_AC_SYNC (0x03 << 2) #define S3C2400_GPE1_EINT1 (0x02 << 2) #define S3C2400_GPE1_nSS (0x03 << 2) #define S3C2410_GPE1_MASK (0x03 << 2) @@ -578,7 +571,6 @@ #define S3C2410_GPE2_INP (0x00 << 4) #define S3C2410_GPE2_OUTP (0x01 << 4) #define S3C2410_GPE2_CDCLK (0x02 << 4) -#define S3C2443_GPE2_AC_BITCLK (0x03 << 4) #define S3C2400_GPE2_EINT2 (0x02 << 4) #define S3C2400_GPE2_I2SSDI (0x03 << 4) @@ -586,7 +578,6 @@ #define S3C2410_GPE3_INP (0x00 << 6) #define S3C2410_GPE3_OUTP (0x01 << 6) #define S3C2410_GPE3_I2SSDI (0x02 << 6) -#define S3C2443_GPE3_AC_SDI (0x03 << 6) #define S3C2400_GPE3_EINT3 (0x02 << 6) #define S3C2400_GPE3_nCTS1 (0x03 << 6) #define S3C2410_GPE3_nSS0 (0x03 << 6) @@ -596,7 +587,6 @@ #define S3C2410_GPE4_INP (0x00 << 8) #define S3C2410_GPE4_OUTP (0x01 << 8) #define S3C2410_GPE4_I2SSDO (0x02 << 8) -#define S3C2443_GPE4_AC_SDO (0x03 << 8) #define S3C2400_GPE4_EINT4 (0x02 << 8) #define S3C2400_GPE4_nRTS1 (0x03 << 8) #define S3C2410_GPE4_I2SSDI (0x03 << 8) @@ -606,7 +596,6 @@ #define S3C2410_GPE5_INP (0x00 << 10) #define S3C2410_GPE5_OUTP (0x01 << 10) #define S3C2410_GPE5_SDCLK (0x02 << 10) -#define S3C2443_GPE5_SD1_CLK (0x02 << 10) #define S3C2400_GPE5_EINT5 (0x02 << 10) #define S3C2400_GPE5_TCLK1 (0x03 << 10) @@ -614,32 +603,24 @@ #define S3C2410_GPE6_INP (0x00 << 12) #define S3C2410_GPE6_OUTP (0x01 << 12) #define S3C2410_GPE6_SDCMD (0x02 << 12) -#define S3C2443_GPE6_SD1_CMD (0x02 << 12) -#define S3C2443_GPE6_AC_BITCLK (0x03 << 12) #define S3C2400_GPE6_EINT6 (0x02 << 12) #define S3C2410_GPE7 S3C2410_GPIONO(S3C2410_GPIO_BANKE, 7) #define S3C2410_GPE7_INP (0x00 << 14) #define S3C2410_GPE7_OUTP (0x01 << 14) #define S3C2410_GPE7_SDDAT0 (0x02 << 14) -#define S3C2443_GPE5_SD1_DAT0 (0x02 << 14) -#define S3C2443_GPE7_AC_SDI (0x03 << 14) #define S3C2400_GPE7_EINT7 (0x02 << 14) #define S3C2410_GPE8 S3C2410_GPIONO(S3C2410_GPIO_BANKE, 8) #define S3C2410_GPE8_INP (0x00 << 16) #define S3C2410_GPE8_OUTP (0x01 << 16) #define S3C2410_GPE8_SDDAT1 (0x02 << 16) -#define S3C2443_GPE8_SD1_DAT1 (0x02 << 16) -#define S3C2443_GPE8_AC_SDO (0x03 << 16) #define S3C2400_GPE8_nXDACK0 (0x02 << 16) #define S3C2410_GPE9 S3C2410_GPIONO(S3C2410_GPIO_BANKE, 9) #define S3C2410_GPE9_INP (0x00 << 18) #define S3C2410_GPE9_OUTP (0x01 << 18) #define S3C2410_GPE9_SDDAT2 (0x02 << 18) -#define S3C2443_GPE9_SD1_DAT2 (0x02 << 18) -#define S3C2443_GPE9_AC_SYNC (0x03 << 18) #define S3C2400_GPE9_nXDACK1 (0x02 << 18) #define S3C2400_GPE9_nXBACK (0x03 << 18) @@ -647,8 +628,6 @@ #define S3C2410_GPE10_INP (0x00 << 20) #define S3C2410_GPE10_OUTP (0x01 << 20) #define S3C2410_GPE10_SDDAT3 (0x02 << 20) -#define S3C2443_GPE10_SD1_DAT3 (0x02 << 20) -#define S3C2443_GPE10_AC_nRESET (0x03 << 20) #define S3C2400_GPE10_nXDREQ0 (0x02 << 20) #define S3C2410_GPE11 S3C2410_GPIONO(S3C2410_GPIO_BANKE, 11) @@ -817,7 +796,6 @@ #define S3C2400_GPG4_MMCCLK (0x02 << 8) #define S3C2400_GPG4_I2SSDI (0x03 << 8) #define S3C2410_GPG4_LCDPWREN (0x03 << 8) -#define S3C2443_GPG4_LCDPWRDN (0x03 << 8) #define S3C2410_GPG5 S3C2410_GPIONO(S3C2410_GPIO_BANKG, 5) #define S3C2410_GPG5_INP (0x00 << 10) @@ -825,7 +803,7 @@ #define S3C2410_GPG5_EINT13 (0x02 << 10) #define S3C2400_GPG5_MMCCMD (0x02 << 10) #define S3C2400_GPG5_IICSDA (0x03 << 10) -#define S3C2410_GPG5_SPIMISO1 (0x03 << 10) /* not s3c2443 */ +#define S3C2410_GPG5_SPIMISO1 (0x03 << 10) #define S3C2410_GPG6 S3C2410_GPIONO(S3C2410_GPIO_BANKG, 6) #define S3C2410_GPG6_INP (0x00 << 12) @@ -867,7 +845,6 @@ #define S3C2410_GPG11_OUTP (0x01 << 22) #define S3C2410_GPG11_EINT19 (0x02 << 22) #define S3C2410_GPG11_TCLK1 (0x03 << 22) -#define S3C2443_GPG11_CF_nIREQ (0x03 << 22) #define S3C2410_GPG12 S3C2410_GPIONO(S3C2410_GPIO_BANKG, 12) #define S3C2410_GPG12_INP (0x00 << 24) @@ -875,28 +852,25 @@ #define S3C2410_GPG12_EINT20 (0x02 << 24) #define S3C2410_GPG12_XMON (0x03 << 24) #define S3C2442_GPG12_nSPICS0 (0x03 << 24) -#define S3C2443_GPG12_nINPACK (0x03 << 24) #define S3C2410_GPG13 S3C2410_GPIONO(S3C2410_GPIO_BANKG, 13) #define S3C2410_GPG13_INP (0x00 << 26) #define S3C2410_GPG13_OUTP (0x01 << 26) #define S3C2410_GPG13_EINT21 (0x02 << 26) #define S3C2410_GPG13_nXPON (0x03 << 26) -#define S3C2443_GPG13_CF_nREG (0x03 << 26) #define S3C2410_GPG14 S3C2410_GPIONO(S3C2410_GPIO_BANKG, 14) #define S3C2410_GPG14_INP (0x00 << 28) #define S3C2410_GPG14_OUTP (0x01 << 28) #define S3C2410_GPG14_EINT22 (0x02 << 28) #define S3C2410_GPG14_YMON (0x03 << 28) -#define S3C2443_GPG14_CF_RESET (0x03 << 28) #define S3C2410_GPG15 S3C2410_GPIONO(S3C2410_GPIO_BANKG, 15) #define S3C2410_GPG15_INP (0x00 << 30) #define S3C2410_GPG15_OUTP (0x01 << 30) #define S3C2410_GPG15_EINT23 (0x02 << 30) #define S3C2410_GPG15_nYPON (0x03 << 30) -#define S3C2443_GPG15_CF_PWR (0x03 << 30) + #define S3C2410_GPG_PUPDIS(x) (1<<(x)) diff --git a/trunk/include/asm-arm/arch-s3c2410/regs-s3c2443-clock.h b/trunk/include/asm-arm/arch-s3c2410/regs-s3c2443-clock.h deleted file mode 100644 index ff0536d2de42..000000000000 --- a/trunk/include/asm-arm/arch-s3c2410/regs-s3c2443-clock.h +++ /dev/null @@ -1,194 +0,0 @@ -/* linux/include/asm-arm/arch-s3c2410/regs-clock.h - * - * Copyright (c) 2007 Simtec Electronics - * Ben Dooks - * http://armlinux.simtec.co.uk/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * S3C2443 clock register definitions -*/ - -#ifndef __ASM_ARM_REGS_S3C2443_CLOCK -#define __ASM_ARM_REGS_S3C2443_CLOCK - -#define S3C2443_CLKREG(x) ((x) + S3C24XX_VA_CLKPWR) - -#define S3C2443_PLLCON_MDIVSHIFT 16 -#define S3C2443_PLLCON_PDIVSHIFT 8 -#define S3C2443_PLLCON_SDIVSHIFT 0 -#define S3C2443_PLLCON_MDIVMASK ((1<<(1+(23-16)))-1) -#define S3C2443_PLLCON_PDIVMASK ((1<<(1+(9-8)))-1) -#define S3C2443_PLLCON_SDIVMASK (3) - -#define S3C2443_MPLLCON S3C2443_CLKREG(0x10) -#define S3C2443_EPLLCON S3C2443_CLKREG(0x18) -#define S3C2443_CLKSRC S3C2443_CLKREG(0x20) -#define S3C2443_CLKDIV0 S3C2443_CLKREG(0x24) -#define S3C2443_CLKDIV1 S3C2443_CLKREG(0x28) -#define S3C2443_HCLKCON S3C2443_CLKREG(0x30) -#define S3C2443_PCLKCON S3C2443_CLKREG(0x34) -#define S3C2443_SCLKCON S3C2443_CLKREG(0x38) -#define S3C2443_PWRMODE S3C2443_CLKREG(0x40) -#define S3C2443_SWRST S3C2443_CLKREG(0x44) -#define S3C2443_BUSPRI0 S3C2443_CLKREG(0x50) -#define S3C2443_SYSID S3C2443_CLKREG(0x5C) -#define S3C2443_PWRCFG S3C2443_CLKREG(0x60) -#define S3C2443_RSTCON S3C2443_CLKREG(0x64) - -#define S3C2443_SWRST_RESET (0x533c2443) - -#define S3C2443_PLLCON_OFF (1<<24) - -#define S3C2443_CLKSRC_I2S_EXT (1<<14) -#define S3C2443_CLKSRC_I2S_EPLLDIV (0<<14) -#define S3C2443_CLKSRC_I2S_EPLLREF (2<<14) -#define S3C2443_CLKSRC_I2S_EPLLREF3 (3<<14) -#define S3C2443_CLKSRC_I2S_MASK (3<<14) - -#define S3C2443_CLKSRC_EPLLREF_XTAL (2<<8) -#define S3C2443_CLKSRC_EPLLREF_EXTCLK (3<<8) -#define S3C2443_CLKSRC_EPLLREF_MPLLREF (0<<8) -#define S3C2443_CLKSRC_EPLLREF_MPLLREF2 (1<<8) -#define S3C2443_CLKSRC_EPLLREF_MASK (3<<8) - -#define S3C2443_CLKSRC_ESYSCLK_EPLL (1<<6) -#define S3C2443_CLKSRC_MSYSCLK_MPLL (1<<4) -#define S3C2443_CLKSRC_EXTCLK_DIV (1<<3) - -#define S3C2443_CLKDIV0_DVS (1<<13) -#define S3C2443_CLKDIV0_HALF_HCLK (1<<3) -#define S3C2443_CLKDIV0_HALF_PCLK (1<<2) - -#define S3C2443_CLKDIV0_HCLKDIV_MASK (3<<0) - -#define S3C2443_CLKDIV0_EXTDIV_MASK (3<<6) -#define S3C2443_CLKDIV0_EXTDIV_SHIFT (6) - -#define S3C2443_CLKDIV0_PREDIV_MASK (3<<4) -#define S3C2443_CLKDIV0_PREDIV_SHIFT (4) - -#define S3C2443_CLKDIV0_ARMDIV_MASK (15<<9) -#define S3C2443_CLKDIV0_ARMDIV_SHIFT (9) -#define S3C2443_CLKDIV0_ARMDIV_1 (0<<9) -#define S3C2443_CLKDIV0_ARMDIV_2 (8<<9) -#define S3C2443_CLKDIV0_ARMDIV_3 (2<<9) -#define S3C2443_CLKDIV0_ARMDIV_4 (9<<9) -#define S3C2443_CLKDIV0_ARMDIV_6 (10<<9) -#define S3C2443_CLKDIV0_ARMDIV_8 (11<<9) -#define S3C2443_CLKDIV0_ARMDIV_12 (13<<9) -#define S3C2443_CLKDIV0_ARMDIV_16 (15<<9) - -/* S3C2443_CLKDIV1 */ - -#define S3C2443_CLKDIV1_CAMDIV_MASK (15<<26) -#define S3C2443_CLKDIV1_CAMDIV_SHIFT (26) - -#define S3C2443_CLKDIV1_HSSPIDIV_MASK (3<<24) -#define S3C2443_CLKDIV1_HSSPIDIV_SHIFT (24) - -#define S3C2443_CLKDIV1_DISPDIV_MASK (0xff<<16) -#define S3C2443_CLKDIV1_DISPDIV_SHIFT (16) - -#define S3C2443_CLKDIV1_I2SDIV_MASK (15<<12) -#define S3C2443_CLKDIV1_I2SDIV_SHIFT (12) - -#define S3C2443_CLKDIV1_UARTDIV_MASK (15<<8) -#define S3C2443_CLKDIV1_UARTDIV_SHIFT (8) - -#define S3C2443_CLKDIV1_HSMMCDIV_MASK (3<<6) -#define S3C2443_CLKDIV1_HSMMCDIV_SHIFT (6) - -#define S3C2443_CLKDIV1_USBHOSTDIV_MASK (3<<4) -#define S3C2443_CLKDIV1_USBHOSTDIV_SHIFT (4) - -#define S3C2443_CLKCON_NAND - -#define S3C2443_HCLKCON_DMA0 (1<<0) -#define S3C2443_HCLKCON_DMA1 (1<<1) -#define S3C2443_HCLKCON_DMA2 (1<<2) -#define S3C2443_HCLKCON_DMA3 (1<<3) -#define S3C2443_HCLKCON_DMA4 (1<<4) -#define S3C2443_HCLKCON_DMA5 (1<<5) -#define S3C2443_HCLKCON_CAMIF (1<<8) -#define S3C2443_HCLKCON_DISP (1<<9) -#define S3C2443_HCLKCON_LCDC (1<<10) -#define S3C2443_HCLKCON_USBH (1<<11) -#define S3C2443_HCLKCON_USBD (1<<12) -#define S3C2443_HCLKCON_HSMMC (1<<16) -#define S3C2443_HCLKCON_CFC (1<<17) -#define S3C2443_HCLKCON_SSMC (1<<18) -#define S3C2443_HCLKCON_DRAMC (1<<19) - -#define S3C2443_PCLKCON_UART0 (1<<0) -#define S3C2443_PCLKCON_UART1 (1<<1) -#define S3C2443_PCLKCON_UART2 (1<<2) -#define S3C2443_PCLKCON_UART3 (1<<3) -#define S3C2443_PCLKCON_IIC (1<<4) -#define S3C2443_PCLKCON_SDI (1<<5) -#define S3C2443_PCLKCON_ADC (1<<7) -#define S3C2443_PCLKCON_IIS (1<<9) -#define S3C2443_PCLKCON_PWMT (1<<10) -#define S3C2443_PCLKCON_WDT (1<<11) -#define S3C2443_PCLKCON_RTC (1<<12) -#define S3C2443_PCLKCON_GPIO (1<<13) -#define S3C2443_PCLKCON_SPI0 (1<<14) -#define S3C2443_PCLKCON_SPI1 (1<<15) - -#define S3C2443_SCLKCON_DDRCLK (1<<16) -#define S3C2443_SCLKCON_SSMCCLK (1<<15) -#define S3C2443_SCLKCON_HSSPICLK (1<<14) -#define S3C2443_SCLKCON_HSMMCCLK_EXT (1<<13) -#define S3C2443_SCLKCON_HSMMCCLK_EPLL (1<<12) -#define S3C2443_SCLKCON_CAMCLK (1<<11) -#define S3C2443_SCLKCON_DISPCLK (1<<10) -#define S3C2443_SCLKCON_I2SCLK (1<<9) -#define S3C2443_SCLKCON_UARTCLK (1<<8) -#define S3C2443_SCLKCON_USBHOST (1<<1) - -#include - -static inline unsigned int -s3c2443_get_mpll(unsigned int pllval, unsigned int baseclk) -{ - unsigned int mdiv, pdiv, sdiv; - uint64_t fvco; - - mdiv = pllval >> S3C2443_PLLCON_MDIVSHIFT; - pdiv = pllval >> S3C2443_PLLCON_PDIVSHIFT; - sdiv = pllval >> S3C2443_PLLCON_SDIVSHIFT; - - mdiv &= S3C2443_PLLCON_MDIVMASK; - pdiv &= S3C2443_PLLCON_PDIVMASK; - sdiv &= S3C2443_PLLCON_SDIVMASK; - - fvco = (uint64_t)baseclk * (2 * (mdiv + 8)); - do_div(fvco, pdiv << sdiv); - - return (unsigned int)fvco; -} - -static inline unsigned int -s3c2443_get_epll(unsigned int pllval, unsigned int baseclk) -{ - unsigned int mdiv, pdiv, sdiv; - uint64_t fvco; - - mdiv = pllval >> S3C2443_PLLCON_MDIVSHIFT; - pdiv = pllval >> S3C2443_PLLCON_PDIVSHIFT; - sdiv = pllval >> S3C2443_PLLCON_SDIVSHIFT; - - mdiv &= S3C2443_PLLCON_MDIVMASK; - pdiv &= S3C2443_PLLCON_PDIVMASK; - sdiv &= S3C2443_PLLCON_SDIVMASK; - - fvco = (uint64_t)baseclk * (mdiv + 8); - do_div(fvco, (pdiv + 2) << sdiv); - - return (unsigned int)fvco; -} - -#endif /* __ASM_ARM_REGS_S3C2443_CLOCK */ - diff --git a/trunk/include/asm-arm/arch-s3c2410/regs-serial.h b/trunk/include/asm-arm/arch-s3c2410/regs-serial.h index 8946702a87f5..46f52401d132 100644 --- a/trunk/include/asm-arm/arch-s3c2410/regs-serial.h +++ b/trunk/include/asm-arm/arch-s3c2410/regs-serial.h @@ -35,12 +35,10 @@ #define S3C24XX_VA_UART0 (S3C24XX_VA_UART) #define S3C24XX_VA_UART1 (S3C24XX_VA_UART + 0x4000 ) #define S3C24XX_VA_UART2 (S3C24XX_VA_UART + 0x8000 ) -#define S3C24XX_VA_UART3 (S3C24XX_VA_UART + 0xC000 ) #define S3C2410_PA_UART0 (S3C24XX_PA_UART) #define S3C2410_PA_UART1 (S3C24XX_PA_UART + 0x4000 ) #define S3C2410_PA_UART2 (S3C24XX_PA_UART + 0x8000 ) -#define S3C2443_PA_UART3 (S3C24XX_PA_UART + 0xC000 ) #define S3C2410_URXH (0x24) #define S3C2410_UTXH (0x20) @@ -75,8 +73,6 @@ #define S3C2440_UCON_UCLK (1<<10) #define S3C2440_UCON_PCLK2 (2<<10) #define S3C2440_UCON_FCLK (3<<10) -#define S3C2443_UCON_EPLL (3<<10) - #define S3C2440_UCON2_FCLK_EN (1<<15) #define S3C2440_UCON0_DIVMASK (15 << 12) #define S3C2440_UCON1_DIVMASK (15 << 12) @@ -97,8 +93,6 @@ #define S3C2410_UCON_TXIRQMODE (1<<2) #define S3C2410_UCON_RXIRQMODE (1<<0) #define S3C2410_UCON_RXFIFO_TOI (1<<7) -#define S3C2443_UCON_RXERR_IRQEN (1<<6) -#define S3C2443_UCON_LOOPBACK (1<<5) #define S3C2410_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \ S3C2410_UCON_RXILEVEL | \ @@ -133,7 +127,7 @@ #define S3C2410_UMCOM_AFC (1<<4) #define S3C2410_UMCOM_RTS_LOW (1<<0) -#define S3C2412_UMCON_AFC_63 (0<<5) /* same as s3c2443 */ +#define S3C2412_UMCON_AFC_63 (0<<5) #define S3C2412_UMCON_AFC_56 (1<<5) #define S3C2412_UMCON_AFC_48 (2<<5) #define S3C2412_UMCON_AFC_40 (3<<5) @@ -149,7 +143,6 @@ #define S3C2410_UFSTAT_RXMASK (15<<0) #define S3C2410_UFSTAT_RXSHIFT (0) -/* UFSTAT S3C2443 same as S3C2440 */ #define S3C2440_UFSTAT_TXFULL (1<<14) #define S3C2440_UFSTAT_RXFULL (1<<6) #define S3C2440_UFSTAT_TXSHIFT (8) @@ -164,8 +157,6 @@ #define S3C2410_UERSTAT_OVERRUN (1<<0) #define S3C2410_UERSTAT_FRAME (1<<2) #define S3C2410_UERSTAT_BREAK (1<<3) -#define S3C2443_UERSTAT_PARITY (1<<1) - #define S3C2410_UERSTAT_ANY (S3C2410_UERSTAT_OVERRUN | \ S3C2410_UERSTAT_FRAME | \ S3C2410_UERSTAT_BREAK) @@ -173,8 +164,6 @@ #define S3C2410_UMSTAT_CTS (1<<0) #define S3C2410_UMSTAT_DeltaCTS (1<<2) -#define S3C2443_DIVSLOT (0x2C) - #ifndef __ASSEMBLY__ /* struct s3c24xx_uart_clksrc diff --git a/trunk/include/asm-arm/arch-s3c2410/reset.h b/trunk/include/asm-arm/arch-s3c2410/reset.h deleted file mode 100644 index 4f866cdecab0..000000000000 --- a/trunk/include/asm-arm/arch-s3c2410/reset.h +++ /dev/null @@ -1,22 +0,0 @@ -/* linux/include/asm-arm/arch-s3c2410/reset.h - * - * Copyright (c) 2007 Simtec Electronics - * Ben Dooks - * http://armlinux.simtec.co.uk/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * S3C2410 CPU reset controls -*/ - -#ifndef __ASM_ARCH_RESET_H -#define __ASM_ARCH_RESET_H __FILE__ - -/* This allows the over-ride of the default reset code -*/ - -extern void (*s3c24xx_reset_hook)(void); - -#endif /* __ASM_ARCH_RESET_H */ diff --git a/trunk/include/asm-arm/arch-s3c2410/system.h b/trunk/include/asm-arm/arch-s3c2410/system.h index 1c74ef17da33..ecf250db45fb 100644 --- a/trunk/include/asm-arm/arch-s3c2410/system.h +++ b/trunk/include/asm-arm/arch-s3c2410/system.h @@ -15,16 +15,15 @@ #include #include -#include #include #include void (*s3c24xx_idle)(void); -void (*s3c24xx_reset_hook)(void); void s3c24xx_default_idle(void) { + void __iomem *reg = S3C2410_CLKCON; unsigned long tmp; int i; @@ -34,18 +33,16 @@ void s3c24xx_default_idle(void) /* Warning: going into idle state upsets jtag scanning */ - __raw_writel(__raw_readl(S3C2410_CLKCON) | S3C2410_CLKCON_IDLE, - S3C2410_CLKCON); + __raw_writel(__raw_readl(reg) | (1<<2), reg); /* the samsung port seems to do a loop and then unset idle.. */ for (i = 0; i < 50; i++) { - tmp += __raw_readl(S3C2410_CLKCON); /* ensure loop not optimised out */ + tmp += __raw_readl(reg); /* ensure loop not optimised out */ } /* this bit is not cleared on re-start... */ - __raw_writel(__raw_readl(S3C2410_CLKCON) & ~S3C2410_CLKCON_IDLE, - S3C2410_CLKCON); + __raw_writel(__raw_readl(reg) & ~(1<<2), reg); } static void arch_idle(void) @@ -56,6 +53,7 @@ static void arch_idle(void) s3c24xx_default_idle(); } + static void arch_reset(char mode) { @@ -63,9 +61,6 @@ arch_reset(char mode) cpu_reset(0); } - if (s3c24xx_reset_hook) - s3c24xx_reset_hook(); - printk("arch_reset: attempting watchdog reset\n"); __raw_writel(0, S3C2410_WTCON); /* disable watchdog, to be safe */ diff --git a/trunk/include/asm-arm/arch-s3c2410/udc.h b/trunk/include/asm-arm/arch-s3c2410/udc.h deleted file mode 100644 index e59ec339d614..000000000000 --- a/trunk/include/asm-arm/arch-s3c2410/udc.h +++ /dev/null @@ -1,36 +0,0 @@ -/* linux/include/asm/arch-s3c2410/udc.h - * - * Copyright (c) 2005 Arnaud Patard - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * - * Changelog: - * 14-Mar-2005 RTP Created file - * 02-Aug-2005 RTP File rename - * 07-Sep-2005 BJD Minor cleanups, changed cmd to enum - * 18-Jan-2007 HMW Add per-platform vbus_draw function -*/ - -#ifndef __ASM_ARM_ARCH_UDC_H -#define __ASM_ARM_ARCH_UDC_H - -enum s3c2410_udc_cmd_e { - S3C2410_UDC_P_ENABLE = 1, /* Pull-up enable */ - S3C2410_UDC_P_DISABLE = 2, /* Pull-up disable */ - S3C2410_UDC_P_RESET = 3, /* UDC reset, in case of */ -}; - -struct s3c2410_udc_mach_info { - void (*udc_command)(enum s3c2410_udc_cmd_e); - void (*vbus_draw)(unsigned int ma); - unsigned int vbus_pin; - unsigned char vbus_pin_inverted; -}; - -extern void __init s3c24xx_udc_set_platdata(struct s3c2410_udc_mach_info *); - -#endif /* __ASM_ARM_ARCH_UDC_H */ diff --git a/trunk/include/asm-arm/plat-s3c24xx/s3c2443.h b/trunk/include/asm-arm/plat-s3c24xx/s3c2443.h deleted file mode 100644 index 11d83b5c84e6..000000000000 --- a/trunk/include/asm-arm/plat-s3c24xx/s3c2443.h +++ /dev/null @@ -1,32 +0,0 @@ -/* linux/include/asm-arm/plat-s3c24xx/s3c2443.h - * - * Copyright (c) 2004-2005 Simtec Electronics - * Ben Dooks - * - * Header file for s3c2443 cpu support - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#ifdef CONFIG_CPU_S3C2443 - -struct s3c2410_uartcfg; - -extern int s3c2443_init(void); - -extern void s3c2443_map_io(struct map_desc *mach_desc, int size); - -extern void s3c2443_init_uarts(struct s3c2410_uartcfg *cfg, int no); - -extern void s3c2443_init_clocks(int xtal); - -extern int s3c2443_baseclk_add(void); - -#else -#define s3c2443_init_clocks NULL -#define s3c2443_init_uarts NULL -#define s3c2443_map_io NULL -#define s3c2443_init NULL -#endif diff --git a/trunk/include/asm-arm/system.h b/trunk/include/asm-arm/system.h index aa223fc546af..e5aa372beb94 100644 --- a/trunk/include/asm-arm/system.h +++ b/trunk/include/asm-arm/system.h @@ -193,11 +193,19 @@ extern unsigned int user_debug; #endif #if __LINUX_ARM_ARCH__ >= 6 -#define mb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" \ - : : "r" (0) : "memory") +#define isb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c5, 4" \ + : : "r" (0) : "memory") +#define dsb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" \ + : : "r" (0) : "memory") +#define dmb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" \ + : : "r" (0) : "memory") #else -#define mb() __asm__ __volatile__ ("" : : : "memory") +#define isb() __asm__ __volatile__ ("" : : : "memory") +#define dsb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" \ + : : "r" (0) : "memory") +#define dmb() __asm__ __volatile__ ("" : : : "memory") #endif +#define mb() dmb() #define rmb() mb() #define wmb() mb() #define read_barrier_depends() do { } while(0)