aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/Kconfig5
-rw-r--r--arch/arm/Makefile1
-rw-r--r--arch/arm/boot/compressed/head.S4
-rw-r--r--arch/arm/configs/lpd7a400_defconfig135
-rw-r--r--arch/arm/configs/lpd7a404_defconfig430
-rw-r--r--arch/arm/configs/pnx4008_defconfig2072
-rw-r--r--arch/arm/kernel/entry-common.S2
-rw-r--r--arch/arm/kernel/irq.c4
-rw-r--r--arch/arm/kernel/time.c24
-rw-r--r--arch/arm/mach-lh7a40x/Kconfig5
-rw-r--r--arch/arm/mach-lh7a40x/Makefile19
-rw-r--r--arch/arm/mach-lh7a40x/arch-lpd7a40x.c200
-rw-r--r--arch/arm/mach-lh7a40x/clcd.c241
-rw-r--r--arch/arm/mach-lh7a40x/clocks.c199
-rw-r--r--arch/arm/mach-lh7a40x/common.h1
-rw-r--r--arch/arm/mach-lh7a40x/irq-lh7a404.c17
-rw-r--r--arch/arm/mach-lh7a40x/lcd-panel.h346
-rw-r--r--arch/arm/mach-lh7a40x/ssp-cpld.c343
-rw-r--r--arch/arm/mach-lh7a40x/time.c4
-rw-r--r--arch/arm/mach-pnx4008/Makefile12
-rw-r--r--arch/arm/mach-pnx4008/Makefile.boot4
-rw-r--r--arch/arm/mach-pnx4008/clock.c1010
-rw-r--r--arch/arm/mach-pnx4008/clock.h43
-rw-r--r--arch/arm/mach-pnx4008/core.c207
-rw-r--r--arch/arm/mach-pnx4008/dma.c1109
-rw-r--r--arch/arm/mach-pnx4008/gpio.c330
-rw-r--r--arch/arm/mach-pnx4008/irq.c121
-rw-r--r--arch/arm/mach-pnx4008/pm.c184
-rw-r--r--arch/arm/mach-pnx4008/serial.c69
-rw-r--r--arch/arm/mach-pnx4008/sleep.S196
-rw-r--r--arch/arm/mach-pnx4008/time.c141
-rw-r--r--arch/arm/mach-pxa/lubbock.c84
-rw-r--r--arch/arm/mach-s3c2410/Kconfig26
-rw-r--r--arch/arm/mach-s3c2410/Makefile10
-rw-r--r--arch/arm/mach-s3c2410/clock.c2
-rw-r--r--arch/arm/mach-s3c2410/common-smdk.c65
-rw-r--r--arch/arm/mach-s3c2410/cpu.c77
-rw-r--r--arch/arm/mach-s3c2410/cpu.h7
-rw-r--r--arch/arm/mach-s3c2410/devs.c78
-rw-r--r--arch/arm/mach-s3c2410/devs.h8
-rw-r--r--arch/arm/mach-s3c2410/mach-anubis.c2
-rw-r--r--arch/arm/mach-s3c2410/mach-bast.c2
-rw-r--r--arch/arm/mach-s3c2410/mach-h1940.c2
-rw-r--r--arch/arm/mach-s3c2410/mach-nexcoder.c2
-rw-r--r--arch/arm/mach-s3c2410/mach-osiris.c5
-rw-r--r--arch/arm/mach-s3c2410/mach-otom.c2
-rw-r--r--arch/arm/mach-s3c2410/mach-smdk2410.c2
-rw-r--r--arch/arm/mach-s3c2410/mach-smdk2440.c2
-rw-r--r--arch/arm/mach-s3c2410/mach-vr1000.c2
-rw-r--r--arch/arm/mach-s3c2410/pm.c4
-rw-r--r--arch/arm/mach-s3c2410/s3c2410.c85
-rw-r--r--arch/arm/mach-s3c2410/s3c2440-irq.c77
-rw-r--r--arch/arm/mach-s3c2410/s3c2440.c234
-rw-r--r--arch/arm/mach-s3c2410/s3c2442-clock.c171
-rw-r--r--arch/arm/mach-s3c2410/s3c2442.c52
-rw-r--r--arch/arm/mach-s3c2410/s3c2442.h17
-rw-r--r--arch/arm/mach-s3c2410/s3c244x-irq.c142
-rw-r--r--arch/arm/mach-s3c2410/s3c244x.c182
-rw-r--r--arch/arm/mach-s3c2410/s3c244x.h25
-rw-r--r--arch/arm/mach-s3c2410/sleep.S2
-rw-r--r--arch/arm/mm/Kconfig4
61 files changed, 8231 insertions, 620 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 08b7cc900cae..f47cf9af3bc8 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -270,6 +270,11 @@ config ARCH_AT91RM9200
Say Y here if you intend to run this kernel on an Atmel
AT91RM9200-based board.
+config ARCH_PNX4008
+ bool "Philips Nexperia PNX4008 Mobile"
+ help
+ This enables support for Philips PNX4008 mobile platform.
+
endchoice
source "arch/arm/mach-clps711x/Kconfig"
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 6f8e84c1c1f2..6c97aa70d3bc 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -116,6 +116,7 @@ endif
machine-$(CONFIG_ARCH_REALVIEW) := realview
machine-$(CONFIG_ARCH_AT91RM9200) := at91rm9200
machine-$(CONFIG_ARCH_EP93XX) := ep93xx
+ machine-$(CONFIG_ARCH_PNX4008) := pnx4008
ifeq ($(CONFIG_ARCH_EBSA110),y)
# This is what happens if you forget the IOCS16 line.
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index b56f5e691d65..23016f6aa645 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -605,8 +605,8 @@ proc_types:
b __armv4_mmu_cache_off
b __armv4_mmu_cache_flush
- .word 0x00070000 @ ARMv6
- .word 0x000f0000
+ .word 0x0007b000 @ ARMv6
+ .word 0x0007f000
b __armv4_mmu_cache_on
b __armv4_mmu_cache_off
b __armv6_mmu_cache_flush
diff --git a/arch/arm/configs/lpd7a400_defconfig b/arch/arm/configs/lpd7a400_defconfig
index 67eaa26c2647..bf9cf9c6d2df 100644
--- a/arch/arm/configs/lpd7a400_defconfig
+++ b/arch/arm/configs/lpd7a400_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc1-bk2
-# Mon Mar 28 00:06:33 2005
+# Linux kernel version: 2.6.12
+# Thu Nov 3 14:15:32 2005
#
CONFIG_ARM=y
CONFIG_MMU=y
@@ -17,6 +17,7 @@ CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
@@ -36,6 +37,8 @@ CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_ALL is not set
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
# CONFIG_EPOLL is not set
@@ -71,6 +74,7 @@ CONFIG_BASE_SMALL=0
# CONFIG_ARCH_SA1100 is not set
# CONFIG_ARCH_S3C2410 is not set
# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7952X is not set
CONFIG_ARCH_LH7A40X=y
# CONFIG_ARCH_OMAP is not set
# CONFIG_ARCH_VERSATILE is not set
@@ -84,6 +88,7 @@ CONFIG_ARCH_LH7A40X=y
CONFIG_MACH_LPD7A400=y
# CONFIG_MACH_LPD7A404 is not set
CONFIG_ARCH_LH7A400=y
+CONFIG_LPD7A40X_CPLD_SSP=y
# CONFIG_LH7A40X_CONTIGMEM is not set
# CONFIG_LH7A40X_ONE_BANK_PER_NODE is not set
@@ -110,6 +115,8 @@ CONFIG_ARM_THUMB=y
#
# Bus support
#
+CONFIG_ARM_AMBA=y
+CONFIG_ISA_DMA_API=y
#
# PCCARD (PCMCIA/CardBus) support
@@ -119,6 +126,7 @@ CONFIG_ARM_THUMB=y
#
# Kernel Features
#
+# CONFIG_SMP is not set
CONFIG_PREEMPT=y
CONFIG_DISCONTIGMEM=y
CONFIG_ALIGNMENT_TRAP=y
@@ -175,7 +183,7 @@ CONFIG_MTD=y
# CONFIG_MTD_CONCAT is not set
CONFIG_MTD_PARTITIONS=y
# CONFIG_MTD_REDBOOT_PARTS is not set
-# CONFIG_MTD_CMDLINE_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
# CONFIG_MTD_AFS_PARTS is not set
#
@@ -217,7 +225,10 @@ CONFIG_MTD_CFI_UTIL=y
# Mapping drivers for chip access
#
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
-# CONFIG_MTD_PHYSMAP is not set
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_START=0x00000000
+CONFIG_MTD_PHYSMAP_LEN=0x04000000
+CONFIG_MTD_PHYSMAP_BANKWIDTH=4
# CONFIG_MTD_ARM_INTEGRATOR is not set
# CONFIG_MTD_EDB7312 is not set
@@ -254,7 +265,6 @@ CONFIG_MTD_CFI_UTIL=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_DEV_COW_COMMON is not set
CONFIG_BLK_DEV_LOOP=y
# CONFIG_BLK_DEV_CRYPTOLOOP is not set
@@ -288,13 +298,15 @@ CONFIG_BLK_DEV_IDEDISK=y
# CONFIG_BLK_DEV_IDECD is not set
# CONFIG_BLK_DEV_IDETAPE is not set
# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_BLK_DEV_IDESCSI is not set
# CONFIG_IDE_TASK_IOCTL is not set
+CONFIG_IDE_POLL=y
#
# IDE chipset support/bugfixes
#
CONFIG_IDE_GENERIC=y
-# CONFIG_IDE_ARM is not set
+CONFIG_IDE_ARM=y
# CONFIG_BLK_DEV_IDEDMA is not set
# CONFIG_IDEDMA_AUTO is not set
# CONFIG_BLK_DEV_HD is not set
@@ -302,7 +314,37 @@ CONFIG_IDE_GENERIC=y
#
# SCSI device support
#
-# CONFIG_SCSI is not set
+CONFIG_SCSI=y
+# CONFIG_SCSI_PROC_FS is not set
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+# CONFIG_BLK_DEV_SD is not set
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+
+#
+# SCSI Transport Attributes
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_DEBUG is not set
#
# Multi-device support (RAID and LVM)
@@ -331,7 +373,6 @@ CONFIG_NET=y
#
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK_DEV is not set
CONFIG_UNIX=y
# CONFIG_NET_KEY is not set
CONFIG_INET=y
@@ -438,13 +479,10 @@ CONFIG_INPUT=y
#
# Userland interfaces
#
-CONFIG_INPUT_MOUSEDEV=y
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_MOUSEDEV is not set
# CONFIG_INPUT_JOYDEV is not set
# CONFIG_INPUT_TSDEV is not set
-# CONFIG_INPUT_EVDEV is not set
+CONFIG_INPUT_EVDEV=y
# CONFIG_INPUT_EVBUG is not set
#
@@ -453,7 +491,13 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE is not set
# CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_TOUCHSCREEN is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_MK712 is not set
+CONFIG_TOUCHSCREEN_ADS7843_LH7=y
+CONFIG_HAS_TOUCHSCREEN_ADS7843_LH7=y
# CONFIG_INPUT_MISC is not set
#
@@ -461,7 +505,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
#
# CONFIG_SERIO is not set
# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
#
# Character devices
@@ -479,6 +522,8 @@ CONFIG_HW_CONSOLE=y
#
# Non-8250 serial port support
#
+# CONFIG_SERIAL_AMBA_PL010 is not set
+# CONFIG_SERIAL_AMBA_PL011 is not set
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
CONFIG_SERIAL_LH7A40X=y
@@ -510,7 +555,6 @@ CONFIG_RTC=y
#
# TPM devices
#
-# CONFIG_TCG_TPM is not set
#
# I2C support
@@ -534,18 +578,73 @@ CONFIG_RTC=y
#
# Graphics support
#
-# CONFIG_FB is not set
+CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+CONFIG_FB_SOFT_CURSOR=y
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+CONFIG_FB_ARMCLCD=y
+CONFIG_FB_ARMCLCD_SHARP_LQ035Q7DB02_HRTFT=y
+# CONFIG_FB_ARMCLCD_SHARP_LQ057Q3DC02 is not set
+# CONFIG_FB_ARMCLCD_SHARP_LQ64D343 is not set
+# CONFIG_FB_ARMCLCD_SHARP_LQ10D368 is not set
+# CONFIG_FB_ARMCLCD_SHARP_LQ121S1DG41 is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_VIRTUAL is not set
#
# Console display driver support
#
# CONFIG_VGA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE is not set
+
+#
+# Logo configuration
+#
+# CONFIG_LOGO is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
#
-# CONFIG_SOUND is not set
+CONFIG_SOUND=y
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=y
+# CONFIG_SND_SEQUENCER is not set
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=y
+CONFIG_SND_PCM_OSS=y
+# CONFIG_SND_RTCTIMER is not set
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+
+#
+# Generic devices
+#
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+CONFIG_SND_AC97_CODEC=y
+
+#
+# ALSA ARM devices
+#
+CONFIG_SND_LH7A40X_AC97=y
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
#
# USB support
diff --git a/arch/arm/configs/lpd7a404_defconfig b/arch/arm/configs/lpd7a404_defconfig
index 208d591ebfce..3a57be32e849 100644
--- a/arch/arm/configs/lpd7a404_defconfig
+++ b/arch/arm/configs/lpd7a404_defconfig
@@ -1,52 +1,58 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc1-bk2
-# Mon Mar 28 00:14:08 2005
+# Linux kernel version: 2.6.16
+# Thu Mar 23 17:50:31 2006
#
CONFIG_ARM=y
CONFIG_MMU=y
-CONFIG_UID16=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_GENERIC_IOMAP=y
#
# Code maturity level options
#
CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
# CONFIG_SWAP is not set
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-# CONFIG_HOTPLUG is not set
-CONFIG_KOBJECT_UEVENT=y
CONFIG_IKCONFIG=y
# CONFIG_IKCONFIG_PROC is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_UID16=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_ALL is not set
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_HOTPLUG is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
# CONFIG_EPOLL is not set
-CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SHMEM=y
CONFIG_CC_ALIGN_FUNCTIONS=0
CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
+CONFIG_OBSOLETE_INTERMODULE=y
#
# Loadable module support
@@ -54,6 +60,23 @@ CONFIG_BASE_SMALL=0
# CONFIG_MODULES is not set
#
+# Block layer
+#
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_AS is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+
+#
# System Type
#
# CONFIG_ARCH_CLPS7500 is not set
@@ -71,11 +94,15 @@ CONFIG_BASE_SMALL=0
# CONFIG_ARCH_SA1100 is not set
# CONFIG_ARCH_S3C2410 is not set
# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7952X is not set
CONFIG_ARCH_LH7A40X=y
# CONFIG_ARCH_OMAP is not set
# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_REALVIEW is not set
# CONFIG_ARCH_IMX is not set
# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_AT91RM9200 is not set
#
# LH7A40X Implementations
@@ -110,6 +137,7 @@ CONFIG_ARM_THUMB=y
#
# Bus support
#
+CONFIG_ARM_AMBA=y
#
# PCCARD (PCMCIA/CardBus) support
@@ -120,7 +148,18 @@ CONFIG_ARM_THUMB=y
# Kernel Features
#
CONFIG_PREEMPT=y
+# CONFIG_NO_IDLE_HZ is not set
+# CONFIG_AEABI is not set
+CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
+CONFIG_SELECT_MEMORY_MODEL=y
+# CONFIG_FLATMEM_MANUAL is not set
+CONFIG_DISCONTIGMEM_MANUAL=y
+# CONFIG_SPARSEMEM_MANUAL is not set
CONFIG_DISCONTIGMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_NEED_MULTIPLE_NODES=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4096
CONFIG_ALIGNMENT_TRAP=y
#
@@ -154,6 +193,84 @@ CONFIG_BINFMT_ELF=y
# Power management options
#
# CONFIG_PM is not set
+# CONFIG_APM is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
#
# Device Drivers
@@ -168,6 +285,11 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_DEBUG_DRIVER is not set
#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
# Memory Technology Devices (MTD)
#
CONFIG_MTD=y
@@ -175,7 +297,7 @@ CONFIG_MTD=y
# CONFIG_MTD_CONCAT is not set
CONFIG_MTD_PARTITIONS=y
# CONFIG_MTD_REDBOOT_PARTS is not set
-# CONFIG_MTD_CMDLINE_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
# CONFIG_MTD_AFS_PARTS is not set
#
@@ -186,6 +308,7 @@ CONFIG_MTD_BLOCK=y
# CONFIG_FTL is not set
# CONFIG_NFTL is not set
# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
#
# RAM/ROM/Flash chip drivers
@@ -211,15 +334,18 @@ CONFIG_MTD_CFI_UTIL=y
# CONFIG_MTD_RAM is not set
# CONFIG_MTD_ROM is not set
# CONFIG_MTD_ABSENT is not set
-# CONFIG_MTD_XIP is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
#
# Mapping drivers for chip access
#
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
-# CONFIG_MTD_PHYSMAP is not set
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_START=0x00000000
+CONFIG_MTD_PHYSMAP_LEN=0x04000000
+CONFIG_MTD_PHYSMAP_BANKWIDTH=4
# CONFIG_MTD_ARM_INTEGRATOR is not set
-# CONFIG_MTD_EDB7312 is not set
+# CONFIG_MTD_PLATRAM is not set
#
# Self-contained MTD device drivers
@@ -243,6 +369,11 @@ CONFIG_MTD_CFI_UTIL=y
# CONFIG_MTD_NAND is not set
#
+# OneNAND Flash Device Drivers
+#
+# CONFIG_MTD_ONENAND is not set
+
+#
# Parallel port support
#
# CONFIG_PARPORT is not set
@@ -254,7 +385,6 @@ CONFIG_MTD_CFI_UTIL=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_DEV_COW_COMMON is not set
CONFIG_BLK_DEV_LOOP=y
# CONFIG_BLK_DEV_CRYPTOLOOP is not set
@@ -262,16 +392,7 @@ CONFIG_BLK_DEV_LOOP=y
# CONFIG_BLK_DEV_UB is not set
# CONFIG_BLK_DEV_RAM is not set
CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
# CONFIG_CDROM_PKTCDVD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-# CONFIG_IOSCHED_AS is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-CONFIG_IOSCHED_CFQ=y
# CONFIG_ATA_OVER_ETH is not set
#
@@ -291,12 +412,13 @@ CONFIG_BLK_DEV_IDEDISK=y
# CONFIG_BLK_DEV_IDEFLOPPY is not set
# CONFIG_BLK_DEV_IDESCSI is not set
# CONFIG_IDE_TASK_IOCTL is not set
+CONFIG_IDE_POLL=y
#
# IDE chipset support/bugfixes
#
CONFIG_IDE_GENERIC=y
-# CONFIG_IDE_ARM is not set
+CONFIG_IDE_ARM=y
# CONFIG_BLK_DEV_IDEDMA is not set
# CONFIG_IDEDMA_AUTO is not set
# CONFIG_BLK_DEV_HD is not set
@@ -304,6 +426,7 @@ CONFIG_IDE_GENERIC=y
#
# SCSI device support
#
+# CONFIG_RAID_ATTRS is not set
CONFIG_SCSI=y
# CONFIG_SCSI_PROC_FS is not set
@@ -315,6 +438,7 @@ CONFIG_SCSI=y
# CONFIG_CHR_DEV_OSST is not set
# CONFIG_BLK_DEV_SR is not set
# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
#
# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
@@ -329,10 +453,12 @@ CONFIG_SCSI=y
# CONFIG_SCSI_SPI_ATTRS is not set
# CONFIG_SCSI_FC_ATTRS is not set
# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
#
# SCSI low-level drivers
#
+# CONFIG_ISCSI_TCP is not set
# CONFIG_SCSI_SATA is not set
# CONFIG_SCSI_DEBUG is not set
@@ -344,6 +470,7 @@ CONFIG_SCSI=y
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
@@ -354,70 +481,8 @@ CONFIG_SCSI=y
#
#
-# Networking support
+# Network device support
#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK_DEV is not set
-CONFIG_UNIX=y
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-CONFIG_IP_PNP_RARP=y
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_TUNNEL is not set
-# CONFIG_IP_TCPDIAG is not set
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
@@ -425,11 +490,17 @@ CONFIG_NETDEVICES=y
# CONFIG_TUN is not set
#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
CONFIG_MII=y
CONFIG_SMC91X=y
+# CONFIG_DM9000 is not set
#
# Ethernet (1000 Mbit)
@@ -456,6 +527,8 @@ CONFIG_SMC91X=y
# CONFIG_SLIP is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -470,10 +543,13 @@ CONFIG_INPUT=y
#
# Userland interfaces
#
-# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_JOYDEV is not set
# CONFIG_INPUT_TSDEV is not set
-# CONFIG_INPUT_EVDEV is not set
+CONFIG_INPUT_EVDEV=y
# CONFIG_INPUT_EVBUG is not set
#
@@ -482,7 +558,13 @@ CONFIG_INPUT=y
# CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE is not set
# CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_TOUCHSCREEN is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_MK712 is not set
+CONFIG_TOUCHSCREEN_ADC_LH7=y
+CONFIG_HAS_TOUCHSCREEN_ADC_LH7=y
# CONFIG_INPUT_MISC is not set
#
@@ -490,7 +572,6 @@ CONFIG_INPUT=y
#
# CONFIG_SERIO is not set
# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
#
# Character devices
@@ -508,6 +589,8 @@ CONFIG_HW_CONSOLE=y
#
# Non-8250 serial port support
#
+# CONFIG_SERIAL_AMBA_PL010 is not set
+# CONFIG_SERIAL_AMBA_PL011 is not set
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
CONFIG_SERIAL_LH7A40X=y
@@ -533,13 +616,13 @@ CONFIG_RTC=y
#
# Ftape, the floppy tape device driver
#
-# CONFIG_DRM is not set
# CONFIG_RAW_DRIVER is not set
#
# TPM devices
#
# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
#
# I2C support
@@ -547,10 +630,33 @@ CONFIG_RTC=y
# CONFIG_I2C is not set
#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -563,18 +669,83 @@ CONFIG_RTC=y
#
# Graphics support
#
-# CONFIG_FB is not set
+CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+CONFIG_FB_ARMCLCD=y
+CONFIG_FB_ARMCLCD_SHARP_LQ035Q7DB02_HRTFT=y
+# CONFIG_FB_ARMCLCD_SHARP_LQ057Q3DC02 is not set
+# CONFIG_FB_ARMCLCD_SHARP_LQ64D343 is not set
+# CONFIG_FB_ARMCLCD_SHARP_LQ10D368 is not set
+# CONFIG_FB_ARMCLCD_SHARP_LQ121S1DG41 is not set
+# CONFIG_FB_ARMCLCD_AUO_A070VW01_WIDE is not set
+# CONFIG_FB_ARMCLCD_HITACHI is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_VIRTUAL is not set
#
# Console display driver support
#
# CONFIG_VGA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE is not set
+
+#
+# Logo configuration
+#
+# CONFIG_LOGO is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
#
-# CONFIG_SOUND is not set
+CONFIG_SOUND=y
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=y
+# CONFIG_SND_SEQUENCER is not set
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=y
+CONFIG_SND_PCM_OSS=y
+# CONFIG_SND_RTCTIMER is not set
+# CONFIG_SND_DYNAMIC_MINORS is not set
+CONFIG_SND_SUPPORT_OLD_API=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+
+#
+# Generic devices
+#
+CONFIG_SND_AC97_CODEC=y
+CONFIG_SND_AC97_BUS=y
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+
+#
+# ALSA ARM devices
+#
+# CONFIG_SND_ARMAACI is not set
+CONFIG_SND_LH7A40X_AC97=y
+
+#
+# USB devices
+#
+# CONFIG_SND_USB_AUDIO is not set
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
#
# USB support
@@ -595,6 +766,7 @@ CONFIG_USB_DEVICEFS=y
#
# USB Host Controller Drivers
#
+# CONFIG_USB_ISP116X_HCD is not set
CONFIG_USB_OHCI_HCD=y
# CONFIG_USB_OHCI_BIG_ENDIAN is not set
CONFIG_USB_OHCI_LITTLE_ENDIAN=y
@@ -603,16 +775,19 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
#
# USB Device Class drivers
#
-# CONFIG_USB_BLUETOOTH_TTY is not set
+# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set
# CONFIG_USB_ACM is not set
# CONFIG_USB_PRINTER is not set
#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
#
CONFIG_USB_STORAGE=y
CONFIG_USB_STORAGE_DEBUG=y
-# CONFIG_USB_STORAGE_RW_DETECT is not set
CONFIG_USB_STORAGE_DATAFAB=y
# CONFIG_USB_STORAGE_FREECOM is not set
# CONFIG_USB_STORAGE_ISD200 is not set
@@ -621,22 +796,32 @@ CONFIG_USB_STORAGE_DATAFAB=y
# CONFIG_USB_STORAGE_SDDR09 is not set
# CONFIG_USB_STORAGE_SDDR55 is not set
# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_LIBUSUAL is not set
#
# USB Input Devices
#
CONFIG_USB_HID=y
CONFIG_USB_HIDINPUT=y
+# CONFIG_USB_HIDINPUT_POWERBOOK is not set
# CONFIG_HID_FF is not set
# CONFIG_USB_HIDDEV is not set
# CONFIG_USB_AIPTEK is not set
# CONFIG_USB_WACOM is not set
+# CONFIG_USB_ACECAD is not set
# CONFIG_USB_KBTAB is not set
# CONFIG_USB_POWERMATE is not set
# CONFIG_USB_MTOUCH is not set
+# CONFIG_USB_ITMTOUCH is not set
# CONFIG_USB_EGALAX is not set
+# CONFIG_USB_YEALINK is not set
# CONFIG_USB_XPAD is not set
# CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_ATI_REMOTE2 is not set
+# CONFIG_USB_KEYSPAN_REMOTE is not set
+# CONFIG_USB_APPLETOUCH is not set
#
# USB Imaging devices
@@ -686,16 +871,33 @@ CONFIG_USB_MON=y
# CONFIG_USB_PHIDGETKIT is not set
# CONFIG_USB_PHIDGETSERVO is not set
# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_LD is not set
# CONFIG_USB_TEST is not set
#
-# USB ATM/DSL drivers
+# USB DSL modem support
#
#
# USB Gadget Support
#
-# CONFIG_USB_GADGET is not set
+CONFIG_USB_GADGET=y
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_PXA2XX is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+CONFIG_USB_GADGET_LH7=y
+CONFIG_USB_LH7=y
+# CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+# CONFIG_USB_GADGET_DUALSPEED is not set
+CONFIG_USB_ZERO=y
+# CONFIG_USB_ETH is not set
+# CONFIG_USB_GADGETFS is not set
+# CONFIG_USB_FILE_STORAGE is not set
+# CONFIG_USB_G_SERIAL is not set
#
# MMC/SD Card support
@@ -707,6 +909,7 @@ CONFIG_USB_MON=y
#
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
CONFIG_EXT3_FS_XATTR=y
# CONFIG_EXT3_FS_POSIX_ACL is not set
@@ -716,17 +919,17 @@ CONFIG_JBD=y
CONFIG_FS_MBCACHE=y
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
-
-#
-# XFS support
-#
+# CONFIG_FS_POSIX_ACL is not set
# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
#
# CD-ROM/DVD Filesystems
@@ -749,12 +952,11 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
#
CONFIG_PROC_FS=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-# CONFIG_DEVPTS_FS_XATTR is not set
CONFIG_TMPFS=y
-# CONFIG_TMPFS_XATTR is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+# CONFIG_RELAYFS_FS is not set
+# CONFIG_CONFIGFS_FS is not set
#
# Miscellaneous filesystems
@@ -769,8 +971,8 @@ CONFIG_RAMFS=y
# CONFIG_JFFS_FS is not set
CONFIG_JFFS2_FS=y
CONFIG_JFFS2_FS_DEBUG=0
-# CONFIG_JFFS2_FS_NAND is not set
-# CONFIG_JFFS2_FS_NOR_ECC is not set
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_SUMMARY is not set
# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
CONFIG_JFFS2_ZLIB=y
CONFIG_JFFS2_RTIME=y
@@ -787,12 +989,14 @@ CONFIG_CRAMFS=y
#
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
# CONFIG_NFS_V4 is not set
# CONFIG_NFS_DIRECTIO is not set
# CONFIG_NFSD is not set
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -801,6 +1005,7 @@ CONFIG_SUNRPC=y
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
#
# Partition Types
@@ -820,6 +1025,7 @@ CONFIG_MSDOS_PARTITION=y
# CONFIG_SGI_PARTITION is not set
# CONFIG_ULTRIX_PARTITION is not set
# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
# CONFIG_EFI_PARTITION is not set
#
@@ -875,19 +1081,24 @@ CONFIG_NLS_DEFAULT="iso8859-1"
# Kernel hacking
#
# CONFIG_PRINTK_TIME is not set
-CONFIG_DEBUG_KERNEL=y
CONFIG_MAGIC_SYSRQ=y
-CONFIG_LOG_BUF_SHIFT=14
+CONFIG_DEBUG_KERNEL=y
+CONFIG_LOG_BUF_SHIFT=16
+CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_DEBUG_SLAB is not set
CONFIG_DEBUG_PREEMPT=y
+CONFIG_DEBUG_MUTEXES=y
# CONFIG_DEBUG_SPINLOCK is not set
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
# 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_FRAME_POINTER=y
+CONFIG_FORCED_INLINING=y
+# CONFIG_RCU_TORTURE_TEST is not set
CONFIG_DEBUG_USER=y
# CONFIG_DEBUG_WAITQ is not set
CONFIG_DEBUG_ERRORS=y
@@ -912,6 +1123,7 @@ CONFIG_DEBUG_ERRORS=y
# Library routines
#
# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
CONFIG_ZLIB_INFLATE=y
diff --git a/arch/arm/configs/pnx4008_defconfig b/arch/arm/configs/pnx4008_defconfig
new file mode 100644
index 000000000000..8a078d479d57
--- /dev/null
+++ b/arch/arm/configs/pnx4008_defconfig
@@ -0,0 +1,2072 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.17-rc1
+# Thu Apr 6 17:05:58 2006
+#
+CONFIG_ARM=y
+CONFIG_MMU=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_VECTORS_BASE=0xffff0000
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+CONFIG_SYSCTL=y
+CONFIG_AUDIT=y
+# CONFIG_IKCONFIG is not set
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_UID16=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SHMEM=y
+CONFIG_SLAB=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
+CONFIG_OBSOLETE_INTERMODULE=m
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+# CONFIG_BLK_DEV_IO_TRACE is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
+# System Type
+#
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_IOP3XX is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_AT91RM9200 is not set
+CONFIG_ARCH_PNX4008=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM926T=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5TJ=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
+
+#
+# Bus support
+#
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+CONFIG_PCCARD=m
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_PCMCIA=m
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
+
+#
+# PC-card bridges
+#
+
+#
+# Kernel Features
+#
+CONFIG_PREEMPT=y
+# CONFIG_NO_IDLE_HZ is not set
+CONFIG_HZ=100
+# CONFIG_AEABI is not set
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_CMDLINE="mem=64M console=ttyS0,115200"
+# CONFIG_XIP_KERNEL is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+# CONFIG_FPE_NWFPE is not set
+# CONFIG_FPE_FASTFPE is not set
+# CONFIG_VFP is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_AOUT=m
+CONFIG_BINFMT_MISC=m
+# CONFIG_ARTHUR is not set
+
+#
+# Power management options
+#
+CONFIG_PM=y
+CONFIG_PM_LEGACY=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_APM=m
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=m
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=m
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=m
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# CONFIG_IP_FIB_TRIE is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_FWMARK=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+# CONFIG_IP_ROUTE_MULTIPATH_CACHED is not set
+CONFIG_IP_ROUTE_VERBOSE=y
+# CONFIG_IP_PNP is not set
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+CONFIG_NET_IPGRE_BROADCAST=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_XFRM_TUNNEL=m
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+
+#
+# IP: Virtual Server Configuration
+#
+CONFIG_IP_VS=m
+# CONFIG_IP_VS_DEBUG is not set
+CONFIG_IP_VS_TAB_BITS=12
+
+#
+# IPVS transport protocol load balancing support
+#
+CONFIG_IP_VS_PROTO_TCP=y
+CONFIG_IP_VS_PROTO_UDP=y
+CONFIG_IP_VS_PROTO_ESP=y
+CONFIG_IP_VS_PROTO_AH=y
+
+#
+# IPVS scheduler
+#
+CONFIG_IP_VS_RR=m
+CONFIG_IP_VS_WRR=m
+CONFIG_IP_VS_LC=m
+CONFIG_IP_VS_WLC=m
+CONFIG_IP_VS_LBLC=m
+CONFIG_IP_VS_LBLCR=m
+CONFIG_IP_VS_DH=m
+CONFIG_IP_VS_SH=m
+CONFIG_IP_VS_SED=m
+CONFIG_IP_VS_NQ=m
+
+#
+# IPVS application helper
+#
+CONFIG_IP_VS_FTP=m
+CONFIG_IPV6=m
+CONFIG_IPV6_PRIVACY=y
+# CONFIG_IPV6_ROUTER_PREF is not set
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_INET6_XFRM_TUNNEL=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_IPV6_TUNNEL=m
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_BRIDGE_NETFILTER=y
+
+#
+# Core Netfilter Configuration
+#
+# CONFIG_NETFILTER_NETLINK is not set
+# CONFIG_NETFILTER_XTABLES is not set
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_IP_NF_CONNTRACK=m
+CONFIG_IP_NF_CT_ACCT=y
+CONFIG_IP_NF_CONNTRACK_MARK=y
+# CONFIG_IP_NF_CONNTRACK_EVENTS is not set
+CONFIG_IP_NF_CT_PROTO_SCTP=m
+CONFIG_IP_NF_FTP=m
+CONFIG_IP_NF_IRC=m
+# CONFIG_IP_NF_NETBIOS_NS is not set
+CONFIG_IP_NF_TFTP=m
+CONFIG_IP_NF_AMANDA=m
+# CONFIG_IP_NF_PPTP is not set
+# CONFIG_IP_NF_H323 is not set
+CONFIG_IP_NF_QUEUE=m
+
+#
+# IPv6: Netfilter Configuration (EXPERIMENTAL)
+#
+CONFIG_IP6_NF_QUEUE=m
+
+#
+# DECnet: Netfilter Configuration
+#
+CONFIG_DECNET_NF_GRABULATOR=m
+
+#
+# Bridge: Netfilter Configuration
+#
+CONFIG_BRIDGE_NF_EBTABLES=m
+CONFIG_BRIDGE_EBT_BROUTE=m
+CONFIG_BRIDGE_EBT_T_FILTER=m
+CONFIG_BRIDGE_EBT_T_NAT=m
+CONFIG_BRIDGE_EBT_802_3=m
+CONFIG_BRIDGE_EBT_AMONG=m
+CONFIG_BRIDGE_EBT_ARP=m
+CONFIG_BRIDGE_EBT_IP=m
+CONFIG_BRIDGE_EBT_LIMIT=m
+CONFIG_BRIDGE_EBT_MARK=m
+CONFIG_BRIDGE_EBT_PKTTYPE=m
+CONFIG_BRIDGE_EBT_STP=m
+CONFIG_BRIDGE_EBT_VLAN=m
+CONFIG_BRIDGE_EBT_ARPREPLY=m
+CONFIG_BRIDGE_EBT_DNAT=m
+CONFIG_BRIDGE_EBT_MARK_T=m
+CONFIG_BRIDGE_EBT_REDIRECT=m
+CONFIG_BRIDGE_EBT_SNAT=m
+CONFIG_BRIDGE_EBT_LOG=m
+# CONFIG_BRIDGE_EBT_ULOG is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_SCTP=m
+# CONFIG_SCTP_DBG_MSG is not set
+# CONFIG_SCTP_DBG_OBJCNT is not set
+# CONFIG_SCTP_HMAC_NONE is not set
+# CONFIG_SCTP_HMAC_SHA1 is not set
+CONFIG_SCTP_HMAC_MD5=y
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
+CONFIG_ATM=y
+CONFIG_ATM_CLIP=y
+# CONFIG_ATM_CLIP_NO_ICMP is not set
+CONFIG_ATM_LANE=m
+CONFIG_ATM_MPOA=m
+CONFIG_ATM_BR2684=m
+# CONFIG_ATM_BR2684_IPFILTER is not set
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+CONFIG_DECNET=m
+# CONFIG_DECNET_ROUTER is not set
+CONFIG_LLC=m
+CONFIG_LLC2=m
+CONFIG_IPX=m
+# CONFIG_IPX_INTERN is not set
+CONFIG_ATALK=m
+CONFIG_DEV_APPLETALK=y
+CONFIG_IPDDP=m
+CONFIG_IPDDP_ENCAP=y
+CONFIG_IPDDP_DECAP=y
+CONFIG_X25=m
+CONFIG_LAPB=m
+# CONFIG_NET_DIVERT is not set
+CONFIG_ECONET=m
+CONFIG_ECONET_AUNUDP=y
+CONFIG_ECONET_NATIVE=y
+CONFIG_WAN_ROUTER=m
+
+#
+# QoS and/or fair queueing
+#
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_CLK_JIFFIES=y
+# CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set
+# CONFIG_NET_SCH_CLK_CPU is not set
+
+#
+# Queueing/Scheduling
+#
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_ATM=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_NETEM=m
+CONFIG_NET_SCH_INGRESS=m
+
+#
+# Classification
+#
+CONFIG_NET_CLS=y
+# CONFIG_NET_CLS_BASIC is not set
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_ROUTE=y
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+# CONFIG_CLS_U32_PERF is not set
+# CONFIG_CLS_U32_MARK is not set
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+# CONFIG_NET_EMATCH is not set
+# CONFIG_NET_CLS_ACT is not set
+CONFIG_NET_CLS_POLICE=y
+# CONFIG_NET_CLS_IND is not set
+CONFIG_NET_ESTIMATOR=y
+
+#
+# Network testing
+#
+CONFIG_NET_PKTGEN=m
+CONFIG_HAMRADIO=y
+
+#
+# Packet Radio protocols
+#
+CONFIG_AX25=m
+# CONFIG_AX25_DAMA_SLAVE is not set
+CONFIG_NETROM=m
+CONFIG_ROSE=m
+
+#
+# AX.25 network device drivers
+#
+CONFIG_MKISS=m
+CONFIG_6PACK=m
+CONFIG_BPQETHER=m
+CONFIG_BAYCOM_SER_FDX=m
+CONFIG_BAYCOM_SER_HDX=m
+CONFIG_BAYCOM_PAR=m
+CONFIG_BAYCOM_EPP=m
+CONFIG_YAM=m
+CONFIG_IRDA=m
+
+#
+# IrDA protocols
+#
+CONFIG_IRLAN=m
+CONFIG_IRNET=m
+CONFIG_IRCOMM=m
+# CONFIG_IRDA_ULTRA is not set
+
+#
+# IrDA options
+#
+CONFIG_IRDA_CACHE_LAST_LSAP=y
+CONFIG_IRDA_FAST_RR=y
+CONFIG_IRDA_DEBUG=y
+
+#
+# Infrared-port device drivers
+#
+
+#
+# SIR device drivers
+#
+CONFIG_IRTTY_SIR=m
+
+#
+# Dongle support
+#
+CONFIG_DONGLE=y
+CONFIG_ESI_DONGLE=m
+CONFIG_ACTISYS_DONGLE=m
+CONFIG_TEKRAM_DONGLE=m
+# CONFIG_TOIM3232_DONGLE is not set
+CONFIG_LITELINK_DONGLE=m
+CONFIG_MA600_DONGLE=m
+CONFIG_GIRBIL_DONGLE=m
+CONFIG_MCP2120_DONGLE=m
+CONFIG_OLD_BELKIN_DONGLE=m
+CONFIG_ACT200L_DONGLE=m
+
+#
+# Old SIR device drivers
+#
+CONFIG_IRPORT_SIR=m
+
+#
+# Old Serial dongle support
+#
+# CONFIG_DONGLE_OLD is not set
+
+#
+# FIR device drivers
+#
+CONFIG_USB_IRDA=m
+CONFIG_SIGMATEL_FIR=m
+CONFIG_BT=m
+CONFIG_BT_L2CAP=m
+CONFIG_BT_SCO=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_CMTP=m
+CONFIG_BT_HIDP=m
+
+#
+# Bluetooth device drivers
+#
+CONFIG_BT_HCIUSB=m
+CONFIG_BT_HCIUSB_SCO=y
+CONFIG_BT_HCIUART=m
+CONFIG_BT_HCIUART_H4=y
+CONFIG_BT_HCIUART_BCSP=y
+CONFIG_BT_HCIBCM203X=m
+# CONFIG_BT_HCIBPA10X is not set
+CONFIG_BT_HCIBFUSB=m
+CONFIG_BT_HCIDTL1=m
+CONFIG_BT_HCIBT3C=m
+CONFIG_BT_HCIBLUECARD=m
+CONFIG_BT_HCIBTUART=m
+CONFIG_BT_HCIVHCI=m
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+# CONFIG_IEEE80211_CRYPT_WEP is not set
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+# CONFIG_IEEE80211_SOFTMAC is not set
+CONFIG_WIRELESS_EXT=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=m
+# CONFIG_DEBUG_DRIVER is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=m
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_CONCAT=m
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_REDBOOT_PARTS=m
+CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
+# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set
+# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=m
+CONFIG_MTD_BLOCK=m
+CONFIG_MTD_BLOCK_RO=m
+CONFIG_FTL=m
+CONFIG_NFTL=m
+CONFIG_NFTL_RW=y
+CONFIG_INFTL=m
+# CONFIG_RFD_FTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=m
+CONFIG_MTD_JEDECPROBE=m
+CONFIG_MTD_GEN_PROBE=m
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+CONFIG_MTD_CFI_INTELEXT=m
+CONFIG_MTD_CFI_AMDSTD=m
+CONFIG_MTD_CFI_STAA=m
+CONFIG_MTD_CFI_UTIL=m
+CONFIG_MTD_RAM=m
+CONFIG_MTD_ROM=m
+CONFIG_MTD_ABSENT=m
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+
+#
+# Mapping drivers for chip access
+#
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+CONFIG_MTD_PHYSMAP=m
+CONFIG_MTD_PHYSMAP_START=0x8000000
+CONFIG_MTD_PHYSMAP_LEN=0x4000000
+CONFIG_MTD_PHYSMAP_BANKWIDTH=2
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_IMPA7 is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+CONFIG_MTD_SLRAM=m
+CONFIG_MTD_PHRAM=m
+CONFIG_MTD_MTDRAM=m
+CONFIG_MTDRAM_TOTAL_SIZE=4096
+CONFIG_MTDRAM_ERASE_SIZE=128
+CONFIG_MTD_BLKMTD=m
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+CONFIG_MTD_DOC2000=m
+CONFIG_MTD_DOC2001=m
+CONFIG_MTD_DOC2001PLUS=m
+CONFIG_MTD_DOCPROBE=m
+CONFIG_MTD_DOCECC=m
+# CONFIG_MTD_DOCPROBE_ADVANCED is not set
+CONFIG_MTD_DOCPROBE_ADDRESS=0
+
+#
+# NAND Flash Device Drivers
+#
+CONFIG_MTD_NAND=m
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+CONFIG_MTD_NAND_IDS=m
+CONFIG_MTD_NAND_DISKONCHIP=m
+# CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED is not set
+CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0
+# CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+
+#
+# OneNAND Flash Device Drivers
+#
+# CONFIG_MTD_ONENAND is not set
+
+#
+# Parallel port support
+#
+CONFIG_PARPORT=m
+CONFIG_PARPORT_PC=m
+CONFIG_PARPORT_PC_FIFO=y
+# CONFIG_PARPORT_PC_SUPERIO is not set
+CONFIG_PARPORT_PC_PCMCIA=m
+CONFIG_PARPORT_NOT_PC=y
+# CONFIG_PARPORT_ARC is not set
+# CONFIG_PARPORT_GSC is not set
+CONFIG_PARPORT_1284=y
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+CONFIG_PARIDE=m
+CONFIG_PARIDE_PARPORT=m
+
+#
+# Parallel IDE high-level drivers
+#
+CONFIG_PARIDE_PD=m
+CONFIG_PARIDE_PCD=m
+CONFIG_PARIDE_PF=m
+CONFIG_PARIDE_PT=m
+CONFIG_PARIDE_PG=m
+
+#
+# Parallel IDE protocol modules
+#
+CONFIG_PARIDE_ATEN=m
+CONFIG_PARIDE_BPCK=m
+CONFIG_PARIDE_BPCK6=m
+CONFIG_PARIDE_COMM=m
+CONFIG_PARIDE_DSTR=m
+CONFIG_PARIDE_FIT2=m
+CONFIG_PARIDE_FIT3=m
+CONFIG_PARIDE_EPAT=m
+# CONFIG_PARIDE_EPATC8 is not set
+CONFIG_PARIDE_EPIA=m
+CONFIG_PARIDE_FRIQ=m
+CONFIG_PARIDE_FRPW=m
+CONFIG_PARIDE_KBIC=m
+CONFIG_PARIDE_KTTI=m
+CONFIG_PARIDE_ON20=m
+CONFIG_PARIDE_ON26=m
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=m
+CONFIG_BLK_DEV_IDE=m
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=m
+# CONFIG_IDEDISK_MULTI_MODE is not set
+CONFIG_BLK_DEV_IDECS=m
+CONFIG_BLK_DEV_IDECD=m
+CONFIG_BLK_DEV_IDETAPE=m
+CONFIG_BLK_DEV_IDEFLOPPY=m
+CONFIG_BLK_DEV_IDESCSI=m
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=m
+# CONFIG_IDE_ARM is not set
+# CONFIG_BLK_DEV_IDEDMA is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=m
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=m
+CONFIG_CHR_DEV_ST=m
+CONFIG_CHR_DEV_OSST=m
+CONFIG_BLK_DEV_SR=m
+# CONFIG_BLK_DEV_SR_VENDOR is not set
+CONFIG_CHR_DEV_SG=m
+CONFIG_CHR_DEV_SCH=m
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+
+#
+# SCSI Transport Attributes
+#
+CONFIG_SCSI_SPI_ATTRS=m
+CONFIG_SCSI_FC_ATTRS=m
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_ISCSI_TCP is not set
+CONFIG_SCSI_SATA=m
+CONFIG_SCSI_PPA=m
+CONFIG_SCSI_IMM=m
+# CONFIG_SCSI_IZIP_EPP16 is not set
+# CONFIG_SCSI_IZIP_SLOW_CTR is not set
+CONFIG_SCSI_DEBUG=m
+
+#
+# PCMCIA SCSI adapter support
+#
+CONFIG_PCMCIA_AHA152X=m
+CONFIG_PCMCIA_FDOMAIN=m
+CONFIG_PCMCIA_NINJA_SCSI=m
+CONFIG_PCMCIA_QLOGIC=m
+CONFIG_PCMCIA_SYM53C500=m
+
+#
+# Multi-device support (RAID and LVM)
+#
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=m
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD_RAID10=m
+CONFIG_MD_RAID5=m
+# CONFIG_MD_RAID5_RESHAPE is not set
+CONFIG_MD_RAID6=m
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_FAULTY=m
+CONFIG_BLK_DEV_DM=m
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
+# CONFIG_DM_MULTIPATH is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# I2O device support
+#
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=m
+CONFIG_BONDING=m
+CONFIG_EQUALIZER=m
+CONFIG_TUN=m
+
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=m
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+CONFIG_NET_POCKET=y
+CONFIG_DE600=m
+CONFIG_DE620=m
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+
+#
+# Wireless LAN (non-hamradio)
+#
+CONFIG_NET_RADIO=y
+# CONFIG_NET_WIRELESS_RTNETLINK is not set
+
+#
+# Obsolete Wireless cards support (pre-802.11)
+#
+CONFIG_STRIP=m
+CONFIG_PCMCIA_WAVELAN=m
+CONFIG_PCMCIA_NETWAVE=m
+
+#
+# Wireless 802.11 Frequency Hopping cards support
+#
+CONFIG_PCMCIA_RAYCS=m
+
+#
+# Wireless 802.11b ISA/PCI cards support
+#
+CONFIG_HERMES=m
+CONFIG_ATMEL=m
+
+#
+# Wireless 802.11b Pcmcia/Cardbus cards support
+#
+CONFIG_PCMCIA_HERMES=m
+# CONFIG_PCMCIA_SPECTRUM is not set
+CONFIG_AIRO_CS=m
+CONFIG_PCMCIA_ATMEL=m
+CONFIG_PCMCIA_WL3501=m
+# CONFIG_HOSTAP is not set
+CONFIG_NET_WIRELESS=y
+
+#
+# PCMCIA network device support
+#
+CONFIG_NET_PCMCIA=y
+CONFIG_PCMCIA_3C589=m
+CONFIG_PCMCIA_3C574=m
+CONFIG_PCMCIA_FMVJ18X=m
+CONFIG_PCMCIA_PCNET=m
+CONFIG_PCMCIA_NMCLAN=m
+CONFIG_PCMCIA_SMC91C92=m
+CONFIG_PCMCIA_XIRC2PS=m
+CONFIG_PCMCIA_AXNET=m
+
+#
+# Wan interfaces
+#
+CONFIG_WAN=y
+CONFIG_SYNCLINK_SYNCPPP=m
+CONFIG_HDLC=m
+CONFIG_HDLC_RAW=y
+CONFIG_HDLC_RAW_ETH=y
+CONFIG_HDLC_CISCO=y
+CONFIG_HDLC_FR=y
+CONFIG_HDLC_PPP=y
+CONFIG_HDLC_X25=y
+CONFIG_DLCI=m
+CONFIG_DLCI_COUNT=24
+CONFIG_DLCI_MAX=8
+CONFIG_WAN_ROUTER_DRIVERS=y
+CONFIG_LAPBETHER=m
+CONFIG_X25_ASY=m
+
+#
+# ATM drivers
+#
+# CONFIG_ATM_DUMMY is not set
+CONFIG_ATM_TCP=m
+CONFIG_PLIP=m
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_MPPE=m
+CONFIG_PPPOE=m
+CONFIG_PPPOATM=m
+CONFIG_SLIP=m
+CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLIP_SMART=y
+CONFIG_SLIP_MODE_SLIP6=y
+CONFIG_SHAPER=m
+CONFIG_NETCONSOLE=m
+CONFIG_NETPOLL=y
+# CONFIG_NETPOLL_RX is not set
+# CONFIG_NETPOLL_TRAP is not set
+CONFIG_NET_POLL_CONTROLLER=y
+
+#
+# ISDN subsystem
+#
+CONFIG_ISDN=m
+
+#
+# Old ISDN4Linux
+#
+CONFIG_ISDN_I4L=m
+CONFIG_ISDN_PPP=y
+CONFIG_ISDN_PPP_VJ=y
+CONFIG_ISDN_MPP=y
+CONFIG_IPPP_FILTER=y
+CONFIG_ISDN_PPP_BSDCOMP=m
+CONFIG_ISDN_AUDIO=y
+CONFIG_ISDN_TTY_FAX=y
+CONFIG_ISDN_X25=y
+
+#
+# ISDN feature submodules
+#
+CONFIG_ISDN_DRV_LOOP=m
+CONFIG_ISDN_DIVERSION=m
+
+#
+# ISDN4Linux hardware drivers
+#
+
+#
+# Passive cards
+#
+CONFIG_ISDN_DRV_HISAX=m
+
+#
+# D-channel protocol features
+#
+CONFIG_HISAX_EURO=y
+CONFIG_DE_AOC=y
+# CONFIG_HISAX_NO_SENDCOMPLETE is not set
+# CONFIG_HISAX_NO_LLC is not set
+# CONFIG_HISAX_NO_KEYPAD is not set
+CONFIG_HISAX_1TR6=y
+CONFIG_HISAX_NI1=y
+CONFIG_HISAX_MAX_CARDS=8
+
+#
+# HiSax supported cards
+#
+CONFIG_HISAX_16_3=y
+CONFIG_HISAX_S0BOX=y
+CONFIG_HISAX_FRITZPCI=y
+CONFIG_HISAX_AVM_A1_PCMCIA=y
+CONFIG_HISAX_ELSA=y
+CONFIG_HISAX_DIEHLDIVA=y
+CONFIG_HISAX_SEDLBAUER=y
+CONFIG_HISAX_NICCY=y
+CONFIG_HISAX_GAZEL=y
+CONFIG_HISAX_HFC_SX=y
+# CONFIG_HISAX_DEBUG is not set
+
+#
+# HiSax PCMCIA card service modules
+#
+CONFIG_HISAX_SEDLBAUER_CS=m
+CONFIG_HISAX_ELSA_CS=m
+CONFIG_HISAX_AVM_A1_CS=m
+CONFIG_HISAX_TELES_CS=m
+
+#
+# HiSax sub driver modules
+#
+CONFIG_HISAX_ST5481=m
+CONFIG_HISAX_HFCUSB=m
+# CONFIG_HISAX_HFC4S8S is not set
+CONFIG_HISAX_HDLC=y
+
+#
+# Active cards
+#
+
+#
+# Siemens Gigaset
+#
+# CONFIG_ISDN_DRV_GIGASET is not set
+
+#
+# CAPI subsystem
+#
+CONFIG_ISDN_CAPI=m
+CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON=y
+CONFIG_ISDN_CAPI_MIDDLEWARE=y
+CONFIG_ISDN_CAPI_CAPI20=m
+CONFIG_ISDN_CAPI_CAPIFS_BOOL=y
+CONFIG_ISDN_CAPI_CAPIFS=m
+CONFIG_ISDN_CAPI_CAPIDRV=m
+
+#
+# CAPI hardware drivers
+#
+
+#
+# Active AVM cards
+#
+CONFIG_CAPI_AVM=y
+CONFIG_ISDN_DRV_AVMB1_B1PCMCIA=m
+CONFIG_ISDN_DRV_AVMB1_AVM_CS=m
+
+#
+# Active Eicon DIVA Server cards
+#
+CONFIG_CAPI_EICON=y
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=m
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+CONFIG_INPUT_JOYDEV=m
+CONFIG_INPUT_TSDEV=m
+CONFIG_INPUT_TSDEV_SCREEN_X=240
+CONFIG_INPUT_TSDEV_SCREEN_Y=320
+CONFIG_INPUT_EVDEV=m
+CONFIG_INPUT_EVBUG=m
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+CONFIG_KEYBOARD_SUNKBD=m
+CONFIG_KEYBOARD_LKKBD=m
+CONFIG_KEYBOARD_XTKBD=m
+CONFIG_KEYBOARD_NEWTON=m
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=m
+CONFIG_MOUSE_SERIAL=m
+CONFIG_MOUSE_VSXXXAA=m
+CONFIG_INPUT_JOYSTICK=y
+CONFIG_JOYSTICK_ANALOG=m
+CONFIG_JOYSTICK_A3D=m
+CONFIG_JOYSTICK_ADI=m
+CONFIG_JOYSTICK_COBRA=m
+CONFIG_JOYSTICK_GF2K=m
+CONFIG_JOYSTICK_GRIP=m
+CONFIG_JOYSTICK_GRIP_MP=m
+CONFIG_JOYSTICK_GUILLEMOT=m
+CONFIG_JOYSTICK_INTERACT=m
+CONFIG_JOYSTICK_SIDEWINDER=m
+CONFIG_JOYSTICK_TMDC=m
+CONFIG_JOYSTICK_IFORCE=m
+CONFIG_JOYSTICK_IFORCE_USB=y
+CONFIG_JOYSTICK_IFORCE_232=y
+CONFIG_JOYSTICK_WARRIOR=m
+CONFIG_JOYSTICK_MAGELLAN=m
+CONFIG_JOYSTICK_SPACEORB=m
+CONFIG_JOYSTICK_SPACEBALL=m
+CONFIG_JOYSTICK_STINGER=m
+# CONFIG_JOYSTICK_TWIDJOY is not set
+CONFIG_JOYSTICK_DB9=m
+CONFIG_JOYSTICK_GAMECON=m
+CONFIG_JOYSTICK_TURBOGRAFX=m
+CONFIG_JOYSTICK_JOYDUMP=m
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_GUNZE=m
+# CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_MK712 is not set
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_UINPUT=m
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=m
+CONFIG_SERIO_PARKBD=m
+CONFIG_SERIO_LIBPS2=y
+CONFIG_SERIO_RAW=m
+CONFIG_GAMEPORT=m
+CONFIG_GAMEPORT_NS558=m
+CONFIG_GAMEPORT_L4=m
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_SERIAL_NONSTANDARD=y
+CONFIG_COMPUTONE=m
+CONFIG_ROCKETPORT=m
+CONFIG_CYCLADES=m
+# CONFIG_CYZ_INTR is not set
+CONFIG_DIGIEPCA=m
+CONFIG_MOXA_INTELLIO=m
+CONFIG_MOXA_SMARTIO=m
+# CONFIG_ISI is not set
+CONFIG_SYNCLINKMP=m
+CONFIG_N_HDLC=m
+# CONFIG_RISCOM8 is not set
+# CONFIG_SPECIALIX is not set
+CONFIG_SX=m
+CONFIG_RIO=m
+CONFIG_RIO_OLDPCI=y
+CONFIG_STALDRV=y
+CONFIG_STALLION=m
+CONFIG_ISTALLION=m
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_CS=m
+CONFIG_SERIAL_8250_NR_UARTS=4
+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=y
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+CONFIG_PRINTER=m
+# CONFIG_LP_CONSOLE is not set
+CONFIG_PPDEV=m
+CONFIG_TIPAR=m
+
+#
+# IPMI
+#
+CONFIG_IPMI_HANDLER=m
+# CONFIG_IPMI_PANIC_EVENT is not set
+CONFIG_IPMI_DEVICE_INTERFACE=m
+CONFIG_IPMI_SI=m
+CONFIG_IPMI_WATCHDOG=m
+CONFIG_IPMI_POWEROFF=m
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+CONFIG_SOFT_WATCHDOG=m
+
+#
+# USB-based Watchdog Cards
+#
+CONFIG_USBPCWATCHDOG=m
+CONFIG_NVRAM=m
+CONFIG_DTLK=m
+CONFIG_R3964=m
+
+#
+# Ftape, the floppy tape device driver
+#
+
+#
+# PCMCIA character devices
+#
+CONFIG_SYNCLINK_CS=m
+# CONFIG_CARDMAN_4000 is not set
+# CONFIG_CARDMAN_4040 is not set
+CONFIG_RAW_DRIVER=m
+CONFIG_MAX_RAW_DEVS=256
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+
+#
+# I2C support
+#
+CONFIG_I2C=m
+CONFIG_I2C_CHARDEV=m
+
+#
+# I2C Algorithms
+#
+CONFIG_I2C_ALGOBIT=m
+CONFIG_I2C_ALGOPCF=m
+CONFIG_I2C_ALGOPCA=m
+
+#
+# I2C Hardware Bus support
+#
+CONFIG_I2C_ISA=m
+CONFIG_I2C_PARPORT=m
+CONFIG_I2C_PARPORT_LIGHT=m
+CONFIG_I2C_STUB=m
+CONFIG_I2C_PCA_ISA=m
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
+CONFIG_SENSORS_EEPROM=m
+CONFIG_SENSORS_PCF8574=m
+# CONFIG_SENSORS_PCA9539 is not set
+CONFIG_SENSORS_PCF8591=m
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+CONFIG_W1=m
+
+#
+# 1-wire Bus Masters
+#
+# CONFIG_W1_MASTER_DS9490 is not set
+# CONFIG_W1_MASTER_DS2482 is not set
+
+#
+# 1-wire Slaves
+#
+# CONFIG_W1_SLAVE_THERM is not set
+# CONFIG_W1_SLAVE_SMEM is not set
+# CONFIG_W1_SLAVE_DS2433 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+CONFIG_HWMON_VID=m
+CONFIG_SENSORS_ADM1021=m
+CONFIG_SENSORS_ADM1025=m
+CONFIG_SENSORS_ADM1026=m
+CONFIG_SENSORS_ADM1031=m
+# CONFIG_SENSORS_ADM9240 is not set
+CONFIG_SENSORS_ASB100=m
+# CONFIG_SENSORS_ATXP1 is not set
+CONFIG_SENSORS_DS1621=m
+# CONFIG_SENSORS_F71805F is not set
+CONFIG_SENSORS_FSCHER=m
+# CONFIG_SENSORS_FSCPOS is not set
+CONFIG_SENSORS_GL518SM=m
+# CONFIG_SENSORS_GL520SM is not set
+CONFIG_SENSORS_IT87=m
+CONFIG_SENSORS_LM63=m
+CONFIG_SENSORS_LM75=m
+CONFIG_SENSORS_LM77=m
+CONFIG_SENSORS_LM78=m
+CONFIG_SENSORS_LM80=m
+CONFIG_SENSORS_LM83=m
+CONFIG_SENSORS_LM85=m
+CONFIG_SENSORS_LM87=m
+CONFIG_SENSORS_LM90=m
+# CONFIG_SENSORS_LM92 is not set
+CONFIG_SENSORS_MAX1619=m
+CONFIG_SENSORS_PC87360=m
+CONFIG_SENSORS_SMSC47M1=m
+# CONFIG_SENSORS_SMSC47B397 is not set
+CONFIG_SENSORS_W83781D=m
+# CONFIG_SENSORS_W83792D is not set
+CONFIG_SENSORS_W83L785TS=m
+CONFIG_SENSORS_W83627HF=m
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Misc devices
+#
+
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+CONFIG_DVB=y
+CONFIG_DVB_CORE=m
+
+#
+# Supported USB Adapters
+#
+# CONFIG_DVB_USB is not set
+CONFIG_DVB_TTUSB_BUDGET=m
+CONFIG_DVB_TTUSB_DEC=m
+CONFIG_DVB_CINERGYT2=m
+CONFIG_DVB_CINERGYT2_TUNING=y
+CONFIG_DVB_CINERGYT2_STREAM_URB_COUNT=32
+CONFIG_DVB_CINERGYT2_STREAM_BUF_SIZE=512
+CONFIG_DVB_CINERGYT2_QUERY_INTERVAL=250
+CONFIG_DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE=y
+CONFIG_DVB_CINERGYT2_RC_QUERY_INTERVAL=100
+
+#
+# Supported FlexCopII (B2C2) Adapters
+#
+# CONFIG_DVB_B2C2_FLEXCOP is not set
+
+#
+# Supported DVB Frontends
+#
+
+#
+# Customise DVB Frontends
+#
+
+#
+# DVB-S (satellite) frontends
+#
+CONFIG_DVB_STV0299=m
+CONFIG_DVB_CX24110=m
+# CONFIG_DVB_CX24123 is not set
+CONFIG_DVB_TDA8083=m
+CONFIG_DVB_MT312=m
+CONFIG_DVB_VES1X93=m
+# CONFIG_DVB_S5H1420 is not set
+
+#
+# DVB-T (terrestrial) frontends
+#
+CONFIG_DVB_SP8870=m
+CONFIG_DVB_SP887X=m
+CONFIG_DVB_CX22700=m
+CONFIG_DVB_CX22702=m
+CONFIG_DVB_L64781=m
+CONFIG_DVB_TDA1004X=m
+CONFIG_DVB_NXT6000=m
+CONFIG_DVB_MT352=m
+# CONFIG_DVB_ZL10353 is not set
+CONFIG_DVB_DIB3000MB=m
+CONFIG_DVB_DIB3000MC=m
+
+#
+# DVB-C (cable) frontends
+#
+CONFIG_DVB_VES1820=m
+CONFIG_DVB_TDA10021=m
+CONFIG_DVB_STV0297=m
+
+#
+# ATSC (North American/Korean Terresterial DTV) frontends
+#
+# CONFIG_DVB_NXT200X is not set
+# CONFIG_DVB_OR51211 is not set
+# CONFIG_DVB_OR51132 is not set
+# CONFIG_DVB_BCM3510 is not set
+# CONFIG_DVB_LGDT330X is not set
+# CONFIG_USB_DABUSB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+
+#
+# Sound
+#
+CONFIG_SOUND=m
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+CONFIG_SND_HWDEP=m
+CONFIG_SND_RAWMIDI=m
+CONFIG_SND_SEQUENCER=m
+CONFIG_SND_SEQ_DUMMY=m
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+CONFIG_SND_PCM_OSS_PLUGINS=y
+CONFIG_SND_SEQUENCER_OSS=y
+# CONFIG_SND_DYNAMIC_MINORS is not set
+CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+
+#
+# Generic devices
+#
+CONFIG_SND_MPU401_UART=m
+CONFIG_SND_DUMMY=m
+CONFIG_SND_VIRMIDI=m
+CONFIG_SND_MTPAV=m
+CONFIG_SND_SERIAL_U16550=m
+CONFIG_SND_MPU401=m
+
+#
+# ALSA ARM devices
+#
+
+#
+# USB devices
+#
+CONFIG_SND_USB_AUDIO=m
+
+#
+# PCMCIA devices
+#
+
+#
+# Open Sound System
+#
+CONFIG_SOUND_PRIME=m
+# CONFIG_OBSOLETE_OSS_DRIVER is not set
+# CONFIG_SOUND_MSNDCLAS is not set
+# CONFIG_SOUND_MSNDPIN is not set
+CONFIG_SOUND_TVMIXER=m
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+CONFIG_USB=m
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_BANDWIDTH=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_SUSPEND is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_ISP116X_HCD is not set
+CONFIG_USB_SL811_HCD=m
+# CONFIG_USB_SL811_CS is not set
+
+#
+# USB Device Class drivers
+#
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=m
+# CONFIG_USB_STORAGE_DEBUG is not set
+CONFIG_USB_STORAGE_DATAFAB=y
+CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_ISD200=y
+CONFIG_USB_STORAGE_DPCM=y
+CONFIG_USB_STORAGE_USBAT=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=m
+CONFIG_USB_HIDINPUT=y
+# CONFIG_USB_HIDINPUT_POWERBOOK is not set
+# CONFIG_HID_FF is not set
+CONFIG_USB_HIDDEV=y
+
+#
+# USB HID Boot Protocol drivers
+#
+CONFIG_USB_KBD=m
+CONFIG_USB_MOUSE=m
+CONFIG_USB_AIPTEK=m
+CONFIG_USB_WACOM=m
+# CONFIG_USB_ACECAD is not set
+CONFIG_USB_KBTAB=m
+CONFIG_USB_POWERMATE=m
+CONFIG_USB_MTOUCH=m
+# CONFIG_USB_ITMTOUCH is not set
+CONFIG_USB_EGALAX=m
+# CONFIG_USB_YEALINK is not set
+CONFIG_USB_XPAD=m
+CONFIG_USB_ATI_REMOTE=m
+# CONFIG_USB_ATI_REMOTE2 is not set
+# CONFIG_USB_KEYSPAN_REMOTE is not set
+# CONFIG_USB_APPLETOUCH is not set
+
+#
+# USB Imaging devices
+#
+CONFIG_USB_MDC800=m
+CONFIG_USB_MICROTEK=m
+
+#
+# USB Network Adapters
+#
+CONFIG_USB_CATC=m
+CONFIG_USB_KAWETH=m
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=m
+CONFIG_USB_USBNET=m
+CONFIG_USB_NET_AX8817X=m
+CONFIG_USB_NET_CDCETHER=m
+# CONFIG_USB_NET_GL620A is not set
+CONFIG_USB_NET_NET1080=m
+# CONFIG_USB_NET_PLUSB is not set
+# CONFIG_USB_NET_RNDIS_HOST is not set
+# CONFIG_USB_NET_CDC_SUBSET is not set
+CONFIG_USB_NET_ZAURUS=m
+# CONFIG_USB_ZD1201 is not set
+CONFIG_USB_MON=y
+
+#
+# USB port drivers
+#
+CONFIG_USB_USS720=m
+
+#
+# USB Serial Converter support
+#
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_GENERIC=y
+# CONFIG_USB_SERIAL_AIRPRIME is not set
+# CONFIG_USB_SERIAL_ANYDATA is not set
+CONFIG_USB_SERIAL_BELKIN=m
+CONFIG_USB_SERIAL_WHITEHEAT=m
+CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
+# CONFIG_USB_SERIAL_CP2101 is not set
+CONFIG_USB_SERIAL_CYPRESS_M8=m
+CONFIG_USB_SERIAL_EMPEG=m
+CONFIG_USB_SERIAL_FTDI_SIO=m
+CONFIG_USB_SERIAL_VISOR=m
+CONFIG_USB_SERIAL_IPAQ=m
+CONFIG_USB_SERIAL_IR=m
+CONFIG_USB_SERIAL_EDGEPORT=m
+CONFIG_USB_SERIAL_EDGEPORT_TI=m
+# CONFIG_USB_SERIAL_GARMIN is not set
+CONFIG_USB_SERIAL_IPW=m
+CONFIG_USB_SERIAL_KEYSPAN_PDA=m
+CONFIG_USB_SERIAL_KEYSPAN=m
+# CONFIG_USB_SERIAL_KEYSPAN_MPR is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19QW is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19QI is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA49WLC is not set
+CONFIG_USB_SERIAL_KLSI=m
+CONFIG_USB_SERIAL_KOBIL_SCT=m
+CONFIG_USB_SERIAL_MCT_U232=m
+# CONFIG_USB_SERIAL_NAVMAN is not set
+CONFIG_USB_SERIAL_PL2303=m
+# CONFIG_USB_SERIAL_HP4X is not set
+CONFIG_USB_SERIAL_SAFE=m
+# CONFIG_USB_SERIAL_SAFE_PADDED is not set
+# CONFIG_USB_SERIAL_TI is not set
+CONFIG_USB_SERIAL_CYBERJACK=m
+CONFIG_USB_SERIAL_XIRCOM=m
+CONFIG_USB_SERIAL_OMNINET=m
+CONFIG_USB_EZUSB=y
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+CONFIG_USB_AUERSWALD=m
+CONFIG_USB_RIO500=m
+CONFIG_USB_LEGOTOWER=m
+CONFIG_USB_LCD=m
+CONFIG_USB_LED=m
+CONFIG_USB_CYTHERM=m
+CONFIG_USB_PHIDGETKIT=m
+CONFIG_USB_PHIDGETSERVO=m
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_LD is not set
+CONFIG_USB_TEST=m
+
+#
+# USB DSL modem support
+#
+CONFIG_USB_ATM=m
+CONFIG_USB_SPEEDTOUCH=m
+# CONFIG_USB_CXACRU is not set
+# CONFIG_USB_UEAGLEATM is not set
+# CONFIG_USB_XUSBATM is not set
+
+#
+# USB Gadget Support
+#
+CONFIG_USB_GADGET=m
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_PXA2XX is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_AT91 is not set
+CONFIG_USB_GADGET_DUMMY_HCD=y
+CONFIG_USB_DUMMY_HCD=m
+CONFIG_USB_GADGET_DUALSPEED=y
+CONFIG_USB_ZERO=m
+CONFIG_USB_ETH=m
+CONFIG_USB_ETH_RNDIS=y
+CONFIG_USB_GADGETFS=m
+CONFIG_USB_FILE_STORAGE=m
+# CONFIG_USB_FILE_STORAGE_TEST is not set
+CONFIG_USB_G_SERIAL=m
+
+#
+# MMC/SD Card support
+#
+CONFIG_MMC=m
+# CONFIG_MMC_DEBUG is not set
+CONFIG_MMC_BLOCK=m
+
+#
+# Real Time Clock
+#
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=m
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_JBD=m
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+CONFIG_REISERFS_FS=m
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+CONFIG_REISERFS_FS_XATTR=y
+CONFIG_REISERFS_FS_POSIX_ACL=y
+CONFIG_REISERFS_FS_SECURITY=y
+CONFIG_JFS_FS=m
+CONFIG_JFS_POSIX_ACL=y
+# CONFIG_JFS_SECURITY is not set
+# CONFIG_JFS_DEBUG is not set
+CONFIG_JFS_STATISTICS=y
+CONFIG_FS_POSIX_ACL=y
+CONFIG_XFS_FS=m
+CONFIG_XFS_EXPORT=y
+CONFIG_XFS_QUOTA=y
+CONFIG_XFS_SECURITY=y
+CONFIG_XFS_POSIX_ACL=y
+CONFIG_XFS_RT=y
+# CONFIG_OCFS2_FS is not set
+CONFIG_MINIX_FS=m
+CONFIG_ROMFS_FS=m
+CONFIG_INOTIFY=y
+CONFIG_QUOTA=y
+CONFIG_QFMT_V1=m
+CONFIG_QFMT_V2=m
+CONFIG_QUOTACTL=y
+CONFIG_DNOTIFY=y
+CONFIG_AUTOFS_FS=m
+CONFIG_AUTOFS4_FS=m
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_ZISOFS_FS=m
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+CONFIG_NTFS_FS=m
+# CONFIG_NTFS_DEBUG is not set
+# CONFIG_NTFS_RW is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+CONFIG_ADFS_FS=m
+# CONFIG_ADFS_FS_RW is not set
+CONFIG_AFFS_FS=m
+CONFIG_HFS_FS=m
+CONFIG_HFSPLUS_FS=m
+CONFIG_BEFS_FS=m
+# CONFIG_BEFS_DEBUG is not set
+CONFIG_BFS_FS=m
+CONFIG_EFS_FS=m
+CONFIG_JFFS_FS=m
+CONFIG_JFFS_FS_VERBOSE=0
+CONFIG_JFFS_PROC_FS=y
+CONFIG_JFFS2_FS=m
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+CONFIG_CRAMFS=y
+CONFIG_VXFS_FS=m
+CONFIG_HPFS_FS=m
+CONFIG_QNX4FS_FS=m
+CONFIG_SYSV_FS=m
+CONFIG_UFS_FS=m
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+CONFIG_NFS_V4=y
+CONFIG_NFS_DIRECTIO=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
+CONFIG_NFSD_V4=y
+CONFIG_NFSD_TCP=y
+CONFIG_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=m
+CONFIG_SUNRPC_GSS=m
+CONFIG_RPCSEC_GSS_KRB5=m
+CONFIG_RPCSEC_GSS_SPKM3=m
+CONFIG_SMB_FS=m
+# CONFIG_SMB_NLS_DEFAULT is not set
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+# CONFIG_CIFS_XATTR is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
+CONFIG_NCP_FS=m
+CONFIG_NCPFS_PACKET_SIGNING=y
+CONFIG_NCPFS_IOCTL_LOCKING=y
+CONFIG_NCPFS_STRONG=y
+CONFIG_NCPFS_NFS_NS=y
+CONFIG_NCPFS_OS2_NS=y
+# CONFIG_NCPFS_SMALLDOS is not set
+CONFIG_NCPFS_NLS=y
+CONFIG_NCPFS_EXTRAS=y
+CONFIG_CODA_FS=m
+# CONFIG_CODA_FS_OLD_API is not set
+CONFIG_AFS_FS=m
+CONFIG_RXRPC=m
+# CONFIG_9P_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_ACORN_PARTITION=y
+# CONFIG_ACORN_PARTITION_CUMANA is not set
+# CONFIG_ACORN_PARTITION_EESOX is not set
+CONFIG_ACORN_PARTITION_ICS=y
+# CONFIG_ACORN_PARTITION_ADFS is not set
+# CONFIG_ACORN_PARTITION_POWERTEC is not set
+CONFIG_ACORN_PARTITION_RISCIX=y
+CONFIG_OSF_PARTITION=y
+CONFIG_AMIGA_PARTITION=y
+CONFIG_ATARI_PARTITION=y
+CONFIG_MAC_PARTITION=y
+CONFIG_MSDOS_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+CONFIG_LDM_PARTITION=y
+# CONFIG_LDM_DEBUG is not set
+CONFIG_SGI_PARTITION=y
+CONFIG_ULTRIX_PARTITION=y
+CONFIG_SUN_PARTITION=y
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="cp437"
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+
+#
+# Profiling support
+#
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=m
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_SLAB is not set
+CONFIG_DEBUG_PREEMPT=y
+CONFIG_DEBUG_MUTEXES=y
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_FS is not set
+# CONFIG_DEBUG_VM is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_UNWIND_INFO is not set
+CONFIG_FORCED_INLINING=y
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_WAITQ is not set
+# CONFIG_DEBUG_ERRORS is not set
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_ICEDCC is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+CONFIG_SECURITY=y
+# CONFIG_SECURITY_NETWORK is not set
+CONFIG_SECURITY_CAPABILITIES=m
+CONFIG_SECURITY_ROOTPLUG=m
+CONFIG_SECURITY_SECLVL=m
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+# CONFIG_CRYPTO_TGR192 is not set
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_TEST=m
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+CONFIG_CRC_CCITT=m
+CONFIG_CRC16=m
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_REED_SOLOMON=m
+CONFIG_REED_SOLOMON_DEC16=y
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index dbcb11a31f78..b5bcebca1cd6 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -271,7 +271,7 @@ ENTRY(sys_call_table)
@ r8 = syscall table
.type sys_syscall, #function
sys_syscall:
- eor scno, r0, #__NR_OABI_SYSCALL_BASE
+ bic scno, r0, #__NR_OABI_SYSCALL_BASE
cmp scno, #__NR_syscall - __NR_SYSCALL_BASE
cmpne scno, #NR_syscalls @ check range
stmloia sp, {r5, r6} @ shuffle args
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index 2d5896b36181..bcc19fbb32df 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -342,10 +342,10 @@ __do_irq(unsigned int irq, struct irqaction *action, struct pt_regs *regs)
#ifdef CONFIG_NO_IDLE_HZ
if (!(action->flags & SA_TIMER) && system_timer->dyn_tick != NULL) {
- write_seqlock(&xtime_lock);
+ spin_lock(&system_timer->dyn_tick->lock);
if (system_timer->dyn_tick->state & DYN_TICK_ENABLED)
system_timer->dyn_tick->handler(irq, 0, regs);
- write_sequnlock(&xtime_lock);
+ spin_unlock(&system_timer->dyn_tick->lock);
}
#endif
diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c
index d6bd435a6857..9c12d4fefbd3 100644
--- a/arch/arm/kernel/time.c
+++ b/arch/arm/kernel/time.c
@@ -379,7 +379,7 @@ static int timer_dyn_tick_enable(void)
int ret = -ENODEV;
if (dyn_tick) {
- write_seqlock_irqsave(&xtime_lock, flags);
+ spin_lock_irqsave(&dyn_tick->lock, flags);
ret = 0;
if (!(dyn_tick->state & DYN_TICK_ENABLED)) {
ret = dyn_tick->enable();
@@ -387,7 +387,7 @@ static int timer_dyn_tick_enable(void)
if (ret == 0)
dyn_tick->state |= DYN_TICK_ENABLED;
}
- write_sequnlock_irqrestore(&xtime_lock, flags);
+ spin_unlock_irqrestore(&dyn_tick->lock, flags);
}
return ret;
@@ -400,7 +400,7 @@ static int timer_dyn_tick_disable(void)
int ret = -ENODEV;
if (dyn_tick) {
- write_seqlock_irqsave(&xtime_lock, flags);
+ spin_lock_irqsave(&dyn_tick->lock, flags);
ret = 0;
if (dyn_tick->state & DYN_TICK_ENABLED) {
ret = dyn_tick->disable();
@@ -408,7 +408,7 @@ static int timer_dyn_tick_disable(void)
if (ret == 0)
dyn_tick->state &= ~DYN_TICK_ENABLED;
}
- write_sequnlock_irqrestore(&xtime_lock, flags);
+ spin_unlock_irqrestore(&dyn_tick->lock, flags);
}
return ret;
@@ -422,15 +422,20 @@ static int timer_dyn_tick_disable(void)
void timer_dyn_reprogram(void)
{
struct dyn_tick_timer *dyn_tick = system_timer->dyn_tick;
- unsigned long next, seq;
+ unsigned long next, seq, flags;
- if (dyn_tick && (dyn_tick->state & DYN_TICK_ENABLED)) {
+ if (!dyn_tick)
+ return;
+
+ spin_lock_irqsave(&dyn_tick->lock, flags);
+ if (dyn_tick->state & DYN_TICK_ENABLED) {
next = next_timer_interrupt();
do {
seq = read_seqbegin(&xtime_lock);
- dyn_tick->reprogram(next_timer_interrupt() - jiffies);
+ dyn_tick->reprogram(next - jiffies);
} while (read_seqretry(&xtime_lock, seq));
}
+ spin_unlock_irqrestore(&dyn_tick->lock, flags);
}
static ssize_t timer_show_dyn_tick(struct sys_device *dev, char *buf)
@@ -499,5 +504,10 @@ void __init time_init(void)
if (system_timer->offset == NULL)
system_timer->offset = dummy_gettimeoffset;
system_timer->init();
+
+#ifdef CONFIG_NO_IDLE_HZ
+ if (system_timer->dyn_tick)
+ system_timer->dyn_tick->lock = SPIN_LOCK_UNLOCKED;
+#endif
}
diff --git a/arch/arm/mach-lh7a40x/Kconfig b/arch/arm/mach-lh7a40x/Kconfig
index 8a17867a6a24..558a34f53b1c 100644
--- a/arch/arm/mach-lh7a40x/Kconfig
+++ b/arch/arm/mach-lh7a40x/Kconfig
@@ -14,6 +14,7 @@ config MACH_LPD7A400
bool "LPD7A400 Card Engine"
select ARCH_LH7A400
# select IDE_POLL
+ select HAS_TOUCHSCREEN_ADS7843_LH7
help
Say Y here if you are using Logic Product Development's
LPD7A400 CardEngine. For the time being, the LPD7A400 and
@@ -23,6 +24,7 @@ config MACH_LPD7A404
bool "LPD7A404 Card Engine"
select ARCH_LH7A404
# select IDE_POLL
+ select HAS_TOUCHSCREEN_ADC_LH7
help
Say Y here if you are using Logic Product Development's
LPD7A404 CardEngine. For the time being, the LPD7A400 and
@@ -34,6 +36,9 @@ config ARCH_LH7A400
config ARCH_LH7A404
bool
+config LPD7A40X_CPLD_SSP
+ bool
+
config LH7A40X_CONTIGMEM
bool "Disable NUMA Support"
depends on ARCH_LH7A40X
diff --git a/arch/arm/mach-lh7a40x/Makefile b/arch/arm/mach-lh7a40x/Makefile
index e90512dbc2d6..94b8615fb3c3 100644
--- a/arch/arm/mach-lh7a40x/Makefile
+++ b/arch/arm/mach-lh7a40x/Makefile
@@ -4,11 +4,14 @@
# Object file lists.
-obj-y := time.o
-obj-$(CONFIG_MACH_KEV7A400) += arch-kev7a400.o irq-lh7a400.o
-obj-$(CONFIG_MACH_LPD7A400) += arch-lpd7a40x.o irq-lh7a400.o
-obj-$(CONFIG_MACH_LPD7A404) += arch-lpd7a40x.o irq-lh7a404.o
-
-obj-m :=
-obj-n :=
-obj- :=
+obj-y := time.o clocks.o
+obj-m :=
+obj-n :=
+obj- :=
+
+obj-$(CONFIG_MACH_KEV7A400) += arch-kev7a400.o irq-lh7a400.o
+obj-$(CONFIG_MACH_LPD7A400) += arch-lpd7a40x.o irq-lh7a400.o
+obj-$(CONFIG_MACH_LPD7A404) += arch-lpd7a40x.o irq-lh7a404.o
+obj-$(CONFIG_LPD7A40X_CPLD_SSP) += ssp-cpld.o
+obj-$(CONFIG_FB_ARMCLCD) += clcd.o
+
diff --git a/arch/arm/mach-lh7a40x/arch-lpd7a40x.c b/arch/arm/mach-lh7a40x/arch-lpd7a40x.c
index 12e23277c5ea..c0e6854289f1 100644
--- a/arch/arm/mach-lh7a40x/arch-lpd7a40x.c
+++ b/arch/arm/mach-lh7a40x/arch-lpd7a40x.c
@@ -23,6 +23,28 @@
#include "common.h"
+#define CPLD_INT_NETHERNET (1<<0)
+#define CPLD_INTMASK_ETHERNET (1<<2)
+#if defined (CONFIG_MACH_LPD7A400)
+# define CPLD_INT_NTOUCH (1<<1)
+# define CPLD_INTMASK_TOUCH (1<<3)
+# define CPLD_INT_PEN (1<<4)
+# define CPLD_INTMASK_PEN (1<<4)
+# define CPLD_INT_PIRQ (1<<4)
+#endif
+#define CPLD_INTMASK_CPLD (1<<7)
+#define CPLD_INT_CPLD (1<<6)
+
+#define CPLD_CONTROL_SWINT (1<<7) /* Disable all CPLD IRQs */
+#define CPLD_CONTROL_OCMSK (1<<6) /* Mask USB1 connect IRQ */
+#define CPLD_CONTROL_PDRV (1<<5) /* PCC_nDRV high */
+#define CPLD_CONTROL_USB1C (1<<4) /* USB1 connect IRQ active */
+#define CPLD_CONTROL_USB1P (1<<3) /* USB1 power disable */
+#define CPLD_CONTROL_AWKP (1<<2) /* Auto-wakeup disabled */
+#define CPLD_CONTROL_LCD_ENABLE (1<<1) /* LCD Vee enable */
+#define CPLD_CONTROL_WRLAN_NENABLE (1<<0) /* SMC91x power disable */
+
+
static struct resource smc91x_resources[] = {
[0] = {
.start = CPLD00_PHYS,
@@ -48,12 +70,12 @@ static struct platform_device smc91x_device = {
static struct resource lh7a40x_usbclient_resources[] = {
[0] = {
.start = USB_PHYS,
- .end = (USB_PHYS + 0xFF),
+ .end = (USB_PHYS + PAGE_SIZE),
.flags = IORESOURCE_MEM,
},
[1] = {
- .start = IRQ_USBINTR,
- .end = IRQ_USBINTR,
+ .start = IRQ_USB,
+ .end = IRQ_USB,
.flags = IORESOURCE_IRQ,
},
};
@@ -61,7 +83,8 @@ static struct resource lh7a40x_usbclient_resources[] = {
static u64 lh7a40x_usbclient_dma_mask = 0xffffffffUL;
static struct platform_device lh7a40x_usbclient_device = {
- .name = "lh7a40x_udc",
+// .name = "lh7a40x_udc",
+ .name = "lh7-udc",
.id = 0,
.dev = {
.dma_mask = &lh7a40x_usbclient_dma_mask,
@@ -101,7 +124,7 @@ static struct platform_device lh7a404_usbhost_device = {
#endif
-static struct platform_device *lpd7a40x_devs[] __initdata = {
+static struct platform_device* lpd7a40x_devs[] __initdata = {
&smc91x_device,
&lh7a40x_usbclient_device,
#if defined (CONFIG_ARCH_LH7A404)
@@ -113,29 +136,52 @@ extern void lpd7a400_map_io (void);
static void __init lpd7a40x_init (void)
{
- CPLD_CONTROL |= (1<<6); /* Mask USB1 connection IRQ */
+#if defined (CONFIG_MACH_LPD7A400)
+ CPLD_CONTROL |= 0
+ | CPLD_CONTROL_SWINT /* Disable software interrupt */
+ | CPLD_CONTROL_OCMSK; /* Mask USB1 connection IRQ */
CPLD_CONTROL &= ~(0
- | (1<<1) /* Disable LCD */
- | (1<<0) /* Enable WLAN */
+ | CPLD_CONTROL_LCD_ENABLE /* Disable LCD */
+ | CPLD_CONTROL_WRLAN_NENABLE /* Enable SMC91x */
);
+#endif
+
+#if defined (CONFIG_MACH_LPD7A404)
+ CPLD_CONTROL &= ~(0
+ | CPLD_CONTROL_WRLAN_NENABLE /* Enable SMC91x */
+ );
+#endif
platform_add_devices (lpd7a40x_devs, ARRAY_SIZE (lpd7a40x_devs));
+#if defined (CONFIG_FB_ARMCLCD)
+ lh7a40x_clcd_init ();
+#endif
}
static void lh7a40x_ack_cpld_irq (u32 irq)
{
- /* CPLD doesn't have ack capability */
+ /* CPLD doesn't have ack capability, but some devices may */
+
+#if defined (CPLD_INTMASK_TOUCH)
+ /* The touch control *must* mask the the interrupt because the
+ * interrupt bit is read by the driver to determine if the pen
+ * is still down. */
+ if (irq == IRQ_TOUCH)
+ CPLD_INTERRUPTS |= CPLD_INTMASK_TOUCH;
+#endif
}
static void lh7a40x_mask_cpld_irq (u32 irq)
{
switch (irq) {
case IRQ_LPD7A40X_ETH_INT:
- CPLD_INTERRUPTS = CPLD_INTERRUPTS | 0x4;
+ CPLD_INTERRUPTS |= CPLD_INTMASK_ETHERNET;
break;
- case IRQ_LPD7A400_TS:
- CPLD_INTERRUPTS = CPLD_INTERRUPTS | 0x8;
+#if defined (IRQ_TOUCH)
+ case IRQ_TOUCH:
+ CPLD_INTERRUPTS |= CPLD_INTMASK_TOUCH;
break;
+#endif
}
}
@@ -143,11 +189,13 @@ static void lh7a40x_unmask_cpld_irq (u32 irq)
{
switch (irq) {
case IRQ_LPD7A40X_ETH_INT:
- CPLD_INTERRUPTS = CPLD_INTERRUPTS & ~ 0x4;
+ CPLD_INTERRUPTS &= ~CPLD_INTMASK_ETHERNET;
break;
- case IRQ_LPD7A400_TS:
- CPLD_INTERRUPTS = CPLD_INTERRUPTS & ~ 0x8;
+#if defined (IRQ_TOUCH)
+ case IRQ_TOUCH:
+ CPLD_INTERRUPTS &= ~CPLD_INTMASK_TOUCH;
break;
+#endif
}
}
@@ -164,11 +212,13 @@ static void lpd7a40x_cpld_handler (unsigned int irq, struct irqdesc *desc,
desc->chip->ack (irq);
- if ((mask & 0x1) == 0) /* WLAN */
+ if ((mask & (1<<0)) == 0) /* WLAN */
IRQ_DISPATCH (IRQ_LPD7A40X_ETH_INT);
- if ((mask & 0x2) == 0) /* Touch */
- IRQ_DISPATCH (IRQ_LPD7A400_TS);
+#if defined (IRQ_TOUCH)
+ if ((mask & (1<<1)) == 0) /* Touch */
+ IRQ_DISPATCH (IRQ_TOUCH);
+#endif
desc->chip->unmask (irq); /* Level-triggered need this */
}
@@ -204,9 +254,21 @@ void __init lh7a40x_init_board_irq (void)
/* Then, configure CPLD interrupt */
- CPLD_INTERRUPTS = 0x9c; /* Disable all CPLD interrupts */
+ /* Disable all CPLD interrupts */
+#if defined (CONFIG_MACH_LPD7A400)
+ CPLD_INTERRUPTS = CPLD_INTMASK_TOUCH | CPLD_INTMASK_PEN
+ | CPLD_INTMASK_ETHERNET;
+ /* *** FIXME: don't know why we need 7 and 4. 7 is way wrong
+ and 4 is uncefined. */
+ // (1<<7)|(1<<4)|(1<<3)|(1<<2);
+#endif
+#if defined (CONFIG_MACH_LPD7A404)
+ CPLD_INTERRUPTS = CPLD_INTMASK_ETHERNET;
+ /* *** FIXME: don't know why we need 6 and 5, neither is defined. */
+ // (1<<6)|(1<<5)|(1<<3);
+#endif
GPIO_PFDD &= ~(1 << pinCPLD); /* Make input */
- GPIO_INTTYPE1 |= (1 << pinCPLD); /* Edge triggered */
+ GPIO_INTTYPE1 &= ~(1 << pinCPLD); /* Level triggered */
GPIO_INTTYPE2 &= ~(1 << pinCPLD); /* Active low */
barrier ();
GPIO_GPIOFINTEN |= (1 << pinCPLD); /* Enable */
@@ -216,7 +278,7 @@ void __init lh7a40x_init_board_irq (void)
for (irq = IRQ_BOARD_START;
irq < IRQ_BOARD_START + NR_IRQ_BOARD; ++irq) {
set_irq_chip (irq, &lpd7a40x_cpld_chip);
- set_irq_handler (irq, do_edge_IRQ);
+ set_irq_handler (irq, do_level_IRQ);
set_irq_flags (irq, IRQF_VALID);
}
@@ -226,91 +288,109 @@ void __init lh7a40x_init_board_irq (void)
lpd7a40x_cpld_handler);
}
-static struct map_desc lpd7a400_io_desc[] __initdata = {
+static struct map_desc lpd7a40x_io_desc[] __initdata = {
{
- .virtual = IO_VIRT,
+ .virtual = IO_VIRT,
.pfn = __phys_to_pfn(IO_PHYS),
- .length = IO_SIZE,
+ .length = IO_SIZE,
.type = MT_DEVICE
- }, { /* Mapping added to work around chip select problems */
+ },
+ { /* Mapping added to work around chip select problems */
.virtual = IOBARRIER_VIRT,
.pfn = __phys_to_pfn(IOBARRIER_PHYS),
.length = IOBARRIER_SIZE,
.type = MT_DEVICE
- }, {
+ },
+ {
.virtual = CF_VIRT,
.pfn = __phys_to_pfn(CF_PHYS),
- .length = CF_SIZE,
+ .length = CF_SIZE,
.type = MT_DEVICE
- }, {
+ },
+ {
.virtual = CPLD02_VIRT,
.pfn = __phys_to_pfn(CPLD02_PHYS),
- .length = CPLD02_SIZE,
+ .length = CPLD02_SIZE,
.type = MT_DEVICE
- }, {
+ },
+ {
.virtual = CPLD06_VIRT,
.pfn = __phys_to_pfn(CPLD06_PHYS),
- .length = CPLD06_SIZE,
+ .length = CPLD06_SIZE,
+ .type = MT_DEVICE
+ },
+ {
+ .virtual = CPLD08_VIRT,
+ .pfn = __phys_to_pfn(CPLD08_PHYS),
+ .length = CPLD08_SIZE,
.type = MT_DEVICE
- }, {
+ },
+ {
.virtual = CPLD08_VIRT,
.pfn = __phys_to_pfn(CPLD08_PHYS),
- .length = CPLD08_SIZE,
+ .length = CPLD08_SIZE,
.type = MT_DEVICE
- }, {
+ },
+ {
+ .virtual = CPLD0A_VIRT,
+ .pfn = __phys_to_pfn(CPLD0A_PHYS),
+ .length = CPLD0A_SIZE,
+ .type = MT_DEVICE
+ },
+ {
.virtual = CPLD0C_VIRT,
.pfn = __phys_to_pfn(CPLD0C_PHYS),
- .length = CPLD0C_SIZE,
+ .length = CPLD0C_SIZE,
.type = MT_DEVICE
- }, {
+ },
+ {
.virtual = CPLD0E_VIRT,
.pfn = __phys_to_pfn(CPLD0E_PHYS),
- .length = CPLD0E_SIZE,
+ .length = CPLD0E_SIZE,
.type = MT_DEVICE
- }, {
+ },
+ {
.virtual = CPLD10_VIRT,
.pfn = __phys_to_pfn(CPLD10_PHYS),
- .length = CPLD10_SIZE,
+ .length = CPLD10_SIZE,
.type = MT_DEVICE
- }, {
+ },
+ {
.virtual = CPLD12_VIRT,
.pfn = __phys_to_pfn(CPLD12_PHYS),
- .length = CPLD12_SIZE,
+ .length = CPLD12_SIZE,
.type = MT_DEVICE
- }, {
+ },
+ {
.virtual = CPLD14_VIRT,
.pfn = __phys_to_pfn(CPLD14_PHYS),
- .length = CPLD14_SIZE,
+ .length = CPLD14_SIZE,
.type = MT_DEVICE
- }, {
+ },
+ {
.virtual = CPLD16_VIRT,
.pfn = __phys_to_pfn(CPLD16_PHYS),
- .length = CPLD16_SIZE,
+ .length = CPLD16_SIZE,
.type = MT_DEVICE
- }, {
+ },
+ {
.virtual = CPLD18_VIRT,
.pfn = __phys_to_pfn(CPLD18_PHYS),
- .length = CPLD18_SIZE,
+ .length = CPLD18_SIZE,
.type = MT_DEVICE
- }, {
+ },
+ {
.virtual = CPLD1A_VIRT,
.pfn = __phys_to_pfn(CPLD1A_PHYS),
- .length = CPLD1A_SIZE,
+ .length = CPLD1A_SIZE,
.type = MT_DEVICE
},
- /* This mapping is redundant since the smc driver performs another. */
-/* { CPLD00_VIRT, CPLD00_PHYS, CPLD00_SIZE, MT_DEVICE }, */
};
void __init
-lpd7a400_map_io(void)
+lpd7a40x_map_io(void)
{
- iotable_init (lpd7a400_io_desc, ARRAY_SIZE (lpd7a400_io_desc));
-
- /* Fixup (improve) Static Memory Controller settings */
- SMC_BCR0 = 0x200039af; /* Boot Flash */
- SMC_BCR6 = 0x1000fbe0; /* CPLD */
- SMC_BCR7 = 0x1000b2c2; /* Compact Flash */
+ iotable_init (lpd7a40x_io_desc, ARRAY_SIZE (lpd7a40x_io_desc));
}
#ifdef CONFIG_MACH_LPD7A400
@@ -320,7 +400,7 @@ MACHINE_START (LPD7A400, "Logic Product Development LPD7A400-10")
.phys_io = 0x80000000,
.io_pg_offst = ((io_p2v (0x80000000))>>18) & 0xfffc,
.boot_params = 0xc0000100,
- .map_io = lpd7a400_map_io,
+ .map_io = lpd7a40x_map_io,
.init_irq = lh7a400_init_irq,
.timer = &lh7a40x_timer,
.init_machine = lpd7a40x_init,
@@ -335,7 +415,7 @@ MACHINE_START (LPD7A404, "Logic Product Development LPD7A404-10")
.phys_io = 0x80000000,
.io_pg_offst = ((io_p2v (0x80000000))>>18) & 0xfffc,
.boot_params = 0xc0000100,
- .map_io = lpd7a400_map_io,
+ .map_io = lpd7a40x_map_io,
.init_irq = lh7a404_init_irq,
.timer = &lh7a40x_timer,
.init_machine = lpd7a40x_init,
diff --git a/arch/arm/mach-lh7a40x/clcd.c b/arch/arm/mach-lh7a40x/clcd.c
new file mode 100644
index 000000000000..93751fee793d
--- /dev/null
+++ b/arch/arm/mach-lh7a40x/clcd.c
@@ -0,0 +1,241 @@
+/*
+ * arch/arm/mach-lh7a40x/clcd.c
+ *
+ * Copyright (C) 2004 Marc Singer
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/sysdev.h>
+#include <linux/interrupt.h>
+
+//#include <linux/module.h>
+//#include <linux/time.h>
+//#include <asm/hardware.h>
+
+//#include <asm/mach/time.h>
+#include <asm/irq.h>
+#include <asm/mach/irq.h>
+
+#include <asm/system.h>
+#include <asm/hardware.h>
+#include <linux/amba/bus.h>
+#include <linux/amba/clcd.h>
+
+#define HRTFTC_HRSETUP __REG(HRTFTC_PHYS + 0x00)
+#define HRTFTC_HRCON __REG(HRTFTC_PHYS + 0x04)
+#define HRTFTC_HRTIMING1 __REG(HRTFTC_PHYS + 0x08)
+#define HRTFTC_HRTIMING2 __REG(HRTFTC_PHYS + 0x0c)
+
+#define ALI_SETUP __REG(ALI_PHYS + 0x00)
+#define ALI_CONTROL __REG(ALI_PHYS + 0x04)
+#define ALI_TIMING1 __REG(ALI_PHYS + 0x08)
+#define ALI_TIMING2 __REG(ALI_PHYS + 0x0c)
+
+#include "lcd-panel.h"
+
+static void lh7a40x_clcd_disable (struct clcd_fb *fb)
+{
+#if defined (CONFIG_MACH_LPD7A400)
+ CPLD_CONTROL &= ~(1<<1); /* Disable LCD Vee */
+#endif
+
+#if defined (CONFIG_MACH_LPD7A404)
+ GPIO_PCD &= ~(1<<3); /* Disable LCD Vee */
+#endif
+
+#if defined (CONFIG_ARCH_LH7A400)
+ HRTFTC_HRSETUP &= ~(1<<13); /* Disable HRTFT controller */
+#endif
+
+#if defined (CONFIG_ARCH_LH7A404)
+ ALI_SETUP &= ~(1<<13); /* Disable ALI */
+#endif
+}
+
+static void lh7a40x_clcd_enable (struct clcd_fb *fb)
+{
+ struct clcd_panel_extra* extra
+ = (struct clcd_panel_extra*) fb->board_data;
+
+#if defined (CONFIG_MACH_LPD7A400)
+ CPLD_CONTROL |= (1<<1); /* Enable LCD Vee */
+#endif
+
+#if defined (CONFIG_MACH_LPD7A404)
+ GPIO_PCDD &= ~(1<<3); /* Enable LCD Vee */
+ GPIO_PCD |= (1<<3);
+#endif
+
+#if defined (CONFIG_ARCH_LH7A400)
+
+ if (extra) {
+ HRTFTC_HRSETUP
+ = (1 << 13)
+ | ((fb->fb.var.xres - 1) << 4)
+ | 0xc
+ | (extra->hrmode ? 1 : 0);
+ HRTFTC_HRCON
+ = ((extra->clsen ? 1 : 0) << 1)
+ | ((extra->spsen ? 1 : 0) << 0);
+ HRTFTC_HRTIMING1
+ = (extra->pcdel << 8)
+ | (extra->revdel << 4)
+ | (extra->lpdel << 0);
+ HRTFTC_HRTIMING2
+ = (extra->spldel << 9)
+ | (extra->pc2del << 0);
+ }
+ else
+ HRTFTC_HRSETUP
+ = (1 << 13)
+ | 0xc;
+#endif
+
+#if defined (CONFIG_ARCH_LH7A404)
+
+ if (extra) {
+ ALI_SETUP
+ = (1 << 13)
+ | ((fb->fb.var.xres - 1) << 4)
+ | 0xc
+ | (extra->hrmode ? 1 : 0);
+ ALI_CONTROL
+ = ((extra->clsen ? 1 : 0) << 1)
+ | ((extra->spsen ? 1 : 0) << 0);
+ ALI_TIMING1
+ = (extra->pcdel << 8)
+ | (extra->revdel << 4)
+ | (extra->lpdel << 0);
+ ALI_TIMING2
+ = (extra->spldel << 9)
+ | (extra->pc2del << 0);
+ }
+ else
+ ALI_SETUP
+ = (1 << 13)
+ | 0xc;
+#endif
+
+}
+
+#define FRAMESIZE(s) (((s) + PAGE_SIZE - 1)&PAGE_MASK)
+
+static int lh7a40x_clcd_setup (struct clcd_fb *fb)
+{
+ dma_addr_t dma;
+ u32 len = FRAMESIZE (lcd_panel.mode.xres*lcd_panel.mode.yres
+ *(lcd_panel.bpp/8));
+
+ fb->panel = &lcd_panel;
+
+ /* Enforce the sync polarity defaults */
+ if (!(fb->panel->tim2 & TIM2_IHS))
+ fb->fb.var.sync |= FB_SYNC_HOR_HIGH_ACT;
+ if (!(fb->panel->tim2 & TIM2_IVS))
+ fb->fb.var.sync |= FB_SYNC_VERT_HIGH_ACT;
+
+#if defined (HAS_LCD_PANEL_EXTRA)
+ fb->board_data = &lcd_panel_extra;
+#endif
+
+ fb->fb.screen_base
+ = dma_alloc_writecombine (&fb->dev->dev, len,
+ &dma, GFP_KERNEL);
+ printk ("CLCD: LCD setup fb virt 0x%p phys 0x%p l %x io 0x%p \n",
+ fb->fb.screen_base, (void*) dma, len,
+ (void*) io_p2v (CLCDC_PHYS));
+ printk ("CLCD: pixclock %d\n", lcd_panel.mode.pixclock);
+
+ if (!fb->fb.screen_base) {
+ printk(KERN_ERR "CLCD: unable to map framebuffer\n");
+ return -ENOMEM;
+ }
+
+#if defined (USE_RGB555)
+ fb->fb.var.green.length = 5; /* Panel uses RGB 5:5:5 */
+#endif
+
+ fb->fb.fix.smem_start = dma;
+ fb->fb.fix.smem_len = len;
+
+ /* Drive PE4 high to prevent CPLD crash */
+ GPIO_PEDD |= (1<<4);
+ GPIO_PED |= (1<<4);
+
+ GPIO_PINMUX |= (1<<1) | (1<<0); /* LCDVD[15:4] */
+
+// fb->fb.fbops->fb_check_var (&fb->fb.var, &fb->fb);
+// fb->fb.fbops->fb_set_par (&fb->fb);
+
+ return 0;
+}
+
+static int lh7a40x_clcd_mmap (struct clcd_fb *fb, struct vm_area_struct *vma)
+{
+ return dma_mmap_writecombine(&fb->dev->dev, vma,
+ fb->fb.screen_base,
+ fb->fb.fix.smem_start,
+ fb->fb.fix.smem_len);
+}
+
+static void lh7a40x_clcd_remove (struct clcd_fb *fb)
+{
+ dma_free_writecombine (&fb->dev->dev, fb->fb.fix.smem_len,
+ fb->fb.screen_base, fb->fb.fix.smem_start);
+}
+
+static struct clcd_board clcd_platform_data = {
+ .name = "lh7a40x FB",
+ .check = clcdfb_check,
+ .decode = clcdfb_decode,
+ .enable = lh7a40x_clcd_enable,
+ .setup = lh7a40x_clcd_setup,
+ .mmap = lh7a40x_clcd_mmap,
+ .remove = lh7a40x_clcd_remove,
+ .disable = lh7a40x_clcd_disable,
+};
+
+#define IRQ_CLCDC (IRQ_LCDINTR)
+
+#define AMBA_DEVICE(name,busid,base,plat,pid) \
+static struct amba_device name##_device = { \
+ .dev = { \
+ .coherent_dma_mask = ~0, \
+ .bus_id = busid, \
+ .platform_data = plat, \
+ }, \
+ .res = { \
+ .start = base##_PHYS, \
+ .end = (base##_PHYS) + (4*1024) - 1, \
+ .flags = IORESOURCE_MEM, \
+ }, \
+ .dma_mask = ~0, \
+ .irq = { IRQ_##base, }, \
+ /* .dma = base##_DMA,*/ \
+ .periphid = pid, \
+}
+
+AMBA_DEVICE(clcd, "cldc-lh7a40x", CLCDC, &clcd_platform_data, 0x41110);
+
+static struct amba_device *amba_devs[] __initdata = {
+ &clcd_device,
+};
+
+void __init lh7a40x_clcd_init (void)
+{
+ int i;
+ int result;
+ printk ("CLCD: registering amba devices\n");
+ for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
+ struct amba_device *d = amba_devs[i];
+ result = amba_device_register(d, &iomem_resource);
+ printk (" %d -> %d\n", i ,result);
+ }
+}
diff --git a/arch/arm/mach-lh7a40x/clocks.c b/arch/arm/mach-lh7a40x/clocks.c
new file mode 100644
index 000000000000..2291afe9f23e
--- /dev/null
+++ b/arch/arm/mach-lh7a40x/clocks.c
@@ -0,0 +1,199 @@
+/* arch/arm/mach-lh7a40x/clocks.c
+ *
+ * Copyright (C) 2004 Marc Singer
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/cpufreq.h>
+#include <asm/hardware.h>
+#include <asm/arch/clocks.h>
+#include <linux/err.h>
+
+struct module;
+struct icst525_params;
+
+struct clk {
+ struct list_head node;
+ unsigned long rate;
+ struct module *owner;
+ const char *name;
+// void *data;
+// const struct icst525_params *params;
+// void (*setvco)(struct clk *, struct icst525_vco vco);
+};
+
+int clk_register(struct clk *clk);
+void clk_unregister(struct clk *clk);
+
+/* ----- */
+
+#define MAINDIV1(c) (((c) >> 7) & 0x0f)
+#define MAINDIV2(c) (((c) >> 11) & 0x1f)
+#define PS(c) (((c) >> 18) & 0x03)
+#define PREDIV(c) (((c) >> 2) & 0x1f)
+#define HCLKDIV(c) (((c) >> 0) & 0x02)
+#define PCLKDIV(c) (((c) >> 16) & 0x03)
+
+unsigned int cpufreq_get (unsigned int cpu) /* in kHz */
+{
+ return fclkfreq_get ()/1000;
+}
+EXPORT_SYMBOL(cpufreq_get);
+
+unsigned int fclkfreq_get (void)
+{
+ unsigned int clkset = CSC_CLKSET;
+ unsigned int gclk
+ = XTAL_IN
+ / (1 << PS(clkset))
+ * (MAINDIV1(clkset) + 2)
+ / (PREDIV(clkset) + 2)
+ * (MAINDIV2(clkset) + 2)
+ ;
+ return gclk;
+}
+
+unsigned int hclkfreq_get (void)
+{
+ unsigned int clkset = CSC_CLKSET;
+ unsigned int hclk = fclkfreq_get () / (HCLKDIV(clkset) + 1);
+
+ return hclk;
+}
+
+unsigned int pclkfreq_get (void)
+{
+ unsigned int clkset = CSC_CLKSET;
+ int pclkdiv = PCLKDIV(clkset);
+ unsigned int pclk;
+ if (pclkdiv == 0x3)
+ pclkdiv = 0x2;
+ pclk = hclkfreq_get () / (1 << pclkdiv);
+
+ return pclk;
+}
+
+/* ----- */
+
+static LIST_HEAD(clocks);
+static DECLARE_MUTEX(clocks_sem);
+
+struct clk *clk_get (struct device *dev, const char *id)
+{
+ struct clk *p;
+ struct clk *clk = ERR_PTR(-ENOENT);
+
+ down (&clocks_sem);
+ list_for_each_entry (p, &clocks, node) {
+ if (strcmp (id, p->name) == 0
+ && try_module_get(p->owner)) {
+ clk = p;
+ break;
+ }
+ }
+ up (&clocks_sem);
+
+ return clk;
+}
+EXPORT_SYMBOL(clk_get);
+
+void clk_put (struct clk *clk)
+{
+ module_put(clk->owner);
+}
+EXPORT_SYMBOL(clk_put);
+
+int clk_enable (struct clk *clk)
+{
+ return 0;
+}
+EXPORT_SYMBOL(clk_enable);
+
+void clk_disable (struct clk *clk)
+{
+}
+EXPORT_SYMBOL(clk_disable);
+
+int clk_use (struct clk *clk)
+{
+ return 0;
+}
+EXPORT_SYMBOL(clk_use);
+
+void clk_unuse (struct clk *clk)
+{
+}
+EXPORT_SYMBOL(clk_unuse);
+
+unsigned long clk_get_rate (struct clk *clk)
+{
+ return clk->rate;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+long clk_round_rate (struct clk *clk, unsigned long rate)
+{
+ return rate;
+}
+EXPORT_SYMBOL(clk_round_rate);
+
+int clk_set_rate (struct clk *clk, unsigned long rate)
+{
+ int ret = -EIO;
+ return ret;
+}
+EXPORT_SYMBOL(clk_set_rate);
+
+#if 0
+/*
+ * These are fixed clocks.
+ */
+static struct clk kmi_clk = {
+ .name = "KMIREFCLK",
+ .rate = 24000000,
+};
+
+static struct clk uart_clk = {
+ .name = "UARTCLK",
+ .rate = 24000000,
+};
+
+static struct clk mmci_clk = {
+ .name = "MCLK",
+ .rate = 33000000,
+};
+#endif
+
+static struct clk clcd_clk = {
+ .name = "CLCDCLK",
+ .rate = 0,
+};
+
+int clk_register (struct clk *clk)
+{
+ down (&clocks_sem);
+ list_add (&clk->node, &clocks);
+ up (&clocks_sem);
+ return 0;
+}
+EXPORT_SYMBOL(clk_register);
+
+void clk_unregister (struct clk *clk)
+{
+ down (&clocks_sem);
+ list_del (&clk->node);
+ up (&clocks_sem);
+}
+EXPORT_SYMBOL(clk_unregister);
+
+static int __init clk_init (void)
+{
+ clk_register(&clcd_clk);
+ return 0;
+}
+arch_initcall(clk_init);
diff --git a/arch/arm/mach-lh7a40x/common.h b/arch/arm/mach-lh7a40x/common.h
index ea8de7e3ab1b..18e8bb4eb202 100644
--- a/arch/arm/mach-lh7a40x/common.h
+++ b/arch/arm/mach-lh7a40x/common.h
@@ -12,6 +12,7 @@ extern struct sys_timer lh7a40x_timer;
extern void lh7a400_init_irq (void);
extern void lh7a404_init_irq (void);
+extern void lh7a40x_clcd_init (void);
extern void lh7a40x_init_board_irq (void);
#define IRQ_DISPATCH(irq) desc_handle_irq((irq),(irq_desc + irq), regs)
diff --git a/arch/arm/mach-lh7a40x/irq-lh7a404.c b/arch/arm/mach-lh7a40x/irq-lh7a404.c
index e902e3d87da4..2685a81454d2 100644
--- a/arch/arm/mach-lh7a40x/irq-lh7a404.c
+++ b/arch/arm/mach-lh7a40x/irq-lh7a404.c
@@ -28,13 +28,17 @@
static unsigned char irq_pri_vic1[] = {
#if defined (USE_PRIORITIES)
-IRQ_GPIO3INTR,
+ IRQ_GPIO3INTR, /* CPLD */
+ IRQ_DMAM2P4, IRQ_DMAM2P5, /* AC97 */
#endif
};
static unsigned char irq_pri_vic2[] = {
#if defined (USE_PRIORITIES)
- IRQ_T3UI, IRQ_GPIO7INTR,
+ IRQ_T3UI, /* Timer */
+ IRQ_GPIO7INTR, /* CPLD */
IRQ_UART1INTR, IRQ_UART2INTR, IRQ_UART3INTR,
+ IRQ_LCDINTR, /* LCD */
+ IRQ_TSCINTR, /* ADC/Touchscreen */
#endif
};
@@ -98,10 +102,19 @@ static struct irqchip lh7a404_gpio_vic2_chip = {
/* IRQ initialization */
+#if defined (CONFIG_ARCH_LH7A400) && defined (CONFIG_ARCH_LH7A404)
+extern void* branch_irq_lh7a400;
+#endif
+
void __init lh7a404_init_irq (void)
{
int irq;
+#if defined (CONFIG_ARCH_LH7A400) && defined (CONFIG_ARCH_LH7A404)
+#define NOP 0xe1a00000 /* mov r0, r0 */
+ branch_irq_lh7a400 = NOP;
+#endif
+
VIC1_INTENCLR = 0xffffffff;
VIC2_INTENCLR = 0xffffffff;
VIC1_INTSEL = 0; /* All IRQs */
diff --git a/arch/arm/mach-lh7a40x/lcd-panel.h b/arch/arm/mach-lh7a40x/lcd-panel.h
new file mode 100644
index 000000000000..4fb2efc4950f
--- /dev/null
+++ b/arch/arm/mach-lh7a40x/lcd-panel.h
@@ -0,0 +1,346 @@
+/* lcd-panel.h
+ $Id$
+
+ written by Marc Singer
+ 18 Jul 2005
+
+ Copyright (C) 2005 Marc Singer
+
+ -----------
+ DESCRIPTION
+ -----------
+
+ Only one panel may be defined at a time.
+
+ The pixel clock is calculated to be no greater than the target.
+
+ Each timing value is accompanied by a specification comment.
+
+ UNITS/MIN/TYP/MAX
+
+ Most of the units will be in clocks.
+
+ USE_RGB555
+
+ Define this macro to configure the AMBA LCD controller to use an
+ RGB555 encoding for the pels instead of the normal RGB565.
+
+ LPD9520, LPD79524, LPD7A400, LPD7A404-10, LPD7A404-11
+
+ These boards are best approximated by 555 for all panels. Some
+ can use an extra low-order bit of blue in bit 16 of the color
+ value, but we don't have a way to communicate this non-linear
+ mapping to the kernel.
+
+*/
+
+#if !defined (__LCD_PANEL_H__)
+# define __LCD_PANEL_H__
+
+#if defined (MACH_LPD79520)\
+ || defined (MACH_LPD79524)\
+ || defined (MACH_LPD7A400)\
+ || defined (MACH_LPD7A404)
+# define USE_RGB555
+#endif
+
+struct clcd_panel_extra {
+ unsigned int hrmode;
+ unsigned int clsen;
+ unsigned int spsen;
+ unsigned int pcdel;
+ unsigned int revdel;
+ unsigned int lpdel;
+ unsigned int spldel;
+ unsigned int pc2del;
+};
+
+#define NS_TO_CLOCK(ns,c) ((((ns)*((c)/1000) + (1000000 - 1))/1000000))
+#define CLOCK_TO_DIV(e,c) (((c) + (e) - 1)/(e))
+
+#if defined CONFIG_FB_ARMCLCD_SHARP_LQ035Q7DB02_HRTFT
+
+ /* Logic Product Development LCD 3.5" QVGA HRTFT -10 */
+ /* Sharp PN LQ035Q7DB02 w/HRTFT controller chip */
+
+#define PIX_CLOCK_TARGET (6800000)
+#define PIX_CLOCK_DIVIDER CLOCK_TO_DIV (PIX_CLOCK_TARGET, HCLK)
+#define PIX_CLOCK (HCLK/PIX_CLOCK_DIVIDER)
+
+static struct clcd_panel lcd_panel = {
+ .mode = {
+ .name = "3.5in QVGA (LQ035Q7DB02)",
+ .xres = 240,
+ .yres = 320,
+ .pixclock = PIX_CLOCK,
+ .left_margin = 16,
+ .right_margin = 21,
+ .upper_margin = 8, // line/8/8/8
+ .lower_margin = 5,
+ .hsync_len = 61,
+ .vsync_len = NS_TO_CLOCK (60, PIX_CLOCK),
+ .vmode = FB_VMODE_NONINTERLACED,
+ },
+ .width = -1,
+ .height = -1,
+ .tim2 = TIM2_IPC | (PIX_CLOCK_DIVIDER - 2),
+ .cntl = CNTL_LCDTFT | CNTL_WATERMARK,
+ .bpp = 16,
+};
+
+#define HAS_LCD_PANEL_EXTRA
+
+static struct clcd_panel_extra lcd_panel_extra = {
+ .hrmode = 1,
+ .clsen = 1,
+ .spsen = 1,
+ .pcdel = 8,
+ .revdel = 7,
+ .lpdel = 13,
+ .spldel = 77,
+ .pc2del = 208,
+};
+
+#endif
+
+#if defined CONFIG_FB_ARMCLCD_SHARP_LQ057Q3DC02
+
+ /* Logic Product Development LCD 5.7" QVGA -10 */
+ /* Sharp PN LQ057Q3DC02 */
+ /* QVGA mode, V/Q=LOW */
+
+/* From Sharp on 2006.1.3. I believe some of the values are incorrect
+ * based on the datasheet.
+
+ Timing0 TIMING1 TIMING2 CONTROL
+ 0x140A0C4C 0x080504EF 0x013F380D 0x00000829
+ HBP= 20 VBP= 8 BCD= 0
+ HFP= 10 VFP= 5 CPL=319
+ HSW= 12 VSW= 1 IOE= 0
+ PPL= 19 LPP=239 IPC= 1
+ IHS= 1
+ IVS= 1
+ ACB= 0
+ CSEL= 0
+ PCD= 13
+
+ */
+
+/* The full horozontal cycle (Th) is clock/360/400/450. */
+/* The full vertical cycle (Tv) is line/251/262/280. */
+
+#define PIX_CLOCK_TARGET (6300000) /* -/6.3/7 MHz */
+#define PIX_CLOCK_DIVIDER CLOCK_TO_DIV (PIX_CLOCK_TARGET, HCLK)
+#define PIX_CLOCK (HCLK/PIX_CLOCK_DIVIDER)
+
+static struct clcd_panel lcd_panel = {
+ .mode = {
+ .name = "5.7in QVGA (LQ057Q3DC02)",
+ .xres = 320,
+ .yres = 240,
+ .pixclock = PIX_CLOCK,
+ .left_margin = 11,
+ .right_margin = 400-11-320-2,
+ .upper_margin = 7, // line/7/7/7
+ .lower_margin = 262-7-240-2,
+ .hsync_len = 2, // clk/2/96/200
+ .vsync_len = 2, // line/2/-/34
+ .vmode = FB_VMODE_NONINTERLACED,
+ },
+ .width = -1,
+ .height = -1,
+ .tim2 = TIM2_IHS | TIM2_IVS
+ | (PIX_CLOCK_DIVIDER - 2),
+ .cntl = CNTL_LCDTFT | CNTL_WATERMARK,
+ .bpp = 16,
+};
+
+#endif
+
+#if defined CONFIG_FB_ARMCLCD_SHARP_LQ64D343
+
+ /* Logic Product Development LCD 6.4" VGA -10 */
+ /* Sharp PN LQ64D343 */
+
+/* The full horozontal cycle (Th) is clock/750/800/900. */
+/* The full vertical cycle (Tv) is line/515/525/560. */
+
+#define PIX_CLOCK_TARGET (28330000)
+#define PIX_CLOCK_DIVIDER CLOCK_TO_DIV (PIX_CLOCK_TARGET, HCLK)
+#define PIX_CLOCK (HCLK/PIX_CLOCK_DIVIDER)
+
+static struct clcd_panel lcd_panel = {
+ .mode = {
+ .name = "6.4in QVGA (LQ64D343)",
+ .xres = 640,
+ .yres = 480,
+ .pixclock = PIX_CLOCK,
+ .left_margin = 32,
+ .right_margin = 800-32-640-96,
+ .upper_margin = 32, // line/34/34/34
+ .lower_margin = 540-32-480-2,
+ .hsync_len = 96, // clk/2/96/200
+ .vsync_len = 2, // line/2/-/34
+ .vmode = FB_VMODE_NONINTERLACED,
+ },
+ .width = -1,
+ .height = -1,
+ .tim2 = TIM2_IHS | TIM2_IVS
+ | (PIX_CLOCK_DIVIDER - 2),
+ .cntl = CNTL_LCDTFT | CNTL_WATERMARK,
+ .bpp = 16,
+};
+
+#endif
+
+#if defined CONFIG_FB_ARMCLCD_SHARP_LQ10D368
+
+ /* Logic Product Development LCD 10.4" VGA -10 */
+ /* Sharp PN LQ10D368 */
+
+#define PIX_CLOCK_TARGET (28330000)
+#define PIX_CLOCK_DIVIDER CLOCK_TO_DIV (PIX_CLOCK_TARGET, HCLK)
+#define PIX_CLOCK (HCLK/PIX_CLOCK_DIVIDER)
+
+static struct clcd_panel lcd_panel = {
+ .mode = {
+ .name = "10.4in VGA (LQ10D368)",
+ .xres = 640,
+ .yres = 480,
+ .pixclock = PIX_CLOCK,
+ .left_margin = 21,
+ .right_margin = 15,
+ .upper_margin = 34,
+ .lower_margin = 5,
+ .hsync_len = 96,
+ .vsync_len = 16,
+ .vmode = FB_VMODE_NONINTERLACED,
+ },
+ .width = -1,
+ .height = -1,
+ .tim2 = TIM2_IHS | TIM2_IVS
+ | (PIX_CLOCK_DIVIDER - 2),
+ .cntl = CNTL_LCDTFT | CNTL_WATERMARK,
+ .bpp = 16,
+};
+
+#endif
+
+#if defined CONFIG_FB_ARMCLCD_SHARP_LQ121S1DG41
+
+ /* Logic Product Development LCD 12.1" SVGA -10 */
+ /* Sharp PN LQ121S1DG41, was LQ121S1DG31 */
+
+/* Note that with a 99993900 Hz HCLK, it is not possible to hit the
+ * target clock frequency range of 35MHz to 42MHz. */
+
+/* If the target pixel clock is substantially lower than the panel
+ * spec, this is done to prevent the LCD display from glitching when
+ * the CPU is under load. A pixel clock higher than 25MHz
+ * (empirically determined) will compete with the CPU for bus cycles
+ * for the Ethernet chip. However, even a pixel clock of 10MHz
+ * competes with Compact Flash interface during some operations
+ * (fdisk, e2fsck). And, at that speed the display may have a visible
+ * flicker. */
+
+/* The full horozontal cycle (Th) is clock/832/1056/1395. */
+
+#define PIX_CLOCK_TARGET (20000000)
+#define PIX_CLOCK_DIVIDER CLOCK_TO_DIV (PIX_CLOCK_TARGET, HCLK)
+#define PIX_CLOCK (HCLK/PIX_CLOCK_DIVIDER)
+
+static struct clcd_panel lcd_panel = {
+ .mode = {
+ .name = "12.1in SVGA (LQ121S1DG41)",
+ .xres = 800,
+ .yres = 600,
+ .pixclock = PIX_CLOCK,
+ .left_margin = 89, // ns/5/-/(1/PIX_CLOCK)-10
+ .right_margin = 1056-800-89-128,
+ .upper_margin = 23, // line/23/23/23
+ .lower_margin = 44,
+ .hsync_len = 128, // clk/2/128/200
+ .vsync_len = 4, // line/2/4/6
+ .vmode = FB_VMODE_NONINTERLACED,
+ },
+ .width = -1,
+ .height = -1,
+ .tim2 = TIM2_IHS | TIM2_IVS
+ | (PIX_CLOCK_DIVIDER - 2),
+ .cntl = CNTL_LCDTFT | CNTL_WATERMARK,
+ .bpp = 16,
+};
+
+#endif
+
+#if defined CONFIG_FB_ARMCLCD_HITACHI
+
+ /* Hitachi*/
+ /* Submitted by Michele Da Rold <michele.darold@ecsproject.com> */
+
+#define PIX_CLOCK_TARGET (49000000)
+#define PIX_CLOCK_DIVIDER CLOCK_TO_DIV (PIX_CLOCK_TARGET, HCLK)
+#define PIX_CLOCK (HCLK/PIX_CLOCK_DIVIDER)
+
+static struct clcd_panel lcd_panel = {
+ .mode = {
+ .name = "Hitachi 800x480",
+ .xres = 800,
+ .yres = 480,
+ .pixclock = PIX_CLOCK,
+ .left_margin = 88,
+ .right_margin = 40,
+ .upper_margin = 32,
+ .lower_margin = 11,
+ .hsync_len = 128,
+ .vsync_len = 2,
+ .vmode = FB_VMODE_NONINTERLACED,
+ },
+ .width = -1,
+ .height = -1,
+ .tim2 = TIM2_IPC | TIM2_IHS | TIM2_IVS
+ | (PIX_CLOCK_DIVIDER - 2),
+ .cntl = CNTL_LCDTFT | CNTL_WATERMARK,
+ .bpp = 16,
+};
+
+#endif
+
+
+#if defined CONFIG_FB_ARMCLCD_AUO_A070VW01_WIDE
+
+ /* AU Optotronics A070VW01 7.0 Wide Screen color Display*/
+ /* Submitted by Michele Da Rold <michele.darold@ecsproject.com> */
+
+#define PIX_CLOCK_TARGET (10000000)
+#define PIX_CLOCK_DIVIDER CLOCK_TO_DIV (PIX_CLOCK_TARGET, HCLK)
+#define PIX_CLOCK (HCLK/PIX_CLOCK_DIVIDER)
+
+static struct clcd_panel lcd_panel = {
+ .mode = {
+ .name = "7.0in Wide (A070VW01)",
+ .xres = 480,
+ .yres = 234,
+ .pixclock = PIX_CLOCK,
+ .left_margin = 30,
+ .right_margin = 25,
+ .upper_margin = 14,
+ .lower_margin = 12,
+ .hsync_len = 100,
+ .vsync_len = 1,
+ .vmode = FB_VMODE_NONINTERLACED,
+ },
+ .width = -1,
+ .height = -1,
+ .tim2 = TIM2_IPC | TIM2_IHS | TIM2_IVS
+ | (PIX_CLOCK_DIVIDER - 2),
+ .cntl = CNTL_LCDTFT | CNTL_WATERMARK,
+ .bpp = 16,
+};
+
+#endif
+
+#undef NS_TO_CLOCK
+#undef CLOCK_TO_DIV
+
+#endif /* __LCD_PANEL_H__ */
diff --git a/arch/arm/mach-lh7a40x/ssp-cpld.c b/arch/arm/mach-lh7a40x/ssp-cpld.c
new file mode 100644
index 000000000000..a10830186dac
--- /dev/null
+++ b/arch/arm/mach-lh7a40x/ssp-cpld.c
@@ -0,0 +1,343 @@
+/* arch/arm/mach-lh7a40x/ssp-cpld.c
+ *
+ * Copyright (C) 2004,2005 Marc Singer
+ *
+ * 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.
+ *
+ * SSP/SPI driver for the CardEngine CPLD.
+ *
+ */
+
+/* NOTES
+ -----
+
+ o *** This driver is cribbed from the 7952x implementation.
+ Some comments may not apply.
+
+ o This driver contains sufficient logic to control either the
+ serial EEPROMs or the audio codec. It is included in the kernel
+ to support the codec. The EEPROMs are really the responsibility
+ of the boot loader and should probably be left alone.
+
+ o The code must be augmented to cope with multiple, simultaneous
+ clients.
+ o The audio codec writes to the codec chip whenever playback
+ starts.
+ o The touchscreen driver writes to the ads chip every time it
+ samples.
+ o The audio codec must write 16 bits, but the touch chip writes
+ are 8 bits long.
+ o We need to be able to keep these configurations separate while
+ simultaneously active.
+
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+//#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+//#include <linux/ioport.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/spinlock.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/hardware.h>
+
+#include <asm/arch/ssp.h>
+
+//#define TALK
+
+#if defined (TALK)
+#define PRINTK(f...) printk (f)
+#else
+#define PRINTK(f...) do {} while (0)
+#endif
+
+#if defined (CONFIG_ARCH_LH7A400)
+# define CPLD_SPID __REGP16(CPLD06_VIRT) /* SPI data */
+# define CPLD_SPIC __REGP16(CPLD08_VIRT) /* SPI control */
+# define CPLD_SPIC_CS_CODEC (1<<0)
+# define CPLD_SPIC_CS_TOUCH (1<<1)
+# define CPLD_SPIC_WRITE (0<<2)
+# define CPLD_SPIC_READ (1<<2)
+# define CPLD_SPIC_DONE (1<<3) /* r/o */
+# define CPLD_SPIC_LOAD (1<<4)
+# define CPLD_SPIC_START (1<<4)
+# define CPLD_SPIC_LOADED (1<<5) /* r/o */
+#endif
+
+#define CPLD_SPI __REGP16(CPLD0A_VIRT) /* SPI operation */
+#define CPLD_SPI_CS_EEPROM (1<<3)
+#define CPLD_SPI_SCLK (1<<2)
+#define CPLD_SPI_TX_SHIFT (1)
+#define CPLD_SPI_TX (1<<CPLD_SPI_TX_SHIFT)
+#define CPLD_SPI_RX_SHIFT (0)
+#define CPLD_SPI_RX (1<<CPLD_SPI_RX_SHIFT)
+
+/* *** FIXME: these timing values are substantially larger than the
+ *** chip requires. We may implement an nsleep () function. */
+#define T_SKH 1 /* Clock time high (us) */
+#define T_SKL 1 /* Clock time low (us) */
+#define T_CS 1 /* Minimum chip select low time (us) */
+#define T_CSS 1 /* Minimum chip select setup time (us) */
+#define T_DIS 1 /* Data setup time (us) */
+
+ /* EEPROM SPI bits */
+#define P_START (1<<9)
+#define P_WRITE (1<<7)
+#define P_READ (2<<7)
+#define P_ERASE (3<<7)
+#define P_EWDS (0<<7)
+#define P_WRAL (0<<7)
+#define P_ERAL (0<<7)
+#define P_EWEN (0<<7)
+#define P_A_EWDS (0<<5)
+#define P_A_WRAL (1<<5)
+#define P_A_ERAL (2<<5)
+#define P_A_EWEN (3<<5)
+
+struct ssp_configuration {
+ int device;
+ int mode;
+ int speed;
+ int frame_size_write;
+ int frame_size_read;
+};
+
+static struct ssp_configuration ssp_configuration;
+static spinlock_t ssp_lock;
+
+static void enable_cs (void)
+{
+ switch (ssp_configuration.device) {
+ case DEVICE_EEPROM:
+ CPLD_SPI |= CPLD_SPI_CS_EEPROM;
+ break;
+ }
+ udelay (T_CSS);
+}
+
+static void disable_cs (void)
+{
+ switch (ssp_configuration.device) {
+ case DEVICE_EEPROM:
+ CPLD_SPI &= ~CPLD_SPI_CS_EEPROM;
+ break;
+ }
+ udelay (T_CS);
+}
+
+static void pulse_clock (void)
+{
+ CPLD_SPI |= CPLD_SPI_SCLK;
+ udelay (T_SKH);
+ CPLD_SPI &= ~CPLD_SPI_SCLK;
+ udelay (T_SKL);
+}
+
+
+/* execute_spi_command
+
+ sends an spi command to a device. It first sends cwrite bits from
+ v. If cread is greater than zero it will read cread bits
+ (discarding the leading 0 bit) and return them. If cread is less
+ than zero it will check for completetion status and return 0 on
+ success or -1 on timeout. If cread is zero it does nothing other
+ than sending the command.
+
+ On the LPD7A400, we can only read or write multiples of 8 bits on
+ the codec and the touch screen device. Here, we round up.
+
+*/
+
+static int execute_spi_command (int v, int cwrite, int cread)
+{
+ unsigned long l = 0;
+
+#if defined (CONFIG_MACH_LPD7A400)
+ /* The codec and touch devices cannot be bit-banged. Instead,
+ * the CPLD provides an eight-bit shift register and a crude
+ * interface. */
+ if ( ssp_configuration.device == DEVICE_CODEC
+ || ssp_configuration.device == DEVICE_TOUCH) {
+ int select = 0;
+
+ PRINTK ("spi(%d %d.%d) 0x%04x",
+ ssp_configuration.device, cwrite, cread,
+ v);
+#if defined (TALK)
+ if (ssp_configuration.device == DEVICE_CODEC)
+ PRINTK (" 0x%03x -> %2d", v & 0x1ff, (v >> 9) & 0x7f);
+#endif
+ PRINTK ("\n");
+
+ if (ssp_configuration.device == DEVICE_CODEC)
+ select = CPLD_SPIC_CS_CODEC;
+ if (ssp_configuration.device == DEVICE_TOUCH)
+ select = CPLD_SPIC_CS_TOUCH;
+ if (cwrite) {
+ for (cwrite = (cwrite + 7)/8; cwrite-- > 0; ) {
+ CPLD_SPID = (v >> (8*cwrite)) & 0xff;
+ CPLD_SPIC = select | CPLD_SPIC_LOAD;
+ while (!(CPLD_SPIC & CPLD_SPIC_LOADED))
+ ;
+ CPLD_SPIC = select;
+ while (!(CPLD_SPIC & CPLD_SPIC_DONE))
+ ;
+ }
+ v = 0;
+ }
+ if (cread) {
+ mdelay (2); /* *** FIXME: required by ads7843? */
+ v = 0;
+ for (cread = (cread + 7)/8; cread-- > 0;) {
+ CPLD_SPID = 0;
+ CPLD_SPIC = select | CPLD_SPIC_READ
+ | CPLD_SPIC_START;
+ while (!(CPLD_SPIC & CPLD_SPIC_LOADED))
+ ;
+ CPLD_SPIC = select | CPLD_SPIC_READ;
+ while (!(CPLD_SPIC & CPLD_SPIC_DONE))
+ ;
+ v = (v << 8) | CPLD_SPID;
+ }
+ }
+ return v;
+ }
+#endif
+
+ PRINTK ("spi(%d) 0x%04x -> 0x%x\r\n", ssp_configuration.device,
+ v & 0x1ff, (v >> 9) & 0x7f);
+
+ enable_cs ();
+
+ v <<= CPLD_SPI_TX_SHIFT; /* Correction for position of SPI_TX bit */
+ while (cwrite--) {
+ CPLD_SPI
+ = (CPLD_SPI & ~CPLD_SPI_TX)
+ | ((v >> cwrite) & CPLD_SPI_TX);
+ udelay (T_DIS);
+ pulse_clock ();
+ }
+
+ if (cread < 0) {
+ int delay = 10;
+ disable_cs ();
+ udelay (1);
+ enable_cs ();
+
+ l = -1;
+ do {
+ if (CPLD_SPI & CPLD_SPI_RX) {
+ l = 0;
+ break;
+ }
+ } while (udelay (1), --delay);
+ }
+ else
+ /* We pulse the clock before the data to skip the leading zero. */
+ while (cread-- > 0) {
+ pulse_clock ();
+ l = (l<<1)
+ | (((CPLD_SPI & CPLD_SPI_RX)
+ >> CPLD_SPI_RX_SHIFT) & 0x1);
+ }
+
+ disable_cs ();
+ return l;
+}
+
+static int ssp_init (void)
+{
+ spin_lock_init (&ssp_lock);
+ memset (&ssp_configuration, 0, sizeof (ssp_configuration));
+ return 0;
+}
+
+
+/* ssp_chip_select
+
+ drops the chip select line for the CPLD shift-register controlled
+ devices. It doesn't enable chip
+
+*/
+
+static void ssp_chip_select (int enable)
+{
+#if defined (CONFIG_MACH_LPD7A400)
+ int select;
+
+ if (ssp_configuration.device == DEVICE_CODEC)
+ select = CPLD_SPIC_CS_CODEC;
+ else if (ssp_configuration.device == DEVICE_TOUCH)
+ select = CPLD_SPIC_CS_TOUCH;
+ else
+ return;
+
+ if (enable)
+ CPLD_SPIC = select;
+ else
+ CPLD_SPIC = 0;
+#endif
+}
+
+static void ssp_acquire (void)
+{
+ spin_lock (&ssp_lock);
+}
+
+static void ssp_release (void)
+{
+ ssp_chip_select (0); /* just in case */
+ spin_unlock (&ssp_lock);
+}
+
+static int ssp_configure (int device, int mode, int speed,
+ int frame_size_write, int frame_size_read)
+{
+ ssp_configuration.device = device;
+ ssp_configuration.mode = mode;
+ ssp_configuration.speed = speed;
+ ssp_configuration.frame_size_write = frame_size_write;
+ ssp_configuration.frame_size_read = frame_size_read;
+
+ return 0;
+}
+
+static int ssp_read (void)
+{
+ return execute_spi_command (0, 0, ssp_configuration.frame_size_read);
+}
+
+static int ssp_write (u16 data)
+{
+ execute_spi_command (data, ssp_configuration.frame_size_write, 0);
+ return 0;
+}
+
+static int ssp_write_read (u16 data)
+{
+ return execute_spi_command (data, ssp_configuration.frame_size_write,
+ ssp_configuration.frame_size_read);
+}
+
+struct ssp_driver lh7a40x_cpld_ssp_driver = {
+ .init = ssp_init,
+ .acquire = ssp_acquire,
+ .release = ssp_release,
+ .configure = ssp_configure,
+ .chip_select = ssp_chip_select,
+ .read = ssp_read,
+ .write = ssp_write,
+ .write_read = ssp_write_read,
+};
+
+
+MODULE_AUTHOR("Marc Singer");
+MODULE_DESCRIPTION("LPD7A40X CPLD SPI driver");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/mach-lh7a40x/time.c b/arch/arm/mach-lh7a40x/time.c
index be377e331f25..ef9af375fcc4 100644
--- a/arch/arm/mach-lh7a40x/time.c
+++ b/arch/arm/mach-lh7a40x/time.c
@@ -1,4 +1,4 @@
-/*
+/*
* arch/arm/mach-lh7a40x/time.c
*
* Copyright (C) 2004 Logic Product Development
@@ -57,7 +57,7 @@ static struct irqaction lh7a40x_timer_irq = {
.handler = lh7a40x_timer_interrupt,
};
-static void __init lh7a40x_timer_init(void)
+static void __init lh7a40x_timer_init (void)
{
/* Stop/disable all timers */
TIMER_CONTROL1 = 0;
diff --git a/arch/arm/mach-pnx4008/Makefile b/arch/arm/mach-pnx4008/Makefile
new file mode 100644
index 000000000000..b457ca0a431a
--- /dev/null
+++ b/arch/arm/mach-pnx4008/Makefile
@@ -0,0 +1,12 @@
+#
+# Makefile for the linux kernel.
+#
+
+obj-y := core.o irq.o time.o clock.o gpio.o serial.o dma.o
+obj-m :=
+obj-n :=
+obj- :=
+
+# Power Management
+obj-$(CONFIG_PM) += pm.o sleep.o
+
diff --git a/arch/arm/mach-pnx4008/Makefile.boot b/arch/arm/mach-pnx4008/Makefile.boot
new file mode 100644
index 000000000000..44c7117e20dd
--- /dev/null
+++ b/arch/arm/mach-pnx4008/Makefile.boot
@@ -0,0 +1,4 @@
+ zreladdr-y := 0x80008000
+params_phys-y := 0x80000100
+initrd_phys-y := 0x80800000
+
diff --git a/arch/arm/mach-pnx4008/clock.c b/arch/arm/mach-pnx4008/clock.c
new file mode 100644
index 000000000000..285b22f631e9
--- /dev/null
+++ b/arch/arm/mach-pnx4008/clock.c
@@ -0,0 +1,1010 @@
+/*
+ * arch/arm/mach-pnx4008/clock.c
+ *
+ * Clock control driver for PNX4008
+ *
+ * Authors: Vitaly Wool, Dmitry Chigirev <source@mvista.com>
+ * Generic clock management functions are partially based on:
+ * linux/arch/arm/mach-omap/clock.c
+ *
+ * 2005-2006 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+
+#include <asm/semaphore.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+
+#include <asm/arch/clock.h>
+#include "clock.h"
+
+/*forward declaration*/
+static struct clk per_ck;
+static struct clk hclk_ck;
+static struct clk ck_1MHz;
+static struct clk ck_13MHz;
+static struct clk ck_pll1;
+static int local_set_rate(struct clk *clk, u32 rate);
+
+static inline void clock_lock(void)
+{
+ local_irq_disable();
+}
+
+static inline void clock_unlock(void)
+{
+ local_irq_enable();
+}
+
+static void propagate_rate(struct clk *clk)
+{
+ struct clk *tmp_clk;
+
+ tmp_clk = clk;
+ while (tmp_clk->propagate_next) {
+ tmp_clk = tmp_clk->propagate_next;
+ local_set_rate(tmp_clk, tmp_clk->user_rate);
+ }
+}
+
+static inline void clk_reg_disable(struct clk *clk)
+{
+ if (clk->enable_reg)
+ __raw_writel(__raw_readl(clk->enable_reg) &
+ ~(1 << clk->enable_shift), clk->enable_reg);
+}
+
+static inline void clk_reg_enable(struct clk *clk)
+{
+ if (clk->enable_reg)
+ __raw_writel(__raw_readl(clk->enable_reg) |
+ (1 << clk->enable_shift), clk->enable_reg);
+}
+
+static inline void clk_reg_disable1(struct clk *clk)
+{
+ if (clk->enable_reg1)
+ __raw_writel(__raw_readl(clk->enable_reg1) &
+ ~(1 << clk->enable_shift1), clk->enable_reg1);
+}
+
+static inline void clk_reg_enable1(struct clk *clk)
+{
+ if (clk->enable_reg1)
+ __raw_writel(__raw_readl(clk->enable_reg1) |
+ (1 << clk->enable_shift1), clk->enable_reg1);
+}
+
+static int clk_wait_for_pll_lock(struct clk *clk)
+{
+ int i;
+ i = 0;
+ while (i++ < 0xFFF && !(__raw_readl(clk->scale_reg) & 1)) ; /*wait for PLL to lock */
+
+ if (!(__raw_readl(clk->scale_reg) & 1)) {
+ printk(KERN_ERR
+ "%s ERROR: failed to lock, scale reg data: %x\n",
+ clk->name, __raw_readl(clk->scale_reg));
+ return -1;
+ }
+ return 0;
+}
+
+static int switch_to_dirty_13mhz(struct clk *clk)
+{
+ int i;
+ int ret;
+ u32 tmp_reg;
+
+ ret = 0;
+
+ if (!clk->rate)
+ clk_reg_enable1(clk);
+
+ tmp_reg = __raw_readl(clk->parent_switch_reg);
+ /*if 13Mhz clock selected, select 13'MHz (dirty) source from OSC */
+ if (!(tmp_reg & 1)) {
+ tmp_reg |= (1 << 1); /* Trigger switch to 13'MHz (dirty) clock */
+ __raw_writel(tmp_reg, clk->parent_switch_reg);
+ i = 0;
+ while (i++ < 0xFFF && !(__raw_readl(clk->parent_switch_reg) & 1)) ; /*wait for 13'MHz selection status */
+
+ if (!(__raw_readl(clk->parent_switch_reg) & 1)) {
+ printk(KERN_ERR
+ "%s ERROR: failed to select 13'MHz, parent sw reg data: %x\n",
+ clk->name, __raw_readl(clk->parent_switch_reg));
+ ret = -1;
+ }
+ }
+
+ if (!clk->rate)
+ clk_reg_disable1(clk);
+
+ return ret;
+}
+
+static int switch_to_clean_13mhz(struct clk *clk)
+{
+ int i;
+ int ret;
+ u32 tmp_reg;
+
+ ret = 0;
+
+ if (!clk->rate)
+ clk_reg_enable1(clk);
+
+ tmp_reg = __raw_readl(clk->parent_switch_reg);
+ /*if 13'Mhz clock selected, select 13MHz (clean) source from OSC */
+ if (tmp_reg & 1) {
+ tmp_reg &= ~(1 << 1); /* Trigger switch to 13MHz (clean) clock */
+ __raw_writel(tmp_reg, clk->parent_switch_reg);
+ i = 0;
+ while (i++ < 0xFFF && (__raw_readl(clk->parent_switch_reg) & 1)) ; /*wait for 13MHz selection status */
+
+ if (__raw_readl(clk->parent_switch_reg) & 1) {
+ printk(KERN_ERR
+ "%s ERROR: failed to select 13MHz, parent sw reg data: %x\n",
+ clk->name, __raw_readl(clk->parent_switch_reg));
+ ret = -1;
+ }
+ }
+
+ if (!clk->rate)
+ clk_reg_disable1(clk);
+
+ return ret;
+}
+
+static int set_13MHz_parent(struct clk *clk, struct clk *parent)
+{
+ int ret = -EINVAL;
+
+ if (parent == &ck_13MHz)
+ ret = switch_to_clean_13mhz(clk);
+ else if (parent == &ck_pll1)
+ ret = switch_to_dirty_13mhz(clk);
+
+ return ret;
+}
+
+#define PLL160_MIN_FCCO 156000
+#define PLL160_MAX_FCCO 320000
+
+/*
+ * Calculate pll160 settings.
+ * Possible input: up to 320MHz with step of clk->parent->rate.
+ * In PNX4008 parent rate for pll160s may be either 1 or 13MHz.
+ * Ignored paths: "feedback" (bit 13 set), "div-by-N".
+ * Setting ARM PLL4 rate to 0 will put CPU into direct run mode.
+ * Setting PLL5 and PLL3 rate to 0 will disable USB and DSP clock input.
+ * Please refer to PNX4008 IC manual for details.
+ */
+
+static int pll160_set_rate(struct clk *clk, u32 rate)
+{
+ u32 tmp_reg, tmp_m, tmp_2p, i;
+ u32 parent_rate;
+ int ret = -EINVAL;
+
+ parent_rate = clk->parent->rate;
+
+ if (!parent_rate)
+ goto out;
+
+ /* set direct run for ARM or disable output for others */
+ clk_reg_disable(clk);
+
+ /* disable source input as well (ignored for ARM) */
+ clk_reg_disable1(clk);
+
+ tmp_reg = __raw_readl(clk->scale_reg);
+ tmp_reg &= ~0x1ffff; /*clear all settings, power down */
+ __raw_writel(tmp_reg, clk->scale_reg);
+
+ rate -= rate % parent_rate; /*round down the input */
+
+ if (rate > PLL160_MAX_FCCO)
+ rate = PLL160_MAX_FCCO;
+
+ if (!rate) {
+ clk->rate = 0;
+ ret = 0;
+ goto out;
+ }
+
+ clk_reg_enable1(clk);
+ tmp_reg = __raw_readl(clk->scale_reg);
+
+ if (rate == parent_rate) {
+ /*enter direct bypass mode */
+ tmp_reg |= ((1 << 14) | (1 << 15));
+ __raw_writel(tmp_reg, clk->scale_reg);
+ clk->rate = parent_rate;
+ clk_reg_enable(clk);
+ ret = 0;
+ goto out;
+ }
+
+ i = 0;
+ for (tmp_2p = 1; tmp_2p < 16; tmp_2p <<= 1) {
+ if (rate * tmp_2p >= PLL160_MIN_FCCO)
+ break;
+ i++;
+ }
+
+ if (tmp_2p > 1)
+ tmp_reg |= ((i - 1) << 11);
+ else
+ tmp_reg |= (1 << 14); /*direct mode, no divide */
+
+ tmp_m = rate * tmp_2p;
+ tmp_m /= parent_rate;
+
+ tmp_reg |= (tmp_m - 1) << 1; /*calculate M */
+ tmp_reg |= (1 << 16); /*power up PLL */
+ __raw_writel(tmp_reg, clk->scale_reg);
+
+ if (clk_wait_for_pll_lock(clk) < 0) {
+ clk_reg_disable(clk);
+ clk_reg_disable1(clk);
+
+ tmp_reg = __raw_readl(clk->scale_reg);
+ tmp_reg &= ~0x1ffff; /*clear all settings, power down */
+ __raw_writel(tmp_reg, clk->scale_reg);
+ clk->rate = 0;
+ ret = -EFAULT;
+ goto out;
+ }
+
+ clk->rate = (tmp_m * parent_rate) / tmp_2p;
+
+ if (clk->flags & RATE_PROPAGATES)
+ propagate_rate(clk);
+
+ clk_reg_enable(clk);
+ ret = 0;
+
+out:
+ return ret;
+}
+
+/*configure PER_CLK*/
+static int per_clk_set_rate(struct clk *clk, u32 rate)
+{
+ u32 tmp;
+
+ tmp = __raw_readl(clk->scale_reg);
+ tmp &= ~(0x1f << 2);
+ tmp |= ((clk->parent->rate / clk->rate) - 1) << 2;
+ __raw_writel(tmp, clk->scale_reg);
+ clk->rate = rate;
+ return 0;
+}
+
+/*configure HCLK*/
+static int hclk_set_rate(struct clk *clk, u32 rate)
+{
+ u32 tmp;
+ tmp = __raw_readl(clk->scale_reg);
+ tmp = tmp & ~0x3;
+ switch (rate) {
+ case 1:
+ break;
+ case 2:
+ tmp |= 1;
+ break;
+ case 4:
+ tmp |= 2;
+ break;
+ }
+
+ __raw_writel(tmp, clk->scale_reg);
+ clk->rate = rate;
+ return 0;
+}
+
+static u32 hclk_round_rate(struct clk *clk, u32 rate)
+{
+ switch (rate) {
+ case 1:
+ case 4:
+ return rate;
+ }
+ return 2;
+}
+
+static u32 per_clk_round_rate(struct clk *clk, u32 rate)
+{
+ return CLK_RATE_13MHZ;
+}
+
+static int on_off_set_rate(struct clk *clk, u32 rate)
+{
+ if (rate) {
+ clk_reg_enable(clk);
+ clk->rate = 1;
+ } else {
+ clk_reg_disable(clk);
+ clk->rate = 0;
+ }
+ return 0;
+}
+
+static int on_off_inv_set_rate(struct clk *clk, u32 rate)
+{
+ if (rate) {
+ clk_reg_disable(clk); /*enable bit is inverted */
+ clk->rate = 1;
+ } else {
+ clk_reg_enable(clk);
+ clk->rate = 0;
+ }
+ return 0;
+}
+
+static u32 on_off_round_rate(struct clk *clk, u32 rate)
+{
+ return (rate ? 1 : 0);
+}
+
+static u32 pll4_round_rate(struct clk *clk, u32 rate)
+{
+ if (rate > CLK_RATE_208MHZ)
+ rate = CLK_RATE_208MHZ;
+ if (rate == CLK_RATE_208MHZ && hclk_ck.user_rate == 1)
+ rate = CLK_RATE_208MHZ - CLK_RATE_13MHZ;
+ return (rate - (rate % (hclk_ck.user_rate * CLK_RATE_13MHZ)));
+}
+
+static u32 pll3_round_rate(struct clk *clk, u32 rate)
+{
+ if (rate > CLK_RATE_208MHZ)
+ rate = CLK_RATE_208MHZ;
+ return (rate - rate % CLK_RATE_13MHZ);
+}
+
+static u32 pll5_round_rate(struct clk *clk, u32 rate)
+{
+ return (rate ? CLK_RATE_48MHZ : 0);
+}
+
+static u32 ck_13MHz_round_rate(struct clk *clk, u32 rate)
+{
+ return (rate ? CLK_RATE_13MHZ : 0);
+}
+
+static int ck_13MHz_set_rate(struct clk *clk, u32 rate)
+{
+ if (rate) {
+ clk_reg_disable(clk); /*enable bit is inverted */
+ udelay(500);
+ clk->rate = CLK_RATE_13MHZ;
+ ck_1MHz.rate = CLK_RATE_1MHZ;
+ } else {
+ clk_reg_enable(clk);
+ clk->rate = 0;
+ ck_1MHz.rate = 0;
+ }
+ return 0;
+}
+
+static int pll1_set_rate(struct clk *clk, u32 rate)
+{
+#if 0 /* doesn't work on some boards, probably a HW BUG */
+ if (rate) {
+ clk_reg_disable(clk); /*enable bit is inverted */
+ if (!clk_wait_for_pll_lock(clk)) {
+ clk->rate = CLK_RATE_13MHZ;
+ } else {
+ clk_reg_enable(clk);
+ clk->rate = 0;
+ }
+
+ } else {
+ clk_reg_enable(clk);
+ clk->rate = 0;
+ }
+#endif
+ return 0;
+}
+
+/* Clock sources */
+
+static struct clk osc_13MHz = {
+ .name = "osc_13MHz",
+ .flags = FIXED_RATE,
+ .rate = CLK_RATE_13MHZ,
+};
+
+static struct clk ck_13MHz = {
+ .name = "ck_13MHz",
+ .parent = &osc_13MHz,
+ .flags = NEEDS_INITIALIZATION,
+ .round_rate = &ck_13MHz_round_rate,
+ .set_rate = &ck_13MHz_set_rate,
+ .enable_reg = OSC13CTRL_REG,
+ .enable_shift = 0,
+ .rate = CLK_RATE_13MHZ,
+};
+
+static struct clk osc_32KHz = {
+ .name = "osc_32KHz",
+ .flags = FIXED_RATE,
+ .rate = CLK_RATE_32KHZ,
+};
+
+/*attached to PLL5*/
+static struct clk ck_1MHz = {
+ .name = "ck_1MHz",
+ .flags = FIXED_RATE | PARENT_SET_RATE,
+ .parent = &ck_13MHz,
+};
+
+/* PLL1 (397) - provides 13' MHz clock */
+static struct clk ck_pll1 = {
+ .name = "ck_pll1",
+ .parent = &osc_32KHz,
+ .flags = NEEDS_INITIALIZATION,
+ .round_rate = &ck_13MHz_round_rate,
+ .set_rate = &pll1_set_rate,
+ .enable_reg = PLLCTRL_REG,
+ .enable_shift = 1,
+ .scale_reg = PLLCTRL_REG,
+ .rate = CLK_RATE_13MHZ,
+};
+
+/* CPU/Bus PLL */
+static struct clk ck_pll4 = {
+ .name = "ck_pll4",
+ .parent = &ck_pll1,
+ .flags = RATE_PROPAGATES | NEEDS_INITIALIZATION,
+ .propagate_next = &per_ck,
+ .round_rate = &pll4_round_rate,
+ .set_rate = &pll160_set_rate,
+ .rate = CLK_RATE_208MHZ,
+ .scale_reg = HCLKPLLCTRL_REG,
+ .enable_reg = PWRCTRL_REG,
+ .enable_shift = 2,
+ .parent_switch_reg = SYSCLKCTRL_REG,
+ .set_parent = &set_13MHz_parent,
+};
+
+/* USB PLL */
+static struct clk ck_pll5 = {
+ .name = "ck_pll5",
+ .parent = &ck_1MHz,
+ .flags = NEEDS_INITIALIZATION,
+ .round_rate = &pll5_round_rate,
+ .set_rate = &pll160_set_rate,
+ .scale_reg = USBCTRL_REG,
+ .enable_reg = USBCTRL_REG,
+ .enable_shift = 18,
+ .enable_reg1 = USBCTRL_REG,
+ .enable_shift1 = 17,
+};
+
+/* XPERTTeak DSP PLL */
+static struct clk ck_pll3 = {
+ .name = "ck_pll3",
+ .parent = &ck_pll1,
+ .flags = NEEDS_INITIALIZATION,
+ .round_rate = &pll3_round_rate,
+ .set_rate = &pll160_set_rate,
+ .scale_reg = DSPPLLCTRL_REG,
+ .enable_reg = DSPCLKCTRL_REG,
+ .enable_shift = 3,
+ .enable_reg1 = DSPCLKCTRL_REG,
+ .enable_shift1 = 2,
+ .parent_switch_reg = DSPCLKCTRL_REG,
+ .set_parent = &set_13MHz_parent,
+};
+
+static struct clk hclk_ck = {
+ .name = "hclk_ck",
+ .parent = &ck_pll4,
+ .flags = PARENT_SET_RATE,
+ .set_rate = &hclk_set_rate,
+ .round_rate = &hclk_round_rate,
+ .scale_reg = HCLKDIVCTRL_REG,
+ .rate = 2,
+ .user_rate = 2,
+};
+
+static struct clk per_ck = {
+ .name = "per_ck",
+ .parent = &ck_pll4,
+ .flags = FIXED_RATE,
+ .propagate_next = &hclk_ck,
+ .set_rate = &per_clk_set_rate,
+ .round_rate = &per_clk_round_rate,
+ .scale_reg = HCLKDIVCTRL_REG,
+ .rate = CLK_RATE_13MHZ,
+ .user_rate = CLK_RATE_13MHZ,
+};
+
+static struct clk m2hclk_ck = {
+ .name = "m2hclk_ck",
+ .parent = &hclk_ck,
+ .flags = NEEDS_INITIALIZATION,
+ .round_rate = &on_off_round_rate,
+ .set_rate = &on_off_inv_set_rate,
+ .rate = 1,
+ .enable_shift = 6,
+ .enable_reg = PWRCTRL_REG,
+};
+
+static struct clk vfp9_ck = {
+ .name = "vfp9_ck",
+ .parent = &ck_pll4,
+ .flags = NEEDS_INITIALIZATION,
+ .round_rate = &on_off_round_rate,
+ .set_rate = &on_off_set_rate,
+ .rate = 1,
+ .enable_shift = 4,
+ .enable_reg = VFP9CLKCTRL_REG,
+};
+
+static struct clk keyscan_ck = {
+ .name = "keyscan_ck",
+ .parent = &osc_32KHz,
+ .flags = NEEDS_INITIALIZATION,
+ .round_rate = &on_off_round_rate,
+ .set_rate = &on_off_set_rate,
+ .enable_shift = 0,
+ .enable_reg = KEYCLKCTRL_REG,
+};
+
+static struct clk touch_ck = {
+ .name = "touch_ck",
+ .parent = &osc_32KHz,
+ .flags = NEEDS_INITIALIZATION,
+ .round_rate = &on_off_round_rate,
+ .set_rate = &on_off_set_rate,
+ .enable_shift = 0,
+ .enable_reg = TSCLKCTRL_REG,
+};
+
+static struct clk pwm1_ck = {
+ .name = "pwm1_ck",
+ .parent = &osc_32KHz,
+ .flags = NEEDS_INITIALIZATION,
+ .round_rate = &on_off_round_rate,
+ .set_rate = &on_off_set_rate,
+ .enable_shift = 0,
+ .enable_reg = PWMCLKCTRL_REG,
+};
+
+static struct clk pwm2_ck = {
+ .name = "pwm2_ck",
+ .parent = &osc_32KHz,
+ .flags = NEEDS_INITIALIZATION,
+ .round_rate = &on_off_round_rate,
+ .set_rate = &on_off_set_rate,
+ .enable_shift = 2,
+ .enable_reg = PWMCLKCTRL_REG,
+};
+
+static struct clk jpeg_ck = {
+ .name = "jpeg_ck",
+ .parent = &hclk_ck,
+ .flags = NEEDS_INITIALIZATION,
+ .round_rate = &on_off_round_rate,
+ .set_rate = &on_off_set_rate,
+ .enable_shift = 0,
+ .enable_reg = JPEGCLKCTRL_REG,
+};
+
+static struct clk ms_ck = {
+ .name = "ms_ck",
+ .parent = &ck_pll4,
+ .flags = NEEDS_INITIALIZATION,
+ .round_rate = &on_off_round_rate,
+ .set_rate = &on_off_set_rate,
+ .enable_shift = 5,
+ .enable_reg = MSCTRL_REG,
+};
+
+static struct clk dum_ck = {
+ .name = "dum_ck",
+ .parent = &hclk_ck,
+ .flags = NEEDS_INITIALIZATION,
+ .round_rate = &on_off_round_rate,
+ .set_rate = &on_off_set_rate,
+ .enable_shift = 0,
+ .enable_reg = DUMCLKCTRL_REG,
+};
+
+static struct clk flash_ck = {
+ .name = "flash_ck",
+ .parent = &hclk_ck,
+ .round_rate = &on_off_round_rate,
+ .set_rate = &on_off_set_rate,
+ .enable_shift = 1, /* Only MLC clock supported */
+ .enable_reg = FLASHCLKCTRL_REG,
+};
+
+static struct clk i2c0_ck = {
+ .name = "i2c0_ck",
+ .parent = &per_ck,
+ .flags = NEEDS_INITIALIZATION,
+ .round_rate = &on_off_round_rate,
+ .set_rate = &on_off_set_rate,
+ .enable_shift = 0,
+ .enable_reg = I2CCLKCTRL_REG,
+};
+
+static struct clk i2c1_ck = {
+ .name = "i2c1_ck",
+ .parent = &per_ck,
+ .flags = NEEDS_INITIALIZATION,
+ .round_rate = &on_off_round_rate,
+ .set_rate = &on_off_set_rate,
+ .enable_shift = 1,
+ .enable_reg = I2CCLKCTRL_REG,
+};
+
+static struct clk i2c2_ck = {
+ .name = "i2c2_ck",
+ .parent = &per_ck,
+ .flags = NEEDS_INITIALIZATION,
+ .round_rate = &on_off_round_rate,
+ .set_rate = &on_off_set_rate,
+ .enable_shift = 2,
+ .enable_reg = USB_OTG_CLKCTRL_REG,
+};
+
+static struct clk spi0_ck = {
+ .name = "spi0_ck",
+ .parent = &hclk_ck,
+ .flags = NEEDS_INITIALIZATION,
+ .round_rate = &on_off_round_rate,
+ .set_rate = &on_off_set_rate,
+ .enable_shift = 0,
+ .enable_reg = SPICTRL_REG,
+};
+
+static struct clk spi1_ck = {
+ .name = "spi1_ck",
+ .parent = &hclk_ck,
+ .flags = NEEDS_INITIALIZATION,
+ .round_rate = &on_off_round_rate,
+ .set_rate = &on_off_set_rate,
+ .enable_shift = 4,
+ .enable_reg = SPICTRL_REG,
+};
+
+static struct clk dma_ck = {
+ .name = "dma_ck",
+ .parent = &hclk_ck,
+ .round_rate = &on_off_round_rate,
+ .set_rate = &on_off_set_rate,
+ .enable_shift = 0,
+ .enable_reg = DMACLKCTRL_REG,
+};
+
+static struct clk uart3_ck = {
+ .name = "uart3_ck",
+ .parent = &per_ck,
+ .flags = NEEDS_INITIALIZATION,
+ .round_rate = &on_off_round_rate,
+ .set_rate = &on_off_set_rate,
+ .rate = 1,
+ .enable_shift = 0,
+ .enable_reg = UARTCLKCTRL_REG,
+};
+
+static struct clk uart4_ck = {
+ .name = "uart4_ck",
+ .parent = &per_ck,
+ .flags = NEEDS_INITIALIZATION,
+ .round_rate = &on_off_round_rate,
+ .set_rate = &on_off_set_rate,
+ .enable_shift = 1,
+ .enable_reg = UARTCLKCTRL_REG,
+};
+
+static struct clk uart5_ck = {
+ .name = "uart5_ck",
+ .parent = &per_ck,
+ .flags = NEEDS_INITIALIZATION,
+ .round_rate = &on_off_round_rate,
+ .set_rate = &on_off_set_rate,
+ .rate = 1,
+ .enable_shift = 2,
+ .enable_reg = UARTCLKCTRL_REG,
+};
+
+static struct clk uart6_ck = {
+ .name = "uart6_ck",
+ .parent = &per_ck,
+ .flags = NEEDS_INITIALIZATION,
+ .round_rate = &on_off_round_rate,
+ .set_rate = &on_off_set_rate,
+ .enable_shift = 3,
+ .enable_reg = UARTCLKCTRL_REG,
+};
+
+/* These clocks are visible outside this module
+ * and can be initialized
+ */
+static struct clk *onchip_clks[] = {
+ &ck_13MHz,
+ &ck_pll1,
+ &ck_pll4,
+ &ck_pll5,
+ &ck_pll3,
+ &vfp9_ck,
+ &m2hclk_ck,
+ &hclk_ck,
+ &dma_ck,
+ &flash_ck,
+ &dum_ck,
+ &keyscan_ck,
+ &pwm1_ck,
+ &pwm2_ck,
+ &jpeg_ck,
+ &ms_ck,
+ &touch_ck,
+ &i2c0_ck,
+ &i2c1_ck,
+ &i2c2_ck,
+ &spi0_ck,
+ &spi1_ck,
+ &uart3_ck,
+ &uart4_ck,
+ &uart5_ck,
+ &uart6_ck,
+};
+
+static int local_set_rate(struct clk *clk, u32 rate)
+{
+ int ret = -EINVAL;
+ if (clk->set_rate) {
+
+ if (clk->user_rate == clk->rate && clk->parent->rate) {
+ /* if clock enabled or rate not set */
+ clk->user_rate = clk->round_rate(clk, rate);
+ ret = clk->set_rate(clk, clk->user_rate);
+ } else
+ clk->user_rate = clk->round_rate(clk, rate);
+ ret = 0;
+ }
+ return ret;
+}
+
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+ int ret = -EINVAL;
+
+ if (clk->flags & FIXED_RATE)
+ goto out;
+
+ clock_lock();
+ if ((clk->flags & PARENT_SET_RATE) && clk->parent) {
+
+ clk->user_rate = clk->round_rate(clk, rate);
+ /* parent clock needs to be refreshed
+ for the setting to take effect */
+ } else {
+ ret = local_set_rate(clk, rate);
+ }
+ ret = 0;
+ clock_unlock();
+
+out:
+ return ret;
+}
+
+EXPORT_SYMBOL(clk_set_rate);
+
+struct clk *clk_get(struct device *dev, const char *id)
+{
+ struct clk *clk = ERR_PTR(-ENOENT);
+ struct clk **clkp;
+
+ clock_lock();
+ for (clkp = onchip_clks; clkp < onchip_clks + ARRAY_SIZE(onchip_clks);
+ clkp++) {
+ if (strcmp(id, (*clkp)->name) == 0
+ && try_module_get((*clkp)->owner)) {
+ clk = (*clkp);
+ break;
+ }
+ }
+ clock_unlock();
+
+ return clk;
+}
+EXPORT_SYMBOL(clk_get);
+
+void clk_put(struct clk *clk)
+{
+ clock_lock();
+ if (clk && !IS_ERR(clk))
+ module_put(clk->owner);
+ clock_unlock();
+}
+EXPORT_SYMBOL(clk_put);
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+ unsigned long ret;
+ clock_lock();
+ ret = clk->rate;
+ clock_unlock();
+ return ret;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+static int local_clk_enable(struct clk *clk)
+{
+ int ret = 0;
+
+ if (!(clk->flags & FIXED_RATE) && !clk->rate && clk->set_rate
+ && clk->user_rate)
+ ret = clk->set_rate(clk, clk->user_rate);
+ return ret;
+}
+
+static void local_clk_disable(struct clk *clk)
+{
+ if (!(clk->flags & FIXED_RATE) && clk->rate && clk->set_rate)
+ clk->set_rate(clk, 0);
+}
+
+int clk_enable(struct clk *clk)
+{
+ int ret = 0;
+
+ clock_lock();
+ ret = local_clk_enable(clk);
+ clock_unlock();
+ return ret;
+}
+
+EXPORT_SYMBOL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+ clock_lock();
+ local_clk_disable(clk);
+ clock_unlock();
+}
+
+EXPORT_SYMBOL(clk_disable);
+
+static void local_clk_unuse(struct clk *clk)
+{
+ if (clk->usecount > 0 && !(--clk->usecount)) {
+ local_clk_disable(clk);
+ if (clk->parent)
+ local_clk_unuse(clk->parent);
+ }
+}
+
+static int local_clk_use(struct clk *clk)
+{
+ int ret = 0;
+ if (clk->usecount++ == 0) {
+ if (clk->parent)
+ ret = local_clk_use(clk->parent);
+
+ if (ret != 0) {
+ clk->usecount--;
+ goto out;
+ }
+
+ ret = local_clk_enable(clk);
+
+ if (ret != 0 && clk->parent) {
+ local_clk_unuse(clk->parent);
+ clk->usecount--;
+ }
+ }
+out:
+ return ret;
+}
+
+/* The main purpose of clk_use ans clk_unuse functions
+ * is to control switching 13MHz oscillator and PLL1 (13'MHz),
+ * so that they are disabled whenever none of PLL2-5 is using them.
+ * Although in theory these functions should work with any clock,
+ * please use them only on PLL2 - PLL5 to avoid confusion.
+ */
+int clk_use(struct clk *clk)
+{
+ int ret = 0;
+
+ clock_lock();
+ ret = local_clk_use(clk);
+ clock_unlock();
+ return ret;
+}
+EXPORT_SYMBOL(clk_use);
+
+void clk_unuse(struct clk *clk)
+{
+
+ clock_lock();
+ local_clk_unuse(clk);
+ clock_unlock();
+}
+
+EXPORT_SYMBOL(clk_unuse);
+
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+ long ret;
+ clock_lock();
+ if (clk->round_rate)
+ ret = clk->round_rate(clk, rate);
+ else
+ ret = clk->rate;
+ clock_unlock();
+ return ret;
+}
+
+EXPORT_SYMBOL(clk_round_rate);
+
+int clk_set_parent(struct clk *clk, struct clk *parent)
+{
+ int ret = -ENODEV;
+ if (!clk->set_parent)
+ goto out;
+
+ clock_lock();
+ ret = clk->set_parent(clk, parent);
+ if (!ret)
+ clk->parent = parent;
+ clock_unlock();
+
+out:
+ return ret;
+}
+
+EXPORT_SYMBOL(clk_set_parent);
+
+static int __init clk_init(void)
+{
+ struct clk **clkp;
+
+ /* Disable autoclocking, as it doesn't seem to work */
+ __raw_writel(0xff, AUTOCLK_CTRL);
+
+ for (clkp = onchip_clks; clkp < onchip_clks + ARRAY_SIZE(onchip_clks);
+ clkp++) {
+ if (((*clkp)->flags & NEEDS_INITIALIZATION)
+ && ((*clkp)->set_rate)) {
+ (*clkp)->user_rate = (*clkp)->rate;
+ local_set_rate((*clkp), (*clkp)->user_rate);
+ if ((*clkp)->set_parent)
+ (*clkp)->set_parent((*clkp), (*clkp)->parent);
+ }
+ pr_debug("%s: clock %s, rate %ld\n",
+ __FUNCTION__, (*clkp)->name, (*clkp)->rate);
+ }
+
+ clk_use(&ck_pll4);
+
+ /* if ck_13MHz is not used, disable it. */
+ if (ck_13MHz.usecount == 0)
+ local_clk_disable(&ck_13MHz);
+
+ /* Disable autoclocking */
+ __raw_writeb(0xff, AUTOCLK_CTRL);
+
+ return 0;
+}
+
+arch_initcall(clk_init);
diff --git a/arch/arm/mach-pnx4008/clock.h b/arch/arm/mach-pnx4008/clock.h
new file mode 100644
index 000000000000..cd58f372cfd0
--- /dev/null
+++ b/arch/arm/mach-pnx4008/clock.h
@@ -0,0 +1,43 @@
+/*
+ * arch/arm/mach-pnx4008/clock.h
+ *
+ * Clock control driver for PNX4008 - internal header file
+ *
+ * Author: Vitaly Wool <source@mvista.com>
+ *
+ * 2006 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+#ifndef __ARCH_ARM_PNX4008_CLOCK_H__
+#define __ARCH_ARM_PNX4008_CLOCK_H__
+
+struct clk {
+ struct list_head node;
+ struct module *owner;
+ const char *name;
+ struct clk *parent;
+ struct clk *propagate_next;
+ u32 rate;
+ u32 user_rate;
+ s8 usecount;
+ u32 flags;
+ u32 scale_reg;
+ u8 enable_shift;
+ u32 enable_reg;
+ u8 enable_shift1;
+ u32 enable_reg1;
+ u32 parent_switch_reg;
+ u32(*round_rate) (struct clk *, u32);
+ int (*set_rate) (struct clk *, u32);
+ int (*set_parent) (struct clk * clk, struct clk * parent);
+};
+
+/* Flags */
+#define RATE_PROPAGATES (1<<0)
+#define NEEDS_INITIALIZATION (1<<1)
+#define PARENT_SET_RATE (1<<2)
+#define FIXED_RATE (1<<3)
+
+#endif
diff --git a/arch/arm/mach-pnx4008/core.c b/arch/arm/mach-pnx4008/core.c
new file mode 100644
index 000000000000..ba91daad64fb
--- /dev/null
+++ b/arch/arm/mach-pnx4008/core.c
@@ -0,0 +1,207 @@
+/*
+ * arch/arm/mach-pnx4008/core.c
+ *
+ * PNX4008 core startup code
+ *
+ * Authors: Vitaly Wool, Dmitry Chigirev,
+ * Grigory Tolstolytkin, Dmitry Pervushin <source@mvista.com>
+ *
+ * Based on reference code received from Philips:
+ * Copyright (C) 2003 Philips Semiconductors
+ *
+ * 2005 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/serial_8250.h>
+#include <linux/device.h>
+#include <linux/spi/spi.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/system.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+
+#include <asm/arch/irq.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/dma.h>
+
+struct resource spipnx_0_resources[] = {
+ {
+ .start = PNX4008_SPI1_BASE,
+ .end = PNX4008_SPI1_BASE + SZ_4K,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = PER_SPI1_REC_XMIT,
+ .flags = IORESOURCE_DMA,
+ }, {
+ .start = SPI1_INT,
+ .flags = IORESOURCE_IRQ,
+ }, {
+ .flags = 0,
+ },
+};
+
+struct resource spipnx_1_resources[] = {
+ {
+ .start = PNX4008_SPI2_BASE,
+ .end = PNX4008_SPI2_BASE + SZ_4K,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = PER_SPI2_REC_XMIT,
+ .flags = IORESOURCE_DMA,
+ }, {
+ .start = SPI2_INT,
+ .flags = IORESOURCE_IRQ,
+ }, {
+ .flags = 0,
+ }
+};
+
+static struct spi_board_info spi_board_info[] __initdata = {
+ {
+ .modalias = "m25p80",
+ .max_speed_hz = 1000000,
+ .bus_num = 1,
+ .chip_select = 0,
+ },
+};
+
+static struct platform_device spipnx_1 = {
+ .name = "spipnx",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(spipnx_0_resources),
+ .resource = spipnx_0_resources,
+ .dev = {
+ .coherent_dma_mask = 0xFFFFFFFF,
+ },
+};
+
+static struct platform_device spipnx_2 = {
+ .name = "spipnx",
+ .id = 2,
+ .num_resources = ARRAY_SIZE(spipnx_1_resources),
+ .resource = spipnx_1_resources,
+ .dev = {
+ .coherent_dma_mask = 0xFFFFFFFF,
+ },
+};
+
+static struct plat_serial8250_port platform_serial_ports[] = {
+ {
+ .membase = (void *)__iomem(IO_ADDRESS(PNX4008_UART5_BASE)),
+ .mapbase = (unsigned long)PNX4008_UART5_BASE,
+ .irq = IIR5_INT,
+ .uartclk = PNX4008_UART_CLK,
+ .regshift = 2,
+ .iotype = UPIO_MEM,
+ .flags = UPF_BOOT_AUTOCONF | UPF_BUGGY_UART | UPF_SKIP_TEST,
+ },
+ {
+ .membase = (void *)__iomem(IO_ADDRESS(PNX4008_UART3_BASE)),
+ .mapbase = (unsigned long)PNX4008_UART3_BASE,
+ .irq = IIR3_INT,
+ .uartclk = PNX4008_UART_CLK,
+ .regshift = 2,
+ .iotype = UPIO_MEM,
+ .flags = UPF_BOOT_AUTOCONF | UPF_BUGGY_UART | UPF_SKIP_TEST,
+ },
+ {}
+};
+
+static struct platform_device serial_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = &platform_serial_ports,
+ },
+};
+
+static struct platform_device *devices[] __initdata = {
+ &spipnx_1,
+ &spipnx_2,
+ &serial_device,
+};
+
+
+extern void pnx4008_uart_init(void);
+
+static void __init pnx4008_init(void)
+{
+ /*disable all START interrupt sources,
+ and clear all START interrupt flags */
+ __raw_writel(0, START_INT_ER_REG(SE_PIN_BASE_INT));
+ __raw_writel(0, START_INT_ER_REG(SE_INT_BASE_INT));
+ __raw_writel(0xffffffff, START_INT_RSR_REG(SE_PIN_BASE_INT));
+ __raw_writel(0xffffffff, START_INT_RSR_REG(SE_INT_BASE_INT));
+
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+ spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
+ /* Switch on the UART clocks */
+ pnx4008_uart_init();
+}
+
+static struct map_desc pnx4008_io_desc[] __initdata = {
+ {
+ .virtual = IO_ADDRESS(PNX4008_IRAM_BASE),
+ .pfn = __phys_to_pfn(PNX4008_IRAM_BASE),
+ .length = SZ_64K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IO_ADDRESS(PNX4008_NDF_FLASH_BASE),
+ .pfn = __phys_to_pfn(PNX4008_NDF_FLASH_BASE),
+ .length = SZ_1M - SZ_128K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IO_ADDRESS(PNX4008_JPEG_CONFIG_BASE),
+ .pfn = __phys_to_pfn(PNX4008_JPEG_CONFIG_BASE),
+ .length = SZ_128K * 3,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IO_ADDRESS(PNX4008_DMA_CONFIG_BASE),
+ .pfn = __phys_to_pfn(PNX4008_DMA_CONFIG_BASE),
+ .length = SZ_1M,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IO_ADDRESS(PNX4008_AHB2FAB_BASE),
+ .pfn = __phys_to_pfn(PNX4008_AHB2FAB_BASE),
+ .length = SZ_1M,
+ .type = MT_DEVICE,
+ },
+};
+
+void __init pnx4008_map_io(void)
+{
+ iotable_init(pnx4008_io_desc, ARRAY_SIZE(pnx4008_io_desc));
+}
+
+extern struct sys_timer pnx4008_timer;
+
+MACHINE_START(PNX4008, "Philips PNX4008")
+ /* Maintainer: MontaVista Software Inc. */
+ .phys_io = 0x40090000,
+ .io_pg_offst = (0xf4090000 >> 18) & 0xfffc,
+ .boot_params = 0x80000100,
+ .map_io = pnx4008_map_io,
+ .init_irq = pnx4008_init_irq,
+ .init_machine = pnx4008_init,
+ .timer = &pnx4008_timer,
+MACHINE_END
diff --git a/arch/arm/mach-pnx4008/dma.c b/arch/arm/mach-pnx4008/dma.c
new file mode 100644
index 000000000000..981aa9dcdede
--- /dev/null
+++ b/arch/arm/mach-pnx4008/dma.c
@@ -0,0 +1,1109 @@
+/*
+ * linux/arch/arm/mach-pnx4008/dma.c
+ *
+ * PNX4008 DMA registration and IRQ dispatching
+ *
+ * Author: Vitaly Wool
+ * Copyright: MontaVista Software Inc. (c) 2005
+ *
+ * Based on the code from Nicolas Pitre
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/dma-mapping.h>
+#include <linux/clk.h>
+
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <asm/hardware.h>
+#include <asm/dma.h>
+#include <asm/dma-mapping.h>
+#include <asm/io.h>
+#include <asm/mach/dma.h>
+#include <asm/arch/clock.h>
+
+static struct dma_channel {
+ char *name;
+ void (*irq_handler) (int, int, void *, struct pt_regs *);
+ void *data;
+ struct pnx4008_dma_ll *ll;
+ u32 ll_dma;
+ void *target_addr;
+ int target_id;
+} dma_channels[MAX_DMA_CHANNELS];
+
+static struct ll_pool {
+ void *vaddr;
+ void *cur;
+ dma_addr_t dma_addr;
+ int count;
+} ll_pool;
+
+static spinlock_t ll_lock = SPIN_LOCK_UNLOCKED;
+
+struct pnx4008_dma_ll *pnx4008_alloc_ll_entry(dma_addr_t * ll_dma)
+{
+ struct pnx4008_dma_ll *ll = NULL;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ll_lock, flags);
+ if (ll_pool.count > 4) { /* can give one more */
+ ll = *(struct pnx4008_dma_ll **) ll_pool.cur;
+ *ll_dma = ll_pool.dma_addr + ((void *)ll - ll_pool.vaddr);
+ *(void **)ll_pool.cur = **(void ***)ll_pool.cur;
+ memset(ll, 0, sizeof(*ll));
+ ll_pool.count--;
+ }
+ spin_unlock_irqrestore(&ll_lock, flags);
+
+ return ll;
+}
+
+EXPORT_SYMBOL_GPL(pnx4008_alloc_ll_entry);
+
+void pnx4008_free_ll_entry(struct pnx4008_dma_ll * ll, dma_addr_t ll_dma)
+{
+ unsigned long flags;
+
+ if (ll) {
+ if ((unsigned long)((long)ll - (long)ll_pool.vaddr) > 0x4000) {
+ printk(KERN_ERR "Trying to free entry not allocated by DMA\n");
+ BUG();
+ }
+
+ if (ll->flags & DMA_BUFFER_ALLOCATED)
+ ll->free(ll->alloc_data);
+
+ spin_lock_irqsave(&ll_lock, flags);
+ *(long *)ll = *(long *)ll_pool.cur;
+ *(long *)ll_pool.cur = (long)ll;
+ ll_pool.count++;
+ spin_unlock_irqrestore(&ll_lock, flags);
+ }
+}
+
+EXPORT_SYMBOL_GPL(pnx4008_free_ll_entry);
+
+void pnx4008_free_ll(u32 ll_dma, struct pnx4008_dma_ll * ll)
+{
+ struct pnx4008_dma_ll *ptr;
+ u32 dma;
+
+ while (ll) {
+ dma = ll->next_dma;
+ ptr = ll->next;
+ pnx4008_free_ll_entry(ll, ll_dma);
+
+ ll_dma = dma;
+ ll = ptr;
+ }
+}
+
+EXPORT_SYMBOL_GPL(pnx4008_free_ll);
+
+static int dma_channels_requested = 0;
+
+static inline void dma_increment_usage(void)
+{
+ if (!dma_channels_requested++) {
+ struct clk *clk = clk_get(0, "dma_ck");
+ if (!IS_ERR(clk)) {
+ clk_set_rate(clk, 1);
+ clk_put(clk);
+ }
+ pnx4008_config_dma(-1, -1, 1);
+ }
+}
+static inline void dma_decrement_usage(void)
+{
+ if (!--dma_channels_requested) {
+ struct clk *clk = clk_get(0, "dma_ck");
+ if (!IS_ERR(clk)) {
+ clk_set_rate(clk, 0);
+ clk_put(clk);
+ }
+ pnx4008_config_dma(-1, -1, 0);
+
+ }
+}
+
+static spinlock_t dma_lock = SPIN_LOCK_UNLOCKED;
+
+static inline void pnx4008_dma_lock(void)
+{
+ spin_lock_irq(&dma_lock);
+}
+
+static inline void pnx4008_dma_unlock(void)
+{
+ spin_unlock_irq(&dma_lock);
+}
+
+#define VALID_CHANNEL(c) (((c) >= 0) && ((c) < MAX_DMA_CHANNELS))
+
+int pnx4008_request_channel(char *name, int ch,
+ void (*irq_handler) (int, int, void *,
+ struct pt_regs *), void *data)
+{
+ int i, found = 0;
+
+ /* basic sanity checks */
+ if (!name || (ch != -1 && !VALID_CHANNEL(ch)))
+ return -EINVAL;
+
+ pnx4008_dma_lock();
+
+ /* try grabbing a DMA channel with the requested priority */
+ for (i = MAX_DMA_CHANNELS - 1; i >= 0; i--) {
+ if (!dma_channels[i].name && (ch == -1 || ch == i)) {
+ found = 1;
+ break;
+ }
+ }
+
+ if (found) {
+ dma_increment_usage();
+ dma_channels[i].name = name;
+ dma_channels[i].irq_handler = irq_handler;
+ dma_channels[i].data = data;
+ dma_channels[i].ll = NULL;
+ dma_channels[i].ll_dma = 0;
+ } else {
+ printk(KERN_WARNING "No more available DMA channels for %s\n",
+ name);
+ i = -ENODEV;
+ }
+
+ pnx4008_dma_unlock();
+ return i;
+}
+
+EXPORT_SYMBOL_GPL(pnx4008_request_channel);
+
+void pnx4008_free_channel(int ch)
+{
+ if (!dma_channels[ch].name) {
+ printk(KERN_CRIT
+ "%s: trying to free channel %d which is already freed\n",
+ __FUNCTION__, ch);
+ return;
+ }
+
+ pnx4008_dma_lock();
+ pnx4008_free_ll(dma_channels[ch].ll_dma, dma_channels[ch].ll);
+ dma_channels[ch].ll = NULL;
+ dma_decrement_usage();
+
+ dma_channels[ch].name = NULL;
+ pnx4008_dma_unlock();
+}
+
+EXPORT_SYMBOL_GPL(pnx4008_free_channel);
+
+int pnx4008_config_dma(int ahb_m1_be, int ahb_m2_be, int enable)
+{
+ unsigned long dma_cfg = __raw_readl(DMAC_CONFIG);
+
+ switch (ahb_m1_be) {
+ case 0:
+ dma_cfg &= ~(1 << 1);
+ break;
+ case 1:
+ dma_cfg |= (1 << 1);
+ break;
+ default:
+ break;
+ }
+
+ switch (ahb_m2_be) {
+ case 0:
+ dma_cfg &= ~(1 << 2);
+ break;
+ case 1:
+ dma_cfg |= (1 << 2);
+ break;
+ default:
+ break;
+ }
+
+ switch (enable) {
+ case 0:
+ dma_cfg &= ~(1 << 0);
+ break;
+ case 1:
+ dma_cfg |= (1 << 0);
+ break;
+ default:
+ break;
+ }
+
+ pnx4008_dma_lock();
+ __raw_writel(dma_cfg, DMAC_CONFIG);
+ pnx4008_dma_unlock();
+
+ return 0;
+}
+
+EXPORT_SYMBOL_GPL(pnx4008_config_dma);
+
+int pnx4008_dma_pack_control(const struct pnx4008_dma_ch_ctrl * ch_ctrl,
+ unsigned long *ctrl)
+{
+ int i = 0, dbsize, sbsize, err = 0;
+
+ if (!ctrl || !ch_ctrl) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ *ctrl = 0;
+
+ switch (ch_ctrl->tc_mask) {
+ case 0:
+ break;
+ case 1:
+ *ctrl |= (1 << 31);
+ break;
+
+ default:
+ err = -EINVAL;
+ goto out;
+ }
+
+ switch (ch_ctrl->cacheable) {
+ case 0:
+ break;
+ case 1:
+ *ctrl |= (1 << 30);
+ break;
+
+ default:
+ err = -EINVAL;
+ goto out;
+ }
+ switch (ch_ctrl->bufferable) {
+ case 0:
+ break;
+ case 1:
+ *ctrl |= (1 << 29);
+ break;
+
+ default:
+ err = -EINVAL;
+ goto out;
+ }
+ switch (ch_ctrl->priv_mode) {
+ case 0:
+ break;
+ case 1:
+ *ctrl |= (1 << 28);
+ break;
+
+ default:
+ err = -EINVAL;
+ goto out;
+ }
+ switch (ch_ctrl->di) {
+ case 0:
+ break;
+ case 1:
+ *ctrl |= (1 << 27);
+ break;
+
+ default:
+ err = -EINVAL;
+ goto out;
+ }
+ switch (ch_ctrl->si) {
+ case 0:
+ break;
+ case 1:
+ *ctrl |= (1 << 26);
+ break;
+
+ default:
+ err = -EINVAL;
+ goto out;
+ }
+ switch (ch_ctrl->dest_ahb1) {
+ case 0:
+ break;
+ case 1:
+ *ctrl |= (1 << 25);
+ break;
+
+ default:
+ err = -EINVAL;
+ goto out;
+ }
+ switch (ch_ctrl->src_ahb1) {
+ case 0:
+ break;
+ case 1:
+ *ctrl |= (1 << 24);
+ break;
+
+ default:
+ err = -EINVAL;
+ goto out;
+ }
+ switch (ch_ctrl->dwidth) {
+ case WIDTH_BYTE:
+ *ctrl &= ~(7 << 21);
+ break;
+ case WIDTH_HWORD:
+ *ctrl &= ~(7 << 21);
+ *ctrl |= (1 << 21);
+ break;
+ case WIDTH_WORD:
+ *ctrl &= ~(7 << 21);
+ *ctrl |= (2 << 21);
+ break;
+
+ default:
+ err = -EINVAL;
+ goto out;
+ }
+ switch (ch_ctrl->swidth) {
+ case WIDTH_BYTE:
+ *ctrl &= ~(7 << 18);
+ break;
+ case WIDTH_HWORD:
+ *ctrl &= ~(7 << 18);
+ *ctrl |= (1 << 18);
+ break;
+ case WIDTH_WORD:
+ *ctrl &= ~(7 << 18);
+ *ctrl |= (2 << 18);
+ break;
+
+ default:
+ err = -EINVAL;
+ goto out;
+ }
+ dbsize = ch_ctrl->dbsize;
+ while (!(dbsize & 1)) {
+ i++;
+ dbsize >>= 1;
+ }
+ if (ch_ctrl->dbsize != 1 || i > 8 || i == 1) {
+ err = -EINVAL;
+ goto out;
+ } else if (i > 1)
+ i--;
+ *ctrl &= ~(7 << 15);
+ *ctrl |= (i << 15);
+
+ sbsize = ch_ctrl->sbsize;
+ while (!(sbsize & 1)) {
+ i++;
+ sbsize >>= 1;
+ }
+ if (ch_ctrl->sbsize != 1 || i > 8 || i == 1) {
+ err = -EINVAL;
+ goto out;
+ } else if (i > 1)
+ i--;
+ *ctrl &= ~(7 << 12);
+ *ctrl |= (i << 12);
+
+ if (ch_ctrl->tr_size > 0x7ff) {
+ err = -E2BIG;
+ goto out;
+ }
+ *ctrl &= ~0x7ff;
+ *ctrl |= ch_ctrl->tr_size & 0x7ff;
+
+out:
+ return err;
+}
+
+EXPORT_SYMBOL_GPL(pnx4008_dma_pack_control);
+
+int pnx4008_dma_parse_control(unsigned long ctrl,
+ struct pnx4008_dma_ch_ctrl * ch_ctrl)
+{
+ int err = 0;
+
+ if (!ch_ctrl) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ ch_ctrl->tr_size = ctrl & 0x7ff;
+ ctrl >>= 12;
+
+ ch_ctrl->sbsize = 1 << (ctrl & 7);
+ if (ch_ctrl->sbsize > 1)
+ ch_ctrl->sbsize <<= 1;
+ ctrl >>= 3;
+
+ ch_ctrl->dbsize = 1 << (ctrl & 7);
+ if (ch_ctrl->dbsize > 1)
+ ch_ctrl->dbsize <<= 1;
+ ctrl >>= 3;
+
+ switch (ctrl & 7) {
+ case 0:
+ ch_ctrl->swidth = WIDTH_BYTE;
+ break;
+ case 1:
+ ch_ctrl->swidth = WIDTH_HWORD;
+ break;
+ case 2:
+ ch_ctrl->swidth = WIDTH_WORD;
+ break;
+ default:
+ err = -EINVAL;
+ goto out;
+ }
+ ctrl >>= 3;
+
+ switch (ctrl & 7) {
+ case 0:
+ ch_ctrl->dwidth = WIDTH_BYTE;
+ break;
+ case 1:
+ ch_ctrl->dwidth = WIDTH_HWORD;
+ break;
+ case 2:
+ ch_ctrl->dwidth = WIDTH_WORD;
+ break;
+ default:
+ err = -EINVAL;
+ goto out;
+ }
+ ctrl >>= 3;
+
+ ch_ctrl->src_ahb1 = ctrl & 1;
+ ctrl >>= 1;
+
+ ch_ctrl->dest_ahb1 = ctrl & 1;
+ ctrl >>= 1;
+
+ ch_ctrl->si = ctrl & 1;
+ ctrl >>= 1;
+
+ ch_ctrl->di = ctrl & 1;
+ ctrl >>= 1;
+
+ ch_ctrl->priv_mode = ctrl & 1;
+ ctrl >>= 1;
+
+ ch_ctrl->bufferable = ctrl & 1;
+ ctrl >>= 1;
+
+ ch_ctrl->cacheable = ctrl & 1;
+ ctrl >>= 1;
+
+ ch_ctrl->tc_mask = ctrl & 1;
+
+out:
+ return err;
+}
+
+EXPORT_SYMBOL_GPL(pnx4008_dma_parse_control);
+
+int pnx4008_dma_pack_config(const struct pnx4008_dma_ch_config * ch_cfg,
+ unsigned long *cfg)
+{
+ int err = 0;
+
+ if (!cfg || !ch_cfg) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ *cfg = 0;
+
+ switch (ch_cfg->halt) {
+ case 0:
+ break;
+ case 1:
+ *cfg |= (1 << 18);
+ break;
+
+ default:
+ err = -EINVAL;
+ goto out;
+ }
+ switch (ch_cfg->active) {
+ case 0:
+ break;
+ case 1:
+ *cfg |= (1 << 17);
+ break;
+
+ default:
+ err = -EINVAL;
+ goto out;
+ }
+ switch (ch_cfg->lock) {
+ case 0:
+ break;
+ case 1:
+ *cfg |= (1 << 16);
+ break;
+
+ default:
+ err = -EINVAL;
+ goto out;
+ }
+ switch (ch_cfg->itc) {
+ case 0:
+ break;
+ case 1:
+ *cfg |= (1 << 15);
+ break;
+
+ default:
+ err = -EINVAL;
+ goto out;
+ }
+ switch (ch_cfg->ie) {
+ case 0:
+ break;
+ case 1:
+ *cfg |= (1 << 14);
+ break;
+
+ default:
+ err = -EINVAL;
+ goto out;
+ }
+ switch (ch_cfg->flow_cntrl) {
+ case FC_MEM2MEM_DMA:
+ *cfg &= ~(7 << 11);
+ break;
+ case FC_MEM2PER_DMA:
+ *cfg &= ~(7 << 11);
+ *cfg |= (1 << 11);
+ break;
+ case FC_PER2MEM_DMA:
+ *cfg &= ~(7 << 11);
+ *cfg |= (2 << 11);
+ break;
+ case FC_PER2PER_DMA:
+ *cfg &= ~(7 << 11);
+ *cfg |= (3 << 11);
+ break;
+ case FC_PER2PER_DPER:
+ *cfg &= ~(7 << 11);
+ *cfg |= (4 << 11);
+ break;
+ case FC_MEM2PER_PER:
+ *cfg &= ~(7 << 11);
+ *cfg |= (5 << 11);
+ break;
+ case FC_PER2MEM_PER:
+ *cfg &= ~(7 << 11);
+ *cfg |= (6 << 11);
+ break;
+ case FC_PER2PER_SPER:
+ *cfg |= (7 << 11);
+ break;
+
+ default:
+ err = -EINVAL;
+ goto out;
+ }
+ *cfg &= ~(0x1f << 6);
+ *cfg |= ((ch_cfg->dest_per & 0x1f) << 6);
+
+ *cfg &= ~(0x1f << 1);
+ *cfg |= ((ch_cfg->src_per & 0x1f) << 1);
+
+out:
+ return err;
+}
+
+EXPORT_SYMBOL_GPL(pnx4008_dma_pack_config);
+
+int pnx4008_dma_parse_config(unsigned long cfg,
+ struct pnx4008_dma_ch_config * ch_cfg)
+{
+ int err = 0;
+
+ if (!ch_cfg) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ cfg >>= 1;
+
+ ch_cfg->src_per = cfg & 0x1f;
+ cfg >>= 5;
+
+ ch_cfg->dest_per = cfg & 0x1f;
+ cfg >>= 5;
+
+ switch (cfg & 7) {
+ case 0:
+ ch_cfg->flow_cntrl = FC_MEM2MEM_DMA;
+ break;
+ case 1:
+ ch_cfg->flow_cntrl = FC_MEM2PER_DMA;
+ break;
+ case 2:
+ ch_cfg->flow_cntrl = FC_PER2MEM_DMA;
+ break;
+ case 3:
+ ch_cfg->flow_cntrl = FC_PER2PER_DMA;
+ break;
+ case 4:
+ ch_cfg->flow_cntrl = FC_PER2PER_DPER;
+ break;
+ case 5:
+ ch_cfg->flow_cntrl = FC_MEM2PER_PER;
+ break;
+ case 6:
+ ch_cfg->flow_cntrl = FC_PER2MEM_PER;
+ break;
+ case 7:
+ ch_cfg->flow_cntrl = FC_PER2PER_SPER;
+ }
+ cfg >>= 3;
+
+ ch_cfg->ie = cfg & 1;
+ cfg >>= 1;
+
+ ch_cfg->itc = cfg & 1;
+ cfg >>= 1;
+
+ ch_cfg->lock = cfg & 1;
+ cfg >>= 1;
+
+ ch_cfg->active = cfg & 1;
+ cfg >>= 1;
+
+ ch_cfg->halt = cfg & 1;
+
+out:
+ return err;
+}
+
+EXPORT_SYMBOL_GPL(pnx4008_dma_parse_config);
+
+void pnx4008_dma_split_head_entry(struct pnx4008_dma_config * config,
+ struct pnx4008_dma_ch_ctrl * ctrl)
+{
+ int new_len = ctrl->tr_size, num_entries = 0;
+ int old_len = new_len;
+ int src_width, dest_width, count = 1;
+
+ switch (ctrl->swidth) {
+ case WIDTH_BYTE:
+ src_width = 1;
+ break;
+ case WIDTH_HWORD:
+ src_width = 2;
+ break;
+ case WIDTH_WORD:
+ src_width = 4;
+ break;
+ default:
+ return;
+ }
+
+ switch (ctrl->dwidth) {
+ case WIDTH_BYTE:
+ dest_width = 1;
+ break;
+ case WIDTH_HWORD:
+ dest_width = 2;
+ break;
+ case WIDTH_WORD:
+ dest_width = 4;
+ break;
+ default:
+ return;
+ }
+
+ while (new_len > 0x7FF) {
+ num_entries++;
+ new_len = (ctrl->tr_size + num_entries) / (num_entries + 1);
+ }
+ if (num_entries != 0) {
+ struct pnx4008_dma_ll *ll = NULL;
+ config->ch_ctrl &= ~0x7ff;
+ config->ch_ctrl |= new_len;
+ if (!config->is_ll) {
+ config->is_ll = 1;
+ while (num_entries) {
+ if (!ll) {
+ config->ll =
+ pnx4008_alloc_ll_entry(&config->
+ ll_dma);
+ ll = config->ll;
+ } else {
+ ll->next =
+ pnx4008_alloc_ll_entry(&ll->
+ next_dma);
+ ll = ll->next;
+ }
+
+ if (ctrl->si)
+ ll->src_addr =
+ config->src_addr +
+ src_width * new_len * count;
+ else
+ ll->src_addr = config->src_addr;
+ if (ctrl->di)
+ ll->dest_addr =
+ config->dest_addr +
+ dest_width * new_len * count;
+ else
+ ll->dest_addr = config->dest_addr;
+ ll->ch_ctrl = config->ch_ctrl & 0x7fffffff;
+ ll->next_dma = 0;
+ ll->next = NULL;
+ num_entries--;
+ count++;
+ }
+ } else {
+ struct pnx4008_dma_ll *ll_old = config->ll;
+ unsigned long ll_dma_old = config->ll_dma;
+ while (num_entries) {
+ if (!ll) {
+ config->ll =
+ pnx4008_alloc_ll_entry(&config->
+ ll_dma);
+ ll = config->ll;
+ } else {
+ ll->next =
+ pnx4008_alloc_ll_entry(&ll->
+ next_dma);
+ ll = ll->next;
+ }
+
+ if (ctrl->si)
+ ll->src_addr =
+ config->src_addr +
+ src_width * new_len * count;
+ else
+ ll->src_addr = config->src_addr;
+ if (ctrl->di)
+ ll->dest_addr =
+ config->dest_addr +
+ dest_width * new_len * count;
+ else
+ ll->dest_addr = config->dest_addr;
+ ll->ch_ctrl = config->ch_ctrl & 0x7fffffff;
+ ll->next_dma = 0;
+ ll->next = NULL;
+ num_entries--;
+ count++;
+ }
+ ll->next_dma = ll_dma_old;
+ ll->next = ll_old;
+ }
+ /* adjust last length/tc */
+ ll->ch_ctrl = config->ch_ctrl & (~0x7ff);
+ ll->ch_ctrl |= old_len - new_len * (count - 1);
+ config->ch_ctrl &= 0x7fffffff;
+ }
+}
+
+EXPORT_SYMBOL_GPL(pnx4008_dma_split_head_entry);
+
+void pnx4008_dma_split_ll_entry(struct pnx4008_dma_ll * cur_ll,
+ struct pnx4008_dma_ch_ctrl * ctrl)
+{
+ int new_len = ctrl->tr_size, num_entries = 0;
+ int old_len = new_len;
+ int src_width, dest_width, count = 1;
+
+ switch (ctrl->swidth) {
+ case WIDTH_BYTE:
+ src_width = 1;
+ break;
+ case WIDTH_HWORD:
+ src_width = 2;
+ break;
+ case WIDTH_WORD:
+ src_width = 4;
+ break;
+ default:
+ return;
+ }
+
+ switch (ctrl->dwidth) {
+ case WIDTH_BYTE:
+ dest_width = 1;
+ break;
+ case WIDTH_HWORD:
+ dest_width = 2;
+ break;
+ case WIDTH_WORD:
+ dest_width = 4;
+ break;
+ default:
+ return;
+ }
+
+ while (new_len > 0x7FF) {
+ num_entries++;
+ new_len = (ctrl->tr_size + num_entries) / (num_entries + 1);
+ }
+ if (num_entries != 0) {
+ struct pnx4008_dma_ll *ll = NULL;
+ cur_ll->ch_ctrl &= ~0x7ff;
+ cur_ll->ch_ctrl |= new_len;
+ if (!cur_ll->next) {
+ while (num_entries) {
+ if (!ll) {
+ cur_ll->next =
+ pnx4008_alloc_ll_entry(&cur_ll->
+ next_dma);
+ ll = cur_ll->next;
+ } else {
+ ll->next =
+ pnx4008_alloc_ll_entry(&ll->
+ next_dma);
+ ll = ll->next;
+ }
+
+ if (ctrl->si)
+ ll->src_addr =
+ cur_ll->src_addr +
+ src_width * new_len * count;
+ else
+ ll->src_addr = cur_ll->src_addr;
+ if (ctrl->di)
+ ll->dest_addr =
+ cur_ll->dest_addr +
+ dest_width * new_len * count;
+ else
+ ll->dest_addr = cur_ll->dest_addr;
+ ll->ch_ctrl = cur_ll->ch_ctrl & 0x7fffffff;
+ ll->next_dma = 0;
+ ll->next = NULL;
+ num_entries--;
+ count++;
+ }
+ } else {
+ struct pnx4008_dma_ll *ll_old = cur_ll->next;
+ unsigned long ll_dma_old = cur_ll->next_dma;
+ while (num_entries) {
+ if (!ll) {
+ cur_ll->next =
+ pnx4008_alloc_ll_entry(&cur_ll->
+ next_dma);
+ ll = cur_ll->next;
+ } else {
+ ll->next =
+ pnx4008_alloc_ll_entry(&ll->
+ next_dma);
+ ll = ll->next;
+ }
+
+ if (ctrl->si)
+ ll->src_addr =
+ cur_ll->src_addr +
+ src_width * new_len * count;
+ else
+ ll->src_addr = cur_ll->src_addr;
+ if (ctrl->di)
+ ll->dest_addr =
+ cur_ll->dest_addr +
+ dest_width * new_len * count;
+ else
+ ll->dest_addr = cur_ll->dest_addr;
+ ll->ch_ctrl = cur_ll->ch_ctrl & 0x7fffffff;
+ ll->next_dma = 0;
+ ll->next = NULL;
+ num_entries--;
+ count++;
+ }
+
+ ll->next_dma = ll_dma_old;
+ ll->next = ll_old;
+ }
+ /* adjust last length/tc */
+ ll->ch_ctrl = cur_ll->ch_ctrl & (~0x7ff);
+ ll->ch_ctrl |= old_len - new_len * (count - 1);
+ cur_ll->ch_ctrl &= 0x7fffffff;
+ }
+}
+
+EXPORT_SYMBOL_GPL(pnx4008_dma_split_ll_entry);
+
+int pnx4008_config_channel(int ch, struct pnx4008_dma_config * config)
+{
+ if (!VALID_CHANNEL(ch) || !dma_channels[ch].name)
+ return -EINVAL;
+
+ pnx4008_dma_lock();
+ __raw_writel(config->src_addr, DMAC_Cx_SRC_ADDR(ch));
+ __raw_writel(config->dest_addr, DMAC_Cx_DEST_ADDR(ch));
+
+ if (config->is_ll)
+ __raw_writel(config->ll_dma, DMAC_Cx_LLI(ch));
+ else
+ __raw_writel(0, DMAC_Cx_LLI(ch));
+
+ __raw_writel(config->ch_ctrl, DMAC_Cx_CONTROL(ch));
+ __raw_writel(config->ch_cfg, DMAC_Cx_CONFIG(ch));
+ pnx4008_dma_unlock();
+
+ return 0;
+
+}
+
+EXPORT_SYMBOL_GPL(pnx4008_config_channel);
+
+int pnx4008_channel_get_config(int ch, struct pnx4008_dma_config * config)
+{
+ if (!VALID_CHANNEL(ch) || !dma_channels[ch].name || !config)
+ return -EINVAL;
+
+ pnx4008_dma_lock();
+ config->ch_cfg = __raw_readl(DMAC_Cx_CONFIG(ch));
+ config->ch_ctrl = __raw_readl(DMAC_Cx_CONTROL(ch));
+
+ config->ll_dma = __raw_readl(DMAC_Cx_LLI(ch));
+ config->is_ll = config->ll_dma ? 1 : 0;
+
+ config->src_addr = __raw_readl(DMAC_Cx_SRC_ADDR(ch));
+ config->dest_addr = __raw_readl(DMAC_Cx_DEST_ADDR(ch));
+ pnx4008_dma_unlock();
+
+ return 0;
+}
+
+EXPORT_SYMBOL_GPL(pnx4008_channel_get_config);
+
+int pnx4008_dma_ch_enable(int ch)
+{
+ unsigned long ch_cfg;
+
+ if (!VALID_CHANNEL(ch) || !dma_channels[ch].name)
+ return -EINVAL;
+
+ pnx4008_dma_lock();
+ ch_cfg = __raw_readl(DMAC_Cx_CONFIG(ch));
+ ch_cfg |= 1;
+ __raw_writel(ch_cfg, DMAC_Cx_CONFIG(ch));
+ pnx4008_dma_unlock();
+
+ return 0;
+}
+
+EXPORT_SYMBOL_GPL(pnx4008_dma_ch_enable);
+
+int pnx4008_dma_ch_disable(int ch)
+{
+ unsigned long ch_cfg;
+
+ if (!VALID_CHANNEL(ch) || !dma_channels[ch].name)
+ return -EINVAL;
+
+ pnx4008_dma_lock();
+ ch_cfg = __raw_readl(DMAC_Cx_CONFIG(ch));
+ ch_cfg &= ~1;
+ __raw_writel(ch_cfg, DMAC_Cx_CONFIG(ch));
+ pnx4008_dma_unlock();
+
+ return 0;
+}
+
+EXPORT_SYMBOL_GPL(pnx4008_dma_ch_disable);
+
+int pnx4008_dma_ch_enabled(int ch)
+{
+ unsigned long ch_cfg;
+
+ if (!VALID_CHANNEL(ch) || !dma_channels[ch].name)
+ return -EINVAL;
+
+ pnx4008_dma_lock();
+ ch_cfg = __raw_readl(DMAC_Cx_CONFIG(ch));
+ pnx4008_dma_unlock();
+
+ return ch_cfg & 1;
+}
+
+EXPORT_SYMBOL_GPL(pnx4008_dma_ch_enabled);
+
+static irqreturn_t dma_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
+{
+ int i;
+ unsigned long dint = __raw_readl(DMAC_INT_STAT);
+ unsigned long tcint = __raw_readl(DMAC_INT_TC_STAT);
+ unsigned long eint = __raw_readl(DMAC_INT_ERR_STAT);
+ unsigned long i_bit;
+
+ for (i = MAX_DMA_CHANNELS - 1; i >= 0; i--) {
+ i_bit = 1 << i;
+ if (dint & i_bit) {
+ struct dma_channel *channel = &dma_channels[i];
+
+ if (channel->name && channel->irq_handler) {
+ int cause = 0;
+
+ if (eint & i_bit)
+ cause |= DMA_ERR_INT;
+ if (tcint & i_bit)
+ cause |= DMA_TC_INT;
+ channel->irq_handler(i, cause, channel->data,
+ regs);
+ } else {
+ /*
+ * IRQ for an unregistered DMA channel
+ */
+ printk(KERN_WARNING
+ "spurious IRQ for DMA channel %d\n", i);
+ }
+ if (tcint & i_bit)
+ __raw_writel(i_bit, DMAC_INT_TC_CLEAR);
+ if (eint & i_bit)
+ __raw_writel(i_bit, DMAC_INT_ERR_CLEAR);
+ }
+ }
+ return IRQ_HANDLED;
+}
+
+static int __init pnx4008_dma_init(void)
+{
+ int ret, i;
+
+ ret = request_irq(DMA_INT, dma_irq_handler, 0, "DMA", NULL);
+ if (ret) {
+ printk(KERN_CRIT "Wow! Can't register IRQ for DMA\n");
+ goto out;
+ }
+
+ ll_pool.count = 0x4000 / sizeof(struct pnx4008_dma_ll);
+ ll_pool.cur = ll_pool.vaddr =
+ dma_alloc_coherent(NULL, ll_pool.count * sizeof(struct pnx4008_dma_ll),
+ &ll_pool.dma_addr, GFP_KERNEL);
+
+ if (!ll_pool.vaddr) {
+ ret = -ENOMEM;
+ free_irq(DMA_INT, NULL);
+ goto out;
+ }
+
+ for (i = 0; i < ll_pool.count - 1; i++) {
+ void **addr = ll_pool.vaddr + i * sizeof(struct pnx4008_dma_ll);
+ *addr = (void *)addr + sizeof(struct pnx4008_dma_ll);
+ }
+ *(long *)(ll_pool.vaddr +
+ (ll_pool.count - 1) * sizeof(struct pnx4008_dma_ll)) =
+ (long)ll_pool.vaddr;
+
+ __raw_writel(1, DMAC_CONFIG);
+
+out:
+ return ret;
+}
+arch_initcall(pnx4008_dma_init);
diff --git a/arch/arm/mach-pnx4008/gpio.c b/arch/arm/mach-pnx4008/gpio.c
new file mode 100644
index 000000000000..e1ce050d8fe0
--- /dev/null
+++ b/arch/arm/mach-pnx4008/gpio.c
@@ -0,0 +1,330 @@
+/*
+ * arch/arm/mach-pnx4008/gpio.c
+ *
+ * PNX4008 GPIO driver
+ *
+ * Author: Dmitry Chigirev <source@mvista.com>
+ *
+ * Based on reference code by Iwo Mergler and Z.Tabaaloute from Philips:
+ * Copyright (c) 2005 Koninklijke Philips Electronics N.V.
+ *
+ * 2005 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <asm/semaphore.h>
+#include <asm/io.h>
+#include <asm/arch/platform.h>
+#include <asm/arch/gpio.h>
+
+/* register definitions */
+#define PIO_VA_BASE IO_ADDRESS(PNX4008_PIO_BASE)
+
+#define PIO_INP_STATE (0x00U)
+#define PIO_OUTP_SET (0x04U)
+#define PIO_OUTP_CLR (0x08U)
+#define PIO_OUTP_STATE (0x0CU)
+#define PIO_DRV_SET (0x10U)
+#define PIO_DRV_CLR (0x14U)
+#define PIO_DRV_STATE (0x18U)
+#define PIO_SDINP_STATE (0x1CU)
+#define PIO_SDOUTP_SET (0x20U)
+#define PIO_SDOUTP_CLR (0x24U)
+#define PIO_MUX_SET (0x28U)
+#define PIO_MUX_CLR (0x2CU)
+#define PIO_MUX_STATE (0x30U)
+
+static inline void gpio_lock(void)
+{
+ local_irq_disable();
+}
+
+static inline void gpio_unlock(void)
+{
+ local_irq_enable();
+}
+
+/* Inline functions */
+static inline int gpio_read_bit(u32 reg, int gpio)
+{
+ u32 bit, val;
+ int ret = -EFAULT;
+
+ if (gpio < 0)
+ goto out;
+
+ bit = GPIO_BIT(gpio);
+ if (bit) {
+ val = __raw_readl(PIO_VA_BASE + reg);
+ ret = (val & bit) ? 1 : 0;
+ }
+out:
+ return ret;
+}
+
+static inline int gpio_set_bit(u32 reg, int gpio)
+{
+ u32 bit, val;
+ int ret = -EFAULT;
+
+ if (gpio < 0)
+ goto out;
+
+ bit = GPIO_BIT(gpio);
+ if (bit) {
+ val = __raw_readl(PIO_VA_BASE + reg);
+ val |= bit;
+ __raw_writel(val, PIO_VA_BASE + reg);
+ ret = 0;
+ }
+out:
+ return ret;
+}
+
+/* Very simple access control, bitmap for allocated/free */
+static unsigned long access_map[4];
+#define INP_INDEX 0
+#define OUTP_INDEX 1
+#define GPIO_INDEX 2
+#define MUX_INDEX 3
+
+/*GPIO to Input Mapping */
+static short gpio_to_inp_map[32] = {
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 10, 11, 12, 13, 14, 24, -1
+};
+
+/*GPIO to Mux Mapping */
+static short gpio_to_mux_map[32] = {
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 0, 1, 4, 5, -1
+};
+
+/*Output to Mux Mapping */
+static short outp_to_mux_map[32] = {
+ -1, -1, -1, 6, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 2, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1
+};
+
+int pnx4008_gpio_register_pin(unsigned short pin)
+{
+ unsigned long bit = GPIO_BIT(pin);
+ int ret = -EBUSY; /* Already in use */
+
+ gpio_lock();
+
+ if (GPIO_ISBID(pin)) {
+ if (access_map[GPIO_INDEX] & bit)
+ goto out;
+ access_map[GPIO_INDEX] |= bit;
+
+ } else if (GPIO_ISRAM(pin)) {
+ if (access_map[GPIO_INDEX] & bit)
+ goto out;
+ access_map[GPIO_INDEX] |= bit;
+
+ } else if (GPIO_ISMUX(pin)) {
+ if (access_map[MUX_INDEX] & bit)
+ goto out;
+ access_map[MUX_INDEX] |= bit;
+
+ } else if (GPIO_ISOUT(pin)) {
+ if (access_map[OUTP_INDEX] & bit)
+ goto out;
+ access_map[OUTP_INDEX] |= bit;
+
+ } else if (GPIO_ISIN(pin)) {
+ if (access_map[INP_INDEX] & bit)
+ goto out;
+ access_map[INP_INDEX] |= bit;
+ } else
+ goto out;
+ ret = 0;
+
+out:
+ gpio_unlock();
+ return ret;
+}
+
+EXPORT_SYMBOL(pnx4008_gpio_register_pin);
+
+int pnx4008_gpio_unregister_pin(unsigned short pin)
+{
+ unsigned long bit = GPIO_BIT(pin);
+ int ret = -EFAULT; /* Not registered */
+
+ gpio_lock();
+
+ if (GPIO_ISBID(pin)) {
+ if (~access_map[GPIO_INDEX] & bit)
+ goto out;
+ access_map[GPIO_INDEX] &= ~bit;
+ } else if (GPIO_ISRAM(pin)) {
+ if (~access_map[GPIO_INDEX] & bit)
+ goto out;
+ access_map[GPIO_INDEX] &= ~bit;
+ } else if (GPIO_ISMUX(pin)) {
+ if (~access_map[MUX_INDEX] & bit)
+ goto out;
+ access_map[MUX_INDEX] &= ~bit;
+ } else if (GPIO_ISOUT(pin)) {
+ if (~access_map[OUTP_INDEX] & bit)
+ goto out;
+ access_map[OUTP_INDEX] &= ~bit;
+ } else if (GPIO_ISIN(pin)) {
+ if (~access_map[INP_INDEX] & bit)
+ goto out;
+ access_map[INP_INDEX] &= ~bit;
+ } else
+ goto out;
+ ret = 0;
+
+out:
+ gpio_unlock();
+ return ret;
+}
+
+EXPORT_SYMBOL(pnx4008_gpio_unregister_pin);
+
+unsigned long pnx4008_gpio_read_pin(unsigned short pin)
+{
+ unsigned long ret = -EFAULT;
+ int gpio = GPIO_BIT_MASK(pin);
+ gpio_lock();
+ if (GPIO_ISOUT(pin)) {
+ ret = gpio_read_bit(PIO_OUTP_STATE, gpio);
+ } else if (GPIO_ISRAM(pin)) {
+ if (gpio_read_bit(PIO_DRV_STATE, gpio) == 0) {
+ ret = gpio_read_bit(PIO_SDINP_STATE, gpio);
+ }
+ } else if (GPIO_ISBID(pin)) {
+ ret = gpio_read_bit(PIO_DRV_STATE, gpio);
+ if (ret > 0)
+ ret = gpio_read_bit(PIO_OUTP_STATE, gpio);
+ else if (ret == 0)
+ ret =
+ gpio_read_bit(PIO_INP_STATE, gpio_to_inp_map[gpio]);
+ } else if (GPIO_ISIN(pin)) {
+ ret = gpio_read_bit(PIO_INP_STATE, gpio);
+ }
+ gpio_unlock();
+ return ret;
+}
+
+EXPORT_SYMBOL(pnx4008_gpio_read_pin);
+
+/* Write Value to output */
+int pnx4008_gpio_write_pin(unsigned short pin, int output)
+{
+ int gpio = GPIO_BIT_MASK(pin);
+ int ret = -EFAULT;
+
+ gpio_lock();
+ if (GPIO_ISOUT(pin)) {
+ printk( "writing '%x' to '%x'\n",
+ gpio, output ? PIO_OUTP_SET : PIO_OUTP_CLR );
+ ret = gpio_set_bit(output ? PIO_OUTP_SET : PIO_OUTP_CLR, gpio);
+ } else if (GPIO_ISRAM(pin)) {
+ if (gpio_read_bit(PIO_DRV_STATE, gpio) > 0)
+ ret = gpio_set_bit(output ? PIO_SDOUTP_SET :
+ PIO_SDOUTP_CLR, gpio);
+ } else if (GPIO_ISBID(pin)) {
+ if (gpio_read_bit(PIO_DRV_STATE, gpio) > 0)
+ ret = gpio_set_bit(output ? PIO_OUTP_SET :
+ PIO_OUTP_CLR, gpio);
+ }
+ gpio_unlock();
+ return ret;
+}
+
+EXPORT_SYMBOL(pnx4008_gpio_write_pin);
+
+/* Value = 1 : Set GPIO pin as output */
+/* Value = 0 : Set GPIO pin as input */
+int pnx4008_gpio_set_pin_direction(unsigned short pin, int output)
+{
+ int gpio = GPIO_BIT_MASK(pin);
+ int ret = -EFAULT;
+
+ gpio_lock();
+ if (GPIO_ISBID(pin) || GPIO_ISRAM(pin)) {
+ ret = gpio_set_bit(output ? PIO_DRV_SET : PIO_DRV_CLR, gpio);
+ }
+ gpio_unlock();
+ return ret;
+}
+
+EXPORT_SYMBOL(pnx4008_gpio_set_pin_direction);
+
+/* Read GPIO pin direction: 0= pin used as input, 1= pin used as output*/
+int pnx4008_gpio_read_pin_direction(unsigned short pin)
+{
+ int gpio = GPIO_BIT_MASK(pin);
+ int ret = -EFAULT;
+
+ gpio_lock();
+ if (GPIO_ISBID(pin) || GPIO_ISRAM(pin)) {
+ ret = gpio_read_bit(PIO_DRV_STATE, gpio);
+ }
+ gpio_unlock();
+ return ret;
+}
+
+EXPORT_SYMBOL(pnx4008_gpio_read_pin_direction);
+
+/* Value = 1 : Set pin to muxed function */
+/* Value = 0 : Set pin as GPIO */
+int pnx4008_gpio_set_pin_mux(unsigned short pin, int output)
+{
+ int gpio = GPIO_BIT_MASK(pin);
+ int ret = -EFAULT;
+
+ gpio_lock();
+ if (GPIO_ISBID(pin)) {
+ ret =
+ gpio_set_bit(output ? PIO_MUX_SET : PIO_MUX_CLR,
+ gpio_to_mux_map[gpio]);
+ } else if (GPIO_ISOUT(pin)) {
+ ret =
+ gpio_set_bit(output ? PIO_MUX_SET : PIO_MUX_CLR,
+ outp_to_mux_map[gpio]);
+ } else if (GPIO_ISMUX(pin)) {
+ ret = gpio_set_bit(output ? PIO_MUX_SET : PIO_MUX_CLR, gpio);
+ }
+ gpio_unlock();
+ return ret;
+}
+
+EXPORT_SYMBOL(pnx4008_gpio_set_pin_mux);
+
+/* Read pin mux function: 0= pin used as GPIO, 1= pin used for muxed function*/
+int pnx4008_gpio_read_pin_mux(unsigned short pin)
+{
+ int gpio = GPIO_BIT_MASK(pin);
+ int ret = -EFAULT;
+
+ gpio_lock();
+ if (GPIO_ISBID(pin)) {
+ ret = gpio_read_bit(PIO_MUX_STATE, gpio_to_mux_map[gpio]);
+ } else if (GPIO_ISOUT(pin)) {
+ ret = gpio_read_bit(PIO_MUX_STATE, outp_to_mux_map[gpio]);
+ } else if (GPIO_ISMUX(pin)) {
+ ret = gpio_read_bit(PIO_MUX_STATE, gpio);
+ }
+ gpio_unlock();
+ return ret;
+}
+
+EXPORT_SYMBOL(pnx4008_gpio_read_pin_mux);
diff --git a/arch/arm/mach-pnx4008/irq.c b/arch/arm/mach-pnx4008/irq.c
new file mode 100644
index 000000000000..9b0a8e084e99
--- /dev/null
+++ b/arch/arm/mach-pnx4008/irq.c
@@ -0,0 +1,121 @@
+/*
+ * arch/arm/mach-pnx4008/irq.c
+ *
+ * PNX4008 IRQ controller driver
+ *
+ * Author: Dmitry Chigirev <source@mvista.com>
+ *
+ * Based on reference code received from Philips:
+ * Copyright (C) 2003 Philips Semiconductors
+ *
+ * 2005 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/device.h>
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/system.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/map.h>
+#include <asm/arch/irq.h>
+
+static u8 pnx4008_irq_type[NR_IRQS] = PNX4008_IRQ_TYPES;
+
+static void pnx4008_mask_irq(unsigned int irq)
+{
+ __raw_writel(__raw_readl(INTC_ER(irq)) & ~INTC_BIT(irq), INTC_ER(irq)); /* mask interrupt */
+}
+
+static void pnx4008_unmask_irq(unsigned int irq)
+{
+ __raw_writel(__raw_readl(INTC_ER(irq)) | INTC_BIT(irq), INTC_ER(irq)); /* unmask interrupt */
+}
+
+static void pnx4008_mask_ack_irq(unsigned int irq)
+{
+ __raw_writel(__raw_readl(INTC_ER(irq)) & ~INTC_BIT(irq), INTC_ER(irq)); /* mask interrupt */
+ __raw_writel(INTC_BIT(irq), INTC_SR(irq)); /* clear interrupt status */
+}
+
+static int pnx4008_set_irq_type(unsigned int irq, unsigned int type)
+{
+ switch (type) {
+ case IRQT_RISING:
+ __raw_writel(__raw_readl(INTC_ATR(irq)) | INTC_BIT(irq), INTC_ATR(irq)); /*edge sensitive */
+ __raw_writel(__raw_readl(INTC_APR(irq)) | INTC_BIT(irq), INTC_APR(irq)); /*rising edge */
+ set_irq_handler(irq, do_edge_IRQ);
+ break;
+ case IRQT_FALLING:
+ __raw_writel(__raw_readl(INTC_ATR(irq)) | INTC_BIT(irq), INTC_ATR(irq)); /*edge sensitive */
+ __raw_writel(__raw_readl(INTC_APR(irq)) & ~INTC_BIT(irq), INTC_APR(irq)); /*falling edge */
+ set_irq_handler(irq, do_edge_IRQ);
+ break;
+ case IRQT_LOW:
+ __raw_writel(__raw_readl(INTC_ATR(irq)) & ~INTC_BIT(irq), INTC_ATR(irq)); /*level sensitive */
+ __raw_writel(__raw_readl(INTC_APR(irq)) & ~INTC_BIT(irq), INTC_APR(irq)); /*low level */
+ set_irq_handler(irq, do_level_IRQ);
+ break;
+ case IRQT_HIGH:
+ __raw_writel(__raw_readl(INTC_ATR(irq)) & ~INTC_BIT(irq), INTC_ATR(irq)); /*level sensitive */
+ __raw_writel(__raw_readl(INTC_APR(irq)) | INTC_BIT(irq), INTC_APR(irq)); /* high level */
+ set_irq_handler(irq, do_level_IRQ);
+ break;
+
+ /* IRQT_BOTHEDGE is not supported */
+ default:
+ printk(KERN_ERR "PNX4008 IRQ: Unsupported irq type %d\n", type);
+ return -1;
+ }
+ return 0;
+}
+
+static struct irqchip pnx4008_irq_chip = {
+ .ack = pnx4008_mask_ack_irq,
+ .mask = pnx4008_mask_irq,
+ .unmask = pnx4008_unmask_irq,
+ .set_type = pnx4008_set_irq_type,
+};
+
+void __init pnx4008_init_irq(void)
+{
+ unsigned int i;
+
+ /* configure and enable IRQ 0,1,30,31 (cascade interrupts) mask all others */
+ pnx4008_set_irq_type(SUB1_IRQ_N, pnx4008_irq_type[SUB1_IRQ_N]);
+ pnx4008_set_irq_type(SUB2_IRQ_N, pnx4008_irq_type[SUB2_IRQ_N]);
+ pnx4008_set_irq_type(SUB1_FIQ_N, pnx4008_irq_type[SUB1_FIQ_N]);
+ pnx4008_set_irq_type(SUB2_FIQ_N, pnx4008_irq_type[SUB2_FIQ_N]);
+
+ __raw_writel((1 << SUB2_FIQ_N) | (1 << SUB1_FIQ_N) |
+ (1 << SUB2_IRQ_N) | (1 << SUB1_IRQ_N),
+ INTC_ER(MAIN_BASE_INT));
+ __raw_writel(0, INTC_ER(SIC1_BASE_INT));
+ __raw_writel(0, INTC_ER(SIC2_BASE_INT));
+
+ /* configure all other IRQ's */
+ for (i = 0; i < NR_IRQS; i++) {
+ if (i == SUB2_FIQ_N || i == SUB1_FIQ_N ||
+ i == SUB2_IRQ_N || i == SUB1_IRQ_N)
+ continue;
+ set_irq_flags(i, IRQF_VALID);
+ set_irq_chip(i, &pnx4008_irq_chip);
+ pnx4008_set_irq_type(i, pnx4008_irq_type[i]);
+ }
+}
+
diff --git a/arch/arm/mach-pnx4008/pm.c b/arch/arm/mach-pnx4008/pm.c
new file mode 100644
index 000000000000..3649cd3dfc9a
--- /dev/null
+++ b/arch/arm/mach-pnx4008/pm.c
@@ -0,0 +1,184 @@
+/*
+ * arch/arm/mach-pnx4008/pm.c
+ *
+ * Power Management driver for PNX4008
+ *
+ * Authors: Vitaly Wool, Dmitry Chigirev <source@mvista.com>
+ *
+ * 2005 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+
+#include <linux/pm.h>
+#include <linux/rtc.h>
+#include <linux/sched.h>
+#include <linux/proc_fs.h>
+#include <linux/pm.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+
+#include <asm/io.h>
+#include <asm/mach-types.h>
+#include <asm/cacheflush.h>
+#include <asm/arch/pm.h>
+#include <asm/arch/clock.h>
+
+#define SRAM_VA IO_ADDRESS(PNX4008_IRAM_BASE)
+
+static void *saved_sram;
+
+static struct clk *pll4_clk;
+
+static inline void pnx4008_standby(void)
+{
+ void (*pnx4008_cpu_standby_ptr) (void);
+
+ local_irq_disable();
+ local_fiq_disable();
+
+ clk_disable(pll4_clk);
+
+ /*saving portion of SRAM to be used by suspend function. */
+ memcpy(saved_sram, (void *)SRAM_VA, pnx4008_cpu_standby_sz);
+
+ /*make sure SRAM copy gets physically written into SDRAM.
+ SDRAM will be placed into self-refresh during power down */
+ flush_cache_all();
+
+ /*copy suspend function into SRAM */
+ memcpy((void *)SRAM_VA, pnx4008_cpu_standby, pnx4008_cpu_standby_sz);
+
+ /*do suspend */
+ pnx4008_cpu_standby_ptr = (void *)SRAM_VA;
+ pnx4008_cpu_standby_ptr();
+
+ /*restoring portion of SRAM that was used by suspend function */
+ memcpy((void *)SRAM_VA, saved_sram, pnx4008_cpu_standby_sz);
+
+ clk_enable(pll4_clk);
+
+ local_fiq_enable();
+ local_irq_enable();
+}
+
+static inline void pnx4008_suspend(void)
+{
+ void (*pnx4008_cpu_suspend_ptr) (void);
+
+ local_irq_disable();
+ local_fiq_disable();
+
+ clk_disable(pll4_clk);
+
+ __raw_writel(0xffffffff, START_INT_RSR_REG(SE_PIN_BASE_INT));
+ __raw_writel(0xffffffff, START_INT_RSR_REG(SE_INT_BASE_INT));
+
+ /*saving portion of SRAM to be used by suspend function. */
+ memcpy(saved_sram, (void *)SRAM_VA, pnx4008_cpu_suspend_sz);
+
+ /*make sure SRAM copy gets physically written into SDRAM.
+ SDRAM will be placed into self-refresh during power down */
+ flush_cache_all();
+
+ /*copy suspend function into SRAM */
+ memcpy((void *)SRAM_VA, pnx4008_cpu_suspend, pnx4008_cpu_suspend_sz);
+
+ /*do suspend */
+ pnx4008_cpu_suspend_ptr = (void *)SRAM_VA;
+ pnx4008_cpu_suspend_ptr();
+
+ /*restoring portion of SRAM that was used by suspend function */
+ memcpy((void *)SRAM_VA, saved_sram, pnx4008_cpu_suspend_sz);
+
+ clk_enable(pll4_clk);
+
+ local_fiq_enable();
+ local_irq_enable();
+}
+
+static int pnx4008_pm_enter(suspend_state_t state)
+{
+ switch (state) {
+ case PM_SUSPEND_STANDBY:
+ pnx4008_standby();
+ break;
+ case PM_SUSPEND_MEM:
+ pnx4008_suspend();
+ break;
+ case PM_SUSPEND_DISK:
+ return -ENOTSUPP;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+/*
+ * Called after processes are frozen, but before we shut down devices.
+ */
+static int pnx4008_pm_prepare(suspend_state_t state)
+{
+ switch (state) {
+ case PM_SUSPEND_STANDBY:
+ case PM_SUSPEND_MEM:
+ break;
+
+ case PM_SUSPEND_DISK:
+ return -ENOTSUPP;
+ break;
+
+ default:
+ return -EINVAL;
+ break;
+ }
+ return 0;
+}
+
+/*
+ * Called after devices are re-setup, but before processes are thawed.
+ */
+static int pnx4008_pm_finish(suspend_state_t state)
+{
+ return 0;
+}
+
+/*
+ * Set to PM_DISK_FIRMWARE so we can quickly veto suspend-to-disk.
+ */
+static struct pm_ops pnx4008_pm_ops = {
+ .prepare = pnx4008_pm_prepare,
+ .enter = pnx4008_pm_enter,
+ .finish = pnx4008_pm_finish,
+};
+
+static int __init pnx4008_pm_init(void)
+{
+ u32 sram_size_to_allocate;
+
+ pll4_clk = clk_get(0, "ck_pll4");
+ if (IS_ERR(pll4_clk)) {
+ printk(KERN_ERR
+ "PM Suspend cannot acquire ARM(PLL4) clock control\n");
+ return PTR_ERR(pll4_clk);
+ }
+
+ if (pnx4008_cpu_standby_sz > pnx4008_cpu_suspend_sz)
+ sram_size_to_allocate = pnx4008_cpu_standby_sz;
+ else
+ sram_size_to_allocate = pnx4008_cpu_suspend_sz;
+
+ saved_sram = kmalloc(sram_size_to_allocate, GFP_ATOMIC);
+ if (!saved_sram) {
+ printk(KERN_ERR
+ "PM Suspend: cannot allocate memory to save portion of SRAM\n");
+ clk_put(pll4_clk);
+ return -ENOMEM;
+ }
+
+ pm_set_ops(&pnx4008_pm_ops);
+ return 0;
+}
+
+late_initcall(pnx4008_pm_init);
diff --git a/arch/arm/mach-pnx4008/serial.c b/arch/arm/mach-pnx4008/serial.c
new file mode 100644
index 000000000000..2e1e04cc048c
--- /dev/null
+++ b/arch/arm/mach-pnx4008/serial.c
@@ -0,0 +1,69 @@
+/*
+ * linux/arch/arm/mach-pnx4008/serial.c
+ *
+ * PNX4008 UART initialization
+ *
+ * Copyright: MontaVista Software Inc. (c) 2005
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+#include <asm/io.h>
+
+#include <asm/arch/platform.h>
+#include <asm/arch/hardware.h>
+
+#include <linux/serial_core.h>
+#include <linux/serial_reg.h>
+#include <asm/arch/pm.h>
+
+#include <asm/arch/clock.h>
+
+#define UART_3 0
+#define UART_4 1
+#define UART_5 2
+#define UART_6 3
+#define UART_UNKNOWN (-1)
+
+#define UART3_BASE_VA IO_ADDRESS(PNX4008_UART3_BASE)
+#define UART4_BASE_VA IO_ADDRESS(PNX4008_UART4_BASE)
+#define UART5_BASE_VA IO_ADDRESS(PNX4008_UART5_BASE)
+#define UART6_BASE_VA IO_ADDRESS(PNX4008_UART6_BASE)
+
+#define UART_FCR_OFFSET 8
+#define UART_FIFO_SIZE 64
+
+void pnx4008_uart_init(void)
+{
+ u32 tmp;
+ int i = UART_FIFO_SIZE;
+
+ __raw_writel(0xC1, UART5_BASE_VA + UART_FCR_OFFSET);
+ __raw_writel(0xC1, UART3_BASE_VA + UART_FCR_OFFSET);
+
+ /* Send a NULL to fix the UART HW bug */
+ __raw_writel(0x00, UART5_BASE_VA);
+ __raw_writel(0x00, UART3_BASE_VA);
+
+ while (i--) {
+ tmp = __raw_readl(UART5_BASE_VA);
+ tmp = __raw_readl(UART3_BASE_VA);
+ }
+ __raw_writel(0, UART5_BASE_VA + UART_FCR_OFFSET);
+ __raw_writel(0, UART3_BASE_VA + UART_FCR_OFFSET);
+
+ /* setup wakeup interrupt */
+ start_int_set_rising_edge(SE_U3_RX_INT);
+ start_int_ack(SE_U3_RX_INT);
+ start_int_umask(SE_U3_RX_INT);
+
+ start_int_set_rising_edge(SE_U5_RX_INT);
+ start_int_ack(SE_U5_RX_INT);
+ start_int_umask(SE_U5_RX_INT);
+}
+
diff --git a/arch/arm/mach-pnx4008/sleep.S b/arch/arm/mach-pnx4008/sleep.S
new file mode 100644
index 000000000000..93c802bac269
--- /dev/null
+++ b/arch/arm/mach-pnx4008/sleep.S
@@ -0,0 +1,196 @@
+/*
+ * linux/arch/arm/mach-pnx4008/sleep.S
+ *
+ * PNX4008 support for STOP mode and SDRAM self-refresh
+ *
+ * Authors: Dmitry Chigirev, Vitaly Wool <source@mvista.com>
+ *
+ * 2005 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+
+#include <linux/config.h>
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/hardware.h>
+
+#define PWRMAN_VA_BASE IO_ADDRESS(PNX4008_PWRMAN_BASE)
+#define PWR_CTRL_REG_OFFS 0x44
+
+#define SDRAM_CFG_VA_BASE IO_ADDRESS(PNX4008_SDRAM_CFG_BASE)
+#define MPMC_STATUS_REG_OFFS 0x4
+
+ .text
+
+ENTRY(pnx4008_cpu_suspend)
+ @this function should be entered in Direct run mode.
+
+ @ save registers on stack
+ stmfd sp!, {r0 - r6, lr}
+
+ @ setup Power Manager base address in r4
+ @ and put it's value in r5
+ mov r4, #(PWRMAN_VA_BASE & 0xff000000)
+ orr r4, r4, #(PWRMAN_VA_BASE & 0x00ff0000)
+ orr r4, r4, #(PWRMAN_VA_BASE & 0x0000ff00)
+ orr r4, r4, #(PWRMAN_VA_BASE & 0x000000ff)
+ ldr r5, [r4, #PWR_CTRL_REG_OFFS]
+
+ @ setup SDRAM controller base address in r2
+ @ and put it's value in r3
+ mov r2, #(SDRAM_CFG_VA_BASE & 0xff000000)
+ orr r2, r2, #(SDRAM_CFG_VA_BASE & 0x00ff0000)
+ orr r2, r2, #(SDRAM_CFG_VA_BASE & 0x0000ff00)
+ orr r2, r2, #(SDRAM_CFG_VA_BASE & 0x000000ff)
+ ldr r3, [r2, #MPMC_STATUS_REG_OFFS] @extra read - HW bug workaround
+
+ @ clear SDRAM self-refresh bit latch
+ and r5, r5, #(~(1 << 8))
+ @ clear SDRAM self-refresh bit
+ and r5, r5, #(~(1 << 9))
+ str r5, [r4, #PWR_CTRL_REG_OFFS]
+
+ @ do save current bit settings in r1
+ mov r1, r5
+
+ @ set SDRAM self-refresh bit
+ orr r5, r5, #(1 << 9)
+ str r5, [r4, #PWR_CTRL_REG_OFFS]
+
+ @ set SDRAM self-refresh bit latch
+ orr r5, r5, #(1 << 8)
+ str r5, [r4, #PWR_CTRL_REG_OFFS]
+
+ @ clear SDRAM self-refresh bit latch
+ and r5, r5, #(~(1 << 8))
+ str r5, [r4, #PWR_CTRL_REG_OFFS]
+
+ @ clear SDRAM self-refresh bit
+ and r5, r5, #(~(1 << 9))
+ str r5, [r4, #PWR_CTRL_REG_OFFS]
+
+ @ wait for SDRAM to get into self-refresh mode
+2: ldr r3, [r2, #MPMC_STATUS_REG_OFFS]
+ tst r3, #(1 << 2)
+ beq 2b
+
+ @ to prepare SDRAM to get out of self-refresh mode after wakeup
+ orr r5, r5, #(1 << 7)
+ str r5, [r4, #PWR_CTRL_REG_OFFS]
+
+ @ do enter stop mode
+ orr r5, r5, #(1 << 0)
+ str r5, [r4, #PWR_CTRL_REG_OFFS]
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ @ sleeping now...
+
+ @ coming out of STOP mode into Direct Run mode
+ @ clear STOP mode and SDRAM self-refresh bits
+ str r1, [r4, #PWR_CTRL_REG_OFFS]
+
+ @ wait for SDRAM to get out self-refresh mode
+3: ldr r3, [r2, #MPMC_STATUS_REG_OFFS]
+ tst r3, #5
+ bne 3b
+
+ @ restore regs and return
+ ldmfd sp!, {r0 - r6, pc}
+
+ENTRY(pnx4008_cpu_suspend_sz)
+ .word . - pnx4008_cpu_suspend
+
+ENTRY(pnx4008_cpu_standby)
+ @ save registers on stack
+ stmfd sp!, {r0 - r6, lr}
+
+ @ setup Power Manager base address in r4
+ @ and put it's value in r5
+ mov r4, #(PWRMAN_VA_BASE & 0xff000000)
+ orr r4, r4, #(PWRMAN_VA_BASE & 0x00ff0000)
+ orr r4, r4, #(PWRMAN_VA_BASE & 0x0000ff00)
+ orr r4, r4, #(PWRMAN_VA_BASE & 0x000000ff)
+ ldr r5, [r4, #PWR_CTRL_REG_OFFS]
+
+ @ setup SDRAM controller base address in r2
+ @ and put it's value in r3
+ mov r2, #(SDRAM_CFG_VA_BASE & 0xff000000)
+ orr r2, r2, #(SDRAM_CFG_VA_BASE & 0x00ff0000)
+ orr r2, r2, #(SDRAM_CFG_VA_BASE & 0x0000ff00)
+ orr r2, r2, #(SDRAM_CFG_VA_BASE & 0x000000ff)
+ ldr r3, [r2, #MPMC_STATUS_REG_OFFS] @extra read - HW bug workaround
+
+ @ clear SDRAM self-refresh bit latch
+ and r5, r5, #(~(1 << 8))
+ @ clear SDRAM self-refresh bit
+ and r5, r5, #(~(1 << 9))
+ str r5, [r4, #PWR_CTRL_REG_OFFS]
+
+ @ do save current bit settings in r1
+ mov r1, r5
+
+ @ set SDRAM self-refresh bit
+ orr r5, r5, #(1 << 9)
+ str r5, [r4, #PWR_CTRL_REG_OFFS]
+
+ @ set SDRAM self-refresh bit latch
+ orr r5, r5, #(1 << 8)
+ str r5, [r4, #PWR_CTRL_REG_OFFS]
+
+ @ clear SDRAM self-refresh bit latch
+ and r5, r5, #(~(1 << 8))
+ str r5, [r4, #PWR_CTRL_REG_OFFS]
+
+ @ clear SDRAM self-refresh bit
+ and r5, r5, #(~(1 << 9))
+ str r5, [r4, #PWR_CTRL_REG_OFFS]
+
+ @ wait for SDRAM to get into self-refresh mode
+2: ldr r3, [r2, #MPMC_STATUS_REG_OFFS]
+ tst r3, #(1 << 2)
+ beq 2b
+
+ @ set 'get out of self-refresh mode after wakeup' bit
+ orr r5, r5, #(1 << 7)
+ str r5, [r4, #PWR_CTRL_REG_OFFS]
+
+ mcr p15, 0, r0, c7, c0, 4 @ kinda sleeping now...
+
+ @ set SDRAM self-refresh bit latch
+ orr r5, r5, #(1 << 8)
+ str r5, [r4, #PWR_CTRL_REG_OFFS]
+
+ @ clear SDRAM self-refresh bit latch
+ and r5, r5, #(~(1 << 8))
+ str r5, [r4, #PWR_CTRL_REG_OFFS]
+
+ @ wait for SDRAM to get out self-refresh mode
+3: ldr r3, [r2, #MPMC_STATUS_REG_OFFS]
+ tst r3, #5
+ bne 3b
+
+ @ restore regs and return
+ ldmfd sp!, {r0 - r6, pc}
+
+ENTRY(pnx4008_cpu_standby_sz)
+ .word . - pnx4008_cpu_standby
+
+ENTRY(pnx4008_cache_clean_invalidate)
+ stmfd sp!, {r0 - r6, lr}
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+ mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache
+#else
+1: mrc p15, 0, r15, c7, c14, 3 @ test,clean,invalidate
+ bne 1b
+#endif
+ ldmfd sp!, {r0 - r6, pc}
diff --git a/arch/arm/mach-pnx4008/time.c b/arch/arm/mach-pnx4008/time.c
new file mode 100644
index 000000000000..4ce680698529
--- /dev/null
+++ b/arch/arm/mach-pnx4008/time.c
@@ -0,0 +1,141 @@
+/*
+ * arch/arm/mach-pnx4008/time.c
+ *
+ * PNX4008 Timers
+ *
+ * Authors: Vitaly Wool, Dmitry Chigirev, Grigory Tolstolytkin <source@mvista.com>
+ *
+ * 2005 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/module.h>
+#include <linux/kallsyms.h>
+
+#include <asm/system.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/leds.h>
+#include <asm/irq.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/time.h>
+
+#include <linux/time.h>
+#include <linux/timex.h>
+#include <asm/errno.h>
+
+/*! Note: all timers are UPCOUNTING */
+
+/*!
+ * Returns number of us since last clock interrupt. Note that interrupts
+ * will have been disabled by do_gettimeoffset()
+ */
+static unsigned long pnx4008_gettimeoffset(void)
+{
+ u32 ticks_to_match =
+ __raw_readl(HSTIM_MATCH0) - __raw_readl(HSTIM_COUNTER);
+ u32 elapsed = LATCH - ticks_to_match;
+ return (elapsed * (tick_nsec / 1000)) / LATCH;
+}
+
+/*!
+ * IRQ handler for the timer
+ */
+static irqreturn_t pnx4008_timer_interrupt(int irq, void *dev_id,
+ struct pt_regs *regs)
+{
+ if (__raw_readl(HSTIM_INT) & MATCH0_INT) {
+
+ write_seqlock(&xtime_lock);
+
+ do {
+ timer_tick(regs);
+
+ /*
+ * this algorithm takes care of possible delay
+ * for this interrupt handling longer than a normal
+ * timer period
+ */
+ __raw_writel(__raw_readl(HSTIM_MATCH0) + LATCH,
+ HSTIM_MATCH0);
+ __raw_writel(MATCH0_INT, HSTIM_INT); /* clear interrupt */
+
+ /*
+ * The goal is to keep incrementing HSTIM_MATCH0
+ * register until HSTIM_MATCH0 indicates time after
+ * what HSTIM_COUNTER indicates.
+ */
+ } while ((signed)
+ (__raw_readl(HSTIM_MATCH0) -
+ __raw_readl(HSTIM_COUNTER)) < 0);
+
+ write_sequnlock(&xtime_lock);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction pnx4008_timer_irq = {
+ .name = "PNX4008 Tick Timer",
+ .flags = SA_INTERRUPT | SA_TIMER,
+ .handler = pnx4008_timer_interrupt
+};
+
+/*!
+ * Set up timer and timer interrupt.
+ */
+static __init void pnx4008_setup_timer(void)
+{
+ __raw_writel(RESET_COUNT, MSTIM_CTRL);
+ while (__raw_readl(MSTIM_COUNTER)) ; /* wait for reset to complete. 100% guarantee event */
+ __raw_writel(0, MSTIM_CTRL); /* stop the timer */
+ __raw_writel(0, MSTIM_MCTRL);
+
+ __raw_writel(RESET_COUNT, HSTIM_CTRL);
+ while (__raw_readl(HSTIM_COUNTER)) ; /* wait for reset to complete. 100% guarantee event */
+ __raw_writel(0, HSTIM_CTRL);
+ __raw_writel(0, HSTIM_MCTRL);
+ __raw_writel(0, HSTIM_CCR);
+ __raw_writel(12, HSTIM_PMATCH); /* scale down to 1 MHZ */
+ __raw_writel(LATCH, HSTIM_MATCH0);
+ __raw_writel(MR0_INT, HSTIM_MCTRL);
+
+ setup_irq(HSTIMER_INT, &pnx4008_timer_irq);
+
+ __raw_writel(COUNT_ENAB | DEBUG_EN, HSTIM_CTRL); /*start timer, stop when JTAG active */
+}
+
+/* Timer Clock Control in PM register */
+#define TIMCLK_CTRL_REG IO_ADDRESS((PNX4008_PWRMAN_BASE + 0xBC))
+#define WATCHDOG_CLK_EN 1
+#define TIMER_CLK_EN 2 /* HS and MS timers? */
+
+static u32 timclk_ctrl_reg_save;
+
+void pnx4008_timer_suspend(void)
+{
+ timclk_ctrl_reg_save = __raw_readl(TIMCLK_CTRL_REG);
+ __raw_writel(0, TIMCLK_CTRL_REG); /* disable timers */
+}
+
+void pnx4008_timer_resume(void)
+{
+ __raw_writel(timclk_ctrl_reg_save, TIMCLK_CTRL_REG); /* enable timers */
+}
+
+struct sys_timer pnx4008_timer = {
+ .init = pnx4008_setup_timer,
+ .offset = pnx4008_gettimeoffset,
+ .suspend = pnx4008_timer_suspend,
+ .resume = pnx4008_timer_resume,
+};
+
diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c
index 3e26d7ce5bb2..1ab26c6914f2 100644
--- a/arch/arm/mach-pxa/lubbock.c
+++ b/arch/arm/mach-pxa/lubbock.c
@@ -22,6 +22,10 @@
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/ads7846.h>
+#include <asm/arch/pxa2xx_spi.h>
+
#include <asm/setup.h>
#include <asm/memory.h>
#include <asm/mach-types.h>
@@ -196,6 +200,78 @@ static struct resource smc91x_resources[] = {
},
};
+/* ADS7846 is connected through SSP ... and if your board has J5 populated,
+ * you can select it to replace the ucb1400 by switching the touchscreen cable
+ * (to J5) and poking board registers (as done below). Else it's only useful
+ * for the temperature sensors.
+ */
+static struct resource pxa_ssp_resources[] = {
+ [0] = {
+ .start = __PREG(SSCR0_P(1)),
+ .end = __PREG(SSCR0_P(1)) + 0x14,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_SSP,
+ .end = IRQ_SSP,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct pxa2xx_spi_master pxa_ssp_master_info = {
+ .ssp_type = PXA25x_SSP,
+ .clock_enable = CKEN3_SSP,
+ .num_chipselect = 0,
+};
+
+static struct platform_device pxa_ssp = {
+ .name = "pxa2xx-spi",
+ .id = 1,
+ .resource = pxa_ssp_resources,
+ .num_resources = ARRAY_SIZE(pxa_ssp_resources),
+ .dev = {
+ .platform_data = &pxa_ssp_master_info,
+ },
+};
+
+static int lubbock_ads7846_pendown_state(void)
+{
+ /* TS_BUSY is bit 8 in LUB_MISC_RD, but pendown is irq-only */
+ return 0;
+}
+
+static struct ads7846_platform_data ads_info = {
+ .model = 7846,
+ .vref_delay_usecs = 100, /* internal, no cap */
+ .get_pendown_state = lubbock_ads7846_pendown_state,
+ // .x_plate_ohms = 500, /* GUESS! */
+ // .y_plate_ohms = 500, /* GUESS! */
+};
+
+static void ads7846_cs(u32 command)
+{
+ static const unsigned TS_nCS = 1 << 11;
+ lubbock_set_misc_wr(TS_nCS, (command == PXA2XX_CS_ASSERT) ? 0 : TS_nCS);
+}
+
+static struct pxa2xx_spi_chip ads_hw = {
+ .tx_threshold = 1,
+ .rx_threshold = 2,
+ .cs_control = ads7846_cs,
+};
+
+static struct spi_board_info spi_board_info[] __initdata = { {
+ .modalias = "ads7846",
+ .platform_data = &ads_info,
+ .controller_data = &ads_hw,
+ .irq = LUBBOCK_BB_IRQ,
+ .max_speed_hz = 120000 /* max sample rate at 3V */
+ * 26 /* command + data + overhead */,
+ .bus_num = 1,
+ .chip_select = 0,
+},
+};
+
static struct platform_device smc91x_device = {
.name = "smc91x",
.id = -1,
@@ -272,6 +348,7 @@ static struct platform_device *devices[] __initdata = {
&smc91x_device,
&lubbock_flash_device[0],
&lubbock_flash_device[1],
+ &pxa_ssp,
};
static struct pxafb_mach_info sharp_lm8v31 __initdata = {
@@ -400,6 +477,8 @@ static void __init lubbock_init(void)
lubbock_flash_data[flashboot^1].name = "application-flash";
lubbock_flash_data[flashboot].name = "boot-rom";
(void) platform_add_devices(devices, ARRAY_SIZE(devices));
+
+ spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
}
static struct map_desc lubbock_io_desc[] __initdata = {
@@ -416,6 +495,11 @@ static void __init lubbock_map_io(void)
pxa_map_io();
iotable_init(lubbock_io_desc, ARRAY_SIZE(lubbock_io_desc));
+ /* SSP data pins */
+ pxa_gpio_mode(GPIO23_SCLK_MD);
+ pxa_gpio_mode(GPIO25_STXD_MD);
+ pxa_gpio_mode(GPIO26_SRXD_MD);
+
/* This enables the BTUART */
pxa_gpio_mode(GPIO42_BTRXD_MD);
pxa_gpio_mode(GPIO43_BTTXD_MD);
diff --git a/arch/arm/mach-s3c2410/Kconfig b/arch/arm/mach-s3c2410/Kconfig
index 970f98dadffc..0c334136db7c 100644
--- a/arch/arm/mach-s3c2410/Kconfig
+++ b/arch/arm/mach-s3c2410/Kconfig
@@ -70,6 +70,18 @@ config ARCH_S3C2440
help
Say Y here if you are using the SMDK2440.
+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_VR1000
bool "Thorcom VR1000"
select CPU_S3C2410
@@ -109,12 +121,26 @@ config CPU_S3C2410
Support for S3C2410 and S3C2410A family from the S3C24XX line
of Samsung Mobile CPUs.
+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 CPU_S3C244X
help
Support for S3C2440 Samsung Mobile CPU based systems.
+config CPU_S3C2442
+ bool
+ depends on ARCH_S3C2420
+ select CPU_S3C244X
+ help
+ Support for S3C2442 Samsung Mobile CPU based systems.
+
comment "S3C2410 Boot"
config S3C2410_BOOT_WATCHDOG
diff --git a/arch/arm/mach-s3c2410/Makefile b/arch/arm/mach-s3c2410/Makefile
index 3e5712db6b52..5e09355cd4f4 100644
--- a/arch/arm/mach-s3c2410/Makefile
+++ b/arch/arm/mach-s3c2410/Makefile
@@ -24,6 +24,11 @@ obj-$(CONFIG_S3C2410_DMA) += dma.o
obj-$(CONFIG_PM) += pm.o sleep.o
obj-$(CONFIG_PM_SIMTEC) += pm-simtec.o
+# S3C244X support
+
+obj-$(CONFIG_CPU_S3C244X) += s3c244x.o
+obj-$(CONFIG_CPU_S3C244X) += s3c244x-irq.o
+
# S3C2440 support
obj-$(CONFIG_CPU_S3C2440) += s3c2440.o s3c2440-dsc.o
@@ -31,6 +36,11 @@ obj-$(CONFIG_CPU_S3C2440) += s3c2440-irq.o
obj-$(CONFIG_CPU_S3C2440) += s3c2440-clock.o
obj-$(CONFIG_CPU_S3C2440) += s3c2410-gpio.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
diff --git a/arch/arm/mach-s3c2410/clock.c b/arch/arm/mach-s3c2410/clock.c
index 6de713ad319a..99d174612b53 100644
--- a/arch/arm/mach-s3c2410/clock.c
+++ b/arch/arm/mach-s3c2410/clock.c
@@ -70,7 +70,7 @@ void inline s3c24xx_clk_enable(unsigned int clocks, unsigned int enable)
clkcon &= ~clocks;
/* ensure none of the special function bits set */
- clkcon &= ~(S3C2410_CLKCON_IDLE|S3C2410_CLKCON_POWER);
+ clkcon &= ~(S3C2410_CLKCON_IDLE|S3C2410_CLKCON_POWER | 3);
__raw_writel(clkcon, S3C2410_CLKCON);
}
diff --git a/arch/arm/mach-s3c2410/common-smdk.c b/arch/arm/mach-s3c2410/common-smdk.c
index c940890f621f..a40eaa656177 100644
--- a/arch/arm/mach-s3c2410/common-smdk.c
+++ b/arch/arm/mach-s3c2410/common-smdk.c
@@ -34,6 +34,7 @@
#include <asm/irq.h>
#include <asm/arch/regs-gpio.h>
+#include <asm/arch/leds-gpio.h>
#include <asm/arch/nand.h>
@@ -41,6 +42,66 @@
#include "devs.h"
#include "pm.h"
+/* LED devices */
+
+static struct s3c24xx_led_platdata smdk_pdata_led4 = {
+ .gpio = S3C2410_GPF4,
+ .flags = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE,
+ .name = "led4",
+ .def_trigger = "timer",
+};
+
+static struct s3c24xx_led_platdata smdk_pdata_led5 = {
+ .gpio = S3C2410_GPF5,
+ .flags = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE,
+ .name = "led5",
+ .def_trigger = "nand-disk",
+};
+
+static struct s3c24xx_led_platdata smdk_pdata_led6 = {
+ .gpio = S3C2410_GPF6,
+ .flags = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE,
+ .name = "led6",
+};
+
+static struct s3c24xx_led_platdata smdk_pdata_led7 = {
+ .gpio = S3C2410_GPF7,
+ .flags = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE,
+ .name = "led7",
+};
+
+static struct platform_device smdk_led4 = {
+ .name = "s3c24xx_led",
+ .id = 0,
+ .dev = {
+ .platform_data = &smdk_pdata_led4,
+ },
+};
+
+static struct platform_device smdk_led5 = {
+ .name = "s3c24xx_led",
+ .id = 1,
+ .dev = {
+ .platform_data = &smdk_pdata_led5,
+ },
+};
+
+static struct platform_device smdk_led6 = {
+ .name = "s3c24xx_led",
+ .id = 2,
+ .dev = {
+ .platform_data = &smdk_pdata_led6,
+ },
+};
+
+static struct platform_device smdk_led7 = {
+ .name = "s3c24xx_led",
+ .id = 3,
+ .dev = {
+ .platform_data = &smdk_pdata_led7,
+ },
+};
+
/* NAND parititon from 2.4.18-swl5 */
static struct mtd_partition smdk_default_nand_part[] = {
@@ -111,6 +172,10 @@ static struct s3c2410_platform_nand smdk_nand_info = {
static struct platform_device __initdata *smdk_devs[] = {
&s3c_device_nand,
+ &smdk_led4,
+ &smdk_led5,
+ &smdk_led6,
+ &smdk_led7,
};
void __init smdk_machine_init(void)
diff --git a/arch/arm/mach-s3c2410/cpu.c b/arch/arm/mach-s3c2410/cpu.c
index 70c34fcf7858..52842e6e86e6 100644
--- a/arch/arm/mach-s3c2410/cpu.c
+++ b/arch/arm/mach-s3c2410/cpu.c
@@ -37,12 +37,16 @@
#include <asm/mach/map.h>
#include <asm/arch/regs-gpio.h>
+#include <asm/arch/regs-serial.h>
#include "cpu.h"
+#include "devs.h"
#include "clock.h"
#include "s3c2400.h"
#include "s3c2410.h"
+#include "s3c244x.h"
#include "s3c2440.h"
+#include "s3c2442.h"
struct cpu_table {
unsigned long idcode;
@@ -59,6 +63,7 @@ struct cpu_table {
static const char name_s3c2400[] = "S3C2400";
static const char name_s3c2410[] = "S3C2410";
static const char name_s3c2440[] = "S3C2440";
+static const char name_s3c2442[] = "S3C2442";
static const char name_s3c2410a[] = "S3C2410A";
static const char name_s3c2440a[] = "S3C2440A";
@@ -84,22 +89,31 @@ static struct cpu_table cpu_ids[] __initdata = {
{
.idcode = 0x32440000,
.idmask = 0xffffffff,
- .map_io = s3c2440_map_io,
- .init_clocks = s3c2440_init_clocks,
- .init_uarts = s3c2440_init_uarts,
+ .map_io = s3c244x_map_io,
+ .init_clocks = s3c244x_init_clocks,
+ .init_uarts = s3c244x_init_uarts,
.init = s3c2440_init,
.name = name_s3c2440
},
{
.idcode = 0x32440001,
.idmask = 0xffffffff,
- .map_io = s3c2440_map_io,
- .init_clocks = s3c2440_init_clocks,
- .init_uarts = s3c2440_init_uarts,
+ .map_io = s3c244x_map_io,
+ .init_clocks = s3c244x_init_clocks,
+ .init_uarts = s3c244x_init_uarts,
.init = s3c2440_init,
.name = name_s3c2440a
},
{
+ .idcode = 0x32440aaa,
+ .idmask = 0xffffffff,
+ .map_io = s3c244x_map_io,
+ .init_clocks = s3c244x_init_clocks,
+ .init_uarts = s3c244x_init_uarts,
+ .init = s3c2442_init,
+ .name = name_s3c2442
+ },
+ {
.idcode = 0x0, /* S3C2400 doesn't have an idcode */
.idmask = 0xffffffff,
.map_io = s3c2400_map_io,
@@ -175,13 +189,13 @@ void __init s3c24xx_init_io(struct map_desc *mach_desc, int size)
panic("Unknown S3C24XX CPU");
}
+ printk("CPU %s (id 0x%08lx)\n", cpu->name, idcode);
+
if (cpu->map_io == NULL || cpu->init == NULL) {
printk(KERN_ERR "CPU %s support not enabled\n", cpu->name);
panic("Unsupported S3C24XX CPU");
}
- printk("CPU %s (id 0x%08lx)\n", cpu->name, idcode);
-
(cpu->map_io)(mach_desc, size);
}
@@ -208,6 +222,49 @@ void __init s3c24xx_init_clocks(int xtal)
(cpu->init_clocks)(xtal);
}
+/* uart management */
+
+static int nr_uarts __initdata = 0;
+
+static struct s3c2410_uartcfg uart_cfgs[3];
+
+/* s3c24xx_init_uartdevs
+ *
+ * copy the specified platform data and configuration into our central
+ * set of devices, before the data is thrown away after the init process.
+ *
+ * This also fills in the array passed to the serial driver for the
+ * early initialisation of the console.
+*/
+
+void __init s3c24xx_init_uartdevs(char *name,
+ struct s3c24xx_uart_resources *res,
+ struct s3c2410_uartcfg *cfg, int no)
+{
+ struct platform_device *platdev;
+ struct s3c2410_uartcfg *cfgptr = uart_cfgs;
+ struct s3c24xx_uart_resources *resp;
+ int uart;
+
+ memcpy(cfgptr, cfg, sizeof(struct s3c2410_uartcfg) * no);
+
+ for (uart = 0; uart < no; uart++, cfg++, cfgptr++) {
+ platdev = s3c24xx_uart_src[cfgptr->hwport];
+
+ resp = res + cfgptr->hwport;
+
+ s3c24xx_uart_devs[uart] = platdev;
+
+ platdev->name = name;
+ platdev->resource = resp->resources;
+ platdev->num_resources = resp->nr_resources;
+
+ platdev->dev.platform_data = cfgptr;
+ }
+
+ nr_uarts = no;
+}
+
void __init s3c24xx_init_uarts(struct s3c2410_uartcfg *cfg, int no)
{
if (cpu == NULL)
@@ -232,6 +289,10 @@ static int __init s3c_arch_init(void)
if (ret != 0)
return ret;
+ ret = platform_add_devices(s3c24xx_uart_devs, nr_uarts);
+ if (ret != 0)
+ return ret;
+
if (board != NULL) {
struct platform_device **ptr = board->devices;
int i;
diff --git a/arch/arm/mach-s3c2410/cpu.h b/arch/arm/mach-s3c2410/cpu.h
index fc1067783f6d..40862899b2f1 100644
--- a/arch/arm/mach-s3c2410/cpu.h
+++ b/arch/arm/mach-s3c2410/cpu.h
@@ -31,6 +31,8 @@
#define print_mhz(m) ((m) / MHZ), ((m / 1000) % 1000)
/* forward declaration */
+struct s3c24xx_uart_resources;
+struct platform_device;
struct s3c2410_uartcfg;
struct map_desc;
@@ -44,6 +46,10 @@ extern void s3c24xx_init_uarts(struct s3c2410_uartcfg *cfg, int no);
extern void s3c24xx_init_clocks(int xtal);
+extern void s3c24xx_init_uartdevs(char *name,
+ struct s3c24xx_uart_resources *res,
+ struct s3c2410_uartcfg *cfg, int no);
+
/* the board structure is used at first initialsation time
* to get info such as the devices to register for this
* board. This is done because platfrom_add_devices() cannot
@@ -68,3 +74,4 @@ extern struct sys_timer s3c24xx_timer;
/* system device classes */
extern struct sysdev_class s3c2440_sysclass;
+extern struct sysdev_class s3c2442_sysclass;
diff --git a/arch/arm/mach-s3c2410/devs.c b/arch/arm/mach-s3c2410/devs.c
index ca09ba516e4c..ad3845e329ba 100644
--- a/arch/arm/mach-s3c2410/devs.c
+++ b/arch/arm/mach-s3c2410/devs.c
@@ -38,10 +38,86 @@
#include <asm/arch/regs-serial.h>
#include "devs.h"
+#include "cpu.h"
/* Serial port registrations */
-struct platform_device *s3c24xx_uart_devs[3];
+static struct resource s3c2410_uart0_resource[] = {
+ [0] = {
+ .start = S3C2410_PA_UART0,
+ .end = S3C2410_PA_UART0 + 0x3fff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_S3CUART_RX0,
+ .end = IRQ_S3CUART_ERR0,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static struct resource s3c2410_uart1_resource[] = {
+ [0] = {
+ .start = S3C2410_PA_UART1,
+ .end = S3C2410_PA_UART1 + 0x3fff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_S3CUART_RX1,
+ .end = IRQ_S3CUART_ERR1,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static struct resource s3c2410_uart2_resource[] = {
+ [0] = {
+ .start = S3C2410_PA_UART2,
+ .end = S3C2410_PA_UART2 + 0x3fff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_S3CUART_RX2,
+ .end = IRQ_S3CUART_ERR2,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+struct s3c24xx_uart_resources s3c2410_uart_resources[] __initdata = {
+ [0] = {
+ .resources = s3c2410_uart0_resource,
+ .nr_resources = ARRAY_SIZE(s3c2410_uart0_resource),
+ },
+ [1] = {
+ .resources = s3c2410_uart1_resource,
+ .nr_resources = ARRAY_SIZE(s3c2410_uart1_resource),
+ },
+ [2] = {
+ .resources = s3c2410_uart2_resource,
+ .nr_resources = ARRAY_SIZE(s3c2410_uart2_resource),
+ },
+};
+
+/* yart devices */
+
+static struct platform_device s3c24xx_uart_device0 = {
+ .id = 0,
+};
+
+static struct platform_device s3c24xx_uart_device1 = {
+ .id = 1,
+};
+
+static struct platform_device s3c24xx_uart_device2 = {
+ .id = 2,
+};
+
+struct platform_device *s3c24xx_uart_src[3] = {
+ &s3c24xx_uart_device0,
+ &s3c24xx_uart_device1,
+ &s3c24xx_uart_device2,
+};
+
+struct platform_device *s3c24xx_uart_devs[3] = {
+};
/* USB Host Controller */
diff --git a/arch/arm/mach-s3c2410/devs.h b/arch/arm/mach-s3c2410/devs.h
index 52c4bab5c761..fa124ed920e0 100644
--- a/arch/arm/mach-s3c2410/devs.h
+++ b/arch/arm/mach-s3c2410/devs.h
@@ -17,7 +17,15 @@
#include <linux/config.h>
#include <linux/platform_device.h>
+struct s3c24xx_uart_resources {
+ struct resource *resources;
+ unsigned long nr_resources;
+};
+
+extern struct s3c24xx_uart_resources s3c2410_uart_resources[];
+
extern struct platform_device *s3c24xx_uart_devs[];
+extern struct platform_device *s3c24xx_uart_src[];
extern struct platform_device s3c_device_usb;
extern struct platform_device s3c_device_lcd;
diff --git a/arch/arm/mach-s3c2410/mach-anubis.c b/arch/arm/mach-s3c2410/mach-anubis.c
index cc97fbf66291..52bf718137d4 100644
--- a/arch/arm/mach-s3c2410/mach-anubis.c
+++ b/arch/arm/mach-s3c2410/mach-anubis.c
@@ -131,7 +131,7 @@ static struct s3c24xx_uart_clksrc anubis_serial_clocks[] = {
};
-static struct s3c2410_uartcfg anubis_uartcfgs[] = {
+static struct s3c2410_uartcfg anubis_uartcfgs[] __initdata = {
[0] = {
.hwport = 0,
.flags = 0,
diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c
index 995bb8add331..947234df8160 100644
--- a/arch/arm/mach-s3c2410/mach-bast.c
+++ b/arch/arm/mach-s3c2410/mach-bast.c
@@ -208,7 +208,7 @@ static struct s3c24xx_uart_clksrc bast_serial_clocks[] = {
};
-static struct s3c2410_uartcfg bast_uartcfgs[] = {
+static struct s3c2410_uartcfg bast_uartcfgs[] __initdata = {
[0] = {
.hwport = 0,
.flags = 0,
diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c
index 646a3a5d33a5..aec431b2830a 100644
--- a/arch/arm/mach-s3c2410/mach-h1940.c
+++ b/arch/arm/mach-s3c2410/mach-h1940.c
@@ -72,7 +72,7 @@ static struct map_desc h1940_iodesc[] __initdata = {
#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
-static struct s3c2410_uartcfg h1940_uartcfgs[] = {
+static struct s3c2410_uartcfg h1940_uartcfgs[] __initdata = {
[0] = {
.hwport = 0,
.flags = 0,
diff --git a/arch/arm/mach-s3c2410/mach-nexcoder.c b/arch/arm/mach-s3c2410/mach-nexcoder.c
index 07d09509a626..065a1d4e860b 100644
--- a/arch/arm/mach-s3c2410/mach-nexcoder.c
+++ b/arch/arm/mach-s3c2410/mach-nexcoder.c
@@ -51,7 +51,7 @@ static struct map_desc nexcoder_iodesc[] __initdata = {
#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
#define UFCON S3C2410_UFCON_RXTRIG12 | S3C2410_UFCON_FIFOMODE
-static struct s3c2410_uartcfg nexcoder_uartcfgs[] = {
+static struct s3c2410_uartcfg nexcoder_uartcfgs[] __initdata = {
[0] = {
.hwport = 0,
.flags = 0,
diff --git a/arch/arm/mach-s3c2410/mach-osiris.c b/arch/arm/mach-s3c2410/mach-osiris.c
index ae0787557751..858fd03c6bc5 100644
--- a/arch/arm/mach-s3c2410/mach-osiris.c
+++ b/arch/arm/mach-s3c2410/mach-osiris.c
@@ -95,8 +95,7 @@ static struct s3c24xx_uart_clksrc osiris_serial_clocks[] = {
}
};
-
-static struct s3c2410_uartcfg osiris_uartcfgs[] = {
+static struct s3c2410_uartcfg osiris_uartcfgs[] __initdata = {
[0] = {
.hwport = 0,
.flags = 0,
@@ -107,7 +106,7 @@ static struct s3c2410_uartcfg osiris_uartcfgs[] = {
.clocks_size = ARRAY_SIZE(osiris_serial_clocks)
},
[1] = {
- .hwport = 2,
+ .hwport = 1,
.flags = 0,
.ucon = UCON,
.ulcon = ULCON,
diff --git a/arch/arm/mach-s3c2410/mach-otom.c b/arch/arm/mach-s3c2410/mach-otom.c
index b39daedf93ca..c71673fd9955 100644
--- a/arch/arm/mach-s3c2410/mach-otom.c
+++ b/arch/arm/mach-s3c2410/mach-otom.c
@@ -45,7 +45,7 @@ static struct map_desc otom11_iodesc[] __initdata = {
#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
#define UFCON S3C2410_UFCON_RXTRIG12 | S3C2410_UFCON_FIFOMODE
-static struct s3c2410_uartcfg otom11_uartcfgs[] = {
+static struct s3c2410_uartcfg otom11_uartcfgs[] __initdata = {
[0] = {
.hwport = 0,
.flags = 0,
diff --git a/arch/arm/mach-s3c2410/mach-smdk2410.c b/arch/arm/mach-s3c2410/mach-smdk2410.c
index 2db932d72c5a..25f7e9f4dcee 100644
--- a/arch/arm/mach-s3c2410/mach-smdk2410.c
+++ b/arch/arm/mach-s3c2410/mach-smdk2410.c
@@ -65,7 +65,7 @@ static struct map_desc smdk2410_iodesc[] __initdata = {
#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[] = {
+static struct s3c2410_uartcfg smdk2410_uartcfgs[] __initdata = {
[0] = {
.hwport = 0,
.flags = 0,
diff --git a/arch/arm/mach-s3c2410/mach-smdk2440.c b/arch/arm/mach-s3c2410/mach-smdk2440.c
index 5fffd1d51047..d661c6b7ff56 100644
--- a/arch/arm/mach-s3c2410/mach-smdk2440.c
+++ b/arch/arm/mach-s3c2410/mach-smdk2440.c
@@ -86,7 +86,7 @@ static struct map_desc smdk2440_iodesc[] __initdata = {
#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
-static struct s3c2410_uartcfg smdk2440_uartcfgs[] = {
+static struct s3c2410_uartcfg smdk2440_uartcfgs[] __initdata = {
[0] = {
.hwport = 0,
.flags = 0,
diff --git a/arch/arm/mach-s3c2410/mach-vr1000.c b/arch/arm/mach-s3c2410/mach-vr1000.c
index 785fc9cdcf7c..d18efb279d3d 100644
--- a/arch/arm/mach-s3c2410/mach-vr1000.c
+++ b/arch/arm/mach-s3c2410/mach-vr1000.c
@@ -166,7 +166,7 @@ static struct s3c24xx_uart_clksrc vr1000_serial_clocks[] = {
}
};
-static struct s3c2410_uartcfg vr1000_uartcfgs[] = {
+static struct s3c2410_uartcfg vr1000_uartcfgs[] __initdata = {
[0] = {
.hwport = 0,
.flags = 0,
diff --git a/arch/arm/mach-s3c2410/pm.c b/arch/arm/mach-s3c2410/pm.c
index fe57d966a34d..43e9a550a203 100644
--- a/arch/arm/mach-s3c2410/pm.c
+++ b/arch/arm/mach-s3c2410/pm.c
@@ -58,7 +58,11 @@ unsigned long s3c_pm_flags;
/* cache functions from arch/arm/mm/proc-arm920.S */
+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
extern void arm920_flush_kern_cache_all(void);
+#else
+static void arm920_flush_kern_cache_all(void) { }
+#endif
#define PFX "s3c24xx-pm: "
diff --git a/arch/arm/mach-s3c2410/s3c2410.c b/arch/arm/mach-s3c2410/s3c2410.c
index 0a2013a76549..0852e87a79c4 100644
--- a/arch/arm/mach-s3c2410/s3c2410.c
+++ b/arch/arm/mach-s3c2410/s3c2410.c
@@ -42,6 +42,7 @@
#include "s3c2410.h"
#include "cpu.h"
+#include "devs.h"
#include "clock.h"
/* Initial IO mappings */
@@ -55,93 +56,13 @@ static struct map_desc s3c2410_iodesc[] __initdata = {
IODESC_ENT(WATCHDOG),
};
-static struct resource s3c_uart0_resource[] = {
- [0] = {
- .start = S3C2410_PA_UART0,
- .end = S3C2410_PA_UART0 + 0x3fff,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = IRQ_S3CUART_RX0,
- .end = IRQ_S3CUART_ERR0,
- .flags = IORESOURCE_IRQ,
- }
-
-};
-
-static struct resource s3c_uart1_resource[] = {
- [0] = {
- .start = S3C2410_PA_UART1,
- .end = S3C2410_PA_UART1 + 0x3fff,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = IRQ_S3CUART_RX1,
- .end = IRQ_S3CUART_ERR1,
- .flags = IORESOURCE_IRQ,
- }
-};
-
-static struct resource s3c_uart2_resource[] = {
- [0] = {
- .start = S3C2410_PA_UART2,
- .end = S3C2410_PA_UART2 + 0x3fff,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = IRQ_S3CUART_RX2,
- .end = IRQ_S3CUART_ERR2,
- .flags = IORESOURCE_IRQ,
- }
-};
-
/* our uart devices */
-static struct platform_device s3c_uart0 = {
- .name = "s3c2410-uart",
- .id = 0,
- .num_resources = ARRAY_SIZE(s3c_uart0_resource),
- .resource = s3c_uart0_resource,
-};
-
-
-static struct platform_device s3c_uart1 = {
- .name = "s3c2410-uart",
- .id = 1,
- .num_resources = ARRAY_SIZE(s3c_uart1_resource),
- .resource = s3c_uart1_resource,
-};
-
-static struct platform_device s3c_uart2 = {
- .name = "s3c2410-uart",
- .id = 2,
- .num_resources = ARRAY_SIZE(s3c_uart2_resource),
- .resource = s3c_uart2_resource,
-};
-
-static struct platform_device *uart_devices[] __initdata = {
- &s3c_uart0,
- &s3c_uart1,
- &s3c_uart2
-};
-
-static int s3c2410_uart_count = 0;
-
/* uart registration process */
void __init s3c2410_init_uarts(struct s3c2410_uartcfg *cfg, int no)
{
- struct platform_device *platdev;
- int uart;
-
- for (uart = 0; uart < no; uart++, cfg++) {
- platdev = uart_devices[cfg->hwport];
-
- s3c24xx_uart_devs[uart] = platdev;
- platdev->dev.platform_data = cfg;
- }
-
- s3c2410_uart_count = uart;
+ s3c24xx_init_uartdevs("s3c2410-uart", s3c2410_uart_resources, cfg, no);
}
/* s3c2410_map_io
@@ -193,5 +114,5 @@ int __init s3c2410_init(void)
{
printk("S3C2410: Initialising architecture\n");
- return platform_add_devices(s3c24xx_uart_devs, s3c2410_uart_count);
+ return 0;
}
diff --git a/arch/arm/mach-s3c2410/s3c2440-irq.c b/arch/arm/mach-s3c2410/s3c2440-irq.c
index 278d0044c85d..acfe3870727b 100644
--- a/arch/arm/mach-s3c2410/s3c2440-irq.c
+++ b/arch/arm/mach-s3c2410/s3c2440-irq.c
@@ -100,73 +100,12 @@ static struct irqchip s3c_irq_wdtac97 = {
.ack = s3c_irq_wdtac97_ack,
};
-/* camera irq */
-
-static void s3c_irq_demux_cam(unsigned int irq,
- struct irqdesc *desc,
- struct pt_regs *regs)
-{
- unsigned int subsrc, submsk;
- struct irqdesc *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 >>= 11;
- subsrc &= 3;
-
- if (subsrc != 0) {
- if (subsrc & 1) {
- mydesc = irq_desc + IRQ_S3C2440_CAM_C;
- desc_handle_irq(IRQ_S3C2440_CAM_C, mydesc, regs);
- }
- if (subsrc & 2) {
- mydesc = irq_desc + IRQ_S3C2440_CAM_P;
- desc_handle_irq(IRQ_S3C2440_CAM_P, mydesc, regs);
- }
- }
-}
-
-#define INTMSK_CAM (1UL << (IRQ_CAM - IRQ_EINT0))
-
-static void
-s3c_irq_cam_mask(unsigned int irqno)
-{
- s3c_irqsub_mask(irqno, INTMSK_CAM, 3<<11);
-}
-
-static void
-s3c_irq_cam_unmask(unsigned int irqno)
-{
- s3c_irqsub_unmask(irqno, INTMSK_CAM);
-}
-
-static void
-s3c_irq_cam_ack(unsigned int irqno)
-{
- s3c_irqsub_maskack(irqno, INTMSK_CAM, 3<<11);
-}
-
-static struct irqchip s3c_irq_cam = {
- .mask = s3c_irq_cam_mask,
- .unmask = s3c_irq_cam_unmask,
- .ack = s3c_irq_cam_ack,
-};
-
static int s3c2440_irq_add(struct sys_device *sysdev)
{
unsigned int irqno;
printk("S3C2440: IRQ Support\n");
- set_irq_chip(IRQ_NFCON, &s3c_irq_level_chip);
- set_irq_handler(IRQ_NFCON, do_level_IRQ);
- set_irq_flags(IRQ_NFCON, IRQF_VALID);
-
/* add new chained handler for wdt, ac7 */
set_irq_chip(IRQ_WDT, &s3c_irq_level_chip);
@@ -179,18 +118,6 @@ static int s3c2440_irq_add(struct sys_device *sysdev)
set_irq_flags(irqno, IRQF_VALID);
}
- /* add chained handler for camera */
-
- set_irq_chip(IRQ_CAM, &s3c_irq_level_chip);
- set_irq_handler(IRQ_CAM, do_level_IRQ);
- set_irq_chained_handler(IRQ_CAM, s3c_irq_demux_cam);
-
- for (irqno = IRQ_S3C2440_CAM_C; irqno <= IRQ_S3C2440_CAM_P; irqno++) {
- set_irq_chip(irqno, &s3c_irq_cam);
- set_irq_handler(irqno, do_level_IRQ);
- set_irq_flags(irqno, IRQF_VALID);
- }
-
return 0;
}
@@ -198,10 +125,10 @@ static struct sysdev_driver s3c2440_irq_driver = {
.add = s3c2440_irq_add,
};
-static int s3c24xx_irq_driver(void)
+static int s3c2440_irq_init(void)
{
return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_irq_driver);
}
-arch_initcall(s3c24xx_irq_driver);
+arch_initcall(s3c2440_irq_init);
diff --git a/arch/arm/mach-s3c2410/s3c2440.c b/arch/arm/mach-s3c2410/s3c2440.c
index b7fe6d9453fb..0ab50f44f318 100644
--- a/arch/arm/mach-s3c2410/s3c2440.c
+++ b/arch/arm/mach-s3c2410/s3c2440.c
@@ -1,6 +1,6 @@
/* linux/arch/arm/mach-s3c2410/s3c2440.c
*
- * Copyright (c) 2004-2005 Simtec Electronics
+ * Copyright (c) 2004-2006 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
*
* Samsung S3C2440 Mobile CPU support
@@ -8,16 +8,6 @@
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
- *
- * Modifications:
- * 24-Aug-2004 BJD Start of s3c2440 support
- * 12-Oct-2004 BJD Moved clock info out to clock.c
- * 01-Nov-2004 BJD Fixed clock build code
- * 09-Nov-2004 BJD Added sysdev for power management
- * 04-Nov-2004 BJD New serial registration
- * 15-Nov-2004 BJD Rename the i2c device for the s3c2440
- * 14-Jan-2005 BJD Moved clock init code into seperate function
- * 14-Jan-2005 BJD Removed un-used clock bits
*/
#include <linux/kernel.h>
@@ -50,234 +40,20 @@
#include "cpu.h"
#include "pm.h"
-
-static struct map_desc s3c2440_iodesc[] __initdata = {
- IODESC_ENT(USBHOST),
- IODESC_ENT(CLKPWR),
- IODESC_ENT(LCD),
- IODESC_ENT(TIMER),
- IODESC_ENT(ADC),
- IODESC_ENT(WATCHDOG),
-};
-
-static struct resource s3c_uart0_resource[] = {
- [0] = {
- .start = S3C2410_PA_UART0,
- .end = S3C2410_PA_UART0 + 0x3fff,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = IRQ_S3CUART_RX0,
- .end = IRQ_S3CUART_ERR0,
- .flags = IORESOURCE_IRQ,
- }
-
-};
-
-static struct resource s3c_uart1_resource[] = {
- [0] = {
- .start = S3C2410_PA_UART1,
- .end = S3C2410_PA_UART1 + 0x3fff,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = IRQ_S3CUART_RX1,
- .end = IRQ_S3CUART_ERR1,
- .flags = IORESOURCE_IRQ,
- }
-};
-
-static struct resource s3c_uart2_resource[] = {
- [0] = {
- .start = S3C2410_PA_UART2,
- .end = S3C2410_PA_UART2 + 0x3fff,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = IRQ_S3CUART_RX2,
- .end = IRQ_S3CUART_ERR2,
- .flags = IORESOURCE_IRQ,
- }
-};
-
-/* our uart devices */
-
-static struct platform_device s3c_uart0 = {
- .name = "s3c2440-uart",
- .id = 0,
- .num_resources = ARRAY_SIZE(s3c_uart0_resource),
- .resource = s3c_uart0_resource,
-};
-
-static struct platform_device s3c_uart1 = {
- .name = "s3c2440-uart",
- .id = 1,
- .num_resources = ARRAY_SIZE(s3c_uart1_resource),
- .resource = s3c_uart1_resource,
-};
-
-static struct platform_device s3c_uart2 = {
- .name = "s3c2440-uart",
- .id = 2,
- .num_resources = ARRAY_SIZE(s3c_uart2_resource),
- .resource = s3c_uart2_resource,
-};
-
-static struct platform_device *uart_devices[] __initdata = {
- &s3c_uart0,
- &s3c_uart1,
- &s3c_uart2
-};
-
-/* uart initialisation */
-
-static int __initdata s3c2440_uart_count;
-
-void __init s3c2440_init_uarts(struct s3c2410_uartcfg *cfg, int no)
-{
- struct platform_device *platdev;
- int uart;
-
- for (uart = 0; uart < no; uart++, cfg++) {
- platdev = uart_devices[cfg->hwport];
-
- s3c24xx_uart_devs[uart] = platdev;
- platdev->dev.platform_data = cfg;
- }
-
- s3c2440_uart_count = uart;
-}
-
-
-#ifdef CONFIG_PM
-
-static struct sleep_save s3c2440_sleep[] = {
- SAVE_ITEM(S3C2440_DSC0),
- SAVE_ITEM(S3C2440_DSC1),
- SAVE_ITEM(S3C2440_GPJDAT),
- SAVE_ITEM(S3C2440_GPJCON),
- SAVE_ITEM(S3C2440_GPJUP)
-};
-
-static int s3c2440_suspend(struct sys_device *dev, pm_message_t state)
-{
- s3c2410_pm_do_save(s3c2440_sleep, ARRAY_SIZE(s3c2440_sleep));
- return 0;
-}
-
-static int s3c2440_resume(struct sys_device *dev)
-{
- s3c2410_pm_do_restore(s3c2440_sleep, ARRAY_SIZE(s3c2440_sleep));
- return 0;
-}
-
-#else
-#define s3c2440_suspend NULL
-#define s3c2440_resume NULL
-#endif
-
-struct sysdev_class s3c2440_sysclass = {
- set_kset_name("s3c2440-core"),
- .suspend = s3c2440_suspend,
- .resume = s3c2440_resume
-};
-
static struct sys_device s3c2440_sysdev = {
.cls = &s3c2440_sysclass,
};
-void __init s3c2440_map_io(struct map_desc *mach_desc, int size)
+int __init s3c2440_init(void)
{
- /* register our io-tables */
-
- iotable_init(s3c2440_iodesc, ARRAY_SIZE(s3c2440_iodesc));
- iotable_init(mach_desc, size);
-
- /* rename any peripherals used differing from the s3c2410 */
-
- s3c_device_i2c.name = "s3c2440-i2c";
- s3c_device_nand.name = "s3c2440-nand";
+ printk("S3C2440: Initialising architecture\n");
/* change irq for watchdog */
s3c_device_wdt.resource[1].start = IRQ_S3C2440_WDT;
s3c_device_wdt.resource[1].end = IRQ_S3C2440_WDT;
-}
-
-void __init s3c2440_init_clocks(int xtal)
-{
- unsigned long clkdiv;
- unsigned long camdiv;
- unsigned long hclk, fclk, pclk;
- int hdiv = 1;
-
- /* now we've got our machine bits initialised, work out what
- * clocks we've got */
-
- fclk = s3c2410_get_pll(__raw_readl(S3C2410_MPLLCON), xtal) * 2;
-
- clkdiv = __raw_readl(S3C2410_CLKDIVN);
- camdiv = __raw_readl(S3C2440_CAMDIVN);
-
- /* work out clock scalings */
-
- switch (clkdiv & S3C2440_CLKDIVN_HDIVN_MASK) {
- case S3C2440_CLKDIVN_HDIVN_1:
- hdiv = 1;
- break;
-
- case S3C2440_CLKDIVN_HDIVN_2:
- hdiv = 2;
- break;
-
- case S3C2440_CLKDIVN_HDIVN_4_8:
- hdiv = (camdiv & S3C2440_CAMDIVN_HCLK4_HALF) ? 8 : 4;
- break;
-
- case S3C2440_CLKDIVN_HDIVN_3_6:
- hdiv = (camdiv & S3C2440_CAMDIVN_HCLK3_HALF) ? 6 : 3;
- break;
- }
-
- hclk = fclk / hdiv;
- pclk = hclk / ((clkdiv & S3C2440_CLKDIVN_PDIVN)? 2:1);
-
- /* print brief summary of clocks, etc */
-
- printk("S3C2440: core %ld.%03ld MHz, memory %ld.%03ld MHz, peripheral %ld.%03ld MHz\n",
- print_mhz(fclk), print_mhz(hclk), print_mhz(pclk));
-
- /* initialise the clocks here, to allow other things like the
- * console to use them, and to add new ones after the initialisation
- */
-
- s3c24xx_setup_clocks(xtal, fclk, hclk, pclk);
-}
-
-/* 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 s3c2440 based system)
- * as a driver which may support both 2410 and 2440 may try and use it.
-*/
-
-static int __init s3c2440_core_init(void)
-{
- return sysdev_class_register(&s3c2440_sysclass);
-}
-
-core_initcall(s3c2440_core_init);
-
-int __init s3c2440_init(void)
-{
- int ret;
-
- printk("S3C2440: Initialising architecture\n");
- ret = sysdev_register(&s3c2440_sysdev);
- if (ret != 0)
- printk(KERN_ERR "failed to register sysdev for s3c2440\n");
- else
- ret = platform_add_devices(s3c24xx_uart_devs, s3c2440_uart_count);
+ /* register our system device for everything else */
- return ret;
+ return sysdev_register(&s3c2440_sysdev);
}
diff --git a/arch/arm/mach-s3c2410/s3c2442-clock.c b/arch/arm/mach-s3c2410/s3c2442-clock.c
new file mode 100644
index 000000000000..5b7b301eb522
--- /dev/null
+++ b/arch/arm/mach-s3c2410/s3c2442-clock.c
@@ -0,0 +1,171 @@
+/* linux/arch/arm/mach-s3c2410/s3c2442-clock.c
+ *
+ * Copyright (c) 2004-2005 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2442 Clock 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 <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/device.h>
+#include <linux/sysdev.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/mutex.h>
+#include <linux/clk.h>
+
+#include <asm/hardware.h>
+#include <asm/atomic.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+
+#include <asm/arch/regs-clock.h>
+
+#include "clock.h"
+#include "cpu.h"
+
+/* S3C2442 extended clock support */
+
+static unsigned long s3c2442_camif_upll_round(struct clk *clk,
+ unsigned long rate)
+{
+ unsigned long parent_rate = clk_get_rate(clk->parent);
+ int div;
+
+ if (rate > parent_rate)
+ return parent_rate;
+
+ div = parent_rate / rate;
+
+ if (div == 3)
+ return parent_rate / 3;
+
+ /* note, we remove the +/- 1 calculations for the divisor */
+
+ div /= 2;
+
+ if (div < 1)
+ div = 1;
+ else if (div > 16)
+ div = 16;
+
+ return parent_rate / (div * 2);
+}
+
+static int s3c2442_camif_upll_setrate(struct clk *clk, unsigned long rate)
+{
+ unsigned long parent_rate = clk_get_rate(clk->parent);
+ unsigned long camdivn = __raw_readl(S3C2440_CAMDIVN);
+
+ rate = s3c2442_camif_upll_round(clk, rate);
+
+ camdivn &= ~S3C2442_CAMDIVN_CAMCLK_DIV3;
+
+ if (rate == parent_rate) {
+ camdivn &= ~S3C2440_CAMDIVN_CAMCLK_SEL;
+ } else if ((parent_rate / rate) == 3) {
+ camdivn |= S3C2440_CAMDIVN_CAMCLK_SEL;
+ camdivn |= S3C2442_CAMDIVN_CAMCLK_DIV3;
+ } else {
+ camdivn &= ~S3C2440_CAMDIVN_CAMCLK_MASK;
+ camdivn |= S3C2440_CAMDIVN_CAMCLK_SEL;
+ camdivn |= (((parent_rate / rate) / 2) - 1);
+ }
+
+ __raw_writel(camdivn, S3C2440_CAMDIVN);
+
+ return 0;
+}
+
+/* Extra S3C2442 clocks */
+
+static struct clk s3c2442_clk_cam = {
+ .name = "camif",
+ .id = -1,
+ .enable = s3c24xx_clkcon_enable,
+ .ctrlbit = S3C2440_CLKCON_CAMERA,
+};
+
+static struct clk s3c2442_clk_cam_upll = {
+ .name = "camif-upll",
+ .id = -1,
+ .set_rate = s3c2442_camif_upll_setrate,
+ .round_rate = s3c2442_camif_upll_round,
+};
+
+static int s3c2442_clk_add(struct sys_device *sysdev)
+{
+ unsigned long camdivn = __raw_readl(S3C2440_CAMDIVN);
+ unsigned long clkdivn;
+ struct clk *clk_h;
+ struct clk *clk_p;
+ struct clk *clk_upll;
+
+ printk("S3C2442: Clock Support, DVS %s\n",
+ (camdivn & S3C2440_CAMDIVN_DVSEN) ? "on" : "off");
+
+ clk_p = clk_get(NULL, "pclk");
+ clk_h = clk_get(NULL, "hclk");
+ clk_upll = clk_get(NULL, "upll");
+
+ if (IS_ERR(clk_p) || IS_ERR(clk_h) || IS_ERR(clk_upll)) {
+ printk(KERN_ERR "S3C2442: Failed to get parent clocks\n");
+ return -EINVAL;
+ }
+
+ /* check rate of UPLL, and if it is near 96MHz, then change
+ * to using half the UPLL rate for the system */
+
+ if (clk_get_rate(clk_upll) > (94 * MHZ)) {
+ clk_usb_bus.rate = clk_get_rate(clk_upll) / 2;
+
+ mutex_lock(&clocks_mutex);
+
+ clkdivn = __raw_readl(S3C2410_CLKDIVN);
+ clkdivn |= S3C2440_CLKDIVN_UCLK;
+ __raw_writel(clkdivn, S3C2410_CLKDIVN);
+
+ mutex_unlock(&clocks_mutex);
+ }
+
+ s3c2442_clk_cam.parent = clk_h;
+ s3c2442_clk_cam_upll.parent = clk_upll;
+
+ s3c24xx_register_clock(&s3c2442_clk_cam);
+ s3c24xx_register_clock(&s3c2442_clk_cam_upll);
+
+ clk_disable(&s3c2442_clk_cam);
+
+ return 0;
+}
+
+static struct sysdev_driver s3c2442_clk_driver = {
+ .add = s3c2442_clk_add,
+};
+
+static __init int s3c2442_clk_init(void)
+{
+ return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_clk_driver);
+}
+
+arch_initcall(s3c2442_clk_init);
diff --git a/arch/arm/mach-s3c2410/s3c2442.c b/arch/arm/mach-s3c2410/s3c2442.c
new file mode 100644
index 000000000000..debae2430557
--- /dev/null
+++ b/arch/arm/mach-s3c2410/s3c2442.c
@@ -0,0 +1,52 @@
+/* linux/arch/arm/mach-s3c2410/s3c2440.c
+ *
+ * Copyright (c) 2006 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * Samsung 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
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/sysdev.h>
+#include <linux/clk.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+
+#include <asm/arch/regs-clock.h>
+#include <asm/arch/regs-serial.h>
+#include <asm/arch/regs-gpio.h>
+#include <asm/arch/regs-gpioj.h>
+#include <asm/arch/regs-dsc.h>
+
+#include "s3c2442.h"
+#include "clock.h"
+#include "devs.h"
+#include "cpu.h"
+#include "pm.h"
+
+static struct sys_device s3c2442_sysdev = {
+ .cls = &s3c2442_sysclass,
+};
+
+int __init s3c2442_init(void)
+{
+ printk("S3C2442: Initialising architecture\n");
+
+ return sysdev_register(&s3c2442_sysdev);
+}
diff --git a/arch/arm/mach-s3c2410/s3c2442.h b/arch/arm/mach-s3c2410/s3c2442.h
new file mode 100644
index 000000000000..0ae37d24866c
--- /dev/null
+++ b/arch/arm/mach-s3c2410/s3c2442.h
@@ -0,0 +1,17 @@
+/* arch/arm/mach-s3c2410/s3c2442.h
+ *
+ * Copyright (c) 2006 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * Header file for s3c2442 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_S3C2442
+extern int s3c2442_init(void);
+#else
+#define s3c2442_init NULL
+#endif
diff --git a/arch/arm/mach-s3c2410/s3c244x-irq.c b/arch/arm/mach-s3c2410/s3c244x-irq.c
new file mode 100644
index 000000000000..2aadca1ce7eb
--- /dev/null
+++ b/arch/arm/mach-s3c2410/s3c244x-irq.c
@@ -0,0 +1,142 @@
+/* linux/arch/arm/mach-s3c2410/s3c2440-irq.c
+ *
+ * Copyright (c) 2003,2004 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License 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:
+ * 25-Jul-2005 BJD Split from irq.c
+ *
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/ptrace.h>
+#include <linux/sysdev.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+
+#include <asm/mach/irq.h>
+
+#include <asm/arch/regs-irq.h>
+#include <asm/arch/regs-gpio.h>
+
+#include "cpu.h"
+#include "pm.h"
+#include "irq.h"
+
+/* camera irq */
+
+static void s3c_irq_demux_cam(unsigned int irq,
+ struct irqdesc *desc,
+ struct pt_regs *regs)
+{
+ unsigned int subsrc, submsk;
+ struct irqdesc *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 >>= 11;
+ subsrc &= 3;
+
+ if (subsrc != 0) {
+ if (subsrc & 1) {
+ mydesc = irq_desc + IRQ_S3C2440_CAM_C;
+ desc_handle_irq(IRQ_S3C2440_CAM_C, mydesc, regs);
+ }
+ if (subsrc & 2) {
+ mydesc = irq_desc + IRQ_S3C2440_CAM_P;
+ desc_handle_irq(IRQ_S3C2440_CAM_P, mydesc, regs);
+ }
+ }
+}
+
+#define INTMSK_CAM (1UL << (IRQ_CAM - IRQ_EINT0))
+
+static void
+s3c_irq_cam_mask(unsigned int irqno)
+{
+ s3c_irqsub_mask(irqno, INTMSK_CAM, 3<<11);
+}
+
+static void
+s3c_irq_cam_unmask(unsigned int irqno)
+{
+ s3c_irqsub_unmask(irqno, INTMSK_CAM);
+}
+
+static void
+s3c_irq_cam_ack(unsigned int irqno)
+{
+ s3c_irqsub_maskack(irqno, INTMSK_CAM, 3<<11);
+}
+
+static struct irqchip s3c_irq_cam = {
+ .mask = s3c_irq_cam_mask,
+ .unmask = s3c_irq_cam_unmask,
+ .ack = s3c_irq_cam_ack,
+};
+
+static int s3c244x_irq_add(struct sys_device *sysdev)
+{
+ unsigned int irqno;
+
+ set_irq_chip(IRQ_NFCON, &s3c_irq_level_chip);
+ set_irq_handler(IRQ_NFCON, do_level_IRQ);
+ set_irq_flags(IRQ_NFCON, IRQF_VALID);
+
+ /* add chained handler for camera */
+
+ set_irq_chip(IRQ_CAM, &s3c_irq_level_chip);
+ set_irq_handler(IRQ_CAM, do_level_IRQ);
+ set_irq_chained_handler(IRQ_CAM, s3c_irq_demux_cam);
+
+ for (irqno = IRQ_S3C2440_CAM_C; irqno <= IRQ_S3C2440_CAM_P; irqno++) {
+ set_irq_chip(irqno, &s3c_irq_cam);
+ set_irq_handler(irqno, do_level_IRQ);
+ set_irq_flags(irqno, IRQF_VALID);
+ }
+
+ return 0;
+}
+
+static struct sysdev_driver s3c244x_irq_driver = {
+ .add = s3c244x_irq_add,
+};
+
+static int s3c2440_irq_init(void)
+{
+ return sysdev_driver_register(&s3c2440_sysclass, &s3c244x_irq_driver);
+}
+
+arch_initcall(s3c2440_irq_init);
+
+
+static int s3c2442_irq_init(void)
+{
+ return sysdev_driver_register(&s3c2442_sysclass, &s3c244x_irq_driver);
+}
+
+arch_initcall(s3c2442_irq_init);
diff --git a/arch/arm/mach-s3c2410/s3c244x.c b/arch/arm/mach-s3c2410/s3c244x.c
new file mode 100644
index 000000000000..96852a7000db
--- /dev/null
+++ b/arch/arm/mach-s3c2410/s3c244x.c
@@ -0,0 +1,182 @@
+/* linux/arch/arm/mach-s3c2410/s3c244x.c
+ *
+ * Copyright (c) 2004-2006 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * 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
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/sysdev.h>
+#include <linux/clk.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+
+#include <asm/arch/regs-clock.h>
+#include <asm/arch/regs-serial.h>
+#include <asm/arch/regs-gpio.h>
+#include <asm/arch/regs-gpioj.h>
+#include <asm/arch/regs-dsc.h>
+
+#include "s3c2440.h"
+#include "s3c244x.h"
+#include "clock.h"
+#include "devs.h"
+#include "cpu.h"
+#include "pm.h"
+
+static struct map_desc s3c244x_iodesc[] __initdata = {
+ IODESC_ENT(CLKPWR),
+ IODESC_ENT(TIMER),
+ IODESC_ENT(WATCHDOG),
+ IODESC_ENT(LCD),
+ IODESC_ENT(ADC),
+ IODESC_ENT(USBHOST),
+};
+
+/* uart initialisation */
+
+void __init s3c244x_init_uarts(struct s3c2410_uartcfg *cfg, int no)
+{
+ s3c24xx_init_uartdevs("s3c2440-uart", s3c2410_uart_resources, cfg, no);
+}
+
+void __init s3c244x_map_io(struct map_desc *mach_desc, int size)
+{
+ /* register our io-tables */
+
+ iotable_init(s3c244x_iodesc, ARRAY_SIZE(s3c244x_iodesc));
+ iotable_init(mach_desc, size);
+
+ /* rename any peripherals used differing from the s3c2410 */
+
+ s3c_device_i2c.name = "s3c2440-i2c";
+ s3c_device_nand.name = "s3c2440-nand";
+}
+
+void __init s3c244x_init_clocks(int xtal)
+{
+ unsigned long clkdiv;
+ unsigned long camdiv;
+ unsigned long hclk, fclk, pclk;
+ int hdiv = 1;
+
+ /* now we've got our machine bits initialised, work out what
+ * clocks we've got */
+
+ fclk = s3c2410_get_pll(__raw_readl(S3C2410_MPLLCON), xtal) * 2;
+
+ clkdiv = __raw_readl(S3C2410_CLKDIVN);
+ camdiv = __raw_readl(S3C2440_CAMDIVN);
+
+ /* work out clock scalings */
+
+ switch (clkdiv & S3C2440_CLKDIVN_HDIVN_MASK) {
+ case S3C2440_CLKDIVN_HDIVN_1:
+ hdiv = 1;
+ break;
+
+ case S3C2440_CLKDIVN_HDIVN_2:
+ hdiv = 2;
+ break;
+
+ case S3C2440_CLKDIVN_HDIVN_4_8:
+ hdiv = (camdiv & S3C2440_CAMDIVN_HCLK4_HALF) ? 8 : 4;
+ break;
+
+ case S3C2440_CLKDIVN_HDIVN_3_6:
+ hdiv = (camdiv & S3C2440_CAMDIVN_HCLK3_HALF) ? 6 : 3;
+ break;
+ }
+
+ hclk = fclk / hdiv;
+ pclk = hclk / ((clkdiv & S3C2440_CLKDIVN_PDIVN)? 2:1);
+
+ /* print brief summary of clocks, etc */
+
+ printk("S3C244X: core %ld.%03ld MHz, memory %ld.%03ld MHz, peripheral %ld.%03ld MHz\n",
+ print_mhz(fclk), print_mhz(hclk), print_mhz(pclk));
+
+ /* initialise the clocks here, to allow other things like the
+ * console to use them, and to add new ones after the initialisation
+ */
+
+ s3c24xx_setup_clocks(xtal, fclk, hclk, pclk);
+}
+
+#ifdef CONFIG_PM
+
+static struct sleep_save s3c244x_sleep[] = {
+ SAVE_ITEM(S3C2440_DSC0),
+ SAVE_ITEM(S3C2440_DSC1),
+ SAVE_ITEM(S3C2440_GPJDAT),
+ SAVE_ITEM(S3C2440_GPJCON),
+ SAVE_ITEM(S3C2440_GPJUP)
+};
+
+static int s3c244x_suspend(struct sys_device *dev, pm_message_t state)
+{
+ s3c2410_pm_do_save(s3c244x_sleep, ARRAY_SIZE(s3c244x_sleep));
+ return 0;
+}
+
+static int s3c244x_resume(struct sys_device *dev)
+{
+ s3c2410_pm_do_restore(s3c244x_sleep, ARRAY_SIZE(s3c244x_sleep));
+ return 0;
+}
+
+#else
+#define s3c244x_suspend NULL
+#define s3c244x_resume NULL
+#endif
+
+/* Since the S3C2442 and S3C2440 share items, put both sysclasses here */
+
+struct sysdev_class s3c2440_sysclass = {
+ set_kset_name("s3c2440-core"),
+ .suspend = s3c244x_suspend,
+ .resume = s3c244x_resume
+};
+
+struct sysdev_class s3c2442_sysclass = {
+ set_kset_name("s3c2442-core"),
+ .suspend = s3c244x_suspend,
+ .resume = s3c244x_resume
+};
+
+/* 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 s3c2440 based system)
+ * as a driver which may support both 2410 and 2440 may try and use it.
+*/
+
+static int __init s3c2440_core_init(void)
+{
+ return sysdev_class_register(&s3c2440_sysclass);
+}
+
+core_initcall(s3c2440_core_init);
+
+static int __init s3c2442_core_init(void)
+{
+ return sysdev_class_register(&s3c2442_sysclass);
+}
+
+core_initcall(s3c2442_core_init);
diff --git a/arch/arm/mach-s3c2410/s3c244x.h b/arch/arm/mach-s3c2410/s3c244x.h
new file mode 100644
index 000000000000..3e7f5f75134d
--- /dev/null
+++ b/arch/arm/mach-s3c2410/s3c244x.h
@@ -0,0 +1,25 @@
+/* arch/arm/mach-s3c2410/s3c2440.h
+ *
+ * Copyright (c) 2004-2005 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * Header file for S3C2440 and S3C2442 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.
+*/
+
+#if defined(CONFIG_CPU_S3C2440) || defined(CONFIG_CPU_S3C2442)
+
+extern void s3c244x_map_io(struct map_desc *mach_desc, int size);
+
+extern void s3c244x_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+
+extern void s3c244x_init_clocks(int xtal);
+
+#else
+#define s3c244x_init_clocks NULL
+#define s3c244x_init_uarts NULL
+#define s3c244x_map_io NULL
+#endif
diff --git a/arch/arm/mach-s3c2410/sleep.S b/arch/arm/mach-s3c2410/sleep.S
index 73de2eaca22a..5f6761ed96b2 100644
--- a/arch/arm/mach-s3c2410/sleep.S
+++ b/arch/arm/mach-s3c2410/sleep.S
@@ -66,7 +66,9 @@ ENTRY(s3c2410_cpu_suspend)
@@ flush the caches to ensure everything is back out to
@@ SDRAM before the core powers down
+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
bl arm920_flush_kern_cache_all
+#endif
@@ prepare cpu to sleep
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index c55b739e10ba..1ff2f073a55d 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -121,8 +121,8 @@ config CPU_ARM925T
# ARM926T
config CPU_ARM926T
bool "Support ARM926T processor"
- depends on ARCH_INTEGRATOR || ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || MACH_REALVIEW_EB
- default y if ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX
+ depends on ARCH_INTEGRATOR || ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || MACH_REALVIEW_EB || ARCH_PNX4008
+ default y if ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || ARCH_PNX4008
select CPU_32v5
select CPU_ABRT_EV5TJ
select CPU_CACHE_VIVT