Makefile                                 |    7 
 arch/arm/Kconfig                         |   10 
 arch/arm/common/dmabounce.c              |   23 -
 arch/arm/configs/cm_x270_defconfig       | 1312 ++++++++++++++++++++++++++++++
 arch/arm/kernel/bios32.c                 |   36 +
 arch/arm/kernel/vmlinux.lds.S            |    4 
 arch/arm/mach-pxa/Kconfig                |   16 
 arch/arm/mach-pxa/Makefile               |    9 
 arch/arm/mach-pxa/cm-x270-pci.c          |  152 +++
 arch/arm/mach-pxa/cm-x270.c              |  975 ++++++++++++++++++++++
 arch/arm/mach-pxa/it8152.c               |  248 ++++++
 arch/arm/mach-pxa/leds-cm-x270.c         |  134 +++
 arch/arm/mach-pxa/leds.c                 |    2 
 arch/arm/mach-pxa/leds.h                 |    1 
 arch/arm/mach-pxa/pxa27x.c               |    6 
 drivers/block/Kconfig                    |    5 
 drivers/block/Makefile                   |    1 
 drivers/block/cl_flash/CL_Logic.h        |  245 ++++++
 drivers/block/cl_flash/Kconfig           |   11 
 drivers/block/cl_flash/Makefile          |   12 
 drivers/block/cl_flash/cl_blkdev.c       |  731 +++++++++++++++++
 drivers/block/cl_flash/cl_blkdev.h       |   43 +
 drivers/block/cl_flash/cl_common.c       |   52 +
 drivers/block/cl_flash/cl_nanddev_x270.c |  233 +++++
 drivers/block/cl_flash/cl_nordev.c       |  594 ++++++++++++++
 drivers/char/Kconfig                     |    6 
 drivers/char/Makefile                    |    1 
 drivers/char/emv3020.c                   |  365 ++++++++
 drivers/ide/Kconfig                      |    7 
 drivers/ide/arm/Makefile                 |    1 
 drivers/ide/arm/cm-x270-ide.c            |  135 +++
 drivers/mfd/Kconfig                      |   10 
 drivers/mfd/Makefile                     |    7 
 drivers/mfd/mcp-ac97.c                   |  151 +++
 drivers/mfd/mcp-core.c                   |    1 
 drivers/mfd/mcp.h                        |    9 
 drivers/mfd/ucb1x00-core.c               |  127 ++-
 drivers/mfd/ucb1x00-ts.c                 |   44 +
 drivers/mfd/ucb1x00.h                    |    4 
 drivers/mtd/nand/Kconfig                 |    4 
 drivers/mtd/nand/Makefile                |    1 
 drivers/mtd/nand/cmx270-nand.c           |  281 ++++++
 drivers/net/Kconfig                      |    8 
 drivers/net/dm9000.c                     |   11 
 drivers/pcmcia/Makefile                  |    2 
 drivers/pcmcia/pxa2xx_cm_x270.c          |  198 +++++
 drivers/serial/pxa.c                     |   55 +
 drivers/video/Kconfig                    |   10 
 drivers/video/Makefile                   |    1 
 drivers/video/mbx/Makefile               |    7 
 drivers/video/mbx/mbxfb.c                |  659 +++++++++++++++
 drivers/video/mbx/mbxsysfs.c             |  129 +++
 drivers/video/mbx/reg_bits.h             |  489 +++++++++++
 drivers/video/mbx/regs.h                 |  192 ++++
 drivers/video/pxafb.c                    |  104 ++
 include/asm-arm/arch-pxa/cm-x270.h       |   72 ++
 include/asm-arm/arch-pxa/hardware.h      |   11 
 include/asm-arm/arch-pxa/irqs.h          |   24 +
 include/asm-arm/arch-pxa/marathonfb.h    |   28 +
 include/asm-arm/arch-pxa/memory.h        |   13 
 include/asm-arm/arch-pxa/pxafbsetup.h    |   39 +
 include/asm-arm/hardware/it8152.h        |  104 ++
 include/linux/pci_ids.h                  |    1 
 sound/pci/ac97/ac97_codec.c              |    2 
 sound/pci/ac97/ac97_patch.c              |   30 +
 sound/pci/ac97/ac97_patch.h              |    1 
 66 files changed, 8115 insertions(+), 91 deletions(-)

diff --git a/Makefile b/Makefile
index cb57905..dd02f27 100644
--- a/Makefile
+++ b/Makefile
@@ -172,8 +172,11 @@ # Alternatively CROSS_COMPILE can be set
 # Default value for CROSS_COMPILE is not to prefix executables
 # Note: Some architectures assign CROSS_COMPILE in their arch/*/Makefile
 
-ARCH		?= $(SUBARCH)
-CROSS_COMPILE	?=
+#ARCH		?= $(SUBARCH)
+#CROSS_COMPILE	?=
+
+ARCH		= arm
+CROSS_COMPILE	= arm-linux-
 
 # Architecture as present in compile.h
 UTS_MACHINE := $(ARCH)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 32ba00b..2de9ceb 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -331,7 +331,7 @@ config ISA_DMA_API
 	bool
 
 config PCI
-	bool "PCI support" if ARCH_INTEGRATOR_AP || ARCH_VERSATILE_PB
+	bool "PCI support" if ARCH_INTEGRATOR_AP || ARCH_VERSATILE_PB || MACH_ARMCORE
 	help
 	  Find out whether you have a PCI motherboard. PCI is the name of a
 	  bus system, i.e. the way the CPU talks to the other stuff inside
@@ -349,6 +349,12 @@ config PCI_HOST_VIA82C505
 	depends on PCI && ARCH_SHARK
 	default y
 
+config PCI_HOST_ITE8152
+	bool
+	depends on PCI && MACH_ARMCORE
+	default y
+	select DMABOUNCE
+
 source "drivers/pci/Kconfig"
 
 source "drivers/pcmcia/Kconfig"
@@ -484,7 +490,7 @@ config LEDS
 		   ARCH_LUBBOCK || MACH_MAINSTONE || ARCH_NETWINDER || \
 		   ARCH_OMAP || ARCH_P720T || ARCH_PXA_IDP || \
 		   ARCH_SA1100 || ARCH_SHARK || ARCH_VERSATILE || \
-		   ARCH_AT91RM9200
+		   ARCH_AT91RM9200 || MACH_ARMCORE
 	help
 	  If you say Y here, the LEDs on your machine will be used
 	  to provide useful information about your current system status.
diff --git a/arch/arm/common/dmabounce.c b/arch/arm/common/dmabounce.c
index ad6c89a..dc2bbd0 100644
--- a/arch/arm/common/dmabounce.c
+++ b/arch/arm/common/dmabounce.c
@@ -235,7 +235,7 @@ map_single(struct device *dev, void *ptr
 		/*
 		 * Figure out if we need to bounce from the DMA mask.
 		 */
-		needs_bounce = (dma_addr | (dma_addr + size - 1)) & ~mask;
+		needs_bounce = ((dma_addr | (dma_addr + size - 1)) - PHYS_OFFSET) & ~mask;
 	}
 
 	if (device_info && (needs_bounce || dma_needs_bounce(dev, dma_addr, size))) {
@@ -275,6 +275,7 @@ unmap_single(struct device *dev, dma_add
 {
 	struct dmabounce_device_info *device_info = find_dmabounce_dev(dev);
 	struct safe_buffer *buf = NULL;
+	unsigned long flags;
 
 	/*
 	 * Trying to unmap an invalid mapping
@@ -284,6 +285,8 @@ unmap_single(struct device *dev, dma_add
 		return;
 	}
 
+	local_irq_save(flags);
+
 	if (device_info)
 		buf = find_safe_buffer(device_info, dma_addr);
 
@@ -316,8 +319,11 @@ unmap_single(struct device *dev, dma_add
 			ptr = (unsigned long)buf->ptr;
 			dmac_clean_range(ptr, ptr + size);
 		}
+		local_irq_restore(flags);
 		free_safe_buffer(device_info, buf);
 	}
+	else
+		local_irq_restore(flags);
 }
 
 static inline void
@@ -424,18 +430,12 @@ void
 dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
 			enum dma_data_direction dir)
 {
-	unsigned long flags;
-
 	dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n",
 		__func__, (void *) dma_addr, size, dir);
 
 	BUG_ON(dir == DMA_NONE);
 
-	local_irq_save(flags);
-
 	unmap_single(dev, dma_addr, size, dir);
-
-	local_irq_restore(flags);
 }
 
 int
@@ -471,7 +471,6 @@ void
 dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
 		enum dma_data_direction dir)
 {
-	unsigned long flags;
 	int i;
 
 	dev_dbg(dev, "%s(sg=%p,nents=%d,dir=%x)\n",
@@ -479,16 +478,12 @@ dma_unmap_sg(struct device *dev, struct 
 
 	BUG_ON(dir == DMA_NONE);
 
-	local_irq_save(flags);
-
 	for (i = 0; i < nents; i++, sg++) {
 		dma_addr_t dma_addr = sg->dma_address;
 		unsigned int length = sg->length;
 
 		unmap_single(dev, dma_addr, length, dir);
 	}
-
-	local_irq_restore(flags);
 }
 
 void
@@ -632,7 +627,7 @@ #endif
 	list_add(&device_info->node, &dmabounce_devs);
 
 	printk(KERN_INFO "dmabounce: registered device %s on %s bus\n",
-		dev->bus_id, dev->bus->name);
+	       dev->bus_id, dev->bus ? dev->bus->name : "no");
 
 	return 0;
 
@@ -677,7 +672,7 @@ #endif
 	kfree(device_info);
 
 	printk(KERN_INFO "dmabounce: device %s on %s bus unregistered\n",
-		dev->bus_id, dev->bus->name);
+	       dev->bus_id, dev->bus ? dev->bus->name : "no");
 }
 
 
diff --git a/arch/arm/configs/cm_x270_defconfig b/arch/arm/configs/cm_x270_defconfig
new file mode 100644
index 0000000..f87d617
--- /dev/null
+++ b/arch/arm/configs/cm_x270_defconfig
@@ -0,0 +1,1312 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.16
+# Tue Sep 26 10:07:36 2006
+#
+CONFIG_ARM=y
+CONFIG_MMU=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ARCH_MTD_XIP=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION="-cm-x270"
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+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_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
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_OBSOLETE_MODPARM=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+
+#
+# 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_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_L7200 is not set
+CONFIG_ARCH_PXA=y
+# 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
+
+#
+# Intel PXA2xx Implementations
+#
+# CONFIG_ARCH_LUBBOCK is not set
+# CONFIG_MACH_MAINSTONE is not set
+CONFIG_MACH_ARMCORE=y
+# CONFIG_ARCH_PXA_IDP is not set
+# CONFIG_PXA_SHARPSL is not set
+CONFIG_ARMCORE_REV12=y
+# CONFIG_ARMCORE_REV11 is not set
+CONFIG_PXA27x=y
+CONFIG_IWMMXT=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_XSCALE=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5T=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_TLB_V4WBI=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+CONFIG_XSCALE_PMU=y
+CONFIG_DMABOUNCE=y
+
+#
+# Bus support
+#
+CONFIG_PCI=y
+CONFIG_PCI_HOST_ITE8152=y
+# CONFIG_PCI_LEGACY_PROC is not set
+# CONFIG_PCI_DEBUG is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+CONFIG_PCCARD=y
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_PCMCIA=m
+# CONFIG_PCMCIA_LOAD_CIS is not set
+CONFIG_PCMCIA_IOCTL=y
+CONFIG_CARDBUS=y
+
+#
+# PC-card bridges
+#
+CONFIG_YENTA=m
+CONFIG_YENTA_O2=y
+CONFIG_YENTA_RICOH=y
+CONFIG_YENTA_TI=y
+CONFIG_YENTA_ENE_TUNE=y
+CONFIG_YENTA_TOSHIBA=y
+# CONFIG_PD6729 is not set
+# CONFIG_I82092 is not set
+CONFIG_PCMCIA_PXA2XX=m
+CONFIG_PCCARD_NONSTATIC=m
+
+#
+# Kernel Features
+#
+# CONFIG_PREEMPT is not set
+# CONFIG_NO_IDLE_HZ is not set
+# 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_LEDS=y
+CONFIG_LEDS_TIMER=y
+CONFIG_LEDS_CPU=y
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE=""
+# CONFIG_XIP_KERNEL is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_ARTHUR is not set
+
+#
+# Power management options
+#
+CONFIG_PM=y
+CONFIG_PM_LEGACY=y
+# CONFIG_PM_DEBUG 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 is not set
+# 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=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+# CONFIG_IEEE80211_CRYPT_TKIP is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_DEBUG_DRIVER is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=12000
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+CONFIG_ARMCORE_FLASH=y
+# CONFIG_ARMCORE_NOR is not set
+CONFIG_ARMCORE_NAND=y
+
+#
+# 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 is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+CONFIG_BLK_DEV_IDESCSI=m
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=m
+# CONFIG_BLK_DEV_IDEPCI is not set
+# CONFIG_IDE_ARM is not set
+CONFIG_BLK_DEV_IDE_CM_X270=m
+# 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=y
+# CONFIG_SCSI_PROC_FS is not set
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# 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
+# CONFIG_CHR_DEV_SCH 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
+# CONFIG_SCSI_SAS_ATTRS is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_SYM53C8XX_2 is not set
+# CONFIG_SCSI_IPR is not set
+# CONFIG_SCSI_QLOGIC_FC is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_LPFC is not set
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# PCMCIA SCSI adapter support
+#
+# CONFIG_PCMCIA_AHA152X is not set
+# CONFIG_PCMCIA_FDOMAIN is not set
+# CONFIG_PCMCIA_NINJA_SCSI is not set
+# CONFIG_PCMCIA_QLOGIC is not set
+# CONFIG_PCMCIA_SYM53C500 is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
+# CONFIG_FUSION_SAS is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_SMC91X is not set
+CONFIG_DM9000=y
+CONFIG_DM9000_NOEPROM=y
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_AMD8111_ETH is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_B44 is not set
+# CONFIG_FORCEDETH is not set
+# CONFIG_DGRS is not set
+# CONFIG_EEPRO100 is not set
+# CONFIG_E100 is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_8139CP is not set
+CONFIG_8139TOO=m
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_OLD_RX_RESET is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_VIA_RHINE is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_VIA_VELOCITY is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_CHELSIO_T1 is not set
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+CONFIG_NET_RADIO=y
+
+#
+# Obsolete Wireless cards support (pre-802.11)
+#
+# CONFIG_STRIP is not set
+# CONFIG_PCMCIA_WAVELAN is not set
+# CONFIG_PCMCIA_NETWAVE is not set
+
+#
+# Wireless 802.11 Frequency Hopping cards support
+#
+# CONFIG_PCMCIA_RAYCS is not set
+
+#
+# Wireless 802.11b ISA/PCI cards support
+#
+# CONFIG_IPW2100 is not set
+# CONFIG_IPW2200 is not set
+# CONFIG_HERMES is not set
+# CONFIG_ATMEL is not set
+
+#
+# Wireless 802.11b Pcmcia/Cardbus cards support
+#
+# CONFIG_AIRO_CS is not set
+# CONFIG_PCMCIA_WL3501 is not set
+
+#
+# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
+#
+# CONFIG_PRISM54 is not set
+# CONFIG_HOSTAP is not set
+CONFIG_NET_WIRELESS=y
+
+#
+# PCMCIA network device support
+#
+CONFIG_NET_PCMCIA=y
+# CONFIG_PCMCIA_3C589 is not set
+# CONFIG_PCMCIA_3C574 is not set
+# CONFIG_PCMCIA_FMVJ18X is not set
+CONFIG_PCMCIA_PCNET=m
+# CONFIG_PCMCIA_NMCLAN is not set
+# CONFIG_PCMCIA_SMC91C92 is not set
+# CONFIG_PCMCIA_XIRC2PS is not set
+# CONFIG_PCMCIA_AXNET is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NET_FC 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
+#
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+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_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+# CONFIG_SERIAL_8250_CONSOLE is not set
+# CONFIG_SERIAL_8250_CS is not set
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_PXA=y
+CONFIG_SERIAL_PXA_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_DRM is not set
+
+#
+# PCMCIA character devices
+#
+# CONFIG_SYNCLINK_CS is not set
+# CONFIG_CARDMAN_4000 is not set
+# CONFIG_CARDMAN_4040 is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+CONFIG_EMV3020_RTC=y
+
+#
+# I2C support
+#
+# 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 is not set
+# CONFIG_HWMON_VID is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia Capabilities Port drivers
+#
+CONFIG_UCB1400=m
+CONFIG_UCB1400_TS=m
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+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_CIRRUS is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_NVIDIA is not set
+# CONFIG_FB_RIVA is not set
+# CONFIG_FB_MATROX is not set
+# CONFIG_FB_RADEON_OLD is not set
+# CONFIG_FB_RADEON is not set
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_SAVAGE is not set
+# CONFIG_FB_SIS is not set
+# CONFIG_FB_NEOMAGIC is not set
+# CONFIG_FB_KYRO is not set
+# CONFIG_FB_3DFX is not set
+# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_TRIDENT is not set
+CONFIG_FB_PXA=y
+# CONFIG_FB_PXA_PARAMETERS is not set
+CONFIG_FB_MBX=m
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+
+#
+# Logo configuration
+#
+CONFIG_LOGO=y
+CONFIG_LOGO_LINUX_MONO=y
+CONFIG_LOGO_LINUX_VGA16=y
+CONFIG_LOGO_LINUX_CLUT224=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+CONFIG_SOUND=m
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+# CONFIG_SND_SEQUENCER is not set
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+# 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=m
+CONFIG_SND_AC97_BUS=m
+# 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
+
+#
+# PCI devices
+#
+# CONFIG_SND_AD1889 is not set
+# CONFIG_SND_ALI5451 is not set
+# CONFIG_SND_ATIIXP is not set
+# CONFIG_SND_ATIIXP_MODEM is not set
+# CONFIG_SND_AU8810 is not set
+# CONFIG_SND_AU8820 is not set
+# CONFIG_SND_AU8830 is not set
+# CONFIG_SND_AZT3328 is not set
+# CONFIG_SND_BT87X is not set
+# CONFIG_SND_CA0106 is not set
+# CONFIG_SND_CMIPCI is not set
+# CONFIG_SND_CS4281 is not set
+# CONFIG_SND_CS46XX is not set
+# CONFIG_SND_EMU10K1 is not set
+# CONFIG_SND_EMU10K1X is not set
+# CONFIG_SND_ENS1370 is not set
+# CONFIG_SND_ENS1371 is not set
+# CONFIG_SND_ES1938 is not set
+# CONFIG_SND_ES1968 is not set
+# CONFIG_SND_FM801 is not set
+# CONFIG_SND_HDA_INTEL is not set
+# CONFIG_SND_HDSP is not set
+# CONFIG_SND_HDSPM is not set
+# CONFIG_SND_ICE1712 is not set
+# CONFIG_SND_ICE1724 is not set
+# CONFIG_SND_INTEL8X0 is not set
+# CONFIG_SND_INTEL8X0M is not set
+# CONFIG_SND_KORG1212 is not set
+# CONFIG_SND_MAESTRO3 is not set
+# CONFIG_SND_MIXART is not set
+# CONFIG_SND_NM256 is not set
+# CONFIG_SND_PCXHR is not set
+# CONFIG_SND_RME32 is not set
+# CONFIG_SND_RME96 is not set
+# CONFIG_SND_RME9652 is not set
+# CONFIG_SND_SONICVIBES is not set
+# CONFIG_SND_TRIDENT is not set
+# CONFIG_SND_VIA82XX is not set
+# CONFIG_SND_VIA82XX_MODEM is not set
+# CONFIG_SND_VX222 is not set
+# CONFIG_SND_YMFPCI is not set
+
+#
+# ALSA ARM devices
+#
+CONFIG_SND_PXA2XX_PCM=m
+CONFIG_SND_PXA2XX_AC97=m
+
+#
+# USB devices
+#
+# CONFIG_SND_USB_AUDIO is not set
+
+#
+# PCMCIA devices
+#
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_BANDWIDTH is not set
+# 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_EHCI_HCD is not set
+# 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
+# CONFIG_USB_UHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# 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
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# 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_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
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB Multimedia devices
+#
+# CONFIG_USB_DABUSB is not set
+
+#
+# Video4Linux support is needed for USB Multimedia device support
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_USB_ZD1201 is not set
+CONFIG_USB_MON=y
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYTHERM is not set
+# 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 DSL modem support
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+CONFIG_MMC=m
+# CONFIG_MMC_DEBUG is not set
+CONFIG_MMC_BLOCK=m
+CONFIG_MMC_PXA=m
+
+#
+# File systems
+#
+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
+# CONFIG_EXT3_FS_SECURITY is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# 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
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# CONFIG_RELAYFS_FS is not set
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+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
+CONFIG_SMB_FS=y
+# CONFIG_SMB_NLS_DEFAULT is not set
+# CONFIG_CIFS is not set
+# 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
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_LOG_BUF_SHIFT=17
+# CONFIG_DETECT_SOFTLOCKUP is not set
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# 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_FORCED_INLINING=y
+# CONFIG_RCU_TORTURE_TEST is not set
+CONFIG_DEBUG_USER=y
+# CONFIG_DEBUG_WAITQ is not set
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_ICEDCC is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+# CONFIG_CRYPTO_SERPENT is not set
+CONFIG_CRYPTO_AES=m
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_TEA is not set
+CONFIG_CRYPTO_ARC4=m
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
index c4923fa..4ff2a62 100644
--- a/arch/arm/kernel/bios32.c
+++ b/arch/arm/kernel/bios32.c
@@ -280,6 +280,34 @@ static void __devinit pci_fixup_cy82c693
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_CONTAQ, PCI_DEVICE_ID_CONTAQ_82C693, pci_fixup_cy82c693);
 
+static void __init pci_fixup_it8152(struct pci_dev *dev) 
+{
+	int i;
+	if ((dev->class >> 8) == PCI_CLASS_BRIDGE_HOST) {
+		for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+			dev->resource[i].start = 0;
+			dev->resource[i].end   = 0;
+			dev->resource[i].flags = 0;
+		}
+	}
+	if (dev->class == 0x68000) {
+		for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+			dev->resource[i].start = 0;
+			dev->resource[i].end   = 0;
+			dev->resource[i].flags = 0;
+		}
+	}
+	if (dev->class == 0x80103) {
+		for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+			dev->resource[i].start = 0;
+			dev->resource[i].end   = 0;
+			dev->resource[i].flags = 0;
+		}
+	}
+}	
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ITE, PCI_DEVICE_ID_ITE_IT8152, pci_fixup_it8152);
+
+
 void __devinit pcibios_update_irq(struct pci_dev *dev, int irq)
 {
 	if (debug_pci)
@@ -293,9 +321,11 @@ void __devinit pcibios_update_irq(struct
  */
 static inline int pdev_bad_for_parity(struct pci_dev *dev)
 {
-	return (dev->vendor == PCI_VENDOR_ID_INTERG &&
-		(dev->device == PCI_DEVICE_ID_INTERG_2000 ||
-		 dev->device == PCI_DEVICE_ID_INTERG_2010));
+	return ((dev->vendor == PCI_VENDOR_ID_INTERG &&
+		 (dev->device == PCI_DEVICE_ID_INTERG_2000 ||
+		  dev->device == PCI_DEVICE_ID_INTERG_2010)) ||
+		(dev->vendor == PCI_VENDOR_ID_ITE &&
+		 dev->device == PCI_DEVICE_ID_ITE_IT8152));
 }
 
 /*
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
index 2b254e8..310ccf5 100644
--- a/arch/arm/kernel/vmlinux.lds.S
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -175,5 +175,5 @@ #endif
  * If you have to comment these two assert statements out, your
  * binutils is too old (for other reasons as well)
  */
-ASSERT((__proc_info_end - __proc_info_begin), "missing CPU support")
-ASSERT((__arch_info_end - __arch_info_begin), "no machine record defined")
+/* ASSERT((__proc_info_end - __proc_info_begin), "missing CPU support") */
+/* ASSERT((__arch_info_end - __arch_info_begin), "no machine record defined") */
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig
index c1d77f5..0a62a62 100644
--- a/arch/arm/mach-pxa/Kconfig
+++ b/arch/arm/mach-pxa/Kconfig
@@ -15,6 +15,11 @@ config MACH_MAINSTONE
 	select PXA27x
 	select IWMMXT
 
+config MACH_ARMCORE
+	bool "CompuLab CM-X270 modules"
+	select PXA27x
+	select IWMMXT
+
 config ARCH_PXA_IDP
 	bool "Accelent Xscale IDP"
 	select PXA25x
@@ -50,6 +55,17 @@ endchoice
 
 endif
 
+if MACH_ARMCORE
+choice
+	prompt "Select CM-X270 revision"
+	config ARMCORE_REV12
+	bool "CM-X270 revision 1.2"
+	config ARMCORE_REV11
+	bool "CM-X270 revision 1.1"
+endchoice
+
+endif
+
 endmenu
 
 config MACH_POODLE
diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile
index 32526a0..d78d061 100644
--- a/arch/arm/mach-pxa/Makefile
+++ b/arch/arm/mach-pxa/Makefile
@@ -16,12 +16,14 @@ obj-$(CONFIG_PXA_SHARP_Cxx00)	+= spitz.o
 obj-$(CONFIG_MACH_AKITA)	+= akita-ioexp.o
 obj-$(CONFIG_MACH_POODLE)	+= poodle.o
 obj-$(CONFIG_MACH_TOSA)         += tosa.o
+obj-$(CONFIG_MACH_ARMCORE) += cm-x270.o
 
 # Support for blinky lights
 led-y := leds.o
 led-$(CONFIG_ARCH_LUBBOCK) += leds-lubbock.o
 led-$(CONFIG_MACH_MAINSTONE) += leds-mainstone.o
 led-$(CONFIG_ARCH_PXA_IDP) += leds-idp.o
+led-$(CONFIG_MACH_ARMCORE) += leds-cm-x270.o
 
 obj-$(CONFIG_LEDS) += $(led-y)
 
@@ -32,3 +34,10 @@ obj-$(CONFIG_PXA_SSP) += ssp.o
 ifeq ($(CONFIG_PXA27x),y)
 obj-$(CONFIG_PM) += standby.o
 endif
+
+# PCI support on CM-X270
+obj-$(CONFIG_PCI_HOST_ITE8152) += it8152.o
+
+ifeq ($(CONFIG_PCI),y)
+obj-$(CONFIG_MACH_ARMCORE) += cm-x270-pci.o
+endif
diff --git a/arch/arm/mach-pxa/cm-x270-pci.c b/arch/arm/mach-pxa/cm-x270-pci.c
new file mode 100644
index 0000000..73243d3
--- /dev/null
+++ b/arch/arm/mach-pxa/cm-x270-pci.c
@@ -0,0 +1,152 @@
+/*
+ * arch/arm/kernel/cm-x270-pci.c
+ *
+ * PCI bios-type initialisation for PCI machines
+ *
+ * Bits taken from various places.
+ *
+ * Copyright (C) 2006 Compulab, Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+
+#include <asm/irq.h>
+#include <asm/mach/pci.h>
+#include <asm/arch/cm-x270.h>
+#include <asm/mach-types.h>
+
+#include <asm/hardware/it8152.h>
+
+unsigned long armcore_pcibios_min_mem = 0x10000000;
+unsigned long armcore_pcibios_min_io = CMX270_IT8152_VIRT + 0x03e00000 + 0x120000;
+unsigned long it8152_base_address = CMX270_IT8152_VIRT;
+
+/* these symbols needed for CardBus driver (yenta_socket) */
+EXPORT_SYMBOL(armcore_pcibios_min_io);
+EXPORT_SYMBOL(armcore_pcibios_min_mem);
+
+static u8 __init cmx270_pci_swizzle(struct pci_dev *dev, u8 *pin)
+{
+	return PCI_SLOT(dev->devfn);
+}
+
+/* Platform specific IRQ mapping */
+static int __init cmx270_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	if((dev->vendor==0x1283) && (dev->device==0x8152) &&
+	   ((dev->class >> 8)==0x801)) return(CDMA_INT);
+	if((dev->vendor==0x1283) && (dev->device==0x0801) &&
+	   ((dev->class >> 8)==0x401)) return(AUDIO_INT);
+	if((dev->vendor==0x1283) && (dev->device==0x8152) &&
+	   ((dev->class >> 8)==0xc03)) return(USB_INT);
+
+	/* ATXBASE PCI slot */
+	if ( slot == 7 )
+		return(PCI_INTA);
+
+	/* ATXBASE/SB-X270 CardBus */
+	if ( (slot == 8) || (slot == 0) )
+		return(PCI_INTB);
+
+	/* ATXBASE ETH */
+	if ( slot == 9 )
+		return(PCI_INTA);
+
+	/* ARMCore onboard ETH */
+	if ( slot == 15 )
+		return(PCI_INTC);
+
+	/* ARMBase ETH */
+	if ( slot == 16 )
+		return(PCI_INTA);
+
+	/* PC104+ interrupt routing */
+	if ( (slot == 17) || (slot == 19) )
+		return(PCI_INTA);
+	if ( (slot == 18) || (slot == 20) )
+		return(PCI_INTB);
+   
+	return(0);
+}
+
+extern int it8152_pci_setup(int nr, struct pci_sys_data *sys);
+extern struct pci_bus * it8152_pci_scan_bus(int nr, struct pci_sys_data *sys);
+
+static struct pci_bus* __init cmx270_pci_scan_bus(int nr, struct pci_sys_data *sys)
+{
+	IT8152_PCI_CFG_ADDR	= 0x800;
+	if(IT8152_PCI_CFG_DATA == 0x81521283) {
+		printk("PCI Bridge found.\n");
+
+		IT8152_GPIO_GPLR=0x20;
+
+/***********	CardBus Controller on ATXBASE configuration	********/		
+		IT8152_PCI_CFG_ADDR	= 0x4000;
+		if(IT8152_PCI_CFG_DATA == 0xAC51104C) {
+			unsigned int temp;
+			printk("CardBus Bridge found.\n");
+
+			// Configure socket 0
+			IT8152_PCI_CFG_ADDR	= 0x408C;
+			IT8152_PCI_CFG_DATA = 0x1022;
+
+			IT8152_PCI_CFG_ADDR	= 0x4080;
+			IT8152_PCI_CFG_DATA = 0x3844d060;
+
+			IT8152_PCI_CFG_ADDR	= 0x4090;
+			temp = IT8152_PCI_CFG_DATA;
+			temp = temp & 0xFFFF;
+			temp = temp | (0x60440000);
+			IT8152_PCI_CFG_ADDR	= 0x4090;
+			IT8152_PCI_CFG_DATA = temp;
+
+			IT8152_PCI_CFG_ADDR	= 0x4018;
+			IT8152_PCI_CFG_DATA = 0xb0000000;
+
+			// Configure socket 1
+			IT8152_PCI_CFG_ADDR	= 0x418C;
+			IT8152_PCI_CFG_DATA = 0x1022;
+
+			IT8152_PCI_CFG_ADDR	= 0x4180;
+			IT8152_PCI_CFG_DATA = 0x3844d060;
+
+			IT8152_PCI_CFG_ADDR	= 0x4190;
+			temp = IT8152_PCI_CFG_DATA;
+			temp = temp & 0xFFFF;
+			temp = temp | (0x60440000);
+			IT8152_PCI_CFG_ADDR	= 0x4190;
+			IT8152_PCI_CFG_DATA = temp;
+
+			IT8152_PCI_CFG_ADDR	= 0x4118;
+			IT8152_PCI_CFG_DATA = 0xb0000000;  
+ 		}
+/***********	End of CardBus controller configuration	**************/
+	}
+	return it8152_pci_scan_bus(nr, sys);
+}
+
+static struct hw_pci cmx270_pci __initdata = {
+	.swizzle		= cmx270_pci_swizzle,
+	.map_irq		= cmx270_pci_map_irq,
+	.nr_controllers		= 1,
+	.setup			= it8152_pci_setup,
+	.scan			= cmx270_pci_scan_bus,
+};
+
+static int __init cmx270_init_pci(void)
+{
+	if (machine_is_armcore()) {
+		pci_common_init(&cmx270_pci);
+	}
+	return 0;
+}
+
+subsys_initcall(cmx270_init_pci);
diff --git a/arch/arm/mach-pxa/cm-x270.c b/arch/arm/mach-pxa/cm-x270.c
new file mode 100644
index 0000000..b006a8f
--- /dev/null
+++ b/arch/arm/mach-pxa/cm-x270.c
@@ -0,0 +1,975 @@
+/*
+ * linux/arch/arm/mach-pxa/cm-x270.c
+ *
+ * Copyright (C) 2006 CompuLab, Ltd.
+ *
+ * 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/pm.h>
+#include <linux/fb.h>
+#include <linux/platform_device.h>
+#include <linux/sysdev.h>
+#include <linux/dm9000.h>
+#include <linux/serial_8250.h>
+
+#include <asm/types.h>
+#include <asm/setup.h>
+#include <asm/memory.h>
+#include <asm/mach-types.h>
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/delay.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/arch/pxa-regs.h>
+#include <asm/arch/irq.h>
+#include <asm/arch/pxafb.h>
+#include <asm/arch/marathonfb.h>
+#include <asm/arch/ohci.h>
+#include <asm/arch/mmc.h>
+#include <asm/arch/pxafbsetup.h>
+#include <asm/arch/bitfield.h>
+#include <asm/arch/cm-x270.h>
+
+#include <asm/hardware/it8152.h>
+
+#include "generic.h"
+
+#define RTC_PHYS_BASE		(PXA_CS1_PHYS + (5 << 22))
+#define DM9000_PHYS_BASE	(PXA_CS1_PHYS + (6 << 22))
+
+static struct resource cmx270_dm9k_resource[] = {
+	[0] = {
+		.start = DM9000_PHYS_BASE,
+		.end   = DM9000_PHYS_BASE + 4,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = DM9000_PHYS_BASE + 8,
+		.end   = DM9000_PHYS_BASE + 8 + 500,
+		.flags = IORESOURCE_MEM,
+	},
+	[2] = {
+		.start = CMX270_ETHIRQ,
+		.end   = CMX270_ETHIRQ,
+		.flags = IORESOURCE_IRQ,
+	}
+};
+
+/* for the moment we limit ourselves to 32bit IO until some
+ * better IO routines can be written and tested
+ */
+static struct dm9000_plat_data cmx270_dm9k_platdata = {
+	.flags		= DM9000_PLATF_32BITONLY,
+};
+
+/* Ethernet device */
+static struct platform_device cmx270_device_dm9k = {
+	.name		= "dm9000",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(cmx270_dm9k_resource),
+	.resource	= cmx270_dm9k_resource,
+	.dev		= {
+		.platform_data = &cmx270_dm9k_platdata,
+	}
+};
+
+/* audio device */
+static struct platform_device cmx270_audio_device = {
+	.name		= "pxa2xx-ac97",
+	.id		= -1,
+};
+
+/* touchscreen controller */
+static struct platform_device cmx270_ts_device = {
+	.name		= "ucb1x00",
+	.id		= -1,
+};
+
+/* RTC */
+static struct resource cmx270_v3020_resource[] = {
+	[0] = {
+		.start = RTC_PHYS_BASE,
+		.end   = RTC_PHYS_BASE + 4,
+		.flags = IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device cmx270_rtc_device = {
+	.name		= "emv3020-rtc",
+	.num_resources	= ARRAY_SIZE(cmx270_v3020_resource),
+	.resource	= cmx270_v3020_resource,
+	.id		= -1,
+};
+
+/* UART on the ITE8152 chip */
+#ifdef CONFIG_PCI
+static struct plat_serial8250_port ite_uart_port[] = {
+	{
+		.irq		= IRQ_ITESER,		/* interrupt number */
+		.uartclk	= 115200 * 16,	/* UART clock rate */
+		.iotype		= UPIO_MEM,		/* UPIO_* */
+		.flags		= UPF_BOOT_AUTOCONF,
+	},
+	{}
+};
+
+static struct platform_device iteuart_device = {
+	.name		= "serial8250",
+	.id		= PLAT8250_DEV_PLATFORM,
+	.dev			= {
+		.platform_data	= ite_uart_port,
+	},
+};
+#endif
+
+/* 2700G graphics */
+static u64 fb_dma_mask = ~(u64)0;
+
+static struct resource cmx270_2700G_resource[] = {
+	/* frame buffer memory including ODFB and External SDRAM */
+	[0] = {
+		.start = MARATHON_PHYS,
+		.end   = MARATHON_PHYS + 0x02000000,
+		.flags = IORESOURCE_MEM,
+	},
+	/* Marathon registers */
+	[1] = {
+		.start = MARATHON_PHYS + 0x03fe0000,
+		.end   = MARATHON_PHYS + 0x03ffffff,
+		.flags = IORESOURCE_MEM,
+	},
+};
+
+static unsigned long save_lcd_regs[10];
+
+#define LB_TROTTLE_OFF (PXA_CS1_PHYS | (1 << 25))
+#define LB_TROTTLE_MAX (PXA_CS1_PHYS | (1 << 25) | (1 << 22))
+static int cmx270_marathon_probe(struct fb_info *fb)
+{
+	volatile unsigned long *cpld;
+	
+	cpld = (volatile unsigned long*)ioremap(LB_TROTTLE_OFF, 4);
+	
+	if ( !cpld ) {
+		return -ENODEV;
+	}
+	*cpld = 0;
+	iounmap((void*)cpld);
+	
+
+	/* save PXA-270 pin settings before enabling 2700G */
+	save_lcd_regs[0] = GPDR1;
+	save_lcd_regs[1] = GPDR2;
+	save_lcd_regs[2] = GAFR1_U;
+	save_lcd_regs[3] = GAFR2_L;
+	save_lcd_regs[4] = GAFR2_U;
+
+	/* Disable PXA-270 on-chip controller driving pins */
+	GPDR1 &= ~(0xfc000000);
+	GPDR2 &= ~(0x00c03fff);
+	GAFR1_U &= ~(0xfff00000);
+	GAFR2_L &= ~(0x0fffffff);
+	GAFR2_U &= ~(0x0000f000);
+	return 0;
+}
+
+static int cmx270_marathon_remove(struct fb_info *fb)
+{
+	volatile unsigned long *cpld;
+	
+	cpld = (volatile unsigned long*)ioremap(LB_TROTTLE_MAX, 4);
+	
+	if ( !cpld ) {
+		return -ENODEV;
+	}
+	*cpld = 0;
+	iounmap((void*)cpld);
+
+	GPDR1 =   save_lcd_regs[0];
+	GPDR2 =   save_lcd_regs[1];
+	GAFR1_U = save_lcd_regs[2];
+	GAFR2_L = save_lcd_regs[3];
+	GAFR2_U = save_lcd_regs[4];
+	return 0;
+}
+
+static struct mbxfb_platform_data cmx270_2700G_data = {
+	.xres = {
+		.min = 240,
+		.max = 1200,
+		.defval = 640,
+	},
+	.yres = { 
+		.min = 240,
+		.max = 1200,
+		.defval = 480,
+	},
+	.bpp = {
+		.min = 16,
+		.max = 32,
+		.defval = 16,
+	},
+	.memsize = 8*1024*1024,
+	.probe = cmx270_marathon_probe,
+	.remove = cmx270_marathon_remove,
+};
+
+static struct platform_device cmx270_2700G = {
+	.name		= "mbx-fb",
+	.dev		= {
+ 		.platform_data	= &cmx270_2700G_data,
+		.dma_mask	= &fb_dma_mask,
+		.coherent_dma_mask = 0xffffffff,
+	},
+	.num_resources	= ARRAY_SIZE(cmx270_2700G_resource),
+	.resource	= cmx270_2700G_resource,
+	.id		= -1,
+};
+
+/* platform devices */
+static struct platform_device *platform_devices[] __initdata = {
+	&cmx270_device_dm9k,
+	&cmx270_audio_device,
+	&cmx270_ts_device,
+	&cmx270_rtc_device,
+	&cmx270_2700G,
+#ifdef CONFIG_PCI
+	&iteuart_device,
+#endif
+};
+
+#ifdef CONFIG_PCI
+/*
+ * Install handler for IT8152 IRQ.  Yes, yes... we are way down the IRQ
+ * cascade which is not good for IRQ latency, but the hardware has been
+ * designed that way...
+ */
+static inline void cmx270_irq(int irq, struct pt_regs *regs)
+{
+	struct irqdesc *desc;
+	desc = irq_desc + irq;
+	desc->handle(irq, desc, regs);
+}
+
+static void cmx270_irq_demux(unsigned int irq, struct irqdesc *desc,
+			     struct pt_regs *regs)
+{
+	unsigned long pdcnimr, ldcnimr;
+ 	int pdcnirr, ldcnir;
+
+	/* clear our parent irq */
+	GEDR(GPIO_IT8152_IRQ) = GPIO_bit(GPIO_IT8152_IRQ);
+
+	/* read pending IRQs in the chip registers and clear them */
+	pdcnirr = IT8152_INTC_PDCNIRR;
+	ldcnir = IT8152_INTC_LDCNIRR;
+	IT8152_INTC_PDCNIRR = ~pdcnirr;
+	IT8152_INTC_LDCNIRR = ~ldcnir;
+
+	/* mask ITE irqs */
+	pdcnimr = IT8152_INTC_PDCNIMR;
+	ldcnimr = IT8152_INTC_LDCNIMR;
+	IT8152_INTC_PDCNIMR = 0xffff;
+	IT8152_INTC_LDCNIMR = 0xffff;
+ 
+	pdcnirr &= (PCISERR_BIT | H2PTADR_BIT | H2PMAR_BIT |
+		    PCI_INTD_BIT | PCI_INTC_BIT | PCI_INTB_BIT | PCI_INTA_BIT |
+		    USB_INT_BIT | CDMA_INT_BIT);
+		
+	ldcnir &= ITESER_BIT;
+
+	IT8152_INTC_PDCNIRR = ~pdcnirr;
+	IT8152_INTC_LDCNIRR = ~ldcnir;
+
+	/* are there interrupts pending ? */
+	if( (pdcnirr | ldcnir) ) {
+		if (pdcnirr) {
+			if( pdcnirr & PCISERR_BIT )
+				cmx270_irq(PCISERR, regs);
+			if( pdcnirr & H2PTADR_BIT )
+				cmx270_irq(H2PTADR, regs);
+			if( pdcnirr & H2PMAR_BIT )
+				cmx270_irq(H2PMAR, regs);
+			if( pdcnirr & PCI_INTA_BIT )
+				cmx270_irq(PCI_INTA, regs);
+			if( pdcnirr & PCI_INTB_BIT )
+				cmx270_irq(PCI_INTB, regs);
+			if( pdcnirr & PCI_INTC_BIT )
+				cmx270_irq(PCI_INTC, regs);
+			if( pdcnirr & PCI_INTD_BIT )
+				cmx270_irq(PCI_INTD, regs);
+			if( pdcnirr & USB_INT_BIT )
+				cmx270_irq(USB_INT, regs);
+			if( pdcnirr & CDMA_INT_BIT )
+				cmx270_irq(CDMA_INT, regs);
+		}
+		if(ldcnir) {
+			if( ldcnir & ITESER_BIT )
+				cmx270_irq(IRQ_ITESER, regs);
+		}
+	}
+
+	/* re-enable ITE interrupts */
+	IT8152_INTC_PDCNIMR = pdcnimr;
+	IT8152_INTC_LDCNIMR = ldcnimr;
+}
+#else
+unsigned long it8152_base_address = CMX270_IT8152_VIRT;
+#endif
+
+#define CMX270_FLASH_VIRT (CMX270_IDE104_VIRT + PXA_CS_SIZE - (8<<20))
+/* Map PCI companion and IDE/General Purpose CS statically */
+static struct map_desc cmx270_io_desc[] __initdata = {
+	[0] = { /* IDE/general purpose space */
+		.virtual	= CMX270_IDE104_VIRT,
+		.pfn		= __phys_to_pfn(CMX270_IDE104_PHYS),
+		.length		= PXA_CS_SIZE - (8<<20),
+		.type		= MT_DEVICE
+	},
+	[1] = { /* NOR flash */
+		.virtual	= CMX270_FLASH_VIRT,
+		.pfn		= __phys_to_pfn(PXA_CS0_PHYS),
+		.length		= (8<<20), /* up to 8 MByte flash */
+		.type		= MT_DEVICE
+	},
+	[2] = { /* PCI bridge */
+		.virtual	= CMX270_IT8152_VIRT,
+		.pfn		= __phys_to_pfn(CMX270_IT8152_PHYS),
+		.length		= PXA_CS_SIZE,
+		.type		= MT_DEVICE
+	},
+};
+
+/*********************** Display definitions ****************************/
+static int mtype=MTYPE_CRT640x480;
+static int mbpp=-1;
+
+struct cmx270_display_info {
+	struct pxafb_mach_info fb_info;
+	char *display_name;
+};
+
+static struct __initdata cmx270_display_info cmx270_displays[] = {
+	[ MTYPE_STN320x240 ] = {
+		.fb_info = {
+			.pixclock	= 76923,
+			.bpp		= 8,
+			.xres		= 320,
+			.yres		= 240,
+			.hsync_len	= 3,
+			.vsync_len	= 2,
+			.left_margin	= 3,
+			.upper_margin	= 0,
+			.right_margin	= 3,
+			.lower_margin	= 0,
+			.sync		= (FB_SYNC_HOR_HIGH_ACT |
+					   FB_SYNC_VERT_HIGH_ACT),
+			.lccr0		= 0,
+			.lccr3		= (LCCR3_PixClkDiv(0x03) |
+					   LCCR3_Acb(0xff) |
+					   LCCR3_PCP),
+			.cmap_greyscale  = 0,
+			.cmap_inverse	 = 0,
+			.cmap_static	 = 0,
+		},
+		.display_name	 = "STN 320x240",
+	},
+	[ MTYPE_TFT640x480 ] = {
+		.fb_info = {
+			.pixclock	= 38461,
+			.bpp		= 8,
+			.xres		= 640,
+			.yres		= 480,
+			.hsync_len	= 60,
+			.vsync_len	= 2,
+			.left_margin	= 70,
+			.upper_margin	= 10,
+			.right_margin	= 70,
+			.lower_margin	= 5,
+			.sync		= 0,
+			.lccr0		= (LCCR0_PAS),
+			.lccr3		= (LCCR3_PixClkDiv(0x01) |
+					   LCCR3_Acb(0xff) |
+					   LCCR3_PCP),
+			.cmap_greyscale  	= 0,
+			.cmap_inverse	 	= 0,
+			.cmap_static	 	= 0,
+		},
+		.display_name		= "TFT 640x480",
+	},
+	[ MTYPE_CRT640x480 ] = {
+		.fb_info = {
+			.pixclock	= 38461,
+			.bpp		= 8,
+			.xres		= 640,
+			.yres		= 480,
+			.hsync_len	= 63,
+			.vsync_len	= 2,
+			.left_margin	= 81,
+			.upper_margin	= 33,
+			.right_margin	= 16,
+			.lower_margin	= 10,
+			.sync		= (FB_SYNC_HOR_HIGH_ACT |
+					   FB_SYNC_VERT_HIGH_ACT),
+			.lccr0		= (LCCR0_PAS),
+			.lccr3		= (LCCR3_PixClkDiv(0x01) |
+					   LCCR3_Acb(0xff)),
+			.cmap_greyscale  = 0,
+			.cmap_inverse	 = 0,
+			.cmap_static	 = 0,
+		},
+		.display_name	 = "CRT 640x480",
+	},
+	[ MTYPE_CRT800x600 ] = {
+		.fb_info = {
+			.pixclock	= 28846,
+			.bpp		= 8,
+			.xres		= 800,
+			.yres	  	= 600,
+			.hsync_len	= 63,
+			.vsync_len	= 2,
+			.left_margin	= 26,
+			.upper_margin	= 21,
+			.right_margin	= 26,
+			.lower_margin	= 11,
+			.sync		= (FB_SYNC_HOR_HIGH_ACT |
+					   FB_SYNC_VERT_HIGH_ACT),
+			.lccr0		= (LCCR0_PAS),
+			.lccr3		= (LCCR3_PixClkDiv(0x02) |
+					   LCCR3_Acb(0xff)),
+			.cmap_greyscale = 0,
+			.cmap_inverse	= 0,
+			.cmap_static	= 0,
+		},
+		.display_name	= "CRT 800x600",
+	},
+	[ MTYPE_CRT1024x768 ] = {
+		.fb_info = {
+			.pixclock = 0,
+			.xres = 0,
+			.yres = 0,
+		},
+		.display_name	= "CRT 1024x768",
+	},
+	[ MTYPE_USER_DEFINED ] = {
+		.fb_info = {
+			.pixclock	= LCD_PIXCLOCK,
+			.bpp		= LCD_BPP,
+			.xres		= LCD_XRES,
+			.yres		= LCD_YRES,
+			.hsync_len	= LCD_HORIZONTAL_SYNC_PULSE_WIDTH,
+			.vsync_len	= LCD_VERTICAL_SYNC_PULSE_WIDTH,
+			.left_margin	= LCD_BEGIN_OF_LINE_WAIT_COUNT,
+			.upper_margin	= LCD_BEGIN_FRAME_WAIT_COUNT,
+			.right_margin	= LCD_END_OF_LINE_WAIT_COUNT,
+			.lower_margin	= LCD_END_OF_FRAME_WAIT_COUNT,
+			.sync		= LCD_SYNC,
+			.lccr0		= LCD_LCCR0,
+			.lccr3		= LCD_LCCR3,
+			.cmap_greyscale = CMAP_GREYSCALE,
+			.cmap_inverse	= CMAP_INVERSE,
+			.cmap_static  	= CMAP_STATIC,
+		},
+		.display_name	= LCD_NAME,
+	},
+	[ MTYPE_TFT320x240 ] = {
+		.fb_info = {
+			.pixclock	= 134615,
+			.bpp		= 16,
+			.xres		= 320,
+			.yres		= 240,
+			.hsync_len	= 63,
+			.vsync_len	= 7,
+			.left_margin	= 75,
+			.upper_margin	= 0,
+			.right_margin	= 15,
+			.lower_margin	= 15,
+			.sync		= 0,
+			.lccr0		= (LCCR0_PAS),
+			.lccr3		= (LCCR3_PixClkDiv(0x06) |
+					   LCCR3_Acb(0xff) |
+					   LCCR3_PCP),
+			.cmap_greyscale  = 0,
+			.cmap_inverse	 = 0,
+			.cmap_static	 = 0,
+		},
+		.display_name	= "TFT 320x240",
+	},
+	[ MTYPE_STN640x480 ] = {
+		.fb_info = {
+			.pixclock	= 57692,
+			.bpp		= 8,
+			.xres		= 640,
+			.yres		= 480,
+			.hsync_len	= 4,
+			.vsync_len	= 2,
+			.left_margin	= 10,
+			.upper_margin	= 5,
+			.right_margin	= 10,
+			.lower_margin	= 5,
+			.sync		= (FB_SYNC_HOR_HIGH_ACT |
+					   FB_SYNC_VERT_HIGH_ACT),
+			.lccr0		= 0,
+			.lccr3		= (LCCR3_PixClkDiv(0x02) |
+					   LCCR3_Acb(0xff)),
+			.cmap_greyscale  = 0,
+			.cmap_inverse	 = 0,
+			.cmap_static	 = 0,
+		},
+		.display_name	= "STN 640x480",
+	},
+};
+
+static int __init monitor_params(char *str)
+{
+	mtype = simple_strtol(str, NULL, 0);
+	return 1;
+}
+
+__setup("monitor=", monitor_params);
+
+static int __init fb_bpp(char *str)
+{
+	mbpp = simple_strtol(str, NULL, 0);
+	return 1;
+}
+
+__setup("bpp=", fb_bpp);
+
+/* PXA27x OHCI controller setup */
+static int cmx270_ohci_init(struct device *dev)
+{
+	/* Set the Power Control Polarity Low */
+	UHCHR = (UHCHR | UHCHR_PCPL) &
+		~(UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSE);
+
+	return 0;
+}
+
+static struct pxaohci_platform_data cmx270_ohci_platform_data = {
+	.port_mode	= PMM_PERPORT_MODE,
+	.init		= cmx270_ohci_init,
+};
+
+
+static int cmx270_mci_init(struct device *dev, irqreturn_t (*mstone_detect_int)(int, void *, struct pt_regs *), void *data)
+{
+	int err;
+
+	/*
+	 * setup GPIO for PXA27x MMC controller
+	 */
+	pxa_gpio_mode(GPIO32_MMCCLK_MD);
+	pxa_gpio_mode(GPIO112_MMCCMD_MD);
+	pxa_gpio_mode(GPIO92_MMCDAT0_MD);
+	pxa_gpio_mode(GPIO109_MMCDAT1_MD);
+	pxa_gpio_mode(GPIO110_MMCDAT2_MD);
+	pxa_gpio_mode(GPIO111_MMCDAT3_MD);
+
+	/* SB-X270 uses GPIO105 as SD power enable */
+	pxa_gpio_mode(105 | GPIO_OUT);
+
+	/* card detect IRQ on GPIO 83 */
+	pxa_gpio_mode(IRQ_TO_GPIO(CMX270_MMC_IRQ));
+	set_irq_type(CMX270_MMC_IRQ, IRQT_FALLING);
+
+	err = request_irq(CMX270_MMC_IRQ, mstone_detect_int, SA_INTERRUPT,
+			     "MMC card detect", data);
+	if (err) {
+		printk(KERN_ERR "cmx270_mci_init: MMC/SD: can't request MMC card detect IRQ\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+static void cmx270_mci_setpower(struct device *dev, unsigned int vdd)
+{
+	struct pxamci_platform_data* p_d = dev->platform_data;
+
+	if (( 1 << vdd) & p_d->ocr_mask) {
+		printk(KERN_DEBUG "%s: on\n", __FUNCTION__);
+		GPCR(105) = GPIO_bit(105);
+	} else {
+		GPSR(105) = GPIO_bit(105);
+		printk(KERN_DEBUG "%s: off\n", __FUNCTION__);
+	}
+}
+
+static void cmx270_mci_exit(struct device *dev, void *data)
+{
+	free_irq(CMX270_MMC_IRQ, data);
+}
+
+static struct pxamci_platform_data cmx270_mci_platform_data = {
+	.ocr_mask	= MMC_VDD_32_33|MMC_VDD_33_34,
+	.init 		= cmx270_mci_init,
+	.setpower 	= cmx270_mci_setpower,
+	.exit		= cmx270_mci_exit,
+};
+
+
+#ifdef CONFIG_PM
+/* timeout for RTC wakeup */
+unsigned int cmx270_suspend_timeout;
+
+static ssize_t timeout_show(struct subsystem * subsys, char * buf)
+{
+	char * s = buf;
+
+	s += sprintf(s,"%d seconds\n", cmx270_suspend_timeout);
+	return (s - buf);
+}
+
+static ssize_t timeout_store(struct subsystem * subsys, const char * buf, size_t n)
+{
+	char *endp = 0;
+	int timeout;
+
+	timeout = simple_strtoul(buf, &endp, 10);
+	if ( *endp && *endp != '\n')
+		return -EINVAL;
+
+	cmx270_suspend_timeout = timeout;
+	return n;
+}
+
+static struct subsys_attribute timeout_attr = {
+	.attr	= {
+		.name = __stringify(timeout),
+		.mode = 0644,
+	},
+	.show	= timeout_show,
+	.store	= timeout_store,
+};
+
+static struct attribute * g[] = {
+	&timeout_attr.attr,
+	NULL,
+};
+
+static struct attribute_group attr_group = {
+	.attrs = g,
+};
+
+extern struct subsystem power_subsys;
+static unsigned long sleep_save_ite[10];
+static unsigned long sleep_save_msc[10];
+
+static int cmx270_suspend(struct sys_device *dev, pm_message_t state)
+{
+#ifdef CONFIG_PCI
+	/* save ITE state */
+	sleep_save_ite[0] = IT8152_INTC_PDCNIMR;
+	sleep_save_ite[1] = IT8152_INTC_LPCNIMR;
+	sleep_save_ite[2] = IT8152_INTC_LPNIAR;
+
+	/* Clear ITE IRQ's */
+	IT8152_INTC_PDCNIRR = 0;
+	IT8152_INTC_LPCNIRR = 0;
+#endif
+
+	/* save MSC registers */
+	sleep_save_msc[0] = MSC0;
+	sleep_save_msc[1] = MSC1;
+	sleep_save_msc[2] = MSC2;
+
+	/* setup power saving mode registers */
+	PCFR = 0x0;
+	PSLR = 0xff400000;
+	PMCR  = 0x00000005;
+	PWER  = 0x80000000;
+	PFER  = 0x00000000;
+	PRER  = 0x00000000;
+	PGSR0 = 0xC0018800;
+	PGSR1 = 0x004F0002;
+	PGSR2 = 0x6021C000;
+	PGSR3 = 0x00020000;
+
+	if ( cmx270_suspend_timeout ) {
+		RTAR = RCNR + cmx270_suspend_timeout;
+		cmx270_suspend_timeout = 0;
+	}
+
+	return 0;
+}
+
+static int cmx270_resume(struct sys_device *dev)
+{
+#ifdef CONFIG_PCI
+	/* restore IT8152 state */
+	IT8152_INTC_PDCNIMR = sleep_save_ite[0];
+	IT8152_INTC_LPCNIMR = sleep_save_ite[1];
+	IT8152_INTC_LPNIAR = sleep_save_ite[2];
+#endif
+
+	/* restore MSC registers */
+	MSC0 = sleep_save_msc[0];
+	MSC1 = sleep_save_msc[1];
+	MSC2 = sleep_save_msc[2];
+
+	return 0;
+}
+
+static struct sysdev_class cmx270_pm_sysclass = {
+	set_kset_name("pm"),
+	.resume = cmx270_resume,
+	.suspend = cmx270_suspend,
+};
+
+static struct sys_device cmx270_pm_device = {
+	.cls = &cmx270_pm_sysclass,
+};
+
+static int __init cmx270_pm_init(void)
+{
+	int error;
+	error = sysdev_class_register(&cmx270_pm_sysclass);
+	if (error == 0)
+		error = sysdev_register(&cmx270_pm_device);
+
+	error = sysfs_create_group(&power_subsys.kset.kobj,&attr_group);
+	return error;
+}
+#else
+static int __init cmx270_pm_init(void) { return 0; }
+#endif
+
+/* SA1111 compatibiliy 8 bit read register needed for proper function
+   of ITE8152 UART */
+#define MEMC_SA1111	__REG(0x48000064)  
+
+static void __init cmx270_init(void)
+{
+	/* set display timings for VGA 640x480 by default */
+	struct cmx270_display_info *tfbi = &cmx270_displays[2];
+
+	MEMC_SA1111 = 0x3c;
+
+	cmx270_pm_init();
+	
+	if ( mtype >= 0 && mtype < ARRAY_SIZE(cmx270_displays) )
+		tfbi = &cmx270_displays[mtype];
+
+	/* use default instead of unsupported displays */
+	if ( tfbi->fb_info.pixclock == 0 &&
+	     tfbi->fb_info.xres == 0 &&
+	     tfbi->fb_info.yres == 0 ) {
+		printk(KERN_WARNING "CM-X270 does not support %s display\n", cmx270_displays[mtype].display_name);
+		tfbi = &cmx270_displays[2];
+	}
+	     
+	/* setup color depth */
+	if( mtype == MTYPE_USER_DEFINED ) {
+		mbpp = tfbi->fb_info.bpp;
+	}
+	if( mbpp > 0 ) {
+		if( (mbpp!=1) && (mbpp!=2) && (mbpp!=4) &&
+		    (mbpp!=8) && (mbpp!=16)) {
+			printk(KERN_WARNING "Illegal BPP value "
+			       "supplied, leaving default\n");
+			mbpp = 8;
+		}
+	} 
+	else mbpp = 8;
+	tfbi->fb_info.bpp = mbpp;
+	     
+	printk(KERN_INFO "Running a %s display with %d bits per pixel\n",
+	       tfbi->display_name, tfbi->fb_info.bpp);
+	set_pxa_fb_info(&tfbi->fb_info);
+	     
+#ifdef CONFIG_PCI
+	/* setup ITE8152 UART base addresses */
+	ite_uart_port[0].membase = (void *)&IT8152_UART_BASE;
+	ite_uart_port[0].mapbase = IT8152_UART_BASE;
+#endif
+
+	/* register CM-X270 platform devices */
+	platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
+
+	/* set MCI and OHCI platform parameters */
+	pxa_set_mci_info(&cmx270_mci_platform_data);
+	pxa_set_ohci_info(&cmx270_ohci_platform_data);
+
+	/* This enables the STUART */
+	pxa_gpio_mode(GPIO46_STRXD_MD);
+	pxa_gpio_mode(GPIO47_STTXD_MD);
+
+	/* This enables the BTUART  */ 
+	pxa_gpio_mode(GPIO42_BTRXD_MD);
+	pxa_gpio_mode(GPIO43_BTTXD_MD);
+	pxa_gpio_mode(GPIO44_BTCTS_MD);
+	pxa_gpio_mode(GPIO45_BTRTS_MD);
+}
+
+int machine_is_cmx270l(void)
+{
+	int is_l = 0;
+	volatile unsigned char *flash =
+		(volatile unsigned char *)(CMX270_FLASH_VIRT + 0x3ffe8UL);
+	char rev[10];
+	int i;
+
+	memset(rev, 0, 10);
+	for ( i = 0; i < 8; i++ )
+		rev[i] = flash[i];
+	if ( (rev[6] - '0') > 1 )
+		is_l = 1;
+
+	printk(KERN_DEBUG "%s: revision read: %s, is_l = %d\n",
+	       __FUNCTION__, rev, is_l);
+
+	return is_l;
+}
+
+#ifdef CONFIG_PCI
+static void cmx270_mask_irq(unsigned int irq)
+{
+	switch(irq) {
+		case IT8152_IRQ(0):
+			IT8152_INTC_PDCNIMR |= PCISERR_BIT;
+			break;
+		case IT8152_IRQ(1):
+			IT8152_INTC_PDCNIMR |= H2PTADR_BIT;
+			break;
+		case IT8152_IRQ(2):
+			IT8152_INTC_PDCNIMR |= H2PMAR_BIT;
+			break;
+		case IT8152_IRQ(3):
+			IT8152_INTC_PDCNIMR |= PCI_INTA_BIT;
+			break;
+		case IT8152_IRQ(4):
+			IT8152_INTC_PDCNIMR |= PCI_INTB_BIT;
+			break;
+		case IT8152_IRQ(5):
+			IT8152_INTC_PDCNIMR |= PCI_INTC_BIT;
+			break;
+		case IT8152_IRQ(6):
+			IT8152_INTC_PDCNIMR |= PCI_INTD_BIT;
+			break;
+		case IT8152_IRQ(7):
+			IT8152_INTC_PDCNIMR |= USB_INT_BIT;
+			break;
+		case IT8152_IRQ(9):
+			IT8152_INTC_PDCNIMR |= CDMA_INT_BIT;
+			break;
+		case IT8152_IRQ(10):
+			IT8152_INTC_LDCNIMR |= ITESER_BIT;
+			break;
+	}
+}
+
+static void cmx270_unmask_irq(unsigned int irq)
+{
+	switch(irq) {
+		case IT8152_IRQ(0):
+			IT8152_INTC_PDCNIMR &= (~PCISERR_BIT);
+			break;
+		case IT8152_IRQ(1):
+			IT8152_INTC_PDCNIMR &= (~H2PTADR_BIT);
+			break;
+		case IT8152_IRQ(2):
+			IT8152_INTC_PDCNIMR &= (~H2PMAR_BIT);
+			break;
+		case IT8152_IRQ(3):
+			IT8152_INTC_PDCNIMR &= (~PCI_INTA_BIT);
+			break;
+		case IT8152_IRQ(4):
+			IT8152_INTC_PDCNIMR &= (~PCI_INTB_BIT);
+			break;
+		case IT8152_IRQ(5):
+			IT8152_INTC_PDCNIMR &= (~PCI_INTC_BIT);
+			break;
+		case IT8152_IRQ(6):
+			IT8152_INTC_PDCNIMR &= (~PCI_INTD_BIT);
+			break;
+		case IT8152_IRQ(7):
+			IT8152_INTC_PDCNIMR &= (~USB_INT_BIT);
+			break;
+		case IT8152_IRQ(9):
+			IT8152_INTC_PDCNIMR &= (~CDMA_INT_BIT);
+			break;
+		case IT8152_IRQ(10):
+			IT8152_INTC_LDCNIMR &= (~ITESER_BIT);
+			break;
+	}
+}
+
+static struct irqchip cmx270_irq_chip = {
+	.ack		= cmx270_mask_irq,
+	.mask		= cmx270_mask_irq,
+	.unmask		= cmx270_unmask_irq,
+};
+#endif
+
+static void __init cmx270_init_irq(void)
+{
+	int irq;
+
+	pxa_init_irq();
+
+	/* LED and NAND GPIOs should not be probed for IRQ */
+	irq_desc[IRQ_GPIO(11)].probe_ok = 0;
+	irq_desc[IRQ_GPIO(89)].probe_ok = 0;
+	irq_desc[IRQ_GPIO(93)].probe_ok = 0;
+	irq_desc[IRQ_GPIO(94)].probe_ok = 0;
+
+	IT8152_INTC_PDCNIMR = 0xffff;
+
+#ifdef CONFIG_PCI
+	/* Disable and clear IRQ's for ITE8152 */
+	IT8152_INTC_PDCNIMR = 0xffff;
+	IT8152_INTC_PDCNIRR = 0;
+	IT8152_INTC_LPCNIMR = 0xffff;
+	IT8152_INTC_LPCNIRR = 0;
+	IT8152_INTC_LDCNIMR = 0xffff;
+	IT8152_INTC_LDCNIRR = 0;
+
+	/* Set IT8152 serial port IRQ as active high*/
+	IT8152_INTC_LDNIAR |= ITESER_BIT;
+
+	for(irq = IT8152_IRQ(0); irq <= IT8152_IRQ_MAX; irq++) {
+		set_irq_chip(irq, &cmx270_irq_chip);
+		set_irq_handler(irq, do_level_IRQ);
+		set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+	}
+
+	/* INTC signal from IT8152 is connected to GPIO0 */
+	pxa_gpio_mode(IRQ_GPIO_IT8152_IRQ);
+	set_irq_chained_handler(IRQ_GPIO_IT8152_IRQ, cmx270_irq_demux);
+	set_irq_type(IRQ_GPIO_IT8152_IRQ, IRQT_RISING);
+#endif
+
+	/* Setup interrupt for dm9000 */
+	pxa_gpio_mode(IRQ_TO_GPIO(CMX270_ETHIRQ));
+	set_irq_type(CMX270_ETHIRQ, IRQT_RISING);
+
+	/* Setup interrupt for 2700G */
+	pxa_gpio_mode(IRQ_TO_GPIO(CMX270_GFXIRQ));
+	set_irq_type(CMX270_GFXIRQ, IRQT_FALLING);
+}
+
+static void __init cmx270_map_io(void)
+{
+	pxa_map_io();
+	iotable_init(cmx270_io_desc, ARRAY_SIZE(cmx270_io_desc));
+}
+
+
+MACHINE_START(ARMCORE, "Compulab CM-x270")
+	.boot_params	= 0xa0000100,
+	.phys_io	= 0x40000000,
+	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
+	.map_io		= cmx270_map_io,
+	.init_irq	= cmx270_init_irq,
+	.timer		= &pxa_timer,
+	.init_machine	= cmx270_init,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/it8152.c b/arch/arm/mach-pxa/it8152.c
new file mode 100644
index 0000000..91bb49c
--- /dev/null
+++ b/arch/arm/mach-pxa/it8152.c
@@ -0,0 +1,248 @@
+/*
+ * arch/arm/common/it8152.c: PCI functions for IT8152
+ *
+ * Compulab Ltd, 2002-2006
+ *
+ * The DMA bouncing is taken from arch/arm/mach-ixp4xx/common-pci.c
+ * (see this file for respective copyrights)
+ *
+ * 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/sched.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/ptrace.h>
+#include <linux/interrupt.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <asm/mach/map.h>
+
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/mach/pci.h>
+#include <asm/hardware/it8152.h>
+
+#define MAX_SLOTS		21
+
+static unsigned long
+it8152_pci_dev_base_address(struct pci_bus *bus, unsigned int devfn)
+{
+	unsigned long addr = 0;
+
+	if (bus->number == 0) {
+			if (devfn < PCI_DEVFN(MAX_SLOTS, 0))
+				addr = (devfn << 8);
+	} else
+		addr = (bus->number << 16) | (devfn << 8);
+
+	return addr;
+}
+
+static int
+it8152_pci_read_config(struct pci_bus *bus, unsigned int devfn, int where,
+		    int size, u32 *value)
+{
+	unsigned long addr = it8152_pci_dev_base_address(bus, devfn);
+	u32 v;
+	int shift;
+
+#ifdef CONFIG_MACH_ARMCORE
+	if(devfn!=0) IT8152_GPIO_GPLR=0x00;
+#endif	
+	shift = (where & 3);
+
+	IT8152_PCI_CFG_ADDR = (addr + where);
+	v = (IT8152_PCI_CFG_DATA  >> (8 * (shift)));	
+
+	*value = v;
+
+#ifdef CONFIG_MACH_ARMCORE
+	if(devfn!=0) IT8152_GPIO_GPLR=0x20;
+#endif	
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+
+static int
+it8152_pci_write_config(struct pci_bus *bus, unsigned int devfn, int where,
+		     int size, u32 value)
+{
+	unsigned long addr = it8152_pci_dev_base_address(bus, devfn);
+	u32 v, vtemp, mask=0;
+	int shift;
+
+#ifdef CONFIG_MACH_ARMCORE
+	if(devfn!=0) IT8152_GPIO_GPLR=0x00;
+#endif
+
+	if(size==1) mask=0xff;
+	if(size==2) mask=0xffff;
+
+	shift = (where & 3);
+
+	IT8152_PCI_CFG_ADDR = addr + where;
+	vtemp = IT8152_PCI_CFG_DATA;
+
+	if(mask) vtemp &= ~(mask << (8 * shift));
+	else vtemp = 0;
+
+	v = (value << (8 * shift));
+	IT8152_PCI_CFG_ADDR = addr + where;
+	IT8152_PCI_CFG_DATA  = (v | vtemp);
+
+#ifdef CONFIG_MACH_ARMCORE
+	if(devfn!=0) IT8152_GPIO_GPLR=0x20;
+#endif
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops it8152_ops = {
+	.read = it8152_pci_read_config,
+	.write = it8152_pci_write_config,
+};
+
+static struct resource it8152_io = {
+	.name	= "IT8152 PCI I/O region",
+	.flags	= IORESOURCE_IO,
+};
+
+static struct resource it8152_mem1 = {
+	.name	= "First IT8152 PCI memory region",
+	.start	= 0x10000000,
+	.end	= 0x13e00000,
+	.flags	= IORESOURCE_MEM,
+};
+
+/*
+ * The following functions are needed for DMA bouncing.
+ * ITE8152 chip can addrees up to 64MByte, so all the devices
+ * connected to ITE8152 (PCI and USB) should have limited DMA window
+ */
+
+/*
+ * Setup DMA mask to 64MB on devices connected to ITE8152. Ignore all
+ * other devices.
+ */
+static int it8152_pci_platform_notify(struct device *dev)
+{
+	if ( dev->bus == &pci_bus_type ) {
+		if ( dev->dma_mask )
+			*dev->dma_mask =  SZ_64M - 1;
+		dev->coherent_dma_mask = SZ_64M - 1;
+		dmabounce_register_dev(dev, 2048, 4096);
+	}
+	return 0;
+}
+
+static int it8152_pci_platform_notify_remove(struct device *dev)
+{
+	if ( dev->bus == &pci_bus_type ) {
+		dmabounce_unregister_dev(dev);
+	}
+	return 0;
+}
+
+int dma_needs_bounce(struct device *dev, dma_addr_t dma_addr, size_t size)
+{
+	dev_dbg(dev, "%s: dma_addr %08x, size %08x\n",
+		__FUNCTION__, dma_addr, size);
+	return (dev->bus == &pci_bus_type ) && 
+		((dma_addr + size - PHYS_OFFSET) >= SZ_64M);
+}
+
+/*
+ * Only first 64MB of memory can be accessed via PCI.
+ * We use GFP_DMA to allocate safe buffers to do map/unmap.
+ * This is really ugly and we need a better way of specifying
+ * DMA-capable regions of memory.
+ */
+void __init it8152_adjust_zones(int node, unsigned long *zone_size,
+	unsigned long *zhole_size)
+{
+	unsigned int sz = SZ_64M >> PAGE_SHIFT;
+
+	/*
+	 * Only adjust if > 64M on current system
+	 */
+	if (node || (zone_size[0] <= sz))
+		return;
+
+	zone_size[1] = zone_size[0] - sz;
+	zone_size[0] = sz;
+	zhole_size[1] = zhole_size[0];
+	zhole_size[0] = 0;
+}
+
+/*
+ * We override these so we properly do dmabounce otherwise drivers
+ * are able to set the dma_mask to 0xffffffff and we can no longer
+ * trap bounces. :(
+ *
+ * We just return true on everyhing except for < 64MB in which case 
+ * we will fail miseralby and die since we can't handle that case.
+ */
+int
+pci_set_dma_mask(struct pci_dev *dev, u64 mask)
+{
+	if (mask >= SZ_64M - 1 )
+		return 0;
+
+	return -EIO;
+}
+    
+int
+pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask)
+{
+	if (mask >= SZ_64M - 1 )
+		return 0;
+
+	return -EIO;
+}
+
+EXPORT_SYMBOL(pci_set_dma_mask);
+EXPORT_SYMBOL(pci_set_consistent_dma_mask);
+
+
+int __init it8152_pci_setup(int nr, struct pci_sys_data *sys)
+{
+	it8152_io.start = IT8152_IO_BASE + 0x12000;
+ 	it8152_io.end	= IT8152_IO_BASE + 0x100000;
+
+	if (request_resource(&ioport_resource, &it8152_io)) {
+		printk(KERN_ERR "PCI: unable to allocate IO region\n");
+		return -EBUSY;
+	}
+	if (request_resource(&iomem_resource, &it8152_mem1)) {
+		printk(KERN_ERR "PCI: unable to allocate memory region\n");
+		return -EBUSY;
+	}
+
+	sys->resource[0] = &it8152_io;
+	sys->resource[1] = &it8152_mem1;
+
+	if (platform_notify || platform_notify_remove) {
+		printk(KERN_ERR "PCI: Can't use platform_notify\n");
+		return -EBUSY;
+	}
+
+	platform_notify = it8152_pci_platform_notify;
+	platform_notify_remove = it8152_pci_platform_notify_remove;
+
+	return 1;  
+}
+			  
+
+struct pci_bus * __init it8152_pci_scan_bus(int nr, struct pci_sys_data *sys)
+{
+	return pci_scan_bus(nr, &it8152_ops, sys);
+}
+
diff --git a/arch/arm/mach-pxa/leds-cm-x270.c b/arch/arm/mach-pxa/leds-cm-x270.c
new file mode 100644
index 0000000..5402b69
--- /dev/null
+++ b/arch/arm/mach-pxa/leds-cm-x270.c
@@ -0,0 +1,134 @@
+/*
+ * linux/arch/arm/mach-pxa/leds-cm-x270.c
+ *
+ * Compulab Ltd., 2003
+ *
+ * Original (leds-footbridge.c) by Russell King
+ * 
+ * Macros for actual LED manipulation should be in machine specific
+ * files in this 'mach' directory.
+ */
+
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/leds.h>
+#include <asm/system.h>
+
+#include <asm/arch/pxa-regs.h>
+#include <asm/arch/cm-x270.h>
+
+#include "leds.h"
+
+#define LED_STATE_ENABLED	1
+#define LED_STATE_CLAIMED	2
+
+#define RED_LED_ON			1
+#define GREEN_LED_ON		2
+
+static unsigned int led_state;
+static unsigned int hw_led_state;
+
+void armcore_leds_event(led_event_t evt)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+
+	switch (evt) {
+	case led_start:
+		hw_led_state = GREEN_LED_ON | RED_LED_ON;
+		led_state = LED_STATE_ENABLED;
+		break;
+
+	case led_stop:
+		led_state &= ~LED_STATE_ENABLED;
+		break;
+
+	case led_claim:
+		led_state |= LED_STATE_CLAIMED;
+		hw_led_state = GREEN_LED_ON | RED_LED_ON;
+		break;
+
+	case led_release:
+		led_state &= ~LED_STATE_CLAIMED;
+		hw_led_state = GREEN_LED_ON | RED_LED_ON;
+		break;
+
+#ifdef CONFIG_LEDS_TIMER
+	case led_timer:
+		if (!(led_state & LED_STATE_CLAIMED))
+			hw_led_state ^= GREEN_LED_ON;
+		break;
+#endif
+
+#ifdef CONFIG_LEDS_CPU
+	case led_idle_start:
+		if (!(led_state & LED_STATE_CLAIMED))
+			hw_led_state &= ~RED_LED_ON;
+		break;
+
+	case led_idle_end:
+		if (!(led_state & LED_STATE_CLAIMED))
+			hw_led_state |= RED_LED_ON;
+		break;
+#endif
+
+	case led_halted:
+		break;
+
+	case led_green_on:
+		if (led_state & LED_STATE_CLAIMED)
+			hw_led_state &= ~GREEN_LED_ON;
+		break;
+
+	case led_green_off:
+		if (led_state & LED_STATE_CLAIMED)
+			hw_led_state |= GREEN_LED_ON;
+		break;
+
+	case led_amber_on:
+		break;
+
+	case led_amber_off:
+		break;
+
+	case led_red_on:
+		if (led_state & LED_STATE_CLAIMED)
+			hw_led_state &= ~RED_LED_ON;
+		break;
+
+	case led_red_off:
+		if (led_state & LED_STATE_CLAIMED)
+			hw_led_state |= RED_LED_ON;
+		break;
+
+	default:
+		break;
+	}
+
+	if  (led_state & LED_STATE_ENABLED) 
+	{
+		if(hw_led_state & RED_LED_ON)  {
+			CMX270_RED_ON();
+//			printk("Red on\n");
+		}
+		else {
+//			printk("Red off\n");
+			CMX270_RED_OFF();
+		}
+		if(hw_led_state & GREEN_LED_ON)  {
+//			printk("Green on\n");
+			CMX270_GREEN_ON();
+		}
+		else {
+//			printk("Green off\n");
+			CMX270_GREEN_OFF();
+		}
+	}
+
+	local_irq_restore(flags);
+}
diff --git a/arch/arm/mach-pxa/leds.c b/arch/arm/mach-pxa/leds.c
index bbe4d5f..a27d027 100644
--- a/arch/arm/mach-pxa/leds.c
+++ b/arch/arm/mach-pxa/leds.c
@@ -24,6 +24,8 @@ pxa_leds_init(void)
 		leds_event = mainstone_leds_event;
 	if (machine_is_pxa_idp())
 		leds_event = idp_leds_event;
+	if (machine_is_armcore())	  
+		leds_event = armcore_leds_event;
 
 	leds_event(led_start);
 	return 0;
diff --git a/arch/arm/mach-pxa/leds.h b/arch/arm/mach-pxa/leds.h
index d98f6e9..0dcc346 100644
--- a/arch/arm/mach-pxa/leds.h
+++ b/arch/arm/mach-pxa/leds.h
@@ -10,3 +10,4 @@
 extern void idp_leds_event(led_event_t evt);
 extern void lubbock_leds_event(led_event_t evt);
 extern void mainstone_leds_event(led_event_t evt);
+extern void armcore_leds_event(led_event_t evt);
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c
index 3baa708..823c32d 100644
--- a/arch/arm/mach-pxa/pxa27x.c
+++ b/arch/arm/mach-pxa/pxa27x.c
@@ -140,10 +140,12 @@ void pxa_cpu_pm_enter(suspend_state_t st
 	extern void pxa_cpu_suspend(unsigned int);
 	extern void pxa_cpu_resume(void);
 
+#ifndef CONFIG_MACH_ARMCORE
 	if (state == PM_SUSPEND_STANDBY)
 		CKEN = CKEN22_MEMC | CKEN9_OSTIMER | CKEN16_LCD |CKEN0_PWM0;
 	else
 		CKEN = CKEN22_MEMC | CKEN9_OSTIMER;
+#endif
 
 	/* ensure voltage-change sequencer not initiated, which hangs */
 	PCFR &= ~PCFR_FVC;
@@ -158,7 +160,11 @@ void pxa_cpu_pm_enter(suspend_state_t st
 	case PM_SUSPEND_MEM:
 		/* set resume return address */
 		PSPR = virt_to_phys(pxa_cpu_resume);
+#ifdef CONFIG_MACH_ARMCORE
+		pxa_cpu_suspend(PWRMODE_DEEPSLEEP);
+#else
 		pxa_cpu_suspend(PWRMODE_SLEEP);
+#endif
 		break;
 	}
 }
diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig
index 8b13316..8ffaad0 100644
--- a/drivers/block/Kconfig
+++ b/drivers/block/Kconfig
@@ -453,4 +453,9 @@ config ATA_OVER_ETH
 	This driver provides Support for ATA over Ethernet block
 	devices like the Coraid EtherDrive (R) Storage Blade.
 
+config ARMCORE_FLASH
+	tristate "ARMCORE flash drivers"
+	depends on MACH_ARMCORE
+	source "drivers/block/cl_flash/Kconfig"
+
 endmenu
diff --git a/drivers/block/Makefile b/drivers/block/Makefile
index 3ec1f8d..ebeb4c6 100644
--- a/drivers/block/Makefile
+++ b/drivers/block/Makefile
@@ -31,3 +31,4 @@ obj-$(CONFIG_VIODASD)		+= viodasd.o
 obj-$(CONFIG_BLK_DEV_SX8)	+= sx8.o
 obj-$(CONFIG_BLK_DEV_UB)	+= ub.o
 
+obj-$(CONFIG_ARMCORE_FLASH) 	+= cl_flash/
diff --git a/drivers/block/cl_flash/CL_Logic.h b/drivers/block/cl_flash/CL_Logic.h
new file mode 100644
index 0000000..fe3e8d7
--- /dev/null
+++ b/drivers/block/cl_flash/CL_Logic.h
@@ -0,0 +1,245 @@
+/*	Module: CL_Logic.h
+	Author: Vova Lifliand
+	Description: Controls Nand flash management logic
+	Notes:
+*/
+
+#ifndef __CL_LOGIC__ 
+#define __CL_LOGIC__
+/*#define CL_NAND_BIG_DELAYS*/
+#if defined(FLASH_PLATFORM_LINUX) || defined(FLASH_PLATFORM_ARMonitor)
+/* Structure packaging */ 
+ #define PACKAGE __attribute__ ((packed,aligned(1)))
+ #define CL_ST static
+#else 
+ #define PACKAGE
+ #define CL_ST 
+#endif 
+ #define FAR
+ #define far 
+/* NOR Flash management constants */
+#define CL_NOR_FLASH_PAGE_SIZE            512      /*  bytes  */
+
+#ifdef FLASH_PLATFORM_DOS
+  #define cl_error_log(x,...){} 
+#endif			/*  MS-DOS  */
+/*  Nand Flash management constants  */
+
+/*  Page size must not be changed because this value is also used for
+    page size of Nand flash  */
+/*#define CL_FLASH_PAGE_SIZE            512      //  bytes  */
+#define CL_FLASH_MAXIMUM_PAGE_SIZE      2048/*  bytes  */
+#define CL_FLASH_MINIMAL_SECTOR_SIZE    512 /* Sectors can't be less than 512 bytes */
+/*#define CL_FLASH_SPARE_AREA_SIZE        16       //  bytes  */
+/*#define CL_FLASH_MAXIMUM_SPARE_AREA_SIZE  128         bytes  - twice the needed for biggest
+    							flash today 2004/05   */
+#define CL_FLASH_MAXIMUM_SPARE_AREA_SIZE  128 /*Stingy with space...*/
+							
+/*  Maximum blocks number in flash - adjust according to maximum flash size  */
+#define CL_MAX_BLKS_NUMBER              8192     /*  good for 128MB flash  */
+												/* Good up to 512 MB flash, if 64kb is the smallest block */
+/*  Number of pages in Nand flash block  */
+/* #define CL_FLASH_PAGES_PER_NAND_BLK     32 */
+/*  Maximum Number of pages in Nand flash block  */
+#define CL_FLASH_MAXIMUM_PAGES_PER_NAND_BLK 128 /* 32 */ /* Can't be more than 255
+							to fit in unsigned char arrays*/
+/*  Number of pages to make free  */
+#define CL_FLASH_FREE_PAGE_PER_BLK      1
+/*  Usable pages per 16 KB Nand flash block  */
+/*#define CL_FLASH_USE_PAGE_PER_BLK       (CL_FLASH_PAGES_PER_NAND_BLK - CL_FLASH_FREE_PAGE_PER_BLK)*/
+#define CL_FLASH_USE_PAGE_PER_BLK       (flogic->nand->pages_per_block - CL_FLASH_FREE_PAGE_PER_BLK)
+/*  Number of logical to physical page translation tables stored in memory
+    Each table size is ~40 bytes  */
+#define CL_LTF_PAGE_TBLS                30
+/*  Always leave a number of blocks unused - just for sure  */
+#define CL_EXTRA_SPARE_BLKS             10
+/*  Define maximum number of different blocks with cached pages  */
+#define CL_MAX_CACHED_BLKS              4
+/*  Number of erases per one launching of anti wearing procedure  */
+#define CL_ERASE_PER_ANTI_WEARING       1000
+
+
+#define CLBYTEPTR      unsigned char far*
+
+
+/*  Flash mapping and accessing interface  */
+typedef struct PACKAGE cl_nand_map_if_t
+{
+    /*  Destroy function must free all allocated resources (such as virtual memory)  */
+    void (*init) (void);
+    void (*destroy) (void);
+    /*  Chip select operation. When on = 1: chip select, on = 0: disable chip select  */
+    /* need_auto_operation - Whe the ON is false, the pin is expected to pulse in accordance
+       with bus transactions. This function exists on x86, but not on ARM */
+    void (*chip_select) (int on, int need_auto_operation);
+    /*  Reading from flash (HW read access, not actual data reading)  */
+    unsigned char (*readb) (unsigned char offset);
+    /*  Writing to flash (HW write access, not actual data writing)  */
+    void (*writeb) (unsigned char offset, unsigned char data);
+    /*  Reads block from flash: reads data from address 0 while incrementing data pointer  */
+    void (*blockread) (CLBYTEPTR data, int count);
+    /*  Writes block to flash: writes data to address 0 while incrementing data pointer  */
+    void (*blockwrite) ( CLBYTEPTR data, int count);
+    /*  Turns on/off activity indication leds  */
+    void (*activity_leds) (short operation, short reclaim);
+    /*  Performs specified delay (parameter in microsecond units)  */
+    int (*sleep) (unsigned long microseconds);
+	/* Wait for completion using R/B line */
+	/* Use microseconds, if R/B line not implemented */
+    int (*rbwait) (unsigned long  microseconds);
+} cl_nand_map_if;
+
+
+/*  Internal flash logic structure  */
+typedef struct cl_logic_t  far*cl_logic;
+
+
+/*  Parameter retrive enum  */
+typedef enum
+{
+    CL_FLASH_TOTAL_SIZE,        /*  Total size of the flash in bytes  */
+    CL_FLASH_HEADS_NUM,         /*  Number of heads  */
+    CL_FLASH_SECTOR_SIZE = 512,       /*  Sector size (in bytes)  =512 - is legacy for ARMonitor only*/
+    CL_FLASH_SECTORS_NUM,       /*  Number of sectors per tracks */
+    CL_FLASH_CYLINDERS_NUM,     /*  Number of cylinders  */
+    CL_FLASH_PAGE_SIZE,         /*  Size of the page without spare area */
+    CL_FLASH_READ_PAGE_CNT,     /*  Read page operations count  */
+    CL_FLASH_WRITE_PAGE_CNT,    /*  Write page operations count  */
+    CL_FLASH_RECLAIM_CNT,       /*  Reclaim block count  */
+    CL_FLASH_BURSTS_NUM,        /*  Bursts of length 'var' numbers  */
+    CL_FLASH_ERASE_CNT,         /*  Erase cnt of block specified by 'var'  */
+    CL_FLASH_BAD_BLOCK_CNT,
+} PACKAGE cl_logic_param;
+
+/*  Direct access type enum  */
+typedef enum 
+{
+    CL_FLASH_READ_PAGE,
+    CL_FLASH_READ_SPARE_AREA,
+    CL_FLASH_READ_BLK_SPARES,   /*  All spare areas of specified block  */
+    CL_FLASH_WRITE_PAGE,
+    CL_FLASH_WRITE_SPARE_AREA,
+    CL_FLASH_ERASE_BLOCK        /*  Data ignored  */
+} PACKAGE cl_nand_direct_access_type;
+
+/* memory access type enum */
+typedef enum //Memory areas usage is dscribed in separate document.
+{
+	CL_FLOGIC = 0,
+	CL_NAND,
+	CL_CACHE,
+	CL_CACHE_ORDERED_ARRAY,
+	CL_SP_AREA, 
+	CL_SP_AREA_2, 
+	CL_SP_AREA_3,
+	CL_PAGE, 
+	CL_CACHE_REF
+} PACKAGE  cl_memory_region_name;
+
+#define NUMBER_OF_MEMORY_REGIONS 9
+
+
+typedef enum 
+{
+	CL_FIRST_ALLOCATION_STAGE,
+	CL_SECOND_ALLOCATION_STAGE
+}PACKAGE cl_memory_allocation_stages;
+
+typedef struct cl_memory_pointer_type
+{
+	void far* pMemory;
+	char IN_USE;
+} PACKAGE cl_memory_pointer;
+
+void far* cl_memory_request (cl_memory_region_name mem_name);
+
+void cl_memory_return (cl_memory_region_name mem_name);
+
+/*  Creates flash logic object and attaches it to specified HW nand flash.
+    cache_size is max. number of pages, the cache can hold.
+    The flash is formatted prior initialization if format != 0.
+    When formatting reseved blocks and bad are not erased.  */
+cl_logic cl_logic_create (cl_nand_map_if* nand_if, long cache_size, int format, unsigned short sector_size);
+
+/*  Removes flash logic object and frees all allocated resources.  */
+void cl_logic_free (cl_logic flogic);
+
+/*  Parameters retrival function.  */
+long cl_logic_get_param (cl_logic flogic, cl_logic_param prm, long var);
+
+/*  Read page command.  */
+int cl_logic_read_page (cl_logic flogic,  long fs_sectn,
+                          CLBYTEPTR sector_data);
+
+/*  Write page command.  */
+int cl_logic_write_page (cl_logic flogic,  long fs_pagen,
+                            CLBYTEPTR page_data);
+
+/*  Flushes too old cache. If force_one_flush is TRUE, at least one
+    cached block is flushed.  */
+void cl_logic_on_idle (cl_logic flogic, int force_one_flush);
+
+/*  Flushes all cached data to disk.  */
+void cl_logic_sync (cl_logic flogic);
+
+/*  Direct accessing commands  */
+int cl_logic_direct_access (cl_logic flogic, cl_nand_direct_access_type type,
+                            unsigned short block, unsigned char page, CLBYTEPTR data);
+
+
+/*  NOR Flash Disk Driver  */
+
+/*  The header describes block information  */
+typedef struct
+{
+    unsigned short Signature;       /*  0x1998 for initialized blocks  */
+    unsigned short State;
+    unsigned short EraseCounter;
+    unsigned short PageIndex[128];
+    unsigned short Unused[10];
+    unsigned short BlockReserved;	/*	0xFFFF - usable block, 0 - reserved block  */
+} PACKAGE cl_nor_block_header;
+
+/*  Abstract class for flash access  */
+typedef struct
+{
+    /*  Constructor  */
+    void (*Constructor)(void);
+    /*  Destructor  */
+    void (*Destructor)(void);
+    /*  Define flash access functions  */
+    /*  Returns usable size  */
+    unsigned long (*GetSize)(void);
+    /*  Remaps or unmaps MMS windows, allocated by flash  */
+    void (*EnableFlashMap)(int EnableFlag);
+    /*  Returns number of usable pages, 512 bytes each.  */
+    /*  Doesn't include first page that is used for header - signature, state . . .  */
+    int (*GetPagesPerBlock)(void);
+    /*  Header  */
+    int (*ReadHeader)(unsigned short BlockN, cl_nor_block_header* Header);
+    /*  The PageNum == 0 is first data page and not the header. Max. value of PageNum  */
+    /*  is GetBlockSize() / BytesPerPage - 1 (min. is 0)  */
+    int (*ReadPage)(unsigned short BlockN, unsigned char PageNum, CLBYTEPTR DestBuff);
+    int (*SetBlockState) (unsigned short BlockN, unsigned short Signature,
+			  unsigned short State, unsigned short Reserved);
+    /*  Sets logical page index to zero - invalidates page. PageN is like in WritePage  */
+    int (*InvalidatePage)(unsigned short BlockN, unsigned char PageN);
+    /*  BlockN and PageN - destination location, where PageN doesn't include header  */
+    /*  information (PageN = 0 means first logical page and it's seconds physical page).  */
+    /*  PageIndex is physical page number for further identification (by ReadHeader)  */
+    int (*WritePage)(unsigned short BlockN, unsigned char PageN,
+                      const CLBYTEPTR PageData, unsigned short PageIndex);
+    int (*EraseBlock)(unsigned short BlockN);
+} PACKAGE cl_nor_flash_access;
+
+/*  Define flash access functions  */
+int cl_nor_init_flash (void);
+int cl_nor_free_mem (void);
+int cl_nor_format_flash (int (*ProgressCallback)(int Percentage));
+int cl_nor_write_page (int PageIndex, CLBYTEPTR Data);
+int cl_nor_read_page (int PageIndex, CLBYTEPTR Data);
+int cl_nor_get_disk_param (unsigned long* TotalPage, unsigned long* BytesPerPage,
+			   unsigned long* Cylinders, unsigned long* PagesPerTrk,
+			   unsigned long* Heads);
+#endif      /*  __CL_LOGIC__  */
+
diff --git a/drivers/block/cl_flash/Kconfig b/drivers/block/cl_flash/Kconfig
new file mode 100644
index 0000000..60aa80d
--- /dev/null
+++ b/drivers/block/cl_flash/Kconfig
@@ -0,0 +1,11 @@
+#
+# Block device driver configuration
+#
+
+config ARMCORE_NOR
+	bool "CompuLab NOR flash driver"
+	depends on ARMCORE_FLASH
+config ARMCORE_NAND
+	bool "CompuLab NAND flash driver"
+	depends on ARMCORE_FLASH
+
diff --git a/drivers/block/cl_flash/Makefile b/drivers/block/cl_flash/Makefile
new file mode 100644
index 0000000..538cb2c
--- /dev/null
+++ b/drivers/block/cl_flash/Makefile
@@ -0,0 +1,12 @@
+#
+# Makefile for Compulab flash disk driver
+#
+
+EXTRA_CFLAGS += -DTARGET_ARM_CORE -DFLASH_PLATFORM_LINUX
+
+obj-$(CONFIG_ARMCORE_FLASH)	+= fdrv.o
+
+fdrv-y				+=  cl_nordev.o cl_blkdev.o CL_FlashDrv
+
+
+fdrv-$(CONFIG_MACH_ARMCORE)	+= cl_nanddev_x270.o
diff --git a/drivers/block/cl_flash/cl_blkdev.c b/drivers/block/cl_flash/cl_blkdev.c
new file mode 100644
index 0000000..adb030d
--- /dev/null
+++ b/drivers/block/cl_flash/cl_blkdev.c
@@ -0,0 +1,731 @@
+/*
+ * Flash Disk Driver for Linux.
+ * Generic block device and genric disk implementation
+ *
+ * Copyright Compulab 2003-2006 (c).
+ */
+
+#include <linux/timer.h>
+#include <linux/hdreg.h>
+#include <linux/devfs_fs_kernel.h>
+#include <linux/blkdev.h>
+#include <linux/blkpg.h>
+#include <linux/ioctl.h>
+
+#include "CL_Logic.h"
+#include "cl_blkdev.h"
+
+/*  I/O Controls  */
+#define CL_FLASH_IOC_MAGIC          'f'
+#define CL_FLASH_IO_GET_PARAM        _IOWR (CL_FLASH_IOC_MAGIC, 1, char[12])
+#define CL_FLASH_IO_DIRECT_ACCESS    _IOWR (CL_FLASH_IOC_MAGIC, 2, char[524])
+
+#define FLUSH_INTERVAL	100
+
+struct cl_blkdev;
+
+struct flash_blkdev_ops {
+	/* timer for periodic flushes of NAND flash */
+	void (*flush_proc)(void* dev);
+
+	/* HW specific ioctl */
+	int (*flash_hw_ioctl)(struct cl_blkdev *dev, struct inode *inode,
+			      struct file *file, unsigned int cmd,
+			      unsigned long arg);
+
+	/* HW specific request handling */
+	int (*do_flash_hw_request)(struct cl_blkdev *dev, struct request *q);
+	/* HW specific cleanups */
+	int (*flash_hw_release)(struct cl_blkdev *dev, struct inode *inode,
+				struct file *file);
+};
+
+struct cl_blkdev_priv {
+	/* thread is dead indication */
+	struct completion thread_dead;	
+	/* flag to notify the thread that we are done */
+	int exiting;
+	/* thread wait queue head for requests */
+	wait_queue_head_t thread_wq;
+	/* block device request queue */
+	struct request_queue *rq;
+	/* request queue lock */
+	spinlock_t queue_lock;
+};
+
+struct cl_blkdev {
+	struct cl_blkdev_priv *blkdev_priv;
+	struct gendisk	*flash_disk;
+	struct flash_blkdev_ops *ops;
+	struct semaphore sem;
+	char name[32];
+		
+	int major;
+	void *hw_private; /* Low level hook */
+
+#ifdef CONFIG_PROC_FS
+	/* proc entry */
+	struct proc_dir_entry	*pde;
+#endif
+};
+
+#define FLASH_SECTOR	512
+
+/* declarations of cl_mem_set etc */
+#include "cl_common.c"
+
+
+/***************************************************************/
+/* Flash software write protect setup			       */
+/***************************************************************/
+unsigned long wpstart=0, wpend=0;
+
+static int __init wpstart_det(char *str) /*30-May-04, interrupts */
+{
+	wpstart = simple_strtol(str, NULL, 0);
+	return 1;
+}
+
+static int __init wpend_det(char *str) /*30-May-04, interrupts */
+{
+	wpend = simple_strtol(str, NULL, 0);
+	return 1;
+}
+
+__setup("wpstart=", wpstart_det); 
+__setup("wpend=", wpend_det); 
+
+
+/***************************************************************/
+/* generic block device interface			       */
+/***************************************************************/
+/* cl_blkdev_open: open a device */
+static int cl_blkdev_open(struct inode *inode, struct file *file)
+{
+	return 0;
+}
+
+static int cl_blkdev_check_media_change(struct gendisk* dev)
+{
+	return 0;	    /*	Disk not changed  */
+}
+
+static int cl_blkdev_revalidate(struct gendisk* dev)
+{
+	return 0;
+}
+
+/* cl_blkdev_release: release the device */
+static int cl_blkdev_release(struct inode *inode, struct file *file)
+{
+	struct cl_blkdev *dev;
+	dev = inode->i_bdev->bd_disk->private_data;
+	
+	down (&dev->sem);
+	dev->ops->flash_hw_release(dev, inode, file);
+	up (&dev->sem);
+
+	return 0;
+}
+
+/* 
+   cl_blkdev_ioctl: handle device ioctl's 
+   common ioctls (if any) for NAND and NOR flash are handled here
+   then HW specific ioctl handler is invoked
+ */
+static int cl_blkdev_ioctl(struct inode *inode, 
+			   struct file *file, u_int cmd, u_long arg)
+{
+	struct cl_blkdev *dev;
+
+	if ((!inode) || !(inode->i_rdev))
+		return -EINVAL;
+
+	dev = inode->i_bdev->bd_disk->private_data;
+	return dev->ops->flash_hw_ioctl(dev, inode, file, cmd, arg);
+}
+
+static struct block_device_operations flash_fops =
+{
+	.owner			= THIS_MODULE,
+	.open			= cl_blkdev_open,
+	.release		= cl_blkdev_release,
+	.ioctl			= cl_blkdev_ioctl,
+	.media_changed 		= cl_blkdev_check_media_change,
+	.revalidate_disk	= cl_blkdev_revalidate
+};
+
+static int cl_nand_request (struct cl_blkdev *_dev, struct request * req);
+
+/* wake up the flashdiskd thread to handle the request */
+static void do_cl_blkdev_request(struct request_queue *rq)
+{
+	struct cl_blkdev *dev = rq->queuedata;
+	wake_up(&dev->blkdev_priv->thread_wq);
+}
+
+void cl_blkdev_suspend(struct cl_blkdev* dev)
+{
+	dev->ops->flush_proc(dev);
+}
+
+/***************************************************************/
+/* flashdiskd thread is handling all transfer requests         */
+/***************************************************************/
+static int cl_flashdisk_thread(void *arg)
+{
+	struct cl_blkdev *dev = (struct cl_blkdev*)arg;
+	struct request_queue *rq = dev->blkdev_priv->rq;
+	unsigned long flush_period = msecs_to_jiffies(FLUSH_INTERVAL);
+	unsigned long last_flush_jiffies = jiffies;
+
+	current->flags |= PF_MEMALLOC/*  | PF_NOFREEZE */;
+	daemonize("%sd", "flashdisk");
+
+	while (!dev->blkdev_priv->exiting) {
+		struct request *req;
+		int res = 0;
+		DECLARE_WAITQUEUE(wait, current);
+
+		try_to_freeze();
+
+		spin_lock_irq(rq->queue_lock);
+		req = elv_next_request(rq);
+
+		if (!req) {
+			add_wait_queue(&dev->blkdev_priv->thread_wq, &wait);
+			set_current_state(TASK_INTERRUPTIBLE);
+
+			spin_unlock_irq(rq->queue_lock);
+
+			schedule();
+			remove_wait_queue(&dev->blkdev_priv->thread_wq, &wait);
+
+			continue;
+		}
+
+		dev = req->rq_disk->private_data;
+		spin_unlock_irq(rq->queue_lock);
+
+		down(&dev->sem);
+		res = dev->ops->do_flash_hw_request(dev, req);
+
+		if ( jiffies - last_flush_jiffies > flush_period ) {
+			if ( dev->ops->flush_proc )
+				dev->ops->flush_proc(dev);
+			last_flush_jiffies = jiffies;
+		}
+		up(&dev->sem);
+
+		spin_lock_irq(rq->queue_lock);
+		end_request(req, res);
+		spin_unlock_irq(rq->queue_lock);
+	}
+	complete_and_exit(&dev->blkdev_priv->thread_dead, 0);
+}
+
+/***************************************************************/
+/* block device initialization routines                        */
+/***************************************************************/
+
+/*
+  cl_blkdev_init: 
+	- initialize and register generic block device, 
+	- initialize timers for peroidic flushes
+	- initialize thread syncronization data
+	- start request processing thread
+
+  dev	- preallocated device that should be initialized
+  ops	- HW specific implementation of block device ioctl, do_request etc
+  name	- device name
+*/
+int cl_blkdev_init(struct cl_blkdev *dev, 
+		   struct flash_blkdev_ops *ops, const char *name)
+{
+	int ret;
+
+	/* allocate the thread synchronization structure */
+	dev->blkdev_priv = kmalloc(sizeof(*dev->blkdev_priv), GFP_KERNEL);
+	if (!dev->blkdev_priv)
+		return -ENOMEM;
+	memset(dev->blkdev_priv, 0, sizeof(*dev->blkdev_priv));
+
+	dev->ops = ops;
+	dev->major = 0;
+	strcpy(dev->name, name);
+
+	/* register block device */
+	if ((dev->major = register_blkdev(dev->major, dev->name)) <= 0) {
+		printk("flash: Unable to get major number.\n");
+		return -ENODEV;
+	}
+	else 
+		printk("Major number received: %d\n", dev->major);
+
+	/* initialize data for 'flashdiskd' thread */
+	spin_lock_init(&dev->blkdev_priv->queue_lock);
+	init_completion(&dev->blkdev_priv->thread_dead);
+	init_waitqueue_head(&dev->blkdev_priv->thread_wq);
+	init_MUTEX(&dev->sem);
+
+	/* initialize block device request queue */
+	dev->blkdev_priv->rq = blk_init_queue(do_cl_blkdev_request, 
+					      &dev->blkdev_priv->queue_lock);
+	if(!dev->blkdev_priv->rq) {
+		printk ("Could not initialize queue.\n");
+		unregister_blkdev(dev->major, dev->name);
+		kfree(dev->blkdev_priv);
+		return -ENOMEM;
+	}
+	dev->blkdev_priv->rq->queuedata = dev;
+	blk_queue_hardsect_size(dev->blkdev_priv->rq, FLASH_SECTOR);
+
+	/* start thread */
+	ret = kernel_thread(cl_flashdisk_thread, dev, CLONE_KERNEL);
+	if (ret < 0) {
+		blk_cleanup_queue(dev->blkdev_priv->rq);
+		unregister_blkdev(dev->major, dev->name);
+		kfree(dev->blkdev_priv);
+		printk(KERN_ERR "%s: kernel_thread returned %d\n", __FUNCTION__, ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+/*
+  cl_blkdev_register_disk:
+	- allocate generic dik object
+	- setup the disk (major, minors, name, ops)
+	- register the disk
+
+  dev	- block device enclosing the disk
+  name	- disk name
+  size	- size of the disk in sectors
+*/
+int cl_blkdev_register_disk(struct cl_blkdev *dev, 
+			    const char* name, sector_t size)
+{
+	/* allocate disk data structure */
+	dev->flash_disk = alloc_disk(16);
+	if (! dev->flash_disk) 
+		return -ENOMEM;
+	
+	/* initialize disk parameters */
+	dev->flash_disk->major = dev->major;
+	dev->flash_disk->first_minor = 0;
+	dev->flash_disk->fops = &flash_fops;
+	dev->flash_disk->private_data = dev;
+	dev->flash_disk->queue = dev->blkdev_priv->rq;
+
+	/* set /dev node names */
+	strcpy(dev->flash_disk->disk_name, name);
+	strcpy(dev->flash_disk->devfs_name, name);
+	set_capacity(dev->flash_disk, size);
+
+	/*  Insert this disk into linked list of disks  */
+	add_disk(dev->flash_disk);
+
+	return 0;
+}
+
+/*
+  cl_blkdev_unregister: unregister flash disk and associated block device
+*/
+void cl_blkdev_unregister(struct cl_blkdev *dev)
+{
+	dev->blkdev_priv->exiting = 1;
+	wake_up(&dev->blkdev_priv->thread_wq);
+	wait_for_completion(&dev->blkdev_priv->thread_dead);
+
+	del_gendisk(dev->flash_disk);
+	put_disk(dev->flash_disk);
+	blk_cleanup_queue(dev->blkdev_priv->rq);
+
+	unregister_blkdev(dev->major, dev->name);
+}
+
+/***************************************************************/
+/* NAND flash specific                                         */
+/***************************************************************/
+int format = 0;
+MODULE_PARM(format, "i");
+
+#define CACHE_SIZE 128
+
+/* This buffer is used for cach allocation, when cash size is bigger
+   than 128kb. 300 KB is the approximate amount needed for cache of 128
+   pages, 2kb each. */
+#define BUFFER_SIZE (300 * 1024)
+#define MAXIMUM_ALLOCATABLE_MEMORY (128 * 1024)
+char tmp_buff[BUFFER_SIZE];
+
+/* 
+   cl_nand_mem_alloc: allocates memory for driver cache 
+*/
+void* cl_nand_mem_alloc (unsigned long size)
+{
+	static int buf_not_used = 1;
+	if ((size > MAXIMUM_ALLOCATABLE_MEMORY) && 
+	    (size < BUFFER_SIZE) && buf_not_used) {
+		buf_not_used = 0;
+		return (void*)tmp_buff;
+	}
+	return kmalloc (size, GFP_KERNEL);
+}
+
+/* 
+   cl_nand_mem_free: frees memory allocated for driver cache 
+*/
+void cl_nand_mem_free (void* ptr)
+{
+	kfree (ptr);
+}
+
+/* 
+   cl_nand_flush_proc: flushes driver caches to the device
+*/
+static void cl_nand_flush_proc (void* _dev)
+{
+	struct cl_blkdev *blkdev = (struct cl_blkdev*)_dev;
+	struct cl_nand_dev *dev = (struct cl_nand_dev*)blkdev->hw_private;
+
+	dev->logic_sync(dev->logic);
+	cl_trace_log ("Data synced\n");
+	dev->last_end_write_cmd = 0;
+}
+
+/* 
+   cl_nand_request: handles an incoming IO request 
+*/
+static int cl_nand_request (struct cl_blkdev *_dev, struct request * req)
+{
+	struct cl_blkdev *blkdev = (struct cl_blkdev*)_dev;
+	struct cl_nand_dev *dev = (struct cl_nand_dev*)blkdev->hw_private;
+
+	u_int block, count;
+	int code=1, i;
+
+	block = req->sector;
+	count = req->current_nr_sectors;
+
+	switch (rq_data_dir(req)) {
+		case 0:	/* READ */
+			for (i = 0, code = 1;  i < count;  i++)
+				if (!dev->logic_read_page(
+					    dev->logic, block + i,
+					    (char*)req->buffer + i * 512)) {
+					cl_trace_log ("Reading failed.\n");
+					code = 0;    /*	failure */
+					break;
+				}
+			break;
+		case 1:	/* WRITE */
+			for (i = 0, code = 1;  i < count;  i++) {
+				if(wpend) {
+					if (((block + i) >= wpstart) || 
+					    ((block + i) <= wpend)) {
+						code=0; 
+						break;
+					}
+				}
+				if (!dev->logic_write_page(
+					    dev->logic, block + i,
+					    (char*)req->buffer + i * 512)) {
+					cl_trace_log ("Writing failed.\n");
+					code = 0;    /*	failure */
+					break;
+				}
+			}
+			dev->last_end_write_cmd = jiffies;
+			break;
+		default:
+			printk("do_flash_request: unknown request\n");
+			break;
+	}
+
+	return code;
+}
+
+/* 
+   cl_nand_ioctl: handles device ioctl's 
+*/
+static int cl_nand_ioctl(struct cl_blkdev *_dev, struct inode *inode,
+			 struct file *file,unsigned int cmd,unsigned long arg)
+{
+	struct cl_nand_dev *dev = (struct cl_nand_dev*)_dev->hw_private;
+
+	cl_trace_log ("flash_ioctl called.\n");
+	printk("fdrv.o ioctl\n");
+	if ((!inode) || !(inode->i_rdev))
+		return -EINVAL;
+
+	switch (cmd) {
+		case HDIO_GETGEO:
+		{
+			struct hd_geometry *geometry = (struct hd_geometry*)arg;
+			if (!geometry)
+				return -EINVAL; /* Bad arguments to ioctl */
+			put_user(dev->logic_get_param(dev->logic,
+						      CL_FLASH_CYLINDERS_NUM, 
+						      0),
+				 &geometry->cylinders);
+			put_user(dev->logic_get_param(dev->logic,
+						      CL_FLASH_HEADS_NUM, 0),
+				 &geometry->heads);
+			put_user(dev->logic_get_param(dev->logic,
+						      CL_FLASH_SECTORS_NUM, 0),
+				 &geometry->sectors);
+			put_user(0, &geometry->start);
+			return 0;
+		}
+		case BLKGETSIZE:
+			if (!arg)
+				return -EINVAL;
+			return put_user(dev->logic_get_param(
+						dev->logic,
+						CL_FLASH_TOTAL_SIZE, 0) / 512,
+					(long *) arg);
+		case HDIO_SET_DMA:
+			/*	We don't use DMA for flash. 
+				This has no meaning  */
+			if (!capable (CAP_SYS_ADMIN))
+				return -EACCES;
+			return 0;
+		case HDIO_GET_DMA:
+			return put_user( 0, (long *) arg);	/*  No DMA  */
+		case HDIO_GET_MULTCOUNT:
+			/*  We don't have a limitation of number of 
+			    sectors in op.  */
+			return put_user (128, (long *) arg);
+		case BLKRRPART:
+		case BLKFLSBUF:
+		case BLKROSET:
+		case BLKROGET:
+		case BLKRASET:
+		case BLKRAGET:
+		case BLKPG:
+		case CL_FLASH_IO_GET_PARAM:
+		{
+			int err;
+			long* prm = (long*)arg;
+			err = access_ok(VERIFY_READ, prm,
+					sizeof(long) * 2) ? 0 : -EFAULT;
+			if (err)
+				return err;
+			err = access_ok(VERIFY_WRITE, prm,
+					sizeof (long)) ? 0 : -EFAULT;
+			if (err)
+				return err;
+			prm[0] = dev->logic_get_param(dev->logic, 
+						      prm[0], prm[1]);
+			return 0;
+		}
+
+		case CL_FLASH_IO_DIRECT_ACCESS:
+		{
+			int err;
+			printk("====> CL_FLASH_IO_DIRECT_ACCESS\n");
+			long* prm = (long*)arg;
+			err = access_ok(VERIFY_READ, prm,
+					sizeof(long) * 3) ? 0 : -EFAULT;
+			if(err) return err;
+			err = access_ok(VERIFY_WRITE, prm,
+					CL_FLASH_SECTOR_SIZE) ? 0 : -EFAULT;
+			if(err) return err;
+			return dev->logic_direct_access(
+				dev->logic,
+				(cl_nand_direct_access_type)prm[0],
+				(unsigned short)prm[1],
+				(unsigned short)prm[2],
+				(unsigned char*)(prm + 3));
+		}
+		
+		default:
+			return -EINVAL;
+	}
+}
+
+/* 
+   cl_nand_release: releases the device 
+*/
+static int cl_nand_release (struct cl_blkdev *_dev,
+			    struct inode *inode, struct file *file)
+{
+	struct cl_nand_dev *dev = (struct cl_nand_dev*)_dev->hw_private;
+
+	dev->logic_sync(dev->logic);
+	cl_trace_log ("Data synced after RELEASE command\n");
+	dev->last_end_write_cmd = 0;
+
+	return 0;
+}
+
+static struct flash_blkdev_ops nand_blkdev_ops = {
+	.flush_proc = cl_nand_flush_proc,
+	.flash_hw_ioctl = cl_nand_ioctl,
+	.do_flash_hw_request = cl_nand_request,
+	.flash_hw_release = cl_nand_release
+};
+
+#ifdef CONFIG_PROC_FS
+/***************************************************************/
+/* proc entry /proc/flashdisk implementation                   */
+/***************************************************************/
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+
+static void cl_nand_proc_show(struct seq_file *s, struct cl_blkdev *_dev)
+{
+	struct cl_nand_dev *dev = _dev->hw_private;
+
+	unsigned long heads, sects, tot_size, cylinders;
+	unsigned short sector_size, page_size;
+	long read_page_cnt, write_page_cnt, reclaim_cnt;
+
+	tot_size = dev->logic_get_param(dev->logic, CL_FLASH_TOTAL_SIZE, 0);
+	heads = dev->logic_get_param(dev->logic, CL_FLASH_HEADS_NUM, 0);
+	sects = dev->logic_get_param(dev->logic, CL_FLASH_SECTOR_SIZE, 0);
+	cylinders = dev->logic_get_param(dev->logic, CL_FLASH_CYLINDERS_NUM, 0);
+	sector_size = dev->logic_get_param(dev->logic, CL_FLASH_SECTOR_SIZE, 0);
+	page_size = dev->logic_get_param(dev->logic, CL_FLASH_PAGE_SIZE, 0);
+	read_page_cnt = dev->logic_get_param(dev->logic,
+					     CL_FLASH_READ_PAGE_CNT, 0);
+	write_page_cnt = dev->logic_get_param(dev->logic,
+					      CL_FLASH_WRITE_PAGE_CNT, 0);
+	reclaim_cnt = dev->logic_get_param(dev->logic, CL_FLASH_RECLAIM_CNT, 0);
+
+
+	seq_printf(s, "NAND flash disk:\n");
+	seq_printf(s, "\ttotal size: %lu Mbytes (%lu bytes)\n",
+		   (tot_size >> 20), tot_size);
+	seq_printf(s, "\theads: %lu \tcylinders: %lu\tsectors: %lu\n", heads,
+		   cylinders, sects);
+	seq_printf(s, "\tsector: %d\tpage: %d\n", sector_size, page_size);
+	seq_printf(s, "Stats:\n");
+	seq_printf(s, "\tread: %ld\twritten: %ld\treclaimed: %ld\n",
+		   read_page_cnt, write_page_cnt, reclaim_cnt);
+}
+
+static int cl_blkdev_proc_show(struct seq_file *s, void *unused)
+{
+	struct cl_blkdev *dev = s->private;
+
+	seq_printf(s, "CompuLab flash disks:\n");
+	cl_nand_proc_show(s, dev);
+
+	return 0;
+}
+
+static int cl_blkdev_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, cl_blkdev_proc_show, PDE(inode)->data);
+}
+
+static struct file_operations proc_ops = {
+	.open		= cl_blkdev_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+		   
+static const char proc_filename[] = "flashdisk";
+
+static void cl_blkdev_proc_create_file(struct cl_blkdev *dev)
+{
+	struct proc_dir_entry *pde;
+	pde = create_proc_entry(proc_filename, 0666, NULL);
+	if (pde == NULL)
+		return;
+
+	pde->proc_fops = &proc_ops;
+	pde->data = dev;
+	dev->pde = pde;
+}
+
+static void cl_blkdev_remove_proc_file(struct cl_blkdev *dev)
+{
+	if (dev->pde)
+		remove_proc_entry(proc_filename, NULL);
+}
+
+#else 
+
+#define cl_blkdev_create_proc_file(x) do {} while(0)
+#define cl_blkdev_remove_proc_file(x) do {} while(0)
+
+#endif
+
+/*******************************************************************/
+/* NAND device initialization and cleanup                          */
+/*******************************************************************/
+/* 
+   cl_nand_flash_init:
+	- initialize the CL_Logic
+	- register the block device and gendisk
+
+   dev	- preallocated cl_nand_dev object 
+   cl_nand_linux - HW interface
+*/
+int cl_nand_flash_init(struct cl_nand_dev *dev, cl_nand_map_if *cl_nand_linux)
+{
+	const char *name = "nand";
+	int ret = 0;
+	printk ("Nand Flash disk driver, CompuLab");
+
+	if( wpend ) 
+		printk("NAND Write Protection activated from %ld to %ld.\n",
+		       wpstart, wpend);
+
+	if (format)
+		printk ("Formatting Nand flash . . .\n");
+	dev->logic = dev->logic_create(cl_nand_linux, CACHE_SIZE, format, FLASH_SECTOR);
+	if (!dev->logic) {
+		printk ("Flash logic couldn't be created.\n");
+		return -1;
+	}
+
+	dev->blkdev = kmalloc(sizeof(*dev->blkdev), GFP_KERNEL);
+	if ( !dev->blkdev ) {
+		return -ENOMEM;
+	}
+	
+	dev->blkdev->hw_private = dev;
+	if ( (ret = cl_blkdev_init(dev->blkdev, &nand_blkdev_ops, name)) ) {
+		printk(KERN_ERR "%s: cl_blkdev initialization failed: %d\n", 
+		       __FUNCTION__, ret);
+		dev->logic_free(dev->logic);
+		return ret;
+	}
+
+	ret = cl_blkdev_register_disk(dev->blkdev, name,
+				      dev->logic_get_param(dev->logic,
+							   CL_FLASH_TOTAL_SIZE, 
+							   0) / 512);
+	if ( ret ) {
+		printk(KERN_ERR "%s: NAND disk registration failed: %d\n", 
+		       __FUNCTION__, ret);
+		cl_blkdev_unregister(dev->blkdev);
+		dev->logic_free(dev->logic);
+		return ret;
+	}
+
+	cl_blkdev_proc_create_file(dev->blkdev);
+
+	return 0;
+}
+
+/* 
+   cl_nand_flash_cleanup: performs cleanup when driver is no longer used
+*/
+void cl_nand_flash_cleanup(struct cl_nand_dev * dev)
+{
+	cl_blkdev_unregister(dev->blkdev);
+	if ( dev->logic )
+		dev->logic_free(dev->logic);
+
+	cl_blkdev_remove_proc_file(dev->blkdev);
+	
+	if ( dev->blkdev )
+		kfree(dev->blkdev);
+}
diff --git a/drivers/block/cl_flash/cl_blkdev.h b/drivers/block/cl_flash/cl_blkdev.h
new file mode 100644
index 0000000..bca1944
--- /dev/null
+++ b/drivers/block/cl_flash/cl_blkdev.h
@@ -0,0 +1,43 @@
+#ifndef __CL_BLKDEV_H__
+#define __CL_BLKDEV_H__
+
+struct cl_blkdev;
+
+struct cl_nand_dev {
+	struct cl_blkdev *blkdev; 
+	cl_logic logic;
+	unsigned long last_end_write_cmd;
+
+	/* CL logic access layer */
+	cl_logic (*logic_create)(cl_nand_map_if*, long,
+				 int, unsigned short);
+	void (*logic_free)(cl_logic);
+	long (*logic_get_param)(cl_logic, cl_logic_param, long);
+	int  (*logic_read_page)(cl_logic, long, CLBYTEPTR);
+	int  (*logic_write_page)(cl_logic, long, CLBYTEPTR);
+	void (*logic_on_idle)(cl_logic, int);
+	void (*logic_sync)(cl_logic);
+	int  (*logic_direct_access)(cl_logic,cl_nand_direct_access_type,
+				    unsigned short, unsigned char, CLBYTEPTR);
+};
+
+extern int cl_nand_flash_init(struct cl_nand_dev *dev, cl_nand_map_if *cl_nand_linux);
+extern void cl_nand_flash_cleanup(struct cl_nand_dev * dev);
+
+#define INIT_NAND_DEV(dev) \
+	do {								\
+		dev->logic = 0;						\
+		dev->blkdev = 0;					\
+		dev->last_end_write_cmd = 0;				\
+		dev->logic_create = cl_logic_create;			\
+		dev->logic_free = cl_logic_free;			\
+		dev->logic_get_param = cl_logic_get_param;		\
+		dev->logic_read_page = cl_logic_read_page;		\
+		dev->logic_write_page = cl_logic_write_page;		\
+		dev->logic_on_idle = cl_logic_on_idle;			\
+		dev->logic_sync = cl_logic_sync;			\
+		dev->logic_direct_access = cl_logic_direct_access;	\
+	} while(0)
+
+
+#endif /*  __CL_BLKDEV_H__ */
diff --git a/drivers/block/cl_flash/cl_common.c b/drivers/block/cl_flash/cl_common.c
new file mode 100644
index 0000000..a0d2a9c
--- /dev/null
+++ b/drivers/block/cl_flash/cl_common.c
@@ -0,0 +1,52 @@
+void cl_zero_mem (void* ptr, long size)
+{
+	memset (ptr, 0, size);
+}
+
+void cl_ff_mem (void* ptr, long size)
+{
+	memset (ptr, 0xff, size);
+}
+void cl_mem_copy (void* dest,  void* src, long size)
+{
+	memcpy (dest, src, size);
+}
+
+int cl_mem_compare (void* mem1, void* mem2, long size)
+{
+	return memcmp (mem1, mem2, size);
+}
+
+unsigned long cl_get_jiffies (void)
+{
+	return jiffies;
+}
+
+unsigned long cl_nand_get_max_cache_time (void)
+{
+	return HZ * 30;       /*  30 seconds in cache maximum  */
+}
+
+void cl_trace_log ( char* format, ...)
+{
+#ifdef DO_CL_TRACE_LOG
+	char full_msg[300];
+	va_list marker;
+
+	va_start(marker, format);
+	vsprintf(full_msg, format, marker);
+	printk(full_msg);
+	va_end(marker);
+#endif
+}
+
+void cl_error_log ( char* format, ...)
+{
+	char full_msg[300];
+	va_list marker;
+
+	va_start(marker, format);
+	vsprintf(full_msg, format, marker);
+	printk(full_msg);
+	va_end(marker);
+}
diff --git a/drivers/block/cl_flash/cl_nanddev_x270.c b/drivers/block/cl_flash/cl_nanddev_x270.c
new file mode 100644
index 0000000..71f05f8
--- /dev/null
+++ b/drivers/block/cl_flash/cl_nanddev_x270.c
@@ -0,0 +1,233 @@
+/*
+ * drivers/block/cl_flash/cl_nandded_x270.c
+ *
+ * Flash Disk Driver for CM-X270 platform.
+ * Low level device interface implementation
+ *
+ * Copyright Compulab 2003-2006 (c).
+ */
+
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/pxa-regs.h>
+#include <asm/arch/cm-x270.h>
+
+#include "CL_Logic.h"
+#include "cl_blkdev.h"
+
+/*  The following macro enables flash activity indication by LEDs  */
+#undef USE_LEDS
+
+#define NAND_RB			(GPLR2 & (1<<25))
+
+#define NandCLE		(1<<0)
+#define NandALE		(1<<1)
+
+/*
+ * Values specific to the ARMCore
+ */
+volatile unsigned long * FLASH_DATA;
+volatile unsigned long * FLASH_DATA_ALE;
+volatile unsigned long * FLASH_DATA_CLE;
+
+/* asm-arm/arch-pxa/hardware.h defines UNCACHED_ADDR */
+volatile unsigned char * UNC = (volatile unsigned char *)UNCACHED_ADDR;
+
+/*******************************************************************/
+/* CM-X270 NAND HW access layer                                    */
+/*******************************************************************/
+static inline void nand_cs_on(void)
+{
+	GPCR0 = 1<<11;
+	while( (GPLR0 & (1<<11)) );
+}
+
+static inline void nand_cs_off(void)
+{
+	unsigned char dummy;
+	asm volatile ("mcr p15, 0, r0, c7, c10, 4":::"r0");
+	dummy=*UNC;
+
+	GPSR0 = 1<<11;
+	while( !(GPLR0 & (1<<11)) );
+}
+
+static void FlashInitial(void)
+{
+}
+
+static void FlashChipSelect (int on, int need_auto_operation)
+{
+	static int cs_state = -1;
+
+	if (need_auto_operation)
+		on = 1;
+
+	if (cs_state == on)
+		return;
+	
+	cs_state = on;
+
+	if (on) {
+		nand_cs_on();
+	}
+	else {
+		nand_cs_off();
+	}
+}
+
+static unsigned char FlashReadByte (unsigned char offset)
+{
+	return (unsigned char)(*FLASH_DATA >> 16);
+}
+
+static void FlashWriteByte (unsigned char offset, unsigned char data)
+{
+    if(offset & NandALE) *FLASH_DATA_ALE = (data << 16);
+    else if(offset & NandCLE) *FLASH_DATA_CLE = (data << 16);
+    else *FLASH_DATA = (data << 16);
+}
+
+static void FlashBlockRead (unsigned char* data, int count)
+{
+    while (count--)	
+        *data++ = (unsigned char)(*FLASH_DATA >> 16);
+}
+
+static void FlashBlockWrite ( unsigned char* data, int count)
+{
+    while (count--)	
+        *FLASH_DATA = (*data++ << 16);
+}
+
+/*  Orange LED used by Linux kernel activity  */
+static void FlashCoreLeds (short operation, short reclaim)
+{
+#ifdef USE_LEDS
+
+#endif
+}
+
+static void do_nothing (void)
+{
+}
+
+int nand_delay(unsigned long microseconds) 
+{
+	if ( microseconds < 1000 ) {
+		udelay(microseconds);
+		return 0;
+	}
+	udelay(1000);
+	udelay(1000);
+	udelay(1000);
+	return 0;
+}
+
+/* Wait on Ready/Busy signal */
+static int RBWait(unsigned long microseconds)
+{
+	unsigned char dummy;
+	int i=0;
+
+	/* ensure there's no outstanding bus transaction */
+	asm volatile ("mcr p15, 0, r0, c7, c10, 4":::"r0");
+	dummy=*UNC;
+
+	/* protect from big delays in R/B GPIO falling edge (or no R/B
+	   falling edge activity) */
+	while((NAND_RB == 1) && (i < 3000)){
+		udelay(1);
+		i++;
+	};
+
+	if ( i > 0 )
+		printk(KERN_DEBUG "%s: No immediate R/B activity\n", __FILE__);
+
+	if (i == 3000){
+		printk(KERN_DEBUG "%s: No R/B activity for 3 ms\n", __FILE__);
+		return (0);
+	}
+
+	i=0;
+
+	/* protect from big delays in R/B GPIO rising edge */
+	while((NAND_RB == 0) && (i < 3000)){
+		udelay(1);
+		i++;
+	};
+
+	if (i == 3000){
+		printk(KERN_DEBUG "%s: R/B timed out\n", __FILE__);
+		return (0);
+	}
+
+	/* ensure there's no outstanding bus transaction */
+	asm volatile ("mcr p15, 0, r0, c7, c10, 4":::"r0");
+	dummy=*UNC;
+
+	return(1);
+}
+
+static cl_nand_map_if cl_nand_linux = {
+        .init = FlashInitial,
+        .destroy = do_nothing,
+        .chip_select = FlashChipSelect,
+        .readb = FlashReadByte,
+        .writeb = FlashWriteByte,
+        .blockread = FlashBlockRead,
+        .blockwrite = FlashBlockWrite,
+        .activity_leds = FlashCoreLeds,
+        .sleep = nand_delay,
+        .rbwait = RBWait
+};
+
+static struct cl_nand_dev nand_dev;
+
+/* 
+   nand_flash_init:
+	- perform board specific initialization
+	- initialize NAND device data structure
+	- initialize block device layer
+*/
+static int nand_flash_init (void)
+{
+	struct cl_nand_dev *dev = &nand_dev;
+
+	FLASH_DATA = (volatile unsigned long*)ioremap(PXA_CS1_PHYS, 12);
+	if (FLASH_DATA == NULL) {
+		printk("Bad NAND flash window at %X (already in use)\n", 0x04000000);
+		return -1;
+	}
+	FLASH_DATA_CLE = FLASH_DATA + 1;
+	FLASH_DATA_ALE = FLASH_DATA + 2;
+
+	INIT_NAND_DEV(dev);
+	return cl_nand_flash_init(dev, &cl_nand_linux);
+}
+
+#ifdef CONFIG_ARMCORE_NAND
+int cl_nand_init_module(void)
+{
+	return nand_flash_init();
+}
+
+void cl_nand_cleanup_module(void)
+{
+	struct cl_nand_dev *dev = &nand_dev;
+	cl_nand_flash_cleanup(dev);
+}
+#else
+int cl_nand_init_module(void)
+{
+	return 0;
+}
+
+void cl_nand_cleanup_module(void)
+{
+}
+#endif
diff --git a/drivers/block/cl_flash/cl_nordev.c b/drivers/block/cl_flash/cl_nordev.c
new file mode 100644
index 0000000..85ae58a
--- /dev/null
+++ b/drivers/block/cl_flash/cl_nordev.c
@@ -0,0 +1,594 @@
+/*  
+    Flash Disk Driver Interface for Linux 2.4.x
+    Written by Vova Lifliand
+*/
+
+/*  Includes  */
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/timer.h>
+#include <linux/genhd.h>
+#include <linux/hdreg.h>
+#include <linux/ioport.h>
+#include <linux/init.h>
+#include <linux/devfs_fs_kernel.h>
+#include <linux/delay.h>
+
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+
+/*  Macros for correct linux/blk.h inclusion  */
+
+#define DEVICE_NAME	    	"nor"
+
+static int major = 0;	    
+
+#define FLASH_SECTOR	512
+
+#include <linux/blkdev.h>
+#include <linux/blkpg.h>
+
+extern void cl_error_log ( char* format, ...);
+extern void cl_trace_log ( char* format, ...);
+extern void cl_mem_copy (void* dest,  void* src, long size);
+
+
+/*  Undefine for custom LEDs usage  */
+#undef USE_LEDS
+
+/*  CrFlash driver interface  */
+#ifndef FLASH_PLATFORM_LINUX
+#define FLASH_PLATFORM_LINUX
+#endif
+#include "CL_Logic.h"
+
+typedef  unsigned long ULONG;
+
+/*  Forward functions declaration  */
+static int flash_open (struct inode *inode,struct file *file);
+static void do_flash_request (request_queue_t * q);
+static int flash_ioctl (struct inode *inode,struct file *file,unsigned int cmd,unsigned long arg);
+static int flash_release (struct inode *inode, struct file *file);
+
+static DECLARE_MUTEX (nor_flash_sem);
+static int nor_flash_sem_catched = 0;
+
+
+volatile unsigned short * NorFlashMem;
+
+static int flash_check_media_change (struct gendisk* dev)
+{
+/*    printk ("flash_check_media_change called.\r\n");*/
+    return 0;	    /*	Disk not changed  */
+}
+
+static int flash_revalidate (struct gendisk* dev)
+{
+/*    printk ("flash_revalidate called.\r\n");*/
+    return 0;
+}
+
+static struct block_device_operations flash_fops =
+{
+	.owner 			= THIS_MODULE,
+	.open			= flash_open,
+	.release		= flash_release,
+	.ioctl			= flash_ioctl,
+	.media_changed 		= flash_check_media_change,
+	.revalidate_disk	= flash_revalidate
+};
+
+static struct gendisk *flash_gendisk;
+static spinlock_t flash_lock;
+static struct request_queue *flash_queue;
+
+
+#ifdef CONFIG_ARMCORE_NOR
+/* nor_flash_init: register the block device number and set up pointer tables */
+int __init nor_flash_init (void)
+{
+    ULONG trash1, trash2, trash3, trash4, TotalSect;
+
+    /*  Request memory for NOR Flash  */
+    NorFlashMem = (volatile unsigned short*)ioremap (0x00000000, 0x800000);
+    if (NorFlashMem == NULL) {
+        printk("Bad NOR flash window at %X (already in use)\n", 0x00000000);
+        return -1;
+    }
+
+    /*  Do flash initialization  */
+    if (!cl_nor_init_flash()) {
+	    printk("NOR: Flash initialization failed\n");
+	    iounmap((void __iomem *)NorFlashMem);
+	    return -1;
+    }
+
+	spin_lock_init(&flash_lock);
+	flash_queue = blk_init_queue(do_flash_request, &flash_lock);
+	if(flash_queue == NULL)
+    {
+        printk ("Could not initialize queue.\r\n");
+	iounmap((void __iomem *)NorFlashMem);
+        return -1;
+    }
+	blk_queue_hardsect_size(flash_queue, FLASH_SECTOR);
+
+    if ((major=register_blkdev (0, DEVICE_NAME)) <= 0)
+    {
+		printk("flash: Unable to get major number \n");
+		iounmap((void __iomem *)NorFlashMem);
+		return -1;
+    }  else printk("Major number received: %d\n", major);
+
+    /*  Insert this disk into linked list of disks  */
+
+    flash_gendisk = alloc_disk(16);
+    if (! flash_gendisk) return -ENOMEM;
+    flash_gendisk->major = major;
+	flash_gendisk->first_minor = 0;
+	flash_gendisk->fops = &flash_fops;
+	flash_gendisk->private_data=NULL;
+	flash_gendisk->queue = flash_queue;
+	strcpy(flash_gendisk->disk_name, "nor");
+    cl_nor_get_disk_param( &TotalSect, &trash1, &trash2, &trash3, &trash4);
+	set_capacity(flash_gendisk, TotalSect);
+    add_disk(flash_gendisk);
+
+    /*  Starting flush timer: the cl_timer_proc will be executed on each timer interrupt  */
+
+    return 0;
+}
+#else
+int __init nor_flash_init (void)
+{
+	return 0;
+}
+#endif
+
+/* flash_open: open a device */
+static int flash_open (struct inode *inode, struct file *file)
+{
+    
+	return 0;
+    
+}
+
+/* do_flash_request: handle an incoming request */
+static void do_flash_request (request_queue_t * q)
+{
+    u_int block, count;
+    int code=1, i;
+	struct request* req=NULL;
+
+    while ((code == 1) && ((req = elv_next_request(q)) != NULL)) 
+    {
+	    block = req->sector;
+	    // printk ("req->nr_sectors = %d.\r\n", req->nr_sectors);
+	    // printk ("req->current_nr_sectors = %d.\r\n", req->current_nr_sectors);
+	    count = req->current_nr_sectors;
+
+	    nor_flash_sem_catched++;
+	    down (&nor_flash_sem);    
+	    
+	    switch (rq_data_dir(req)) {
+		case 0:	// READ
+		    for (i = 0, code = 1;  i < count;  i++) 
+				// printk ("Reading sector %d (of %d).\r\n", block + i, count);
+    			if (!cl_nor_read_page ( block + i,
+					(void *)((char*)req->buffer + i * 512))) {
+				//			printk ("Reading failed.\r\n");
+					    code = 0;    /*	failure  */
+			    		break;
+				}
+				// printk ("Reading completed successfully.\r\n");
+		    break;
+		case 1:	// WRITE
+		    for (i = 0, code = 1;  i < count;  i++) {
+				// printk ("Writing sector %d.\r\n", block + i);
+				if (!cl_nor_write_page ( block + i,
+	 				(void *)((char*)req->buffer + i * 512))) {
+				//			printk ("Writing failed.\r\n");
+			    		code = 0;    /*	failure  */
+					    break;
+				}
+				// printk ("Writing completed successfully.\r\n");
+		    }	
+		    break;
+		default:
+		    printk("do_flash_request: unknown request\n");
+		    break;
+	    }
+	    up (&nor_flash_sem);
+	    nor_flash_sem_catched--;
+		end_request (req, code);	/* wrap up, 0 = fail, 1 = success */
+	}
+}
+
+/* flash_ioctl: handle device ioctl's */
+static int flash_ioctl (struct inode *inode, struct file *file, u_int cmd, u_long arg)
+{
+    ULONG trash1, trash2, trash3, trash4, TotalSect;
+    
+    // printk ("flash_ioctl called.\r\n");
+
+    if ((!inode) || !(inode->i_rdev))
+	return -EINVAL;
+
+    cl_nor_get_disk_param( &TotalSect, &trash1, &trash2, &trash3, &trash4);
+    // printk ("flash_ioctl in switch.\r\n");
+    switch (cmd)
+    {
+	case HDIO_GETGEO:
+	{
+	    struct hd_geometry *geometry = (struct hd_geometry*)arg;
+	    if (!geometry)
+		return -EINVAL;	    /*	Bad arguments to ioctl  */
+	    put_user(TotalSect / 32 , &geometry->cylinders);
+	    put_user(1, &geometry->heads);
+	    put_user(32, &geometry->sectors);
+	    put_user(2, &geometry->start);
+	}
+	case BLKGETSIZE:
+	    if (!arg)
+		return -EINVAL;
+	    return put_user (TotalSect, (long *) arg);
+	case HDIO_SET_DMA:	    /*	We don't use DMA for flash. This has no meaning  */
+	    if (!capable (CAP_SYS_ADMIN))
+		return -EACCES;
+	    return 0;
+	case HDIO_GET_DMA:
+	    return put_user( 0, (long *) arg);	/*  No DMA  */
+	case HDIO_GET_MULTCOUNT:	/*  We don't have a limitation of number of sectors in op.  */
+	    return put_user (128, (long *) arg);
+	case BLKFLSBUF:
+	case BLKROSET:
+	case BLKROGET:
+	case BLKRASET:
+	case BLKRAGET:
+	case BLKPG:
+    
+	default:
+	    return -EINVAL;
+    }
+}
+
+/* flash_release: release the device */
+static int flash_release (struct inode *inode, struct file *file)
+{
+    
+    return 0;
+}
+
+#ifdef CONFIG_ARMCORE_NOR
+static void flash_done (void)
+{
+	del_gendisk(flash_gendisk);
+	put_disk(flash_gendisk);    
+    blk_cleanup_queue(flash_queue);
+
+    /*	Free memory allocated by flash module  */
+    cl_nor_free_mem ();
+
+    unregister_blkdev (major, DEVICE_NAME);
+}
+#else
+static void flash_done (void)
+{
+}
+#endif
+
+extern int cl_nand_init_module(void);
+extern void cl_nand_cleanup_module(void);
+
+int flash_init_module(void)
+{
+    int error;
+
+    error = cl_nand_init_module();
+    if (error) return error;
+
+    error = nor_flash_init();
+    if (error) return error;
+
+    return 0;
+}
+
+void flash_cleanup_module(void)
+{
+    flash_done();
+    cl_nand_cleanup_module();
+}
+
+module_init (flash_init_module);
+module_exit (flash_cleanup_module);	
+
+//-------------------- CMNLIN.C ---------
+
+#define TRUE 1
+#define FALSE 0
+
+#define FL_CLKS_PER_SEC		    182
+
+#define NAND_HEAP_SIZE	    64000	    /*	bytes  */
+#define NOR_HEAP_SIZE	    50000	    /*	bytes  */
+
+/*  NOR Flash constants  */
+#define NorFlashBlockSize             0x10000L	/*  64 KB  */
+#define NorFlashDiskPagesPerBlock   127
+
+#define NOR_DRIVE_STARTING_BLOCK	28
+
+/*  NOR Flash Functions Support  */
+
+/*  Constructor / destructor  */
+static void Nor_Create(void);
+/*  Basic operations  */
+static void Nor_EnableFlashMap(int EnableFlag);
+static unsigned long Nor_GetSize(void);
+static int Nor_GetPagesPerBlock(void);
+static int Nor_ReadHeader (unsigned short BlockN, cl_nor_block_header* Header);
+static int Nor_ReadPage (unsigned short BlockN, unsigned char PageNum, CLBYTEPTR DestBuff);
+static int Nor_SetBlockState(unsigned short BlockN, unsigned short Signature,
+			     unsigned short State, unsigned short Reserved);
+static int Nor_InvalidatePage(unsigned short BlockN, unsigned char PageN);
+static int Nor_WritePage(unsigned short BlockN, unsigned char PageN,
+                           CLBYTEPTR PageData, unsigned short PageIndex);
+static int Nor_EraseBlock(unsigned short BlockN);
+
+extern volatile unsigned short * NorFlashMem;
+unsigned char Nor_IntelFlash;
+
+void Nor_EmptyFunc(void){};
+
+cl_nor_flash_access NorFlashAccess =
+	{
+		Nor_Create,
+		Nor_EmptyFunc, /*NULL,*/		/*  Destructor not needed  */
+		Nor_GetSize,
+		Nor_EnableFlashMap,
+		Nor_GetPagesPerBlock,
+		Nor_ReadHeader,
+		Nor_ReadPage,
+		Nor_SetBlockState,
+		Nor_InvalidatePage,
+		Nor_WritePage,
+		Nor_EraseBlock,
+	};
+
+/*  Driver see NOR Flash Blocks as linear, while there are BIOS holes  */
+static int Nor_GetPhysBlockIndex (int BlockN)
+{
+    return (BlockN + NOR_DRIVE_STARTING_BLOCK);
+}
+
+static void NorWrWord(unsigned long index, unsigned short data)
+{
+    *(NorFlashMem+index)=data;
+}
+extern void NorWrWord(unsigned long index, unsigned short data);
+
+static unsigned short NorRdWord(unsigned long index)
+{
+    return *(NorFlashMem+index);
+}
+
+static unsigned char Nor_OutAMDCommand(unsigned short command)
+{
+    NorWrWord(0x555, 0xAAAA);        
+    NorWrWord(0x2AA, 0x5555);        
+    NorWrWord(0x555, command);        
+    return TRUE;
+}
+
+
+static void Nor_Create(void)
+{
+    /*	Nothing should be done here - all services are provided by BIOS  */
+}
+
+static unsigned long Nor_GetSize(void)
+{
+    unsigned long NorFlashSize = 0x100000;
+    unsigned short n;
+/*    unsigned long i; */
+    
+    /*  Determine flash type  */
+    NorWrWord(0, 0xFFFF);
+    NorWrWord(0, 0x9090);
+    if(NorRdWord(0) == 0x89)
+        Nor_IntelFlash = TRUE;
+    else Nor_IntelFlash = FALSE;
+    NorWrWord(0, 0xFFFF);
+
+    /*  Query flash size  */
+    /*  1. Do reset command  */
+    NorWrWord(0, 0xF0F0);        /*  was 0f0f  */
+    NorWrWord(0, 0xFFFF);        /*  Will also reset intel flash  */
+    /*  2. Enter CFI mode  */
+    NorWrWord(0x55, 0x9898);
+    /*  3. Read flash size  */
+/*  READ WHOLE CFI  for (i=10; i<0x3D; i++){
+        n = NorRdWord(i);
+        printk("CFI n=%x\n", n);} */
+    n = NorRdWord(0x27);
+    /*  4. Do reset again - exit CFI mode  */
+    NorWrWord(0, 0xF0F0);        /*  was 0f0f  */
+    NorWrWord(0, 0xFFFF);        /*  Will also reset intel flash  */
+    /*  Exclude BIOS area  */
+    if((n>0x17) | (n<0x14)) n=0x14; // if detection is unsuccessfull (no CFI) default to 1MB
+    NorFlashSize = (1 << n);        /*  2 ^ n  */
+
+    cl_error_log("NOR Flash (%s) size: %d MB total\n",(Nor_IntelFlash ? "Intel" : "AMD"),NorFlashSize / (1024 * 1024));
+                  
+    if(NorFlashSize == (1024 * 1024)) {
+		cl_error_log("1Mb flash not supported!\n");
+		return 0;
+	}
+    
+    return     NorFlashSize -= NOR_DRIVE_STARTING_BLOCK * 64L * 1024L; /*exclude BIOS and jump areas, spareblocks etc.*/
+}
+
+/*  Remaps or unmaps MMS windows, allocated by flash  */
+static void Nor_EnableFlashMap (int EnableFlag)
+{
+    /*	Just to prevent warning  */
+    int x = EnableFlag;
+    EnableFlag = x;
+    /*	Nothing should be done here - all services are provided by BIOS  */
+}
+
+static int Nor_GetPagesPerBlock(void)
+{
+    return NorFlashDiskPagesPerBlock;
+}
+
+static int Nor_ReadHeader (unsigned short BlockN, cl_nor_block_header* Header)
+{
+
+    cl_mem_copy (Header,
+                 (char*)(NorFlashMem + (0x8000 * Nor_GetPhysBlockIndex(BlockN))),
+                 (sizeof (cl_nor_block_header) + 1) & 0xFFFE);
+    return 1;
+}
+
+static int Nor_ReadPage (unsigned short BlockN, unsigned char PageNum, CLBYTEPTR DestBuff)
+{
+    cl_mem_copy (DestBuff,
+                 (char*)(NorFlashMem + (0x8000 * Nor_GetPhysBlockIndex(BlockN)) +
+                               ((PageNum + 1) * (CL_NOR_FLASH_PAGE_SIZE / 2))),
+                 CL_NOR_FLASH_PAGE_SIZE);
+    return 1;
+}
+
+static int Nor_EraseBlock(unsigned short BlockN)
+{
+    unsigned long addr;
+    unsigned short dummy;
+    
+    addr=(Nor_GetPhysBlockIndex(BlockN)*NorFlashBlockSize)/2;
+    if(Nor_IntelFlash)
+    {           /*  Erase block sequence from Intel flash  */
+        NorWrWord(addr, 0xFFFF);
+        NorWrWord(addr, 0x7070);
+        NorWrWord(addr, 0x2020);
+        NorWrWord(addr, 0xD0D0);
+        NorWrWord(addr, 0xD0D0);
+        while(!(NorRdWord(addr) & 128))
+            ;
+        NorWrWord(0, 0xFFFF);
+        return TRUE;
+    }
+    else
+    {
+        /*  Do "erase block" commands sequence  */
+        if(!Nor_OutAMDCommand(0xF0F0))  return FALSE;
+        dummy = NorRdWord(addr);      /*  read and discard  */
+        if(!Nor_OutAMDCommand(0x8080)) return FALSE;
+        NorWrWord(0x555, 0xAAAA);        
+        NorWrWord(0x2AA, 0x5555);        
+        NorWrWord(addr, 0x3030);        
+
+        /*  Waiting block is erased - no timeout here  */
+        while(TRUE)
+        {
+            /*  Stall processor execution for about 20 microseconds <--- it is much less  */
+            for(dummy = 0;  dummy < 20;  dummy++)
+                ;
+            /*  Check if ready  */
+            if(NorRdWord(addr) == 0xFFFF)
+                return TRUE;
+        }
+    }
+}
+
+static int Nor_SetWord (unsigned long ofs, unsigned short word)
+{
+    unsigned short timeout = 0xFFF;
+    unsigned long addr;
+    addr = ((Nor_GetPhysBlockIndex (ofs >> 15))<<15)+(ofs&0x7FFF);// 15 because address is given for word argument
+    /*  The address should be word aligned since accessing by word and not by byte  */
+
+    if(Nor_IntelFlash)
+    {       /*  Write sequence from Intel flash  */
+        NorWrWord(addr, 0x4040);
+        NorWrWord(addr, word);
+        while(timeout--)
+			udelay(1);
+            if(NorRdWord(addr) & 128)
+            {
+                unsigned char res = !(NorRdWord(addr) & 16);
+                NorWrWord(addr, 0x5050);
+                NorWrWord(addr, 0xFFFF);
+                return res;
+            }
+        NorWrWord(0, 0x5050);
+    }
+    else
+    {       /*  Write sequence from AMD flash  */
+        /*  Output command is a necessary sequence to write word  */
+        if(!Nor_OutAMDCommand(0xA0A0))
+            return FALSE;
+
+        /*  Write data  */
+        NorWrWord(addr, word);
+        /*  Wait data written  */
+        while(timeout--)   {
+			udelay(1);
+            if(NorRdWord(addr) == word)
+                return TRUE;
+		}
+    }
+    /*  Failure  */
+    cl_error_log("ERROR: SetWord timeout.");
+
+    return FALSE;
+}
+
+static int Nor_SetBlockState(unsigned short BlockN, unsigned short Signature,
+                              unsigned short State, unsigned short Reserved)
+{
+    return Nor_SetWord ((BlockN * NorFlashBlockSize + 0)/2, Signature) &&
+           Nor_SetWord ((BlockN * NorFlashBlockSize + 2)/2, State) &&
+           Nor_SetWord ((BlockN * NorFlashBlockSize + 26 + 127 * 2)/2, Reserved);
+}
+
+static int Nor_InvalidatePage (unsigned short BlockN, unsigned char PageN)
+{
+    return Nor_SetWord ((BlockN * NorFlashBlockSize + 6 + 2 * PageN)/2, 0);
+}
+
+static int Nor_WritePage (unsigned short BlockN, unsigned char PageN,
+                            CLBYTEPTR PageData, unsigned short PageIndex)
+{
+    int words_left, dest_addr;
+    unsigned short* ptr;
+
+    /*  Write index to first page - header information  */
+    if(!Nor_SetWord((BlockN * NorFlashBlockSize + 6 + 2 * PageN)/2, PageIndex))
+    {
+        cl_error_log("A");
+        return FALSE;       /*  Couldn't write page index  */
+    }
+
+    /*  Write page data  */
+    words_left = (512 >> 1);     /*  Write by word  */
+    dest_addr = BlockN * NorFlashBlockSize + (PageN + 1) * 512;
+    ptr = (unsigned short*)PageData;
+    while(words_left--)
+    {
+        if(!Nor_SetWord(dest_addr/2, *ptr++))
+        {
+            cl_error_log("B");
+            return FALSE;           /*  Page data writing failure  */
+        }
+        dest_addr += 2;     /*  Write by word (2 bytes each write command)  */
+    }
+
+    return TRUE;
+}
+
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index 05ba410..a820db0 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -1020,5 +1020,11 @@ config TELCLOCK
 	  sysfs directory, /sys/devices/platform/telco_clock, with a number of
 	  files for controlling the behavior of this hardware.
 
+
+config EMV3020_RTC
+      tristate "EM-V3020 RTC"
+      ---help---
+        Support for EM Microelectronics V3020 RTC
+
 endmenu
 
diff --git a/drivers/char/Makefile b/drivers/char/Makefile
index 503dd90..625bfd9 100644
--- a/drivers/char/Makefile
+++ b/drivers/char/Makefile
@@ -49,6 +49,7 @@ obj-$(CONFIG_VIOCONS) += viocons.o
 obj-$(CONFIG_VIOTAPE)		+= viotape.o
 obj-$(CONFIG_HVCS)		+= hvcs.o
 obj-$(CONFIG_SGI_MBCS)		+= mbcs.o
+obj-$(CONFIG_EMV3020_RTC)       += emv3020.o
 
 obj-$(CONFIG_PRINTER) += lp.o
 obj-$(CONFIG_TIPAR) += tipar.o
diff --git a/drivers/char/emv3020.c b/drivers/char/emv3020.c
new file mode 100644
index 0000000..df7f1a4
--- /dev/null
+++ b/drivers/char/emv3020.c
@@ -0,0 +1,365 @@
+/*
+ * emv3020.c
+ *
+ * Driver for EMV3020 RTC
+ *
+ * Copyright (C) 2006 Compulab Ltd.
+ *
+ * 
+ * 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/fs.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/rtc.h>
+#include <linux/bcd.h>
+#include <linux/clk.h>
+
+#include <asm/hardware.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/rtc.h>
+
+#include <asm/hardware.h>
+#include <asm/delay.h>
+
+#define EMV3020_VA_RTC		emv3020_rtc_base
+
+static struct resource *emv3020_rtc_mem;
+static void __iomem *emv3020_rtc_base;
+
+#define DEBUG 0
+#if DEBUG
+static unsigned int rtc_debug = DEBUG;
+#else
+#define rtc_debug 0     /* gcc will remove all the debug code for us */
+#endif
+
+static void emv3020_set_reg(unsigned char address, unsigned char data)
+{
+	int i;
+
+	for ( i = 0; i < 4; i++ )
+		writel((address << (16-i)), EMV3020_VA_RTC);
+
+	if ( address < 0xe)
+		for ( i = 0; i < 8; i++)
+			writel((data << (16-i)), EMV3020_VA_RTC);
+}
+
+static unsigned char emv3020_get_reg(unsigned char address)
+{
+	unsigned int data=0;
+	int i, tmp;
+
+	for ( i = 0; i < 4; i++ )
+		writel((address << (16-i)), EMV3020_VA_RTC);
+
+	for ( i = 0; i < 8; i++ ) {
+		tmp = readl(EMV3020_VA_RTC);
+		data |= ((tmp & 0x10000) >> (16 - i));
+	}
+
+	return data;
+}
+
+static int emv3020_detect(struct device *dev) 
+{
+	int i;
+	int temp;
+
+	for ( i=0; i<8; i++)
+		temp = readl(EMV3020_VA_RTC);
+
+	emv3020_set_reg(0x2, 0x33);
+
+	if ( emv3020_get_reg(0x2) == 0x33 ) {
+		emv3020_set_reg(0x0, 0x0);	
+		return 0;
+	}
+
+	return -ENODEV;
+}
+ 
+static int emv3020_rtc_gettime(struct rtc_time *dt)
+{
+	int ret=0;
+
+	emv3020_set_reg(0x0F, 0);
+
+	dt->tm_sec  = emv3020_get_reg(0x02);
+	dt->tm_min  = emv3020_get_reg(0x03);
+	dt->tm_hour = emv3020_get_reg(0x04);
+	dt->tm_mday = emv3020_get_reg(0x05);
+	dt->tm_mon  = emv3020_get_reg(0x06);
+	dt->tm_wday = emv3020_get_reg(0x08);
+	dt->tm_year = emv3020_get_reg(0x07);
+
+	BCD_TO_BIN(dt->tm_sec);
+	BCD_TO_BIN(dt->tm_min);
+	BCD_TO_BIN(dt->tm_hour);
+	BCD_TO_BIN(dt->tm_mday);
+	BCD_TO_BIN(dt->tm_mon);
+	BCD_TO_BIN(dt->tm_wday);
+	BCD_TO_BIN(dt->tm_year);
+	dt->tm_year += 100;
+
+	if(rtc_debug)printk("\n%s : Read RTC values\n",__FUNCTION__);
+	if(rtc_debug)printk("tm_hour: %i\n",dt->tm_hour);
+	if(rtc_debug)printk("tm_min : %i\n",dt->tm_min);
+	if(rtc_debug)printk("tm_sec : %i\n",dt->tm_sec);
+	if(rtc_debug)printk("tm_year: %i\n",dt->tm_year);
+	if(rtc_debug)printk("tm_mon : %i\n",dt->tm_mon);
+	if(rtc_debug)printk("tm_mday: %i\n",dt->tm_mday);
+	if(rtc_debug)printk("tm_wday: %i\n",dt->tm_wday);
+
+	return ret;
+}
+
+static int emv3020_rtc_settime(struct rtc_time *dt)
+{
+	if(rtc_debug)printk("\n%s : Setting RTC values\n",__FUNCTION__);
+	if(rtc_debug)printk("tm_sec : %i\n",dt->tm_sec);
+	if(rtc_debug)printk("tm_min : %i\n",dt->tm_min);
+	if(rtc_debug)printk("tm_hour: %i\n",dt->tm_hour);
+	if(rtc_debug)printk("tm_mday: %i\n",dt->tm_mday);
+	if(rtc_debug)printk("tm_wday: %i\n",dt->tm_wday);
+	if(rtc_debug)printk("tm_year: %i\n",dt->tm_year);
+
+	dt->tm_year %= 100;
+	BIN_TO_BCD(dt->tm_sec);
+	BIN_TO_BCD(dt->tm_min);
+	BIN_TO_BCD(dt->tm_hour);
+	BIN_TO_BCD(dt->tm_mday);
+	BIN_TO_BCD(dt->tm_mon);
+	BIN_TO_BCD(dt->tm_wday);
+	BIN_TO_BCD(dt->tm_year);
+
+	emv3020_set_reg(0x02, dt->tm_sec);
+	emv3020_set_reg(0x03, dt->tm_min);
+	emv3020_set_reg(0x04, dt->tm_hour);
+	emv3020_set_reg(0x05, dt->tm_mday);
+	emv3020_set_reg(0x06, dt->tm_mon);
+	emv3020_set_reg(0x08, dt->tm_wday);
+	emv3020_set_reg(0x07, dt->tm_year);
+
+	emv3020_set_reg(0x0E, 0);
+
+	return 0;
+}
+
+static int emv3020_rtc_open(void)
+{
+	return 0;
+}
+
+static void emv3020_rtc_release(void)
+{
+}
+
+static int emv3020_rtc_ioctl(unsigned int cmd, unsigned long arg)
+{
+	struct rtc_time wtime;
+	int status = 0;
+
+	switch (cmd) {
+		default:
+		case RTC_UIE_ON:
+		case RTC_UIE_OFF:
+		case RTC_PIE_ON:
+		case RTC_PIE_OFF:
+		case RTC_AIE_ON:
+		case RTC_AIE_OFF:
+		case RTC_ALM_SET: 
+		case RTC_ALM_READ:
+		case RTC_IRQP_READ:
+		case RTC_IRQP_SET:
+		case RTC_EPOCH_READ:
+		case RTC_EPOCH_SET:
+		case RTC_WKALM_SET:
+		case RTC_WKALM_RD:
+			status = -EINVAL;
+			break;
+
+		case RTC_RD_TIME:
+			emv3020_rtc_gettime(&wtime);
+			if( copy_to_user((void *)arg, &wtime,
+					 sizeof (struct rtc_time)))
+				status = -EFAULT;
+			break;
+
+		case RTC_SET_TIME:
+			if (!capable(CAP_SYS_TIME)) {
+				status = -EACCES;
+				break;
+			}
+
+			if (copy_from_user(&wtime, (struct rtc_time *)arg,
+					   sizeof(struct rtc_time)) ) {
+				status = -EFAULT;
+				break;
+			}
+
+			emv3020_rtc_settime(&wtime);
+			break;
+	}
+
+	return status;
+}
+
+static char *emv3020_mon2str(unsigned int mon)
+{
+        char *mon2str[12] = {
+          "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+          "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+        };
+        if( mon > 11) return "error";
+        else return mon2str[ mon];
+}
+
+static int emv3020_rtc_proc( char *buf)
+{
+	char *p = buf;
+	struct rtc_time dt;
+
+	emv3020_rtc_gettime(&dt);
+
+	p += sprintf(p, "\nEMV3020 (Real Time Clock)\n");
+	p += sprintf(p, "Date/Time           : %02d-%s-%04d %02d:%02d:%02d\n",
+		     dt.tm_mday,
+		     emv3020_mon2str(dt.tm_mon),
+		     dt.tm_year+1900,
+		     dt.tm_hour,
+		     dt.tm_min,
+		     dt.tm_sec);
+	return  p - buf;
+}
+
+static struct rtc_ops emv3020_rtcops = {
+	.owner		= THIS_MODULE,
+	.open		= emv3020_rtc_open,
+	.release	= emv3020_rtc_release,
+	.ioctl		= emv3020_rtc_ioctl,
+	.read_time	= emv3020_rtc_gettime,
+	.set_time	= emv3020_rtc_settime,
+	.read_alarm	= 0,
+	.set_alarm	= 0,
+	.proc	        = emv3020_rtc_proc,
+};
+
+static int emv3020_rtc_remove(struct device *dev)
+{
+	unregister_rtc(&emv3020_rtcops);
+
+	if (emv3020_rtc_mem != NULL) {
+		pr_debug("emv3020_rtc: releasing emv3020_rtc_mem\n");
+		iounmap(emv3020_rtc_base);
+		release_resource(emv3020_rtc_mem);
+	}
+
+	return 0;
+}
+
+static int emv3020_rtc_probe(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct resource *res;
+	int ret;
+
+	pr_debug("%s: probe=%p, device=%p\n", __FUNCTION__, pdev, dev);
+
+	/* get the memory region */
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (res == NULL) {
+		dev_err(dev, "failed to get memory region resource\n");
+		return -ENOENT;
+	}
+
+	emv3020_rtc_mem = request_mem_region(res->start, 
+					     res->end - res->start + 1,
+					     pdev->name);
+
+	if (emv3020_rtc_mem == NULL) {
+		dev_err(dev, "failed to reserve memory region\n");
+		ret = -ENOENT;
+		goto exit_err;
+	}
+
+	emv3020_rtc_base = ioremap(res->start, res->end - res->start + 1);
+	if (emv3020_rtc_base == NULL) {
+		dev_err(dev, "failed ioremap()\n");
+		ret = -EINVAL;
+		goto exit_err;
+	}
+
+	emv3020_rtc_mem = res;
+	pr_debug("emv3020_rtc_base=%p\n", emv3020_rtc_base);
+
+	/* check to see if everything is setup correctly */
+	if ( (ret = emv3020_detect(dev)) != 0 ) {
+		iounmap(emv3020_rtc_base);
+		release_resource(emv3020_rtc_mem);
+		goto exit_err;
+	}
+
+	/* register RTC and exit */
+	register_rtc(&emv3020_rtcops);
+
+	return 0;
+
+ exit_err:
+	dev_err(dev, "error %d during initialisation\n", ret);
+
+	return ret;
+}
+
+#ifdef CONFIG_PM
+/* EMV3020 RTC Power management control */
+static int emv3020_rtc_suspend(struct device *dev, pm_message_t state)
+{
+	return 0;
+}
+
+static int emv3020_rtc_resume(struct device *dev)
+{
+	return 0;
+}
+#else
+#define emv3020_rtc_suspend NULL
+#define emv3020_rtc_resume  NULL
+#endif
+
+static struct device_driver emv3020_rtcdrv = {
+	.name		= "emv3020-rtc",
+	.bus		= &platform_bus_type,
+	.probe		= emv3020_rtc_probe,
+	.remove		= emv3020_rtc_remove,
+	.suspend	= emv3020_rtc_suspend,
+	.resume		= emv3020_rtc_resume,
+};
+
+static __init int emv3020_init(void)
+{
+	return driver_register(&emv3020_rtcdrv);
+}
+
+static __exit void emv3020_exit(void)
+{
+	driver_unregister(&emv3020_rtcdrv);
+}
+
+module_init(emv3020_init);
+module_exit(emv3020_exit);
+
+
+MODULE_AUTHOR ("Compulab Ltd.");
+MODULE_LICENSE ("GPL");
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig
index d633081..5e7f6ee 100644
--- a/drivers/ide/Kconfig
+++ b/drivers/ide/Kconfig
@@ -850,6 +850,13 @@ config BLK_DEV_IDE_BAST
 	  Say Y here if you want to support the onboard IDE channels on the
 	  Simtec BAST or the Thorcom VR1000
 
+config BLK_DEV_IDE_CM_X270
+	tristate "CompuLab CM-X270 IDE support"
+	depends on ARM && (MACH_ARMCORE)
+	help
+	  Say Y here if you want to support the onboard IDE channels on the
+	  CompuLab CM-X270 module
+
 config BLK_DEV_GAYLE
 	bool "Amiga Gayle IDE interface support"
 	depends on AMIGA
diff --git a/drivers/ide/arm/Makefile b/drivers/ide/arm/Makefile
index 6a78f07..e5cadb7 100644
--- a/drivers/ide/arm/Makefile
+++ b/drivers/ide/arm/Makefile
@@ -2,5 +2,6 @@
 obj-$(CONFIG_BLK_DEV_IDE_ICSIDE)	+= icside.o
 obj-$(CONFIG_BLK_DEV_IDE_RAPIDE)	+= rapide.o
 obj-$(CONFIG_BLK_DEV_IDE_BAST)		+= bast-ide.o
+obj-$(CONFIG_BLK_DEV_IDE_CM_X270)	+= cm-x270-ide.o
 
 EXTRA_CFLAGS	:= -Idrivers/ide
diff --git a/drivers/ide/arm/cm-x270-ide.c b/drivers/ide/arm/cm-x270-ide.c
new file mode 100644
index 0000000..d0e9b8a
--- /dev/null
+++ b/drivers/ide/arm/cm-x270-ide.c
@@ -0,0 +1,135 @@
+/* linux/drivers/ide/arm/cm-x270-ide.c
+ *
+ * Copyright (c) 2006 CompuLab, Ltd
+ *  Mike Rapoport <mike@compulab.co.il>
+ *
+ * Based on linux/drivers/ide/arm/bast-ide.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 version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/ide.h>
+#include <linux/init.h>
+
+#include <asm/mach-types.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/arch/pxa-regs.h>
+#include <asm/arch/cm-x270.h>
+
+#define CMX270_SB270_IDECS0_VIRT (CMX270_IDE104_VIRT + (1<<24) + (1<<25))
+#define CMX270_SB270_IDECS1_VIRT (CMX270_IDE104_VIRT + (1<<25))
+#define CMX270_ATX_IDECS0_VIRT (CMX270_IDE104_VIRT + (1<<25))
+#define CMX270_ATX_IDECS1_VIRT (CMX270_IDE104_VIRT + (1<<25) + (1<<22))
+
+/* list of registered interfaces */
+static ide_hwif_t *ifs[1];
+
+static int __init
+cmx270_ide_register(unsigned int base, unsigned int aux, int irq,
+		 ide_hwif_t **hwif)
+{
+	hw_regs_t hw;
+
+	memset(&hw, 0, sizeof(hw));
+
+	if(!base || !aux) return -EINVAL;
+
+	printk(KERN_DEBUG "%s: base = %08x, aux = %08x\n", __FUNCTION__,
+	       base, aux);
+
+        /* Different mappings for local bus IDE and PCMCIA IDE */
+	if(base == CMX270_SB270_IDECS0_VIRT) {
+		hw.io_ports[IDE_DATA_OFFSET] = base + 0;
+		hw.io_ports[IDE_ERROR_OFFSET] = base + (0x1<<3);
+		hw.io_ports[IDE_NSECTOR_OFFSET]= base + (0x2<<3);
+		hw.io_ports[IDE_SECTOR_OFFSET]= base + (0x3<<3);
+		hw.io_ports[IDE_LCYL_OFFSET]= base + (0x4<<3);
+		hw.io_ports[IDE_HCYL_OFFSET]= base + (0x5<<3);
+		hw.io_ports[IDE_SELECT_OFFSET]=	base + (0x6<<3);
+		hw.io_ports[IDE_STATUS_OFFSET]=	base + (0x7<<3);
+		hw.io_ports[IDE_CONTROL_OFFSET] = aux+(0x6<<3);
+	}
+	else if (base == CMX270_ATX_IDECS0_VIRT) { /* atx base */
+		hw.io_ports[IDE_DATA_OFFSET] = base + 0;
+		hw.io_ports[IDE_ERROR_OFFSET] =	base + 8;
+		hw.io_ports[IDE_NSECTOR_OFFSET]= base + 2;
+		hw.io_ports[IDE_SECTOR_OFFSET]= base + 10;
+		hw.io_ports[IDE_LCYL_OFFSET]= base + 4;
+		hw.io_ports[IDE_HCYL_OFFSET]= base + 12;
+		hw.io_ports[IDE_SELECT_OFFSET]= base + 6; //6;
+		hw.io_ports[IDE_STATUS_OFFSET]= base + 14;
+		hw.io_ports[IDE_CONTROL_OFFSET] = (aux+0x6);
+	} else {
+		printk(KERN_DEBUG "%s: registering wrong IDE i/f\n", __FUNCTION__);
+		hw.io_ports[IDE_DATA_OFFSET] = base + 8;
+		hw.io_ports[IDE_ERROR_OFFSET] = base + 13;
+		hw.io_ports[IDE_NSECTOR_OFFSET] = base + 2;
+		hw.io_ports[IDE_SECTOR_OFFSET] = base + 3;
+		hw.io_ports[IDE_LCYL_OFFSET] = base + 4;
+		hw.io_ports[IDE_HCYL_OFFSET] = base + 5;
+		hw.io_ports[IDE_SELECT_OFFSET] = base + 6;
+		hw.io_ports[IDE_STATUS_OFFSET] = base + 7;
+		hw.io_ports[IDE_CONTROL_OFFSET] = aux;
+	}
+	
+	hw.irq = irq;
+
+	return ide_register_hw(&hw, hwif);
+}
+
+static int __init cmx270_ide_init(void)
+{
+	int retval = 0;
+
+	if (!(machine_is_armcore()))
+		goto out;
+
+	printk("CM-X270: initializing IDE interface\n");
+
+	MSC1 = 0x7ffc7ff4;
+
+	/* Interrupts on rising edge: lines are inverted before they get to
+           the PXA */
+	pxa_gpio_mode(IRQ_TO_GPIO(CMX270_IDE_IRQ));
+
+	/* try SB-X270 */
+	set_irq_type(CMX270_IDE_IRQ, IRQT_RISING);
+	retval = cmx270_ide_register(CMX270_SB270_IDECS0_VIRT,
+				 CMX270_SB270_IDECS1_VIRT,
+				 CMX270_IDE_IRQ, &ifs[0]);
+	if (retval >= 0) {
+		printk(KERN_DEBUG "%s: found IDE interface on SB-X270\n",
+		       __FUNCTION__);
+		goto out;
+	}
+
+	/* SB-X270 detection failed, try ATX */
+	set_irq_type(CMX270_IDE_IRQ, IRQT_FALLING);
+	retval = cmx270_ide_register(CMX270_ATX_IDECS0_VIRT,
+				 CMX270_ATX_IDECS1_VIRT,
+				 CMX270_IDE_IRQ, &ifs[0]);
+
+	if ( retval >= 0 ) {
+		printk(KERN_DEBUG "%s: found IDE interface on ATX\n",
+		       __FUNCTION__);
+		goto out;
+	}
+
+  out:
+	return retval;
+}
+
+module_init(cmx270_ide_init);
+
+MODULE_AUTHOR("CompuLab");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("CompuLab CM-X270 IDE driver");
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 550f297..ed5bb70 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -23,3 +23,13 @@ config MCP_UCB1200_TS
 	depends on MCP_UCB1200 && INPUT
 
 endmenu
+
+config UCB1400
+	tristate
+
+config UCB1400_TS
+	tristate "UCB1400 Touchscreen support"
+	depends on ARCH_LUBBOCK || MACH_MAINSTONE || MACH_ARMCORE
+	select UCB1400
+	select SND_AC97_BUS
+
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index adb29b5..24429d1 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -10,3 +10,10 @@ obj-$(CONFIG_MCP_UCB1200_TS)	+= ucb1x00-
 ifeq ($(CONFIG_SA1100_ASSABET),y)
 obj-$(CONFIG_MCP_UCB1200)	+= ucb1x00-assabet.o
 endif
+
+ucb1400-core-y			:= ucb1x00-core.o mcp-ac97.o
+obj-$(CONFIG_UCB1400_TS)	+= ucb1400-core.o ucb1x00-ts.o
+
+ucb1400-core-$(CONFIG_UCB1400)	:= ucb1x00-core.o mcp-ac97.o
+obj-$(CONFIG_UCB1400_TS)	+= ucb1400-core.o ucb1x00-ts.o
+
diff --git a/drivers/mfd/mcp-ac97.c b/drivers/mfd/mcp-ac97.c
new file mode 100644
index 0000000..223f8c2
--- /dev/null
+++ b/drivers/mfd/mcp-ac97.c
@@ -0,0 +1,151 @@
+/*
+ * linux/drivers/misc/mcp-ac97.c
+ *
+ * Author:	Nicolas Pitre
+ * Created:	Jan 14, 2005
+ * Copyright:	(C) MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This module provides the minimum replacement for mcp-core.c allowing for
+ * the UCB1400 chip to be driven by the ucb1x00 driver over an AC97 link.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/device.h>
+
+#include <sound/driver.h>
+#include <sound/core.h>
+#include <sound/ac97_codec.h>
+
+#include "mcp.h"
+
+/* ucb1x00 SIB register to ucb1400 AC-link register mapping */
+
+static const unsigned char regmap[] = {
+	0x5a,	/* UCB_IO_DATA */
+	0X5C,	/* UCB_IO_DIR */
+	0X5E,	/* UCB_IE_RIS */
+	0x60,	/* UCB_IE_FAL */
+	0x62,	/* UCB_IE_STATUS */
+	0,	/* UCB_TC_A */
+	0,	/* UCB_TC_B */
+	0,	/* UCB_AC_A */
+	0,	/* UCB_AC_B */
+	0x64,	/* UCB_TS_CR */
+	0x66,	/* UCB_ADC_CR */
+	0x68,	/* UCB_ADC_DATA */
+	0x7e,	/* UCB_ID */
+	0,	/* UCB_MODE */
+};
+
+unsigned int mcp_reg_read(struct mcp *mcp, unsigned int reg)
+{
+	ac97_t *ac97 = to_ac97_t(mcp->dev);
+	if (reg < ARRAY_SIZE(regmap)) {
+		reg = regmap[reg];
+		if (reg)
+			return ac97->bus->ops->read(ac97, reg);
+	}
+	return -1;
+}
+EXPORT_SYMBOL(mcp_reg_read);
+
+void mcp_reg_write(struct mcp *mcp, unsigned int reg, unsigned int val)
+{
+	ac97_t *ac97 = to_ac97_t(mcp->dev);
+	if (reg < ARRAY_SIZE(regmap)) {
+		reg = regmap[reg];
+		if (reg)
+			ac97->bus->ops->write(ac97, reg, val);
+	}
+}
+EXPORT_SYMBOL(mcp_reg_write);
+
+void mcp_enable(struct mcp *mcp)
+{
+}
+EXPORT_SYMBOL(mcp_enable);
+
+void mcp_disable(struct mcp *mcp)
+{
+}
+EXPORT_SYMBOL(mcp_disable);
+
+#define to_mcp_driver(d)	container_of(d, struct mcp_driver, drv)
+
+static int mcp_probe(struct device *dev)
+{
+	struct mcp_driver *drv = to_mcp_driver(dev->driver);
+	struct mcp *mcp;
+	int ret;
+
+	ret = -ENOMEM;
+	mcp = kmalloc(sizeof(*mcp), GFP_KERNEL);
+	if (mcp) {
+		memset(mcp, 0, sizeof(*mcp));
+		mcp->owner = THIS_MODULE;
+		mcp->dev = dev;
+		ret = drv->probe(mcp);
+		if (ret)
+			kfree(mcp);
+	}
+	if (!ret)
+		dev_set_drvdata(dev, mcp);
+	return ret;
+}
+
+static int mcp_remove(struct device *dev)
+{
+	struct mcp_driver *drv = to_mcp_driver(dev->driver);
+	struct mcp *mcp = dev_get_drvdata(dev);
+
+	drv->remove(mcp);
+	dev_set_drvdata(dev, NULL);
+	kfree(mcp);
+	return 0;
+}
+
+static int mcp_suspend(struct device *dev, pm_message_t state)
+{
+	struct mcp_driver *drv = to_mcp_driver(dev->driver);
+	struct mcp *mcp = dev_get_drvdata(dev);
+	int ret = 0;
+
+	if (drv->suspend)
+		ret = drv->suspend(mcp, state);
+	return ret;
+}
+
+static int mcp_resume(struct device *dev)
+{
+	struct mcp_driver *drv = to_mcp_driver(dev->driver);
+	struct mcp *mcp = dev_get_drvdata(dev);
+	int ret = 0;
+
+	if (drv->resume)
+		ret = drv->resume(mcp);
+	return ret;
+}
+
+int mcp_driver_register(struct mcp_driver *mcpdrv)
+{
+	mcpdrv->drv.owner = THIS_MODULE;
+	mcpdrv->drv.bus = &ac97_bus_type;
+	mcpdrv->drv.probe = mcp_probe;
+	mcpdrv->drv.remove = mcp_remove;
+	mcpdrv->drv.suspend = mcp_suspend;
+	mcpdrv->drv.resume = mcp_resume;
+	return driver_register(&mcpdrv->drv);
+}
+
+void mcp_driver_unregister(struct mcp_driver *mcpdrv)
+{
+	driver_unregister(&mcpdrv->drv);
+}
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/mcp-core.c b/drivers/mfd/mcp-core.c
index 75f401d..2a7c176 100644
--- a/drivers/mfd/mcp-core.c
+++ b/drivers/mfd/mcp-core.c
@@ -208,6 +208,7 @@ struct mcp *mcp_host_alloc(struct device
 		mcp->attached_device.bus = &mcp_bus_type;
 		mcp->attached_device.dma_mask = parent->dma_mask;
 		mcp->attached_device.release = mcp_release;
+		mcp->dev = &mcp->attached_device;
 	}
 	return mcp;
 }
diff --git a/drivers/mfd/mcp.h b/drivers/mfd/mcp.h
index c093a93..2897d8c 100644
--- a/drivers/mfd/mcp.h
+++ b/drivers/mfd/mcp.h
@@ -19,11 +19,12 @@ struct mcp {
 	int		use_count;
 	unsigned int	sclk_rate;
 	unsigned int	rw_timeout;
-	dma_device_t	dma_audio_rd;
-	dma_device_t	dma_audio_wr;
-	dma_device_t	dma_telco_rd;
-	dma_device_t	dma_telco_wr;
+/* 	dma_device_t	dma_audio_rd; */
+/* 	dma_device_t	dma_audio_wr; */
+/* 	dma_device_t	dma_telco_rd; */
+/* 	dma_device_t	dma_telco_wr; */
 	struct device	attached_device;
+	struct device	*dev;
 };
 
 struct mcp_ops {
diff --git a/drivers/mfd/ucb1x00-core.c b/drivers/mfd/ucb1x00-core.c
index aff83f9..f9a532b 100644
--- a/drivers/mfd/ucb1x00-core.c
+++ b/drivers/mfd/ucb1x00-core.c
@@ -23,6 +23,7 @@ #include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/errno.h>
 #include <linux/interrupt.h>
+#include <linux/kthread.h>
 #include <linux/device.h>
 #include <linux/mutex.h>
 
@@ -31,6 +32,12 @@ #include <asm/hardware.h>
 
 #include "ucb1x00.h"
 
+#if defined(CONFIG_UCB1400) || defined(CONFIG_UCB1400_MODULE)
+#define UCB_IS_1400(id)  ((id) == UCB_ID_1400)
+#else
+#define UCB_IS_1400(id)  (0)
+#endif
+
 static DEFINE_MUTEX(ucb1x00_mutex);
 static LIST_HEAD(ucb1x00_drivers);
 static LIST_HEAD(ucb1x00_devices);
@@ -58,9 +65,9 @@ void ucb1x00_io_set_dir(struct ucb1x00 *
 	spin_lock_irqsave(&ucb->io_lock, flags);
 	ucb->io_dir |= out;
 	ucb->io_dir &= ~in;
+	spin_unlock_irqrestore(&ucb->io_lock, flags);
 
 	ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir);
-	spin_unlock_irqrestore(&ucb->io_lock, flags);
 }
 
 /**
@@ -86,9 +93,9 @@ void ucb1x00_io_write(struct ucb1x00 *uc
 	spin_lock_irqsave(&ucb->io_lock, flags);
 	ucb->io_out |= set;
 	ucb->io_out &= ~clear;
+	spin_unlock_irqrestore(&ucb->io_lock, flags);
 
 	ucb1x00_reg_write(ucb, UCB_IO_DATA, ucb->io_out);
-	spin_unlock_irqrestore(&ucb->io_lock, flags);
 }
 
 /**
@@ -178,7 +185,7 @@ unsigned int ucb1x00_adc_read(struct ucb
 		schedule_timeout(1);
 	}
 
-	return UCB_ADC_DAT(val);
+	return UCB_IS_1400(ucb->id) ? (val & 0x3ff) : ((val & 0x7fe0) >> 5);
 }
 
 /**
@@ -223,6 +230,47 @@ static irqreturn_t ucb1x00_irq(int irqnr
 	return IRQ_HANDLED;
 }
 
+/*
+ * A restriction with interrupts exists when using the ucb1400, as
+ * the codec read/write routines may sleep while waiting for codec
+ * access completion and uses semaphores for access control to the
+ * AC97 bus.  A complete codec read cycle could take  anywhere from
+ * 60 to 100uSec so we *definitely* don't want to spin inside the
+ * interrupt handler waiting for codec access.  So, we handle the
+ * interrupt by scheduling a RT kernel thread to run in process
+ * context instead of interrupt context.
+ */
+static int ucb1x00_thread(void *_ucb)
+{
+	struct task_struct *tsk = current;
+	struct ucb1x00 *ucb = _ucb;
+
+	tsk->policy = SCHED_FIFO;
+	tsk->rt_priority = 1;
+	
+	while (!kthread_should_stop()) {
+		wait_for_completion_interruptible(&ucb->irq_wait);
+		if (try_to_freeze())
+			continue;
+		ucb1x00_irq(ucb->irq, ucb, NULL);
+		enable_irq(ucb->irq);
+	}
+
+	ucb->irq_task = NULL;
+	return 0;
+}
+
+static irqreturn_t ucb1x00_threaded_irq(int irqnr, void *devid, struct pt_regs *regs)
+{
+	struct ucb1x00 *ucb = devid;
+	if (irqnr == ucb->irq) {
+		disable_irq(ucb->irq);
+		complete(&ucb->irq_wait);
+		return IRQ_HANDLED;
+	}
+	return IRQ_NONE;
+}
+
 /**
  *	ucb1x00_hook_irq - hook a UCB1x00 interrupt
  *	@ucb:   UCB1x00 structure describing chip
@@ -276,18 +324,22 @@ void ucb1x00_enable_irq(struct ucb1x00 *
 
 	if (idx < 16) {
 		spin_lock_irqsave(&ucb->lock, flags);
-
-		ucb1x00_enable(ucb);
-		if (edges & UCB_RISING) {
+		if (edges & UCB_RISING)
 			ucb->irq_ris_enbl |= 1 << idx;
-			ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl);
-		}
-		if (edges & UCB_FALLING) {
+		if (edges & UCB_FALLING)
 			ucb->irq_fal_enbl |= 1 << idx;
-			ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl);
-		}
-		ucb1x00_disable(ucb);
 		spin_unlock_irqrestore(&ucb->lock, flags);
+
+		ucb1x00_enable(ucb);
+
+		/* This prevents spurious interrupts on the UCB1400 */
+		ucb1x00_reg_write(ucb, UCB_IE_CLEAR, 1 << idx);
+		ucb1x00_reg_write(ucb, UCB_IE_CLEAR, 0);
+
+		ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl);
+		ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl);
+
+		ucb1x00_disable(ucb);
 	}
 }
 
@@ -305,18 +357,16 @@ void ucb1x00_disable_irq(struct ucb1x00 
 
 	if (idx < 16) {
 		spin_lock_irqsave(&ucb->lock, flags);
-
-		ucb1x00_enable(ucb);
-		if (edges & UCB_RISING) {
+		if (edges & UCB_RISING)
 			ucb->irq_ris_enbl &= ~(1 << idx);
-			ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl);
-		}
-		if (edges & UCB_FALLING) {
+		if (edges & UCB_FALLING)
 			ucb->irq_fal_enbl &= ~(1 << idx);
-			ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl);
-		}
-		ucb1x00_disable(ucb);
 		spin_unlock_irqrestore(&ucb->lock, flags);
+
+		ucb1x00_enable(ucb);
+		ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl);
+		ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl);
+		ucb1x00_disable(ucb);
 	}
 }
 
@@ -349,16 +399,17 @@ int ucb1x00_free_irq(struct ucb1x00 *ucb
 		ucb->irq_ris_enbl &= ~(1 << idx);
 		ucb->irq_fal_enbl &= ~(1 << idx);
 
-		ucb1x00_enable(ucb);
-		ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl);
-		ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl);
-		ucb1x00_disable(ucb);
-
 		irq->fn = NULL;
 		irq->devid = NULL;
 		ret = 0;
 	}
 	spin_unlock_irq(&ucb->lock);
+
+	ucb1x00_enable(ucb);
+	ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl);
+	ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl);
+	ucb1x00_disable(ucb);
+
 	return ret;
 
 bad:
@@ -478,7 +529,7 @@ static int ucb1x00_probe(struct mcp *mcp
 	mcp_enable(mcp);
 	id = mcp_reg_read(mcp, UCB_ID);
 
-	if (id != UCB_ID_1200 && id != UCB_ID_1300) {
+	if (id != UCB_ID_1200 && id != UCB_ID_1300 && !UCB_IS_1400(id)) {
 		printk(KERN_WARNING "UCB1x00 ID not found: %04x\n", id);
 		goto err_disable;
 	}
@@ -491,12 +542,13 @@ static int ucb1x00_probe(struct mcp *mcp
 	memset(ucb, 0, sizeof(struct ucb1x00));
 
 	ucb->cdev.class = &ucb1x00_class;
-	ucb->cdev.dev = &mcp->attached_device;
+	ucb->cdev.dev = mcp->dev;
 	strlcpy(ucb->cdev.class_id, "ucb1x00", sizeof(ucb->cdev.class_id));
 
 	spin_lock_init(&ucb->lock);
 	spin_lock_init(&ucb->io_lock);
 	sema_init(&ucb->adc_sem, 1);
+	init_completion(&ucb->irq_wait);
 
 	ucb->id  = id;
 	ucb->mcp = mcp;
@@ -507,13 +559,22 @@ static int ucb1x00_probe(struct mcp *mcp
 		goto err_free;
 	}
 
-	ret = request_irq(ucb->irq, ucb1x00_irq, SA_TRIGGER_RISING,
-			  "UCB1x00", ucb);
+	ret = request_irq(ucb->irq,
+			  UCB_IS_1400(id) ? ucb1x00_threaded_irq : ucb1x00_irq,
+			  SA_TRIGGER_RISING, "UCB1x00", ucb);
 	if (ret) {
 		printk(KERN_ERR "ucb1x00: unable to grab irq%d: %d\n",
 			ucb->irq, ret);
 		goto err_free;
 	}
+	if (UCB_IS_1400(id)) {
+		ucb->irq_task = kthread_run(ucb1x00_thread, ucb, "kUCB1x00d");
+		if (IS_ERR(ucb->irq_task)) {
+			ret = PTR_ERR(ucb->irq_task);
+			ucb->irq_task = NULL;
+			goto err_irq;
+		}
+	}
 
 	mcp_set_drvdata(mcp, ucb);
 
@@ -531,6 +592,8 @@ static int ucb1x00_probe(struct mcp *mcp
 	goto out;
 
  err_irq:
+	if (UCB_IS_1400(id) && ucb->irq_task)
+		kthread_stop(ucb->irq_task);
 	free_irq(ucb->irq, ucb);
  err_free:
 	kfree(ucb);
@@ -553,6 +616,10 @@ static void ucb1x00_remove(struct mcp *m
 	}
 	mutex_unlock(&ucb1x00_mutex);
 
+	if (UCB_IS_1400(ucb->id) && ucb->irq_task) {
+		complete(&ucb->irq_wait);
+		kthread_stop(ucb->irq_task);
+	}
 	free_irq(ucb->irq, ucb);
 	class_device_unregister(&ucb->cdev);
 }
diff --git a/drivers/mfd/ucb1x00-ts.c b/drivers/mfd/ucb1x00-ts.c
index 79fd062..e68132d 100644
--- a/drivers/mfd/ucb1x00-ts.c
+++ b/drivers/mfd/ucb1x00-ts.c
@@ -35,7 +35,15 @@ #include <linux/kthread.h>
 
 #include <asm/dma.h>
 #include <asm/semaphore.h>
+
+/* FIXME: proper machine detection should be implemented */
+#ifdef CONFIG_SA1100_COLLIE
 #include <asm/arch/collie.h>
+#else
+#define machine_is_collie() (0)
+#define COLLIE_TC35143_GPIO_TBL_CHK (0)
+#endif
+
 #include <asm/mach-types.h>
 
 #include "ucb1x00.h"
@@ -45,7 +53,7 @@ struct ucb1x00_ts {
 	struct input_dev	*idev;
 	struct ucb1x00		*ucb;
 
-	wait_queue_head_t	irq_wait;
+	struct completion	irq_wait;
 	struct task_struct	*rtask;
 	u16			x_res;
 	u16			y_res;
@@ -98,7 +106,8 @@ static inline unsigned int ucb1x00_ts_re
 		udelay(55);
 
 		return ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_AD2, ts->adcsync);
-	} else {
+	} 
+	else {
 		ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
 				  UCB_TS_CR_TSMX_POW | UCB_TS_CR_TSPX_POW |
 				  UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_GND |
@@ -205,7 +214,6 @@ static int ucb1x00_thread(void *_ts)
 {
 	struct ucb1x00_ts *ts = _ts;
 	struct task_struct *tsk = current;
-	DECLARE_WAITQUEUE(wait, tsk);
 	int valid;
 
 	/*
@@ -217,10 +225,8 @@ static int ucb1x00_thread(void *_ts)
 
 	valid = 0;
 
-	add_wait_queue(&ts->irq_wait, &wait);
 	while (!kthread_should_stop()) {
 		unsigned int x, y, p;
-		signed long timeout;
 
 		ts->restart = 0;
 
@@ -242,8 +248,6 @@ static int ucb1x00_thread(void *_ts)
 
 
 		if (ucb1x00_ts_pen_down(ts)) {
-			set_task_state(tsk, TASK_INTERRUPTIBLE);
-
 			ucb1x00_enable_irq(ts->ucb, UCB_IRQ_TSPX, machine_is_collie() ? UCB_RISING : UCB_FALLING);
 			ucb1x00_disable(ts->ucb);
 
@@ -256,7 +260,15 @@ static int ucb1x00_thread(void *_ts)
 				valid = 0;
 			}
 
-			timeout = MAX_SCHEDULE_TIMEOUT;
+			/*
+			 * Since ucb1x00_enable_irq() might sleep due
+			 * to the way the UCB1400 regs are accessed, we
+			 * can't use set_task_state() before that call,
+			 * and not changing state before enabling the
+			 * interrupt is racy. A completion handler avoids
+			 * the issue.
+			 */
+			wait_for_completion_interruptible(&ts->irq_wait);
 		} else {
 			ucb1x00_disable(ts->ucb);
 
@@ -271,16 +283,12 @@ static int ucb1x00_thread(void *_ts)
 			}
 
 			set_task_state(tsk, TASK_INTERRUPTIBLE);
-			timeout = HZ / 100;
+			schedule_timeout(HZ/100);
 		}
 
 		try_to_freeze();
-
-		schedule_timeout(timeout);
 	}
 
-	remove_wait_queue(&ts->irq_wait, &wait);
-
 	ts->rtask = NULL;
 	return 0;
 }
@@ -293,7 +301,7 @@ static void ucb1x00_ts_irq(int idx, void
 {
 	struct ucb1x00_ts *ts = id;
 	ucb1x00_disable_irq(ts->ucb, UCB_IRQ_TSPX, UCB_FALLING);
-	wake_up(&ts->irq_wait);
+	complete(&ts->irq_wait);
 }
 
 static int ucb1x00_ts_open(struct input_dev *idev)
@@ -303,7 +311,7 @@ static int ucb1x00_ts_open(struct input_
 
 	BUG_ON(ts->rtask);
 
-	init_waitqueue_head(&ts->irq_wait);
+	init_completion(&ts->irq_wait);
 	ret = ucb1x00_hook_irq(ts->ucb, UCB_IRQ_TSPX, ucb1x00_ts_irq, ts);
 	if (ret < 0)
 		goto out;
@@ -337,8 +345,10 @@ static void ucb1x00_ts_close(struct inpu
 {
 	struct ucb1x00_ts *ts = idev->private;
 
-	if (ts->rtask)
+	if (ts->rtask) {
+		complete(&ts->irq_wait);
 		kthread_stop(ts->rtask);
+	}
 
 	ucb1x00_enable(ts->ucb);
 	ucb1x00_free_irq(ts->ucb, UCB_IRQ_TSPX, ts);
@@ -358,7 +368,7 @@ static int ucb1x00_ts_resume(struct ucb1
 		 * after sleep.
 		 */
 		ts->restart = 1;
-		wake_up(&ts->irq_wait);
+		complete(&ts->irq_wait);
 	}
 	return 0;
 }
diff --git a/drivers/mfd/ucb1x00.h b/drivers/mfd/ucb1x00.h
index 9c9a647..ff04dc9 100644
--- a/drivers/mfd/ucb1x00.h
+++ b/drivers/mfd/ucb1x00.h
@@ -94,6 +94,7 @@ #define UCB_ADC_DAT(x)		(((x) & 0x7fe0) 
 #define UCB_ID		0x0c
 #define UCB_ID_1200		0x1004
 #define UCB_ID_1300		0x1005
+#define UCB_ID_1400		0x4304
 
 #define UCB_MODE	0x0d
 #define UCB_MODE_DYN_VFLAG_ENA	(1 << 12)
@@ -110,6 +111,8 @@ struct ucb1x00 {
 	spinlock_t		lock;
 	struct mcp		*mcp;
 	unsigned int		irq;
+	struct task_struct	*irq_task;
+	struct completion	irq_wait;
 	struct semaphore	adc_sem;
 	spinlock_t		io_lock;
 	u16			id;
@@ -122,6 +125,7 @@ struct ucb1x00 {
 	struct class_device	cdev;
 	struct list_head	node;
 	struct list_head	devs;
+
 };
 
 struct ucb1x00_driver;
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 1fc4c13..c238ede 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -182,6 +182,10 @@ config MTD_NAND_DISKONCHIP_BBTWRITE
  config MTD_NAND_SHARPSL
  	bool "Support for NAND Flash on Sharp SL Series (C7xx + others)"
  	depends on MTD_NAND && ARCH_PXA
+
+ config MTD_NAND_CM_X270
+ 	tristate "Support for NAND Flash on CompuLab CM-X270"
+ 	depends on MTD_NAND && ARCH_PXA
  
  config MTD_NAND_NANDSIM
  	bool "Support for NAND Flash Simulator"
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index 4174202..9a9e0c9 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -17,6 +17,7 @@ obj-$(CONFIG_MTD_NAND_DISKONCHIP)	+= dis
 obj-$(CONFIG_MTD_NAND_H1900)		+= h1910.o
 obj-$(CONFIG_MTD_NAND_RTC_FROM4)	+= rtc_from4.o
 obj-$(CONFIG_MTD_NAND_SHARPSL)		+= sharpsl.o
+obj-$(CONFIG_MTD_NAND_CM_X270)		+= cmx270-nand.o
 obj-$(CONFIG_MTD_NAND_NANDSIM)		+= nandsim.o
 
 nand-objs = nand_base.o nand_bbt.o
diff --git a/drivers/mtd/nand/cmx270-nand.c b/drivers/mtd/nand/cmx270-nand.c
new file mode 100644
index 0000000..32b6288
--- /dev/null
+++ b/drivers/mtd/nand/cmx270-nand.c
@@ -0,0 +1,281 @@
+/*
+ *  drivers/mtd/nand/cmx270-nand.c
+ *
+ *  Copyright (C) 2005 Compulab, Ltd. (mike@compulab.co.il)
+ *
+ *  Derived from drivers/mtd/nand/h1910.c
+ *       Copyright (C) 2002 Marius Gr�ger (mag@sysgo.de)
+ *       Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de)
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Overview:
+ *   This is a device driver for the NAND flash device found on the
+ *   CM-X270 board.
+ */
+
+#include <linux/config.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/pxa-regs.h>
+
+#define GPIO_NAND_CS	(11)
+#define GPIO_NAND_RB	(89)
+
+#define DRAIN_WB() \
+	do { \
+		unsigned char dummy; \
+		asm volatile ("mcr p15, 0, r0, c7, c10, 4":::"r0"); \
+		dummy=*((volatile unsigned char*)UNCACHED_ADDR); \
+	} while(0);
+
+/*
+ * MTD structure for CM-X270 board
+ */
+static struct mtd_info *cmx270_nand_mtd = NULL;
+
+/*
+ * Module stuff
+ */
+
+#ifdef CONFIG_MTD_PARTITIONS
+/*
+ * Define static partitions for flash device
+ */
+static struct mtd_partition partition_info[] = {
+	[0] = {
+		.name = "cmx270-0",
+		.offset = 0,
+		.size = MTDPART_SIZ_FULL
+	}
+};
+#define NUM_PARTITIONS ARRAY_SIZE(partition_info)
+
+#endif
+
+
+static 	u_char cmx270_read_byte(struct mtd_info *mtd)
+{
+	struct nand_chip *this = mtd->priv;
+	return (readl(this->IO_ADDR_R) >> 16);
+}
+
+static void cmx270_write_byte(struct mtd_info *mtd, u_char byte)
+{
+	struct nand_chip *this = mtd->priv;
+	writel((byte << 16), this->IO_ADDR_W);
+}
+
+static void cmx270_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
+{
+	int i;
+	struct nand_chip *this = mtd->priv;
+
+	for (i=0; i<len; i++) {
+		writel((*buf++ << 16), this->IO_ADDR_W);
+	}
+}
+
+static void cmx270_read_buf(struct mtd_info *mtd, u_char *buf, int len)
+{
+	int i;
+	struct nand_chip *this = mtd->priv;
+
+	for (i=0; i<len; i++) {
+		*buf++ = readl(this->IO_ADDR_R) >> 16;
+	}
+}
+
+static int cmx270_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
+{
+	int i;
+	struct nand_chip *this = mtd->priv;
+
+	for (i=0; i<len; i++) {
+		if ( buf[i] != (u_char)(readl(this->IO_ADDR_R) >> 16) )
+			return -EFAULT;
+	}
+
+	return 0;
+}
+
+static inline void nand_cs_on(void)
+{
+	GPCR(GPIO_NAND_CS) = GPIO_bit(GPIO_NAND_CS);
+}
+
+static void nand_cs_off(void)
+{
+	DRAIN_WB();
+
+	GPSR(GPIO_NAND_CS) = GPIO_bit(GPIO_NAND_CS);
+}
+
+/*
+ *	hardware specific access to control-lines
+ */
+static void cmx270_hwcontrol(struct mtd_info *mtd, int cmd)
+{
+	struct nand_chip* this = (struct nand_chip *) (mtd->priv);
+	unsigned int nandaddr = (unsigned int)this->IO_ADDR_R;
+
+	DRAIN_WB();
+
+	switch(cmd) {
+
+	case NAND_CTL_SETCLE:
+		nandaddr |= (1 << 2);
+		this->IO_ADDR_R = (void __iomem*)nandaddr;
+		this->IO_ADDR_W = (void __iomem*)nandaddr;
+		break;
+	case NAND_CTL_CLRCLE:
+		nandaddr &= ~(1 << 2);
+		this->IO_ADDR_R = (void __iomem*)nandaddr;
+		this->IO_ADDR_W = (void __iomem*)nandaddr;
+		break;
+
+	case NAND_CTL_SETALE:
+		nandaddr |= (1 << 3);
+		this->IO_ADDR_R = (void __iomem*)nandaddr;
+		this->IO_ADDR_W = (void __iomem*)nandaddr;
+		break;
+	case NAND_CTL_CLRALE:
+		nandaddr &= ~(1 << 3);
+		this->IO_ADDR_R = (void __iomem*)nandaddr;
+		this->IO_ADDR_W = (void __iomem*)nandaddr;
+		break;
+
+	case NAND_CTL_SETNCE:
+		nand_cs_on();
+		break;
+	case NAND_CTL_CLRNCE:
+		nand_cs_off();
+		break;
+	}
+
+	DRAIN_WB();
+}
+
+/*
+ *	read device ready pin
+ */
+static int cmx270_device_ready(struct mtd_info *mtd)
+{
+	DRAIN_WB();
+	return ( GPLR(GPIO_NAND_RB) & GPIO_bit(GPIO_NAND_RB) );
+}
+
+/*
+ * Main initialization routine
+ */
+static int __init cmx270_init (void)
+{
+	struct nand_chip *this;
+	const char *part_type = 0;
+	int mtd_parts_nb = 0;
+	struct mtd_partition *mtd_parts = 0;
+	static unsigned int nandaddr = 0;
+
+
+	/* Allocate memory for MTD device structure and private data */
+	cmx270_nand_mtd = kmalloc(sizeof(struct mtd_info) +
+				    sizeof(struct nand_chip),
+				    GFP_KERNEL);
+	if (!cmx270_nand_mtd) {
+		printk("Unable to allocate CM-X270 NAND MTD device structure.\n");
+		return -ENOMEM;
+	}
+
+	nandaddr = (volatile unsigned int)ioremap(PXA_CS1_PHYS, 100);
+
+	/* Get pointer to private data */
+	this = (struct nand_chip *) (&cmx270_nand_mtd[1]);
+
+	/* Initialize structures */
+	memset((char *) cmx270_nand_mtd, 0, sizeof(struct mtd_info));
+	memset((char *) this, 0, sizeof(struct nand_chip));
+
+	/* Link the private data with the MTD structure */
+	cmx270_nand_mtd->priv = this;
+
+	/* insert callbacks */
+	this->IO_ADDR_R = (void __iomem *)nandaddr;
+	this->IO_ADDR_W = (void __iomem *)nandaddr;
+	this->hwcontrol = cmx270_hwcontrol;
+/* 	this->dev_ready = cmx270_device_ready;	/\* unknown whether that was correct or not so we will just do it like this *\/ */
+
+	/* 15 us command delay time */
+	this->chip_delay = 50;
+	this->eccmode = NAND_ECC_SOFT;
+
+	/* read/write functions */
+	this->read_byte = cmx270_read_byte;
+	this->write_byte = cmx270_write_byte;
+	this->read_buf = cmx270_read_buf;
+	this->write_buf = cmx270_write_buf;
+	this->verify_buf = cmx270_verify_buf;
+
+	/* Scan to find existence of the device */
+	if (nand_scan (cmx270_nand_mtd, 1)) {
+		printk(KERN_NOTICE "No NAND device - returning -ENXIO\n");
+		iounmap((void*)nandaddr);
+		kfree (cmx270_nand_mtd);
+		return -ENXIO;
+	}
+
+#ifdef CONFIG_MTD_CMDLINE_PARTS
+	mtd_parts_nb = parse_cmdline_partitions(cmx270_nand_mtd, &mtd_parts,
+						"cmx270");
+	if (mtd_parts_nb > 0)
+	  part_type = "command line";
+	else
+	  mtd_parts_nb = 0;
+#endif
+	if (mtd_parts_nb == 0)
+	{
+		mtd_parts = partition_info;
+		mtd_parts_nb = NUM_PARTITIONS;
+		part_type = "static";
+	}
+
+	/* Register the partitions */
+	printk(KERN_NOTICE "Using %s partition definition\n", part_type);
+	add_mtd_partitions(cmx270_nand_mtd, mtd_parts, mtd_parts_nb);
+
+	/* Return happy */
+	return 0;
+}
+module_init(cmx270_init);
+
+/*
+ * Clean up routine
+ */
+static void __exit cmx270_cleanup (void)
+{
+	struct nand_chip *this;
+
+	this = (struct nand_chip *) (&cmx270_nand_mtd[1]);
+	iounmap(this->IO_ADDR_R);
+
+	/* Release resources, unregister device */
+	nand_release (cmx270_nand_mtd);
+
+	/* Free the MTD device structure */
+	kfree (cmx270_nand_mtd);
+}
+module_exit(cmx270_cleanup);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Mike Rapoport <mike at compulab dot co dot il>");
+MODULE_DESCRIPTION("NAND flash driver for Compulab CM-X270 Core");
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index aa633fa..505f92b 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -865,6 +865,14 @@ config DM9000
 	  <file:Documentation/networking/net-modules.txt>.  The module will be
 	  called dm9000.
 
+config DM9000_NOEPROM
+	bool "DM9000 without EEPROM attached"
+	depends on DM9000
+	---help---
+	  Select this option if you have DM9000 chipset without EEPROM
+	  containing the MAC address. In this case MAC address should
+	  be set either by the bootloader or using ifconfig
+
 config NET_VENDOR_RACAL
 	bool "Racal-Interlan (Micom) NI cards"
 	depends on NET_ETHERNET && ISA
diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c
index 24996da..7e45756 100644
--- a/drivers/net/dm9000.c
+++ b/drivers/net/dm9000.c
@@ -561,8 +561,14 @@ #endif
 		((u16 *) db->srom)[i] = read_srom_word(db, i);
 
 	/* Set Node Address */
+#ifndef CONFIG_DM9000_NOEPROM
 	for (i = 0; i < 6; i++)
 		ndev->dev_addr[i] = db->srom[i];
+#else
+	/* The Node Address was set by bootloader */
+	for (i=0; i<6; i++)
+		ndev->dev_addr[i] = ior(db, 0x10+i);
+#endif
 
 	if (!is_valid_ether_addr(ndev->dev_addr))
 		printk("%s: Invalid ethernet MAC address.  Please "
@@ -1098,6 +1104,10 @@ dm9000_phy_read(struct net_device *dev, 
 	/* The read data keeps on REG_0D & REG_0E */
 	ret = (ior(db, DM9000_EPDRH) << 8) | ior(db, DM9000_EPDRL);
 
+/* 	if ( reg == MII_BMSR ) { */
+/* 		printk(KERN_WARNING "===> %s: ret = %x\n", __FUNCTION__, ret); */
+/* 	} */
+
 	/* restore the previous address */
 	writeb(reg_save, db->io_addr);
 
@@ -1163,7 +1173,6 @@ dm9000_drv_resume(struct platform_device
 		if (netif_running(ndev)) {
 			dm9000_reset(db);
 			dm9000_init_dm9000(ndev);
-
 			netif_device_attach(ndev);
 		}
 	}
diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile
index bcecf51..b6a4173 100644
--- a/drivers/pcmcia/Makefile
+++ b/drivers/pcmcia/Makefile
@@ -68,4 +68,4 @@ sa1100_cs-$(CONFIG_SA1100_SIMPAD)		+= sa
 pxa2xx_cs-$(CONFIG_ARCH_LUBBOCK)		+= pxa2xx_lubbock.o sa1111_generic.o
 pxa2xx_cs-$(CONFIG_MACH_MAINSTONE)		+= pxa2xx_mainstone.o
 pxa2xx_cs-$(CONFIG_PXA_SHARPSL)			+= pxa2xx_sharpsl.o
-
+pxa2xx_cs-$(CONFIG_MACH_ARMCORE)		+= pxa2xx_cm_x270.o
diff --git a/drivers/pcmcia/pxa2xx_cm_x270.c b/drivers/pcmcia/pxa2xx_cm_x270.c
new file mode 100644
index 0000000..eb4df11
--- /dev/null
+++ b/drivers/pcmcia/pxa2xx_cm_x270.c
@@ -0,0 +1,198 @@
+/*
+ * linux/drivers/pcmcia/pxa/pxa_armcore.c
+ *
+ * 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.
+ *
+ * Compulab Ltd., 2003
+ * 
+ */
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/platform_device.h>
+
+#include <pcmcia/ss.h>
+#include <asm/delay.h>
+#include <asm/hardware.h>
+#include <asm/irq.h>
+
+#include <asm/arch/pxa-regs.h>
+#include <asm/arch/cm-x270.h>
+
+#include "soc_common.h"
+
+
+static struct pcmcia_irqs irqs[] = {
+	{ 0, PCMCIA_S0_CD_VALID, "PCMCIA0 CD" },
+	{ 1, PCMCIA_S1_CD_VALID, "PCMCIA1 CD" },
+};
+
+
+static int 
+cmx270_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
+{
+	int return_val=0;
+	
+	GPSR(GPIO48_nPOE) = GPIO_bit(GPIO48_nPOE) |
+		GPIO_bit(GPIO49_nPWE) |
+		GPIO_bit(GPIO50_nPIOR) |
+		GPIO_bit(GPIO51_nPIOW) |
+		GPIO_bit(GPIO85_nPCE_1) |
+		GPIO_bit(GPIO54_nPCE_2);
+
+	pxa_gpio_mode(GPIO48_nPOE_MD);
+	pxa_gpio_mode(GPIO49_nPWE_MD);
+	pxa_gpio_mode(GPIO50_nPIOR_MD);
+	pxa_gpio_mode(GPIO51_nPIOW_MD);
+	pxa_gpio_mode(GPIO85_nPCE_1_MD);
+	pxa_gpio_mode(GPIO54_nPCE_2_MD);
+	//pxa_gpio_mode(GPIO79_pSKTSEL_MD); /* REVISIT: s/b dependent on num sockets (on ATX base not routed)*/
+	pxa_gpio_mode(GPIO55_nPREG_MD);
+	pxa_gpio_mode(GPIO56_nPWAIT_MD);
+	pxa_gpio_mode(GPIO57_nIOIS16_MD);
+
+	// Reset signal 
+	GPDR(GPIO53_nPCE_2) |= GPIO_bit(GPIO53_nPCE_2);
+	GPCR(GPIO53_nPCE_2) = GPIO_bit(GPIO53_nPCE_2);
+	
+	GPDR(IRQ_TO_GPIO(PCMCIA_S0_CD_VALID)) &= ~GPIO_bit(IRQ_TO_GPIO(PCMCIA_S0_CD_VALID));
+	GPDR(IRQ_TO_GPIO(PCMCIA_S1_CD_VALID)) &= ~GPIO_bit(IRQ_TO_GPIO(PCMCIA_S1_CD_VALID));
+	
+	set_irq_type(PCMCIA_S0_CD_VALID, IRQT_BOTHEDGE);
+	set_irq_type(PCMCIA_S1_CD_VALID, IRQT_BOTHEDGE);
+
+	//irq's for slots:
+	GPDR(IRQ_TO_GPIO(PCMCIA_S0_RDYINT)) &= ~GPIO_bit(IRQ_TO_GPIO(PCMCIA_S0_RDYINT));
+	GPDR(IRQ_TO_GPIO(PCMCIA_S1_RDYINT)) &= ~GPIO_bit(IRQ_TO_GPIO(PCMCIA_S1_RDYINT));
+
+	set_irq_type(PCMCIA_S0_RDYINT, IRQT_FALLING);
+	set_irq_type(PCMCIA_S1_RDYINT, IRQT_FALLING);
+	
+	skt->irq = (skt->nr == 0) ? PCMCIA_S0_RDYINT : PCMCIA_S1_RDYINT;
+	return_val = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
+
+	return return_val;
+}
+
+
+static void cmx270_pcmcia_shutdown(struct soc_pcmcia_socket *skt)
+{
+	soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
+
+	set_irq_type(IRQ_TO_GPIO(PCMCIA_S0_CD_VALID), IRQT_NOEDGE);
+	set_irq_type(IRQ_TO_GPIO(PCMCIA_S1_CD_VALID), IRQT_NOEDGE);
+
+	set_irq_type(IRQ_TO_GPIO(PCMCIA_S0_RDYINT), IRQT_NOEDGE);
+	set_irq_type(IRQ_TO_GPIO(PCMCIA_S1_RDYINT), IRQT_NOEDGE);
+}
+
+
+static void cmx270_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
+				    struct pcmcia_state *state)
+{
+
+	state->detect = (PCC_DETECT(skt->nr) == 0) ? 1 : 0;  
+	state->ready  = (PCC_READY(skt->nr) == 0) ? 0 : 1;
+	state->bvd1   = 1;
+	state->bvd2   = 1;
+	state->vs_3v  = 0;
+	state->vs_Xv  = 0;
+	state->wrprot = 0;  /* not available */
+
+}
+
+
+static int
+cmx270_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
+				       const socket_state_t *state)
+{
+
+	GPSR(GPIO49_nPWE) = GPIO_bit(GPIO49_nPWE);
+	pxa_gpio_mode(GPIO49_nPWE | GPIO_OUT);
+	//pxa_gpio_mode(GPIO79_pSKTSEL_MD | GPIO_OUT); /* For 2-socket mode */
+
+	switch(skt->nr){
+	    case 0:
+			if(state->flags & SS_RESET) {
+				//GPCR(GPIO79_pSKTSEL) = GPIO_bit(GPIO79_pSKTSEL); /* For 2-socket mode */
+				//udelay(1);
+				GPCR(GPIO49_nPWE) = GPIO_bit(GPIO49_nPWE);
+				GPSR(GPIO53_nPCE_2) = GPIO_bit(GPIO53_nPCE_2);
+				udelay(10);
+				GPCR(GPIO53_nPCE_2) = GPIO_bit(GPIO53_nPCE_2);
+				GPSR(GPIO49_nPWE) = GPIO_bit(GPIO49_nPWE);
+			}
+		    break;
+		case 1:
+			if(state->flags & SS_RESET) {
+				//GPCR(GPIO79_pSKTSEL) = GPIO_bit(GPIO79_pSKTSEL); /* For 2-socket mode */
+				//udelay(1);
+				GPCR(GPIO49_nPWE) = GPIO_bit(GPIO49_nPWE);
+				GPSR(GPIO53_nPCE_2) = GPIO_bit(GPIO53_nPCE_2);
+				udelay(10);
+				GPCR(GPIO53_nPCE_2) = GPIO_bit(GPIO53_nPCE_2);
+				GPSR(GPIO49_nPWE) = GPIO_bit(GPIO49_nPWE);
+			}
+		    break;
+	}  
+
+	pxa_gpio_mode(GPIO49_nPWE_MD);
+	//pxa_gpio_mode(GPIO79_pSKTSEL_MD); /* For 2-socket mode */
+
+
+	return 0;
+}
+
+static void cmx270_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
+{
+}
+
+static void cmx270_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
+{
+}
+
+
+static struct pcmcia_low_level cmx270_pcmcia_ops = {
+	.owner			= THIS_MODULE,
+	.hw_init		= cmx270_pcmcia_hw_init,
+	.hw_shutdown		= cmx270_pcmcia_shutdown,
+	.socket_state		= cmx270_pcmcia_socket_state,
+	.configure_socket	= cmx270_pcmcia_configure_socket,
+	.socket_init		= cmx270_pcmcia_socket_init,
+	.socket_suspend		= cmx270_pcmcia_socket_suspend,
+	.nr			= 2,
+};
+
+static struct platform_device *cmx270_pcmcia_device;
+
+static int __init cmx270_pcmcia_init(void)
+{
+	int ret;
+
+	cmx270_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1);
+
+	if (!cmx270_pcmcia_device)
+		return -ENOMEM;
+
+	cmx270_pcmcia_device->dev.platform_data = &cmx270_pcmcia_ops;
+
+	printk ("Registering cm-x270 PCMCIA interface.\n");
+	ret = platform_device_add(cmx270_pcmcia_device);
+
+	if (ret)
+		platform_device_put(cmx270_pcmcia_device);
+
+	return ret;
+}
+
+static void __exit cmx270_pcmcia_exit(void)
+{
+	platform_device_unregister(cmx270_pcmcia_device);
+}
+
+module_init(cmx270_pcmcia_init);
+module_exit(cmx270_pcmcia_exit);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/serial/pxa.c b/drivers/serial/pxa.c
index 10535f0..7f7fd02 100644
--- a/drivers/serial/pxa.c
+++ b/drivers/serial/pxa.c
@@ -49,6 +49,21 @@ #include <asm/hardware.h>
 #include <asm/irq.h>
 #include <asm/arch/pxa-regs.h>
 
+#define SERIAL_SA1100_MAJOR	204
+#define MINOR_START		5
+
+#ifdef CONFIG_MACH_ARMCORE
+extern int machine_is_cmx270l(void);
+#define SWITCH_CONSOLE()	\
+	do {	\
+		if ( machine_is_cmx270l() ) { \
+			serial_pxa_switch_ports(&serial_pxa_ports[0], \
+						&serial_pxa_ports[1]); \
+		} \
+	} while (0)
+#else
+#define SWITCH_CONSOLE()	do {} while (0)
+#endif
 
 struct uart_pxa_port {
 	struct uart_port        port;
@@ -584,6 +599,23 @@ serial_pxa_type(struct uart_port *port)
 	return up->name;
 }
 
+static void
+serial_pxa_switch_ports(struct uart_pxa_port* port1,
+			struct uart_pxa_port* port2)
+{
+	int tmp_line;
+	static struct uart_pxa_port tmp_port;
+	
+	tmp_line = port1->port.line;
+	port1->port.line = port2->port.line;
+	port2->port.line = tmp_line;
+
+	memcpy(&tmp_port, port1, sizeof(struct uart_pxa_port));
+	memcpy(port1, port2, sizeof(struct uart_pxa_port));
+	memcpy(port2, &tmp_port, sizeof(struct uart_pxa_port));
+}
+
+
 #ifdef CONFIG_SERIAL_PXA_CONSOLE
 
 static struct uart_pxa_port serial_pxa_ports[];
@@ -683,7 +715,7 @@ serial_pxa_console_setup(struct console 
 }
 
 static struct console serial_pxa_console = {
-	.name		= "ttyS",
+	.name		= "ttySA",
 	.write		= serial_pxa_console_write,
 	.device		= uart_console_device,
 	.setup		= serial_pxa_console_setup,
@@ -695,6 +727,8 @@ static struct console serial_pxa_console
 static int __init
 serial_pxa_console_init(void)
 {
+	SWITCH_CONSOLE();
+
 	register_console(&serial_pxa_console);
 	return 0;
 }
@@ -788,11 +822,16 @@ static struct uart_pxa_port serial_pxa_p
 
 static struct uart_driver serial_pxa_reg = {
 	.owner		= THIS_MODULE,
-	.driver_name	= "PXA serial",
-	.devfs_name	= "tts/",
-	.dev_name	= "ttyS",
-	.major		= TTY_MAJOR,
-	.minor		= 64,
+/* 	.driver_name	= "PXA serial", */
+/* 	.devfs_name	= "tts/", */
+/* 	.dev_name	= "ttyS", */
+/* 	.major		= TTY_MAJOR, */
+/* 	.minor		= 64, */
+	.driver_name		= "ttySA",
+	.dev_name		= "ttySA",
+	.devfs_name		= "ttySA",
+	.major			= SERIAL_SA1100_MAJOR,
+	.minor			= MINOR_START,
 	.nr		= ARRAY_SIZE(serial_pxa_ports),
 	.cons		= PXA_CONSOLE,
 };
@@ -852,6 +891,10 @@ int __init serial_pxa_init(void)
 {
 	int ret;
 
+#ifndef CONFIG_SERIAL_PXA_CONSOLE
+	SWITCH_CONSOLE();
+#endif
+
 	ret = uart_register_driver(&serial_pxa_reg);
 	if (ret != 0)
 		return ret;
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index f5079c7..e49580a 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -1387,6 +1387,16 @@ config FB_PXA_PARAMETERS
 
 	  <file:Documentation/fb/pxafb.txt> describes the available parameters.
 
+config FB_MBX
+	tristate "2700G LCD framebuffer support"
+	depends on FB && ARCH_PXA
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	---help---
+
+	  If unsure, say N.
+
 config FB_W100
 	tristate "W100 frame buffer support"
 	depends on FB && PXA_SHARPSL
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index aa434e7..c6fe5e4 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -94,6 +94,7 @@ obj-$(CONFIG_FB_TX3912)		  += tx3912fb.o
 obj-$(CONFIG_FB_S1D13XXX)	  += s1d13xxxfb.o
 obj-$(CONFIG_FB_IMX)              += imxfb.o
 obj-$(CONFIG_FB_S3C2410)	  += s3c2410fb.o
+obj-$(CONFIG_FB_MBX)		  += mbx/
 
 # Platform or fallback drivers go here
 obj-$(CONFIG_FB_VESA)             += vesafb.o
diff --git a/drivers/video/mbx/Makefile b/drivers/video/mbx/Makefile
new file mode 100644
index 0000000..ef6b729
--- /dev/null
+++ b/drivers/video/mbx/Makefile
@@ -0,0 +1,7 @@
+# Makefile for the Linux video drivers.
+# 5 Aug 1999, James Simmons, <mailto:jsimmons@users.sf.net>
+# Rewritten to use lists instead of if-statements.
+
+# Each configuration option enables a list of files.
+
+obj-$(CONFIG_FB_MBX)	+= mbxfb.o
diff --git a/drivers/video/mbx/mbxfb.c b/drivers/video/mbx/mbxfb.c
new file mode 100644
index 0000000..93dcfa5
--- /dev/null
+++ b/drivers/video/mbx/mbxfb.c
@@ -0,0 +1,659 @@
+/*
+ *  linux/drivers/video/mbx/mbxfb.c
+ *
+ *  Copyright (C) 2006 Compulab, Ltd.
+ *
+ *   Based on pxafb.c
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive for
+ * more details.
+ *
+ *   Intel 2700G (Marathon) Graphics Accelerator Frame Buffer Driver
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+#include <linux/fb.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/cpufreq.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+#include <asm/div64.h>
+#include <asm/arch/pxa-regs.h>
+#include <asm/arch/bitfield.h>
+#include <asm/arch/marathonfb.h>
+
+static unsigned long virt_base_2700;
+#include "regs.h"
+#include "reg_bits.h"
+
+#define MIN_XRES	16
+#define MIN_YRES	16
+#define MAX_XRES	2048
+#define MAX_YRES	2048
+
+/* FIXME: take care of different chip reivsions with different sizes
+   of ODFB */
+#define MEMORY_OFFSET	0x60000
+
+struct mbxfb_info {
+		struct device *dev;
+		
+		struct resource *fb_res;
+		struct resource *fb_req;
+
+		struct resource *reg_res;
+		struct resource *reg_req;
+
+		void __iomem *fb_virt_addr;
+		unsigned long fb_phys_addr;
+
+		void __iomem *reg_virt_addr;
+		unsigned long reg_phys_addr;
+
+		int (*platform_probe)(struct fb_info *fb);
+		int (*platform_remove)(struct fb_info *fb);
+};
+
+static struct fb_var_screeninfo mbxfb_default __initdata = {
+	.xres =		640,
+	.yres =		480,
+	.xres_virtual =	640,
+	.yres_virtual =	480,
+	.bits_per_pixel = 16,
+	.red =		{ 11, 5, 0 },
+      	.green =	{ 5, 6, 0 },
+      	.blue =		{ 0, 5, 0 },
+      	.activate =	FB_ACTIVATE_TEST,
+      	.height =	-1,
+      	.width =	-1,
+      	.pixclock =	40000,
+      	.left_margin =	48,
+      	.right_margin =	16,
+      	.upper_margin =	33,
+      	.lower_margin =	10,
+      	.hsync_len =	96,
+      	.vsync_len =	2,
+      	.vmode =	FB_VMODE_NONINTERLACED,
+	.sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+};
+
+static struct fb_fix_screeninfo mbxfb_fix __initdata = {
+	.id =		"MBX",
+	.type =		FB_TYPE_PACKED_PIXELS,
+	.visual =	FB_VISUAL_TRUECOLOR,
+	.xpanstep =	0,
+	.ypanstep =	0,
+	.ywrapstep =	0,
+	.accel =	FB_ACCEL_NONE,
+};
+
+struct pixclock_div {
+	u8 m;
+	u8 n;
+	u8 p;
+};
+
+static unsigned int mbxfb_get_pixclock(unsigned int pixclock_ps, struct pixclock_div *div)
+{
+	u8  m, n, p;
+	unsigned int err = 0;
+	unsigned int min_err = ~0x0;
+	unsigned int clk;
+	unsigned int best_clk = 0;
+	unsigned int ref_clk = 13000; /* FIXME: take from platform data */
+	unsigned int pixclock;
+
+	/* convert pixclock to KHz */
+	pixclock = PICOS2KHZ(pixclock_ps);
+
+	for ( m = 1; m < 64; m++ ) {
+		for ( n = 1; n < 8; n++ ) {
+			for ( p = 0; p < 8; p++ ) {
+				clk = (ref_clk * m) / (n * (1 << p));
+				err = (clk > pixclock) ? (clk - pixclock) : 
+					(pixclock - clk);
+				if ( err < min_err ) {
+					min_err = err;
+					best_clk = clk;
+					div->m = m;
+					div->n = n;
+					div->p = p;
+				}
+			}
+		}
+	}
+	return KHZ2PICOS(best_clk);
+}
+
+static int
+mbxfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+		   u_int trans, struct fb_info *info)
+{
+	uint val, ret = 1;
+
+	if ( regno < 255 ) {
+		val = (red & 0xff) << 16;
+		val |= (green & 0xff) << 8;
+		val |= (blue & 0xff) << 0;
+		GPLUT = Gplut_Lutadr(regno) | Gplut_Lutdata(val);
+		udelay(1000);
+		ret = 0;
+	}
+	return ret;
+}
+
+static int mbxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+	struct pixclock_div div;
+	
+	var->pixclock = mbxfb_get_pixclock(var->pixclock, &div);
+
+	if (var->xres < MIN_XRES)
+		var->xres = MIN_XRES;
+	if (var->yres < MIN_YRES)
+		var->yres = MIN_YRES;
+	if (var->xres > MAX_XRES)
+		var->xres = MAX_XRES;
+	if (var->yres > MAX_YRES)
+		var->yres = MAX_YRES;
+	var->xres_virtual =
+		max(var->xres_virtual, var->xres);
+	var->yres_virtual =
+		max(var->yres_virtual, var->yres);
+
+	switch (var->bits_per_pixel) {
+	/* FIXME: implement 8 bits-per-pixel */
+	case 8:
+		var->bits_per_pixel = 16;
+	case 16:
+		var->green.length = (var->green.length == 5) ? 5 : 6;
+		var->red.length = 5;
+		var->blue.length = 5;
+		var->transp.length = 6 - var->green.length;
+		var->blue.offset = 0;
+		var->green.offset = 5;
+		var->red.offset = 5 + var->green.length;
+		var->transp.offset =  (5 + var->red.offset) & 15;
+		break;
+	case 24:	/* RGB 888   */
+	case 32:	/* RGBA 8888 */
+		var->red.offset = 16;
+		var->red.length = 8;
+		var->green.offset = 8;
+		var->green.length = 8;
+		var->blue.offset = 0;
+		var->blue.length = 8;
+		var->transp.length = var->bits_per_pixel - 24;
+		var->transp.offset = (var->transp.length) ? 24 : 0;
+		break;
+	}
+	var->red.msb_right = 0;
+	var->green.msb_right = 0;
+	var->blue.msb_right = 0;
+	var->transp.msb_right = 0;
+
+	return 0;
+}
+
+static int mbxfb_set_par(struct fb_info *info)
+{
+	struct fb_var_screeninfo *var = &info->var;
+	struct pixclock_div div;
+	ushort hbps, ht, hfps, has;
+	ushort vbps, vt, vfps, vas;
+
+	info->fix.line_length = var->xres_virtual * var->bits_per_pixel / 8;
+	
+	/* setup color mode */
+	GSCTRL &= ~(FMsk(GSCTRL_GPIXFMT));
+	/* FIXME: add *WORKING* support for 8-bits per color */
+	if ( info->var.bits_per_pixel == 8 ) {
+		GSCTRL |= GSCTRL_GPIXFMT_INDEXED;
+		GSCTRL |= GSCTRL_LUT_EN;
+		GSCTRL &= ~GSCTRL_GAMMA_EN;
+		info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
+		fb_alloc_cmap(&info->cmap, 1<<info->var.bits_per_pixel, 0);
+	}
+	else {
+		fb_dealloc_cmap(&info->cmap);
+		GSCTRL &= ~GSCTRL_LUT_EN;
+		info->fix.visual = FB_VISUAL_TRUECOLOR;
+		switch ( info->var.bits_per_pixel ) {
+			case 16:
+				if ( info->var.green.length == 5 )
+					GSCTRL |= GSCTRL_GPIXFMT_ARGB1555;
+				else
+					GSCTRL |= GSCTRL_GPIXFMT_RGB565;
+				break;
+			case 24:
+				GSCTRL |= GSCTRL_GPIXFMT_RGB888;
+				break;
+			case 32:
+				GSCTRL |= GSCTRL_GPIXFMT_ARGB8888;
+				break;
+		}
+	}
+
+	/* setup resolution */
+	GSCTRL &= ~(FMsk(GSCTRL_GSWIDTH) | FMsk(GSCTRL_GSHEIGHT));
+	GSCTRL |= Gsctrl_Width(info->var.xres - 1) |
+		Gsctrl_Height(info->var.yres - 1);
+	
+	GSADR &= ~(FMsk(GSADR_SRCSTRIDE)); udelay(1000);
+	GSADR |=  Gsadr_Srcstride(info->var.xres * info->var.bits_per_pixel / (8 * 16) - 1); udelay(1000);
+
+	/* setup timings */
+	var->pixclock = mbxfb_get_pixclock(info->var.pixclock, &div);
+
+	DISPPLL = Disp_Pll_M(div.m) | Disp_Pll_N(div.n) | Disp_Pll_P(div.p) | DISP_PLL_EN;
+	
+	hbps = var->hsync_len;
+	has = hbps + var->left_margin;
+	hfps = has + var->xres;
+	ht = hfps + var->right_margin;
+
+	vbps = var->vsync_len;
+	vas = vbps + var->upper_margin;
+	vfps = vas + var->yres;
+	vt = vfps + var->lower_margin;
+
+	DHT01 = Dht01_Hbps(hbps) | Dht01_Ht(ht);
+ 	DHT02 = Dht02_Hlbs(has) | Dht02_Has(has);
+	DHT03 = Dht03_Hfps(hfps) | Dht03_Hrbs(hfps);
+	DHDET = Dhdet_Hdes(has) | Dhdet_Hdef(hfps);
+	
+	DVT01 = Dvt01_Vbps(vbps) | Dvt01_Vt(vt);
+	DVT02 = Dvt02_Vtbs(vas) | Dvt02_Vas(vas);
+	DVT03 = Dvt03_Vfps(vfps) | Dvt03_Vbbs(vfps);
+	DVDET = Dvdet_Vdes(vas) | Dvdet_Vdef(vfps);
+	DVECTRL = Dvectrl_Vevent(vfps) | Dvectrl_Vfetch(vbps);
+	DSCTRL |= DSCTRL_SYNCGEN_EN;
+
+	return 0;
+}
+
+static char *blank_mode[] = {
+	"FB_BLANK_UNBLANK",
+	"FB_BLANK_NORMAL",
+	"FB_BLANK_VSYNC_SUSPEND",
+	"FB_BLANK_HSYNC_SUSPEND",
+	"FB_BLANK_POWERDOWN",
+};
+
+static int mbxfb_blank(int blank, struct fb_info *info)
+{
+	switch (blank) {
+	case FB_BLANK_POWERDOWN:
+	case FB_BLANK_VSYNC_SUSPEND:
+	case FB_BLANK_HSYNC_SUSPEND:
+	case FB_BLANK_NORMAL:
+		DSCTRL &= ~DSCTRL_SYNCGEN_EN; udelay(1000);
+		PIXCLK &= ~PIXCLK_EN; udelay(1000);
+		VOVRCLK &= ~VOVRCLK_EN; udelay(1000);
+		break;
+	case FB_BLANK_UNBLANK:
+		DSCTRL |= DSCTRL_SYNCGEN_EN; udelay(1000);
+		PIXCLK |= PIXCLK_EN; udelay(1000);
+		break;
+	}
+	return 0;
+}
+
+static struct fb_ops mbxfb_ops = {
+	.owner		= THIS_MODULE,
+	.fb_check_var	= mbxfb_check_var,
+	.fb_set_par	= mbxfb_set_par,
+	.fb_setcolreg	= mbxfb_setcolreg,
+	.fb_fillrect	= cfb_fillrect,
+	.fb_copyarea	= cfb_copyarea,
+	.fb_imageblit	= cfb_imageblit,
+	.fb_blank	= mbxfb_blank,
+};
+
+/*
+   Enable external SDRAM controller. Assume that all clocks are active
+   by now. 
+*/
+static void setup_memc(struct fb_info *fbi)
+{
+	unsigned long tmp;
+
+	/* FIXME: use platfrom specific parameters */
+	/* setup SDRAM controller */
+	LMCFG = LMCFG_LMC_DS | LMCFG_LMC_TS | LMCFG_LMD_TS | LMCFG_LMA_TS;
+	udelay(1000);
+	LMPWR = LMPWR_MC_PWR_ACT;
+	udelay(1000);
+	/* setup SDRAM timings */
+	LMTIM = Lmtim_Tras(7) | Lmtim_Trp(3) | Lmtim_Trcd(3) | Lmtim_Trc(9) |
+		Lmtim_Tdpl(2);
+	udelay(1000);
+	/* setup SDRAM refresh rate */
+	LMREFRESH = 0xc2b;
+	udelay(1000);
+	/* setup SDRAM type parameters */
+	LMTYPE = LMTYPE_CASLAT_3 | LMTYPE_BKSZ_2 | LMTYPE_ROWSZ_11 | 
+		LMTYPE_COLSZ_8;
+	udelay(1000);
+	/* enable memory controller */
+	LMPWR = LMPWR_MC_PWR_ACT;
+	udelay(1000);
+
+	tmp = *(unsigned long*)(virt_base_2700 + MEMORY_OFFSET);
+	tmp = *(unsigned long*)(virt_base_2700 + MEMORY_OFFSET);
+	tmp = *(unsigned long*)(virt_base_2700 + MEMORY_OFFSET);
+	tmp = *(unsigned long*)(virt_base_2700 + MEMORY_OFFSET);
+	tmp = *(unsigned long*)(virt_base_2700 + MEMORY_OFFSET);
+	tmp = *(unsigned long*)(virt_base_2700 + MEMORY_OFFSET);
+	tmp = *(unsigned long*)(virt_base_2700 + MEMORY_OFFSET);
+	tmp = *(unsigned long*)(virt_base_2700 + MEMORY_OFFSET);
+	tmp = *(unsigned long*)(virt_base_2700 + MEMORY_OFFSET);
+	tmp = *(unsigned long*)(virt_base_2700 + MEMORY_OFFSET);
+	tmp = *(unsigned long*)(virt_base_2700 + MEMORY_OFFSET);
+}
+
+static void enable_clocks(struct fb_info* fbi)
+{
+	/* enable clocks */
+	SYSCLKSRC = SYSCLKSRC_PLL_2; udelay(1000);
+	PIXCLKSRC = PIXCLKSRC_PLL_1; udelay(1000);
+	CLKSLEEP = 0x00000000; udelay(1000);
+	COREPLL = Core_Pll_M(0x17) | Core_Pll_N(0x3) | Core_Pll_P(0x0) | CORE_PLL_EN; udelay(1000);
+	DISPPLL = Disp_Pll_M(0x1b) | Disp_Pll_N(0x7) | Disp_Pll_P(0x1) | DISP_PLL_EN;
+
+	VOVRCLK = 0x00000000; udelay(1000);
+	PIXCLK = PIXCLK_EN; udelay(1000);
+	MEMCLK = MEMCLK_EN; udelay(1000);
+	M24CLK = 0x00000006; udelay(1000);
+	MBXCLK = 0x00000006; udelay(1000);
+	SDCLK = SDCLK_EN; udelay(1000);
+	PIXCLKDIV = 0x00000001; udelay(1000);
+}
+
+static void setup_graphics(struct fb_info* fbi)
+{
+	unsigned long gsctrl;
+
+	gsctrl = GSCTRL_GAMMA_EN | Gsctrl_Width(fbi->var.xres-1) |
+		Gsctrl_Height(fbi->var.yres-1);
+	switch ( fbi->var.bits_per_pixel ) {
+		case 16:
+			if ( fbi->var.green.length == 5 )
+				gsctrl |= GSCTRL_GPIXFMT_ARGB1555;
+			else
+				gsctrl |= GSCTRL_GPIXFMT_RGB565;
+			break;
+		case 24: gsctrl |= GSCTRL_GPIXFMT_RGB888; break;
+		case 32: gsctrl |= GSCTRL_GPIXFMT_ARGB8888; break;
+	}
+
+	GSCTRL = gsctrl; udelay(1000);
+	GBBASE = 0x00000000; udelay(1000);
+	GDRCTRL = 0x00ffffff; udelay(1000);
+	GSCADR = GSCADR_STR_EN | Gscadr_Gbase_Adr(0x6000); udelay(1000);
+	GPLUT = 0x00000000; udelay(1000);
+}
+
+static void setup_display(struct fb_info* fbi)
+{
+	unsigned long dsctrl = 0;
+ 
+	dsctrl = DSCTRL_BLNK_POL;
+	if ( fbi->var.sync & FB_SYNC_HOR_HIGH_ACT )
+		dsctrl |= DSCTRL_HS_POL;
+	if ( fbi->var.sync & FB_SYNC_VERT_HIGH_ACT )
+		dsctrl |= DSCTRL_VS_POL;
+	DSCTRL = dsctrl; udelay(1000);
+	DMCTRL = 0xd0303010; udelay(1000);
+	DSCTRL |= DSCTRL_SYNCGEN_EN;
+}
+
+static void enable_controller(struct fb_info* fbi)
+{
+	SYSRST = SYSRST_RST;
+	udelay(1000);
+
+	enable_clocks(fbi);
+	setup_memc(fbi);	
+	setup_graphics(fbi);
+	setup_display(fbi);
+}
+
+
+#ifdef CONFIG_PM
+/*
+ * Power management hooks.  Note that we won't be called from IRQ context,
+ * unlike the blank functions above, so we may sleep.
+ */
+static int mbxfb_suspend(struct platform_device *dev, pm_message_t state)
+{
+	/* make frame buffer memory enter self-refresh mode */
+	LMPWR = LMPWR_MC_PWR_SRM;
+	while ( LMPWRSTAT != LMPWRSTAT_MC_PWR_SRM );
+
+	/* reset the device, since it's initial state is 'mostly sleeping' */
+	SYSRST = SYSRST_RST;
+	return 0;
+}
+
+static int mbxfb_resume(struct platform_device *dev)
+{
+	struct fb_info *fbi = (struct fb_info*)platform_get_drvdata(dev);
+
+	enable_clocks(fbi);
+/* 	setup_graphics(fbi); */
+/* 	setup_display(fbi); */
+
+	DSCTRL |= DSCTRL_SYNCGEN_EN;
+	return 0;
+}
+#else
+#define mbxfb_suspend	NULL
+#define mbxfb_resume	NULL
+#endif
+
+#include "mbxsysfs.c"
+
+#define res_size(_r) (((_r)->end - (_r)->start) + 1)
+
+static int mbxfb_probe(struct platform_device *dev)
+{
+	int ret;
+	struct fb_info *fbi;
+	struct mbxfb_info *mfbi;
+	struct mbxfb_platform_data *pdata;
+
+	dev_dbg(dev, "mbxfb_probe\n");
+
+	fbi = framebuffer_alloc(sizeof(struct mbxfb_info), &dev->dev);
+	if ( fbi == NULL ) {
+		dev_err(&dev->dev, "framebuffer_alloc failed\n");
+		return -ENOMEM;
+	}
+
+	mfbi = fbi->par;
+	pdata = dev->dev.platform_data;
+	if ( pdata->probe )
+		mfbi->platform_probe = pdata->probe;
+	if ( pdata->remove )
+		mfbi->platform_remove = pdata->remove;
+
+	mfbi->fb_res = platform_get_resource(dev, IORESOURCE_MEM, 0);
+	mfbi->reg_res = platform_get_resource(dev, IORESOURCE_MEM, 1);
+
+	if ( !mfbi->fb_res || !mfbi->reg_res ) {
+		dev_err(&dev->dev, "no resources found\n");
+		ret = -ENODEV;
+		goto err1;
+	}
+
+	mfbi->fb_req = request_mem_region(mfbi->fb_res->start,
+					  res_size(mfbi->fb_res),
+					  dev->name);
+	if ( mfbi->fb_req == NULL ) {
+		dev_err(&dev->dev, "failed to claim framebuffer memory\n");
+		ret = -EINVAL;
+		goto err1;
+	}
+	mfbi->fb_phys_addr = mfbi->fb_res->start;
+
+	mfbi->reg_req = request_mem_region(mfbi->reg_res->start,
+					  res_size(mfbi->reg_res),
+					   dev->name);
+	if ( mfbi->reg_req == NULL ) {
+		dev_err(&dev->dev, "failed to claim Marathon registers\n");
+		ret = -EINVAL;
+		goto err2;
+	}
+	mfbi->reg_phys_addr = mfbi->reg_res->start;
+
+	mfbi->reg_virt_addr = ioremap_nocache(mfbi->reg_phys_addr,
+					      res_size(mfbi->reg_req));
+	if ( !mfbi->reg_virt_addr ) {
+		dev_err(&dev->dev, "failed to ioremap Marathon registers\n");
+		ret = -EINVAL;
+		goto err3;
+	}
+	virt_base_2700 = mfbi->reg_virt_addr;
+
+	mfbi->fb_virt_addr = ioremap_nocache(mfbi->fb_phys_addr,
+					     res_size(mfbi->fb_req));
+	if ( !mfbi->reg_virt_addr ) {
+		dev_err(&dev->dev, "failed to ioremap frame buffer\n");
+		ret = -EINVAL;
+		goto err4;
+	}
+
+	fbi->screen_base = (char __iomem *)(mfbi->fb_virt_addr + 0x60000); /* FIXME: */
+	fbi->screen_size = 8*1024*1024; /* 8 Megs */ /* FIXME: get from platform */
+	fbi->fbops = &mbxfb_ops;
+
+	fbi->var = mbxfb_default;
+	fbi->fix = mbxfb_fix;
+	fbi->fix.smem_start = mfbi->fb_phys_addr + 0x60000;
+	fbi->fix.smem_len = 8*1024*1024;
+	fbi->fix.line_length = 640*2;
+
+	ret = fb_alloc_cmap(&fbi->cmap, 256, 0);
+	if (ret < 0) {
+		dev_err(&dev->dev, "fb_alloc_cmap failed\n");
+		ret = -EINVAL;
+		goto err5;
+	}
+
+	ret = register_framebuffer(fbi);
+	if (ret < 0) {
+		dev_err(&dev->dev, "register_framebuffer failed\n");
+		ret = -EINVAL;
+		goto err6;
+	}
+
+	platform_set_drvdata(dev, fbi);
+
+	printk(KERN_INFO "fb%d: mbx frame buffer device\n", fbi->node);
+
+	if ( mfbi->platform_probe )
+		mfbi->platform_probe(fbi);
+
+	enable_controller(fbi);
+
+	mbxfb_sysfs_register(fbi);
+
+	return 0;
+
+  err6:
+	fb_dealloc_cmap(&fbi->cmap);
+  err5:
+	iounmap(mfbi->fb_virt_addr);
+  err4:
+	iounmap(mfbi->reg_virt_addr);
+  err3:
+	release_mem_region(mfbi->reg_res->start,
+			   res_size(mfbi->reg_res));
+  err2:
+	release_mem_region(mfbi->fb_res->start,
+			   res_size(mfbi->fb_res));
+  err1:
+	framebuffer_release(fbi);
+
+	return ret;
+}
+
+static int mbxfb_remove(struct platform_device *dev)
+{
+	struct fb_info *fbi = (struct fb_info*)platform_get_drvdata(dev);
+
+	SYSRST = SYSRST_RST;
+	udelay(1000);
+
+	if (fbi) {
+		struct mbxfb_info *mfbi = fbi->par;
+
+		unregister_framebuffer(fbi);
+		if ( mfbi ) {
+			if ( mfbi->platform_remove )
+				mfbi->platform_remove(fbi);
+
+			if ( mfbi->fb_virt_addr )
+				iounmap(mfbi->fb_virt_addr);
+			if ( mfbi->reg_virt_addr )
+				iounmap(mfbi->reg_virt_addr);
+			if ( mfbi->reg_req ) 
+				release_mem_region(mfbi->reg_req->start,
+						   res_size(mfbi->reg_req));
+			if ( mfbi->fb_req ) 
+				release_mem_region(mfbi->fb_req->start,
+						   res_size(mfbi->fb_req));
+		}
+		framebuffer_release(fbi);
+	}
+
+	return 0;
+}
+
+static struct platform_driver mbxfb_driver = {
+	.probe		= mbxfb_probe,
+	.remove		= mbxfb_remove,
+
+#ifdef CONFIG_PM
+	.suspend	= mbxfb_suspend,
+	.resume		= mbxfb_resume,
+#endif
+	.driver		= {
+		.name	= "mbx-fb",
+	},
+};
+
+int __devinit mbxfb_init(void)
+{
+	return platform_driver_register(&mbxfb_driver);
+}
+
+static void __exit mbxfb_exit(void)
+{
+	platform_driver_unregister(&mbxfb_driver);
+}
+
+module_init(mbxfb_init);
+module_exit(mbxfb_exit);
+
+MODULE_DESCRIPTION("loadable framebuffer driver for Marathon device");
+MODULE_AUTHOR("Mike Rapoport, Compulab");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/mbx/mbxsysfs.c b/drivers/video/mbx/mbxsysfs.c
new file mode 100644
index 0000000..4b9571a
--- /dev/null
+++ b/drivers/video/mbx/mbxsysfs.c
@@ -0,0 +1,129 @@
+static ssize_t sysconf_show(struct class_device * subsys, char * buf)
+{
+	char * s = buf;
+
+	s += sprintf(s, "SYSCFG = %08lx\n", SYSCFG);
+	s += sprintf(s, "PFBASE = %08lx\n", PFBASE);
+	s += sprintf(s, "PFCEIL = %08lx\n", PFCEIL);
+	s += sprintf(s, "POLLFLAG = %08lx\n", POLLFLAG);
+	s += sprintf(s, "SYSRST = %08lx\n", SYSRST);
+	return (s - buf);
+}
+
+static ssize_t sysconf_store(struct class_device * subsys, const char * buf, size_t n)
+{
+	return n;
+}
+
+static ssize_t gsctl_show(struct class_device * subsys, char * buf)
+{
+	char * s = buf;
+
+	s += sprintf(s, "GSCTRL = %08lx\n", GSCTRL);
+	s += sprintf(s, "VSCTRL = %08lx\n", VSCTRL);
+	s += sprintf(s, "GBBASE = %08lx\n", GBBASE);
+	s += sprintf(s, "VBBASE = %08lx\n", VBBASE);
+	s += sprintf(s, "GDRCTRL = %08lx\n", GDRCTRL);
+	s += sprintf(s, "VCMSK = %08lx\n", VCMSK);
+	s += sprintf(s, "GSCADR = %08lx\n", GSCADR);
+	s += sprintf(s, "VSCADR = %08lx\n", VSCADR);
+	s += sprintf(s, "VUBASE = %08lx\n", VUBASE);
+	s += sprintf(s, "VVBASE = %08lx\n", VVBASE);
+	s += sprintf(s, "GSADR = %08lx\n", GSADR);
+	s += sprintf(s, "VSADR = %08lx\n", VSADR);
+	s += sprintf(s, "HCCTRL = %08lx\n", HCCTRL);
+	s += sprintf(s, "HCSIZE = %08lx\n", HCSIZE);
+	s += sprintf(s, "HCPOS = %08lx\n", HCPOS);
+	s += sprintf(s, "HCBADR = %08lx\n", HCBADR);
+	s += sprintf(s, "HCCKMSK = %08lx\n", HCCKMSK);
+	s += sprintf(s, "GPLUT = %08lx\n", GPLUT);
+	return (s - buf);
+}
+
+static ssize_t gsctl_store(struct class_device * subsys, const char * buf, size_t n)
+{
+	return n;
+}
+
+static ssize_t display_show(struct class_device * subsys, char * buf)
+{
+	char * s = buf;
+
+	s += sprintf(s, "DSCTRL = %08lx\n", DSCTRL);
+	s += sprintf(s, "DHT01 = %08lx\n", DHT01);
+	s += sprintf(s, "DHT02 = %08lx\n", DHT02);
+	s += sprintf(s, "DHT03 = %08lx\n", DHT03);
+	s += sprintf(s, "DVT01 = %08lx\n", DVT01);
+	s += sprintf(s, "DVT02 = %08lx\n", DVT02);
+	s += sprintf(s, "DVT03 = %08lx\n", DVT03);
+	s += sprintf(s, "DBCOL = %08lx\n", DBCOL);
+	s += sprintf(s, "BGCOLOR = %08lx\n", BGCOLOR);
+	s += sprintf(s, "DINTRS = %08lx\n", DINTRS);
+	s += sprintf(s, "DINTRE = %08lx\n", DINTRE);
+	s += sprintf(s, "DINTRCNT = %08lx\n", DINTRCNT);
+	s += sprintf(s, "DSIG = %08lx\n", DSIG);
+	s += sprintf(s, "DMCTRL = %08lx\n", DMCTRL);
+	s += sprintf(s, "CLIPCTRL = %08lx\n", CLIPCTRL);
+	s += sprintf(s, "SPOCTRL = %08lx\n", SPOCTRL);
+	s += sprintf(s, "SVCTRL = %08lx\n", SVCTRL);
+	s += sprintf(s, "DLSTS = %08lx\n", DLSTS);
+	s += sprintf(s, "DLLCTRL = %08lx\n", DLLCTRL);
+	s += sprintf(s, "DVLNUM = %08lx\n", DVLNUM);
+	s += sprintf(s, "DUCTRL = %08lx\n", DUCTRL);
+	s += sprintf(s, "DVECTRL = %08lx\n", DVECTRL);
+	s += sprintf(s, "DHDET = %08lx\n", DHDET);
+	s += sprintf(s, "DVDET = %08lx\n", DVDET);
+	s += sprintf(s, "DODMSK = %08lx\n", DODMSK);
+	s += sprintf(s, "CSC01 = %08lx\n", CSC01);
+	s += sprintf(s, "CSC02 = %08lx\n", CSC02);
+	s += sprintf(s, "CSC03 = %08lx\n", CSC03);
+	s += sprintf(s, "CSC04 = %08lx\n", CSC04);
+	s += sprintf(s, "CSC05 = %08lx\n", CSC05);
+	return (s - buf);
+}
+
+static ssize_t display_store(struct class_device * subsys, const char * buf, size_t n)
+{
+	return n;
+}
+
+static ssize_t clock_show(struct class_device * subsys, char * buf)
+{
+	char * s = buf;
+
+	s += sprintf(s, "SYSCLKSRC = %08lx\n", SYSCLKSRC);
+	s += sprintf(s, "PIXCLKSRC = %08lx\n", PIXCLKSRC);
+	s += sprintf(s, "CLKSLEEP = %08lx\n", CLKSLEEP);
+	s += sprintf(s, "COREPLL = %08lx\n", COREPLL);
+	s += sprintf(s, "DISPPLL = %08lx\n", DISPPLL);
+	s += sprintf(s, "PLLSTAT = %08lx\n", PLLSTAT);
+	s += sprintf(s, "VOVRCLK = %08lx\n", VOVRCLK);
+	s += sprintf(s, "PIXCLK = %08lx\n", PIXCLK);
+	s += sprintf(s, "MEMCLK = %08lx\n", MEMCLK);
+	s += sprintf(s, "M24CLK = %08lx\n", M24CLK);
+	s += sprintf(s, "MBXCLK = %08lx\n", MBXCLK);
+	s += sprintf(s, "SDCLK = %08lx\n", SDCLK);
+	s += sprintf(s, "PIXCLKDIV = %08lx\n", PIXCLKDIV);
+	return (s - buf);
+}
+
+static ssize_t clock_store(struct class_device * subsys, const char * buf, size_t n)
+{
+	return n;
+}
+
+static struct class_device_attribute mbx_class_attrs[] = {
+	__ATTR(sysconf,0644,sysconf_show,sysconf_store),
+	__ATTR(gsctl,0644,gsctl_show,gsctl_store),
+	__ATTR(display,0644,display_show,display_store),
+	__ATTR(clock,0644,clock_show,clock_store),
+};
+
+
+static void mbxfb_sysfs_register(struct fb_info *fbi)
+{
+	int i;
+	for (i = 0; i < ARRAY_SIZE(mbx_class_attrs); i++)
+		class_device_create_file(fbi->class_device,
+					 &mbx_class_attrs[i]);
+}
diff --git a/drivers/video/mbx/reg_bits.h b/drivers/video/mbx/reg_bits.h
new file mode 100644
index 0000000..be152f6
--- /dev/null
+++ b/drivers/video/mbx/reg_bits.h
@@ -0,0 +1,489 @@
+#ifndef __REG_BITS_2700G_
+#define __REG_BITS_2700G_
+
+/* /\* System Configuration Registers (0x03FE_0000  0x03FE_0010) *\/ */
+/* #define SYSCFG		__REG_2700G(0x03FE0000) */
+/* #define PFBASE		__REG_2700G(0x03FE0004) */
+/* #define PFCEIL		__REG_2700G(0x03FE0008) */
+/* #define POLLFLAG	__REG_2700G(0x03FE000C) */
+
+#define SYSRST_RST	(1 << 0)
+
+/* /\* Interrupt Control Registers (0x03FE_0014  0x03FE_002F) *\/ */
+/* #define NINTPW		__REG_2700G(0x03FE0014) */
+/* #define MINTENABLE	__REG_2700G(0x03FE0018) */
+/* #define MINTSTAT	__REG_2700G(0x03FE001C) */
+/* #define SINTENABLE	__REG_2700G(0x03FE0020) */
+/* #define SINTSTAT	__REG_2700G(0x03FE0024) */
+/* #define SINTCLR		__REG_2700G(0x03FE0028) */
+
+/* SYSCLKSRC - SYSCLK Source Control Register */
+#define SYSCLKSRC_SEL	Fld(2,0)
+#define SYSCLKSRC_REF	((0x0) << FShft(SYSCLKSRC_SEL))
+#define SYSCLKSRC_PLL_1	((0x1) << FShft(SYSCLKSRC_SEL))
+#define SYSCLKSRC_PLL_2	((0x2) << FShft(SYSCLKSRC_SEL))
+
+/* PIXCLKSRC - PIXCLK Source Control Register */
+#define PIXCLKSRC_SEL	Fld(2,0)
+#define PIXCLKSRC_REF	((0x0) << FShft(PIXCLKSRC_SEL))
+#define PIXCLKSRC_PLL_1	((0x1) << FShft(PIXCLKSRC_SEL))
+#define PIXCLKSRC_PLL_2	((0x2) << FShft(PIXCLKSRC_SEL))
+
+/* Clock Disable Register */
+#define CLKSLEEP_SLP	(1 << 0)
+
+/* Core PLL Control Register */
+#define CORE_PLL_M	Fld(6,7)
+#define Core_Pll_M(x)	((x) << FShft(CORE_PLL_M))
+#define CORE_PLL_N	Fld(3,4)
+#define Core_Pll_N(x)	((x) << FShft(CORE_PLL_N))
+#define CORE_PLL_P	Fld(3,1)
+#define Core_Pll_P(x)	((x) << FShft(CORE_PLL_P))
+#define CORE_PLL_EN	(1 << 0)
+
+/* Display PLL Control Register */
+#define DISP_PLL_M	Fld(6,7)
+#define Disp_Pll_M(x)	((x) << FShft(DISP_PLL_M))
+#define DISP_PLL_N	Fld(3,4)
+#define Disp_Pll_N(x)	((x) << FShft(DISP_PLL_N))
+#define DISP_PLL_P	Fld(3,1)
+#define Disp_Pll_P(x)	((x) << FShft(DISP_PLL_P))
+#define DISP_PLL_EN	(1 << 0)
+
+/* PLL status register */
+#define PLLSTAT_CORE_PLL_LOST_L	(1 << 3)
+#define PLLSTAT_CORE_PLL_LSTS	(1 << 2)
+#define PLLSTAT_DISP_PLL_LOST_L	(1 << 1)
+#define PLLSTAT_DISP_PLL_LSTS	(1 << 0)
+
+/* Video and scale clock control register */
+#define VOVRCLK_EN	(1 << 0)
+
+/* Pixel clock control register */
+#define PIXCLK_EN	(1 << 0)
+
+/* Memory clock control register */
+#define MEMCLK_EN	(1 << 0)
+
+/* MBX clock control register */
+#define MBXCLK_DIV	Fld(2,2)
+#define MBXCLK_DIV_1	((0x0) << FShft(MBXCLK_DIV))
+#define MBXCLK_DIV_2	((0x1) << FShft(MBXCLK_DIV))
+#define MBXCLK_DIV_3	((0x2) << FShft(MBXCLK_DIV))
+#define MBXCLK_DIV_4	((0x3) << FShft(MBXCLK_DIV))
+#define MBXCLK_EN	Fld(2,0)
+#define MBXCLK_EN_NONE	((0x0) << FShft(MBXCLK_EN))
+#define MBXCLK_EN_2D	((0x1) << FShft(MBXCLK_EN))
+#define MBXCLK_EN_BOTH	((0x2) << FShft(MBXCLK_EN))
+
+/* M24 clock control register */
+#define M24CLK_DIV	Fld(2,1)
+#define M24CLK_DIV_1	((0x0) << FShft(M24CLK_DIV))
+#define M24CLK_DIV_2	((0x1) << FShft(M24CLK_DIV))
+#define M24CLK_DIV_3	((0x2) << FShft(M24CLK_DIV))
+#define M24CLK_DIV_4	((0x3) << FShft(M24CLK_DIV))
+#define M24CLK_EN	(1 << 0)
+
+/* SDRAM clock control register */
+#define SDCLK_EN	(1 << 0)
+
+/* PixClk Divisor Register */
+#define PIXCLKDIV_PD	Fld(9,0)
+#define Pixclkdiv_Pd(x)	((x) << FShft(PIXCLKDIV_PD))
+
+/* LCD Config control register */ 
+#define LCDCFG_IN_FMT	Fld(3,28)
+#define Lcdcfg_In_Fmt(x)	((x) << FShft(LCDCFG_IN_FMT))
+#define LCDCFG_LCD1DEN_POL	(1 << 27)
+#define LCDCFG_LCD1FCLK_POL	(1 << 26)
+#define LCDCFG_LCD1LCLK_POL	(1 << 25)
+#define LCDCFG_LCD1D_POL	(1 << 24)
+#define LCDCFG_LCD2DEN_POL	(1 << 23)
+#define LCDCFG_LCD2FCLK_POL	(1 << 22)
+#define LCDCFG_LCD2LCLK_POL	(1 << 21)
+#define LCDCFG_LCD2D_POL	(1 << 20)
+#define LCDCFG_LCD1_TS		(1 << 19)
+#define LCDCFG_LCD1D_DS		(1 << 18)
+#define LCDCFG_LCD1C_DS		(1 << 17)
+#define LCDCFG_LCD1_IS_IN	(1 << 16)
+#define LCDCFG_LCD2_TS		(1 << 3)
+#define LCDCFG_LCD2D_DS		(1 << 2)
+#define LCDCFG_LCD2C_DS		(1 << 1)
+#define LCDCFG_LCD2_IS_IN	(1 << 0)
+
+/* On-Die Frame Buffer Power Control Register */
+#define ODFBPWR_SLOW	(1 << 2)
+#define ODFBPWR_MODE	Fld(2,0)
+#define ODFBPWR_MODE_ACT	((0x0) << FShft(ODFBPWR_MODE))
+#define ODFBPWR_MODE_ACT_LP	((0x1) << FShft(ODFBPWR_MODE))
+#define ODFBPWR_MODE_SLEEP	((0x2) << FShft(ODFBPWR_MODE))
+#define ODFBPWR_MODE_SHUTD	((0x3) << FShft(ODFBPWR_MODE))
+
+/* On-Die Frame Buffer Power State Status Register */
+#define ODFBSTAT_ACT	(1 << 2)
+#define ODFBSTAT_SLP	(1 << 1)
+#define ODFBSTAT_SDN	(1 << 0)
+
+/* /\* GPIO Registers (0x03FE_006C  0x03FE_007F) *\/ */
+/* #define GPIOCGF		__REG_2700G(0x03FE006C) */
+/* #define GPIOHI		__REG_2700G(0x03FE0070) */
+/* #define GPIOLO		__REG_2700G(0x03FE0074) */
+/* #define GPIOSTAT	__REG_2700G(0x03FE0078) */
+
+/* /\* Pulse Width Modulator (PWM) Registers (0x03FE_0200  0x03FE_02FF) *\/ */
+/* #define PWMRST		__REG_2700G(0x03FE0200) */
+/* #define PWMCFG		__REG_2700G(0x03FE0204) */
+/* #define PWM0DIV		__REG_2700G(0x03FE0210) */
+/* #define PWM0DUTY	__REG_2700G(0x03FE0214) */
+/* #define PWM0PER		__REG_2700G(0x03FE0218) */
+/* #define PWM1DIV		__REG_2700G(0x03FE0220) */
+/* #define PWM1DUTY	__REG_2700G(0x03FE0224) */
+/* #define PWM1PER		__REG_2700G(0x03FE0228) */
+
+
+/* LMRST - Local Memory (SDRAM) Reset */
+#define LMRST_MC_RST	(1 << 0)
+
+/* LMCFG - Local Memory (SDRAM) Configuration Register */
+#define LMCFG_LMC_DS	(1 << 5)
+#define LMCFG_LMD_DS	(1 << 4)
+#define LMCFG_LMA_DS	(1 << 3)
+#define LMCFG_LMC_TS	(1 << 2)
+#define LMCFG_LMD_TS	(1 << 1)
+#define LMCFG_LMA_TS	(1 << 0)
+
+/* LMPWR - Local Memory (SDRAM) Power Control Register */
+#define LMPWR_MC_PWR_CNT	Fld(2,0)
+#define LMPWR_MC_PWR_ACT	((0x0) << FShft(LMPWR_MC_PWR_CNT)) /* Active */
+#define LMPWR_MC_PWR_SRM	((0x1) << FShft(LMPWR_MC_PWR_CNT)) /* Self-refresh */
+#define LMPWR_MC_PWR_DPD	((0x3) << FShft(LMPWR_MC_PWR_CNT)) /* deep power down */
+
+/* LMPWRSTAT - Local Memory (SDRAM) Power Status Register */
+#define LMPWRSTAT_MC_PWR_CNT	Fld(2,0)
+#define LMPWRSTAT_MC_PWR_ACT	((0x0) << FShft(LMPWRSTAT_MC_PWR_CNT)) /* Active */
+#define LMPWRSTAT_MC_PWR_SRM	((0x1) << FShft(LMPWRSTAT_MC_PWR_CNT)) /* Self-refresh */
+#define LMPWRSTAT_MC_PWR_DPD	((0x3) << FShft(LMPWRSTAT_MC_PWR_CNT)) /* deep power down */
+
+/* LMTYPE - Local Memory (SDRAM) Type Register */
+#define LMTYPE_CASLAT	Fld(3,10)
+#define LMTYPE_CASLAT_1	((0x1) << FShft(LMTYPE_CASLAT))
+#define LMTYPE_CASLAT_2	((0x2) << FShft(LMTYPE_CASLAT))
+#define LMTYPE_CASLAT_3	((0x3) << FShft(LMTYPE_CASLAT))
+#define LMTYPE_BKSZ	Fld(2,8)
+#define LMTYPE_BKSZ_1	((0x1) << FShft(LMTYPE_BKSZ))
+#define LMTYPE_BKSZ_2	((0x2) << FShft(LMTYPE_BKSZ))
+#define LMTYPE_ROWSZ	Fld(4,4)
+#define LMTYPE_ROWSZ_11	((0xb) << FShft(LMTYPE_ROWSZ))
+#define LMTYPE_ROWSZ_12	((0xc) << FShft(LMTYPE_ROWSZ))
+#define LMTYPE_ROWSZ_13	((0xd) << FShft(LMTYPE_ROWSZ))
+#define LMTYPE_COLSZ	Fld(4,0)
+#define LMTYPE_COLSZ_7	((0x7) << FShft(LMTYPE_COLSZ))
+#define LMTYPE_COLSZ_8	((0x8) << FShft(LMTYPE_COLSZ))
+#define LMTYPE_COLSZ_9	((0x9) << FShft(LMTYPE_COLSZ))
+#define LMTYPE_COLSZ_10	((0xa) << FShft(LMTYPE_COLSZ))
+#define LMTYPE_COLSZ_11	((0xb) << FShft(LMTYPE_COLSZ))
+#define LMTYPE_COLSZ_12	((0xc) << FShft(LMTYPE_COLSZ))
+
+/* LMTIM - Local Memory (SDRAM) Timing Register */
+#define LMTIM_TRAS	Fld(4,16)
+#define Lmtim_Tras(x)	((x) << FShft(LMTIM_TRAS))
+#define LMTIM_TRP	Fld(4,12)
+#define Lmtim_Trp(x)	((x) << FShft(LMTIM_TRP))
+#define LMTIM_TRCD	Fld(4,8)
+#define Lmtim_Trcd(x)	((x) << FShft(LMTIM_TRCD))
+#define LMTIM_TRC	Fld(4,4)
+#define Lmtim_Trc(x)	((x) << FShft(LMTIM_TRC))
+#define LMTIM_TDPL	Fld(4,0)
+#define Lmtim_Tdpl(x)	((x) << FShft(LMTIM_TDPL))
+
+/* LMREFRESH - Local Memory (SDRAM) tREF Control Register */
+#define LMREFRESH_TREF	Fld(2,0)
+#define Lmrefresh_Tref(x)	((x) << FShft(LMREFRESH_TREF))
+
+/* #define LMCEMR	__REG_2700G(0x03FE1010) */
+/* #define LMPROTMIN	__REG_2700G(0x03FE1020) */
+/* #define LMPROTMAX	__REG_2700G(0x03FE1024) */
+/* #define LMPROTCFG	__REG_2700G(0x03FE1028) */
+/* #define LMPROTERR	__REG_2700G(0x03FE102C) */
+
+/* GSCTRL - Graphics surface control register */
+#define GSCTRL_LUT_EN	(1 << 31)
+#define GSCTRL_GPIXFMT	Fld(4,27)
+#define GSCTRL_GPIXFMT_INDEXED	((0x0) << FShft(GSCTRL_GPIXFMT))
+#define GSCTRL_GPIXFMT_ARGB4444	((0x4) << FShft(GSCTRL_GPIXFMT))
+#define GSCTRL_GPIXFMT_ARGB1555	((0x5) << FShft(GSCTRL_GPIXFMT))
+#define GSCTRL_GPIXFMT_RGB888	((0x6) << FShft(GSCTRL_GPIXFMT))
+#define GSCTRL_GPIXFMT_RGB565	((0x7) << FShft(GSCTRL_GPIXFMT))
+#define GSCTRL_GPIXFMT_ARGB8888	((0x8) << FShft(GSCTRL_GPIXFMT))
+#define GSCTRL_GAMMA_EN	(1 << 26)
+
+#define GSCTRL_GSWIDTH Fld(11,11)
+#define Gsctrl_Width(Pixel)	/* Display Width [1..2048 pix.]  */ \
+                        (((Pixel) - 1) << FShft(GSCTRL_GSWIDTH))
+
+#define GSCTRL_GSHEIGHT Fld(11,0)
+#define Gsctrl_Height(Pixel)	/* Display Height [1..2048 pix.]  */ \
+                        (((Pixel) - 1) << FShft(GSCTRL_GSHEIGHT))
+
+/* GBBASE fileds */
+#define GBBASE_GLALPHA Fld(8,24)
+#define Gbbase_Glalpha(x)	((x) << FShft(GBBASE_GLALPHA))
+
+#define GBBASE_COLKEY Fld(24,0)
+#define Gbbase_Colkey(x)	((x) << FShft(GBBASE_COLKEY))
+
+/* GDRCTRL fields */
+#define GDRCTRL_PIXDBL	(1 << 31)
+#define GDRCTRL_PIXHLV	(1 << 30)
+#define GDRCTRL_LNDBL	(1 << 29)
+#define GDRCTRL_LNHLV	(1 << 28)
+#define GDRCTRL_COLKEYM	Fld(24,0)
+#define Gdrctrl_Colkeym(x)	((x) << FShft(GDRCTRL_COLKEYM))
+
+/* GSCADR graphics stream control address register fields */
+#define GSCADR_STR_EN	(1 << 31)
+#define GSCADR_COLKEY_EN	(1 << 30)
+#define GSCADR_COLKEYSCR	(1 << 29)
+#define GSCADR_BLEND_M	Fld(2,27)
+#define GSCADR_BLEND_NONE	((0x0) << FShft(GSCADR_BLEND_M))
+#define GSCADR_BLEND_INV	((0x1) << FShft(GSCADR_BLEND_M))
+#define GSCADR_BLEND_GLOB	((0x2) << FShft(GSCADR_BLEND_M))
+#define GSCADR_BLEND_PIX	((0x3) << FShft(GSCADR_BLEND_M))
+#define GSCADR_BLEND_POS	Fld(2,24)
+#define GSCADR_BLEND_GFX	((0x0) << FShft(GSCADR_BLEND_POS))
+#define GSCADR_BLEND_VID	((0x1) << FShft(GSCADR_BLEND_POS))
+#define GSCADR_BLEND_CUR	((0x2) << FShft(GSCADR_BLEND_POS))
+#define GSCADR_GBASE_ADR	Fld(23,0)
+#define Gscadr_Gbase_Adr(x)	((x) << FShft(GSCADR_GBASE_ADR))
+
+/* GSADR graphics stride address register fields */
+#define GSADR_SRCSTRIDE	Fld(10,22)
+#define Gsadr_Srcstride(x)	((x) << FShft(GSADR_SRCSTRIDE))
+#define GSADR_XSTART	Fld(11,11)
+#define Gsadr_Xstart(x)		((x) << FShft(GSADR_XSTART))
+#define GSADR_YSTART	Fld(11,0)
+#define Gsadr_Ystart(y)		((y) << FShft(GSADR_YSTART))
+
+/* GPLUT graphics palette register fields */
+#define GPLUT_LUTADR	Fld(8,24)
+#define Gplut_Lutadr(x)	((x) << FShft(GPLUT_LUTADR))
+#define GPLUT_LUTDATA	Fld(24,0)
+#define Gplut_Lutdata(x)	((x) << FShft(GPLUT_LUTDATA))
+
+/* #define VSCTRL		__REG_2700G(0x03FE2004) */
+/* #define VBBASE		__REG_2700G(0x03FE2024) */
+/* #define VCMSK		__REG_2700G(0x03FE2044) */
+/* #define VSCADR		__REG_2700G(0x03FE2064) */
+/* #define VUBASE		__REG_2700G(0x03FE2084) */
+/* #define VVBASE		__REG_2700G(0x03FE20A4) */
+/* #define VSADR		__REG_2700G(0x03FE20C4) */
+
+
+/* HCCTRL - Hardware Cursor Register fields */
+#define HCCTRL_CUR_EN	(1 << 31)
+#define HCCTRL_COLKEY_EN	(1 << 29)
+#define HCCTRL_COLKEYSRC	(1 << 28)
+#define HCCTRL_BLEND_M	Fld(2,26)
+#define HCCTRL_BLEND_NONE	((0x0) << FShft(HCCTRL_BLEND_M))
+#define HCCTRL_BLEND_INV	((0x1) << FShft(HCCTRL_BLEND_M))
+#define HCCTRL_BLEND_GLOB	((0x2) << FShft(HCCTRL_BLEND_M))
+#define HCCTRL_BLEND_PIX	((0x3) << FShft(HCCTRL_BLEND_M))
+#define HCCTRL_CPIXFMT	Fld(3,23)
+#define HCCTRL_CPIXFMT_RGB332	((0x3) << FShft(HCCTRL_CPIXFMT))
+#define HCCTRL_CPIXFMT_ARGB4444	((0x4) << FShft(HCCTRL_CPIXFMT))
+#define HCCTRL_CPIXFMT_ARGB1555	((0x5) << FShft(HCCTRL_CPIXFMT))
+#define HCCTRL_CBASE_ADR	Fld(23,0)
+#define Hcctrl_Cbase_Adr(x)	((x) << FShft(HCCTRL_CBASE_ADR))
+
+/* HCSIZE Hardware Cursor Size Register fields */
+#define HCSIZE_BLEND_POS	Fld(2,29)
+#define HCSIZE_BLEND_GFX	((0x0) << FShft(HCSIZE_BLEND_POS))
+#define HCSIZE_BLEND_VID	((0x1) << FShft(HCSIZE_BLEND_POS))
+#define HCSIZE_BLEND_CUR	((0x2) << FShft(HCSIZE_BLEND_POS))
+#define HCSIZE_CWIDTH	Fld(3,16)
+#define Hcsize_Cwidth(x)	((x) << FShft(HCSIZE_CWIDTH))
+#define HCSIZE_CHEIGHT	Fld(3,0)
+#define Hcsize_Cheight(x)	((x) << FShft(HCSIZE_CHEIGHT))
+
+/* HCPOS Hardware Cursor Position Register fields */
+#define HCPOS_SWITCHSRC	(1 << 30)
+#define HCPOS_CURBLINK	Fld(6,24)
+#define Hcpos_Curblink(x)	((x) << FShft(HCPOS_CURBLINK))
+#define HCPOS_XSTART	Fld(12,12)
+#define Hcpos_Xstart(x)	((x) << FShft(HCPOS_XSTART))
+#define HCPOS_YSTART	Fld(12,0)
+#define Hcpos_Ystart(y)	((y) << FShft(HCPOS_YSTART))
+
+/* HCBADR Hardware Cursor Blend Address Register */
+#define HCBADR_GLALPHA	Fld(8,24)
+#define Hcbadr_Glalpha(x)	((x) << FShft(HCBADR_GLALPHA))
+#define HCBADR_COLKEY	Fld(24,0)
+#define Hcbadr_Colkey(x)	((x) << FShft(HCBADR_COLKEY))
+
+/* HCCKMSK - Hardware Cursor Color Key Mask Register */
+#define HCCKMSK_COLKEY_M	Fld(24,0)
+#define Hcckmsk_Colkey_M(x)	((x) << FShft(HCCKMSK_COLKEY_M))
+
+/* DSCTRL - Display sync control register */
+#define DSCTRL_SYNCGEN_EN	(1 << 31)
+#define DSCTRL_DPL_RST		(1 << 29)
+#define DSCTRL_PWRDN_M		(1 << 28)
+#define DSCTRL_UPDSYNCCNT	(1 << 26)
+#define DSCTRL_UPDINTCNT	(1 << 25)
+#define DSCTRL_UPDCNT		(1 << 24)
+#define DSCTRL_UPDWAIT	Fld(4,16)
+#define Dsctrl_Updwait(x)	((x) << FShft(DSCTRL_UPDWAIT))
+#define DSCTRL_CLKPOL		(1 << 11)
+#define DSCTRL_CSYNC_EN		(1 << 10)
+#define DSCTRL_VS_SLAVE		(1 << 7)
+#define DSCTRL_HS_SLAVE		(1 << 6)
+#define DSCTRL_BLNK_POL		(1 << 5)
+#define DSCTRL_BLNK_DIS		(1 << 4)
+#define DSCTRL_VS_POL		(1 << 3)
+#define DSCTRL_VS_DIS		(1 << 2)
+#define DSCTRL_HS_POL		(1 << 1)
+#define DSCTRL_HS_DIS		(1 << 0)
+
+/* DHT01 - Display horizontal timing register 01 */
+#define DHT01_HBPS	Fld(12,16)
+#define Dht01_Hbps(x)	((x) << FShft(DHT01_HBPS))
+#define DHT01_HT	Fld(12,0)
+#define Dht01_Ht(x)	((x) << FShft(DHT01_HT))
+
+/* DHT02 - Display horizontal timing register 02 */
+#define DHT02_HAS	Fld(12,16)
+#define Dht02_Has(x)	((x) << FShft(DHT02_HAS))
+#define DHT02_HLBS	Fld(12,0)
+#define Dht02_Hlbs(x)	((x) << FShft(DHT02_HLBS))
+
+/* DHT03 - Display horizontal timing register 03 */
+#define DHT03_HFPS	Fld(12,16)
+#define Dht03_Hfps(x)	((x) << FShft(DHT03_HFPS))
+#define DHT03_HRBS	Fld(12,0)
+#define Dht03_Hrbs(x)	((x) << FShft(DHT03_HRBS))
+
+/* DVT01 - Display vertical timing register 01 */
+#define DVT01_VBPS	Fld(12,16)
+#define Dvt01_Vbps(x)	((x) << FShft(DVT01_VBPS))
+#define DVT01_VT	Fld(12,0)
+#define Dvt01_Vt(x)	((x) << FShft(DVT01_VT))
+
+/* DVT02 - Display vertical timing register 02 */
+#define DVT02_VAS	Fld(12,16)
+#define Dvt02_Vas(x)	((x) << FShft(DVT02_VAS))
+#define DVT02_VTBS	Fld(12,0)
+#define Dvt02_Vtbs(x)	((x) << FShft(DVT02_VTBS))
+
+/* DVT03 - Display vertical timing register 03 */
+#define DVT03_VFPS	Fld(12,16)
+#define Dvt03_Vfps(x)	((x) << FShft(DVT03_VFPS))
+#define DVT03_VBBS	Fld(12,0)
+#define Dvt03_Vbbs(x)	((x) << FShft(DVT03_VBBS))
+
+/* DVECTRL - display vertical event control register */
+#define DVECTRL_VEVENT	Fld(12,16)
+#define Dvectrl_Vevent(x)	((x) << FShft(DVECTRL_VEVENT))
+#define DVECTRL_VFETCH	Fld(12,0)
+#define Dvectrl_Vfetch(x)	((x) << FShft(DVECTRL_VFETCH))
+
+/* DHDET - display horizontal DE timing register */
+#define DHDET_HDES	Fld(12,16)
+#define Dhdet_Hdes(x)	((x) << FShft(DHDET_HDES))
+#define DHDET_HDEF	Fld(12,0)
+#define Dhdet_Hdef(x)	((x) << FShft(DHDET_HDEF))
+
+/* DVDET - display vertical DE timing register */
+#define DVDET_VDES	Fld(12,16)
+#define Dvdet_Vdes(x)	((x) << FShft(DVDET_VDES))
+#define DVDET_VDEF	Fld(12,0)
+#define Dvdet_Vdef(x)	((x) << FShft(DVDET_VDEF))
+
+/* DODMSK - display output data mask register */
+#define DODMSK_MASK_LVL	(1 << 31)
+#define DODMSK_BLNK_LVL	(1 << 30)
+#define DODMSK_MASK_B	Fld(8,16)
+#define Dodmsk_Mask_B(x)	((x) << FShft(DODMSK_MASK_B))
+#define DODMSK_MASK_G	Fld(8,8)
+#define Dodmsk_Mask_G(x)	((x) << FShft(DODMSK_MASK_G))
+#define DODMSK_MASK_R	Fld(8,0)
+#define Dodmsk_Mask_R(x)	((x) << FShft(DODMSK_MASK_R))
+
+/* DBCOL - display border color control register */
+#define DBCOL_BORDCOL	Fld(24,0)
+#define Dbcol_Bordcol(x)	((x) << FShft(DBCOL_BORDCOL))	
+
+/* DVLNUM - display vertical line number register */
+#define DVLNUM_VLINE	Fld(12,0)
+#define Dvlnum_Vline(x)	((x) << FShft(DVLNUM_VLINE))
+
+/* DMCTRL - Display Memory Control Register */
+#define DMCTRL_MEM_REF	Fld(2,30)
+#define DMCTRL_MEM_REF_ACT	((0x0) << FShft(DMCTRL_MEM_REF))
+#define DMCTRL_MEM_REF_HB	((0x1) << FShft(DMCTRL_MEM_REF))
+#define DMCTRL_MEM_REF_VB	((0x2) << FShft(DMCTRL_MEM_REF))
+#define DMCTRL_MEM_REF_BOTH	((0x3) << FShft(DMCTRL_MEM_REF))
+#define DMCTRL_UV_THRHLD	Fld(6,24)
+#define Dmctrl_Uv_Thrhld(x)	((x) << FShft(DMCTRL_UV_THRHLD))
+#define DMCTRL_V_THRHLD		Fld(7,16)
+#define Dmctrl_V_Thrhld(x)	((x) << FShft(DMCTRL_V_THRHLD))
+#define DMCTRL_D_THRHLD		Fld(7,8)
+#define Dmctrl_D_Thrhld(x)	((x) << FShft(DMCTRL_D_THRHLD))
+#define DMCTRL_BURSTLEN	Fld(6,0)
+#define Dmctrl_Burstlen(x)	((x) << FShft(DMCTRL_BURSTLEN))
+
+
+/* DLSTS - display load status register */
+#define DLSTS_RLD_ADONE	(1 << 23)
+/* #define DLSTS_RLD_ADOUT	Fld(23,0) */
+
+/* DLLCTRL - display list load control register */
+#define DLLCTRL_RLD_ADRLN	Fld(8,24)
+#define Dllctrl_Rld_Adrln(x)	((x) << FShft(DLLCTRL_RLD_ADRLN))
+
+/* #define DSIG		__REG_2700G(0x03FE2184) */
+/* #define DINTRS		__REG_2700G(0x03FE2178) */
+/* #define DINTRE		__REG_2700G(0x03FE217C) */
+/* #define DINTRCNT	__REG_2700G(0x03FE2180) */
+/* #define DUCTRL		__REG_2700G(0x03FE230C) */
+
+/* BGCOLOR - background color control register */
+/* #define BGCOLOR		__REG_2700G(0x03FE2174) */
+
+/* #define CLIPCTRL	__REG_2700G(0x03FE218C) */
+/* SPOCTRL - Scale Pitch/Order Control Register */
+#define SPOCTRL_H_SC_BP		(1 << 31)
+#define SPOCTRL_V_SC_BP		(1 << 30)
+#define SPOCTRL_HV_SC_OR	(1 << 29)
+#define SPOCTRL_VS_UR_C		(1 << 27)
+#define SPOCTRL_VORDER	Fld(2,16)
+#define SPOCTRL_VORDER_1TAP	((0x0) << FShft(SPOCTRL_VORDER))
+#define SPOCTRL_VORDER_2TAP	((0x1) << FShft(SPOCTRL_VORDER))
+#define SPOCTRL_VORDER_4TAP	((0x3) << FShft(SPOCTRL_VORDER))
+#define SPOCTRL_VPITCH	Fld(16,0)
+#define Spoctrl_Vpitch(x)	((x) << FShft(SPOCTRL_VPITCH))
+
+/* #define SVCTRL		__REG_2700G(0x03FE2194) */
+
+/* /\* 0x03FE_2198 *\/ */
+/* /\* 0x03FE_21A8 VSCOEFF[0:4] Video Scalar Vertical Coefficient [0:4] 4.14.5 *\/ */
+
+/* #define SHCTRL		__REG_2700G(0x03FE21B0) */
+
+/* /\* 0x03FE_21B4 *\/ */
+/* /\* 0x03FE_21D4 HSCOEFF[0:8] Video Scalar Horizontal Coefficient [0:8] 4.14.7 *\/ */
+
+/* #define SSSIZE		__REG_2700G(0x03FE21D8) */
+
+/* /\* 0x03FE_2200 *\/ */
+/* /\* 0x03FE_2240 VIDGAM[0:16] Video Gamma LUT Index [0:16] 4.15.2 *\/ */
+
+/* /\* 0x03FE_2250 *\/ */
+/* /\* 0x03FE_2290 GFXGAM[0:16] Graphics Gamma LUT Index [0:16] 4.15.3 *\/ */
+
+/* #define CSC01		__REG_2700G(0x03FE2330) */
+/* #define CSC02		__REG_2700G(0x03FE2334) */
+/* #define CSC03		__REG_2700G(0x03FE2338) */
+/* #define CSC04		__REG_2700G(0x03FE233C) */
+/* #define CSC05		__REG_2700G(0x03FE2340) */
+
+#endif /* __REG_BITS_2700G_ */
diff --git a/drivers/video/mbx/regs.h b/drivers/video/mbx/regs.h
new file mode 100644
index 0000000..edf0f14
--- /dev/null
+++ b/drivers/video/mbx/regs.h
@@ -0,0 +1,192 @@
+#ifndef __REGS_2700G_
+#define __REGS_2700G_
+
+/* extern unsigned long virt_base_2700; */
+#define __REG_2700G(x)	(*(volatile unsigned long*)((x)+virt_base_2700))
+
+/* System Configuration Registers (0x0000_0000  0x0000_0010) */
+#define SYSCFG		__REG_2700G(0x00000000)
+#define PFBASE		__REG_2700G(0x00000004)
+#define PFCEIL		__REG_2700G(0x00000008)
+#define POLLFLAG	__REG_2700G(0x0000000c)
+#define SYSRST		__REG_2700G(0x00000010)
+
+/* Interrupt Control Registers (0x0000_0014  0x0000_002F) */
+#define NINTPW		__REG_2700G(0x00000014)
+#define MINTENABLE	__REG_2700G(0x00000018)
+#define MINTSTAT	__REG_2700G(0x0000001c)
+#define SINTENABLE	__REG_2700G(0x00000020)
+#define SINTSTAT	__REG_2700G(0x00000024)
+#define SINTCLR		__REG_2700G(0x00000028)
+
+/* Clock Control Registers (0x0000_002C  0x0000_005F) */
+#define SYSCLKSRC	__REG_2700G(0x0000002c)
+#define PIXCLKSRC	__REG_2700G(0x00000030)
+#define CLKSLEEP	__REG_2700G(0x00000034)
+#define COREPLL		__REG_2700G(0x00000038)
+#define DISPPLL		__REG_2700G(0x0000003c)
+#define PLLSTAT		__REG_2700G(0x00000040)
+#define VOVRCLK		__REG_2700G(0x00000044)
+#define PIXCLK		__REG_2700G(0x00000048)
+#define MEMCLK		__REG_2700G(0x0000004c)
+#define M24CLK		__REG_2700G(0x00000054)
+#define MBXCLK		__REG_2700G(0x00000054)
+#define SDCLK		__REG_2700G(0x00000058)
+#define PIXCLKDIV	__REG_2700G(0x0000005c)
+
+/* LCD Port Control Register (0x0000_0060  0x0000_006F) */
+#define LCD_CONFIG	__REG_2700G(0x00000060)
+
+/* On-Die Frame Buffer Registers (0x0000_0064  0x0000_006B) */
+#define ODFBPWR		__REG_2700G(0x00000064)
+#define ODFBSTAT	__REG_2700G(0x00000068)
+
+/* GPIO Registers (0x0000_006C  0x0000_007F) */
+#define GPIOCGF		__REG_2700G(0x0000006c)
+#define GPIOHI		__REG_2700G(0x00000070)
+#define GPIOLO		__REG_2700G(0x00000074)
+#define GPIOSTAT	__REG_2700G(0x00000078)
+
+/* Pulse Width Modulator (PWM) Registers (0x0000_0200  0x0000_02FF) */
+#define PWMRST		__REG_2700G(0x00000200)
+#define PWMCFG		__REG_2700G(0x00000204)
+#define PWM0DIV		__REG_2700G(0x00000210)
+#define PWM0DUTY	__REG_2700G(0x00000214)
+#define PWM0PER		__REG_2700G(0x00000218)
+#define PWM1DIV		__REG_2700G(0x00000220)
+#define PWM1DUTY	__REG_2700G(0x00000224)
+#define PWM1PER		__REG_2700G(0x00000228)
+
+/* Identification (ID) Registers (0x0000_0300  0x0000_0FFF) */
+#define ID		__REG_2700G(0x00000FF0)
+
+/* Local Memory (SDRAM) Interface Registers (0x0000_1000  0x0000_1FFF) */
+#define LMRST		__REG_2700G(0x00001000)
+#define LMCFG		__REG_2700G(0x00001004)
+#define LMPWR		__REG_2700G(0x00001008)
+#define LMPWRSTAT	__REG_2700G(0x0000100c)
+#define LMCEMR		__REG_2700G(0x00001010)
+#define LMTYPE		__REG_2700G(0x00001014)
+#define LMTIM		__REG_2700G(0x00001018)
+#define LMREFRESH	__REG_2700G(0x0000101c)
+#define LMPROTMIN	__REG_2700G(0x00001020)
+#define LMPROTMAX	__REG_2700G(0x00001024)
+#define LMPROTCFG	__REG_2700G(0x00001028)
+#define LMPROTERR	__REG_2700G(0x0000102c)
+
+/* Plane Controller Registers (0x0000_2000  0x0000_2FFF) */
+#define GSCTRL		__REG_2700G(0x00002000)
+#define VSCTRL		__REG_2700G(0x00002004)
+#define GBBASE		__REG_2700G(0x00002020)
+#define VBBASE		__REG_2700G(0x00002024)
+#define GDRCTRL		__REG_2700G(0x00002040)
+#define VCMSK		__REG_2700G(0x00002044)
+#define GSCADR		__REG_2700G(0x00002060)
+#define VSCADR		__REG_2700G(0x00002064)
+#define VUBASE		__REG_2700G(0x00002084)
+#define VVBASE		__REG_2700G(0x000020a4)
+#define GSADR		__REG_2700G(0x000020c0)
+#define VSADR		__REG_2700G(0x000020c4)
+#define HCCTRL		__REG_2700G(0x00002100)
+#define HCSIZE		__REG_2700G(0x00002110)
+#define HCPOS		__REG_2700G(0x00002120)
+#define HCBADR		__REG_2700G(0x00002130)
+#define HCCKMSK		__REG_2700G(0x00002140)
+#define GPLUT		__REG_2700G(0x00002150)
+#define DSCTRL		__REG_2700G(0x00002154)
+#define DHT01		__REG_2700G(0x00002158)
+#define DHT02		__REG_2700G(0x0000215c)
+#define DHT03		__REG_2700G(0x00002160)
+#define DVT01		__REG_2700G(0x00002164)
+#define DVT02		__REG_2700G(0x00002168)
+#define DVT03		__REG_2700G(0x0000216c)
+#define DBCOL		__REG_2700G(0x00002170)
+#define BGCOLOR		__REG_2700G(0x00002174)
+#define DINTRS		__REG_2700G(0x00002178)
+#define DINTRE		__REG_2700G(0x0000217c)
+#define DINTRCNT	__REG_2700G(0x00002180)
+#define DSIG		__REG_2700G(0x00002184)
+#define DMCTRL		__REG_2700G(0x00002188)
+#define CLIPCTRL	__REG_2700G(0x0000218c)
+#define SPOCTRL		__REG_2700G(0x00002190)
+#define SVCTRL		__REG_2700G(0x00002194)
+
+/* 0x0000_2198 */
+/* 0x0000_21A8 VSCOEFF[0:4] Video Scalar Vertical Coefficient [0:4] 4.14.5 */
+#define VSCOEFF0	__REG_2700G(0x00002198)
+#define VSCOEFF1	__REG_2700G(0x0000219c)
+#define VSCOEFF2	__REG_2700G(0x000021a0)
+#define VSCOEFF3	__REG_2700G(0x000021a4)
+#define VSCOEFF4	__REG_2700G(0x000021a8)
+
+#define SHCTRL		__REG_2700G(0x000021b0)
+
+/* 0x0000_21B4 */
+/* 0x0000_21D4 HSCOEFF[0:8] Video Scalar Horizontal Coefficient [0:8] 4.14.7 */
+#define HSCOEFF0	__REG_2700G(0x000021b4)
+#define HSCOEFF1	__REG_2700G(0x000021b8)
+#define HSCOEFF2	__REG_2700G(0x000021bc)
+#define HSCOEFF3	__REG_2700G(0x000021b0)
+#define HSCOEFF4	__REG_2700G(0x000021c4)
+#define HSCOEFF5	__REG_2700G(0x000021c8)
+#define HSCOEFF6	__REG_2700G(0x000021cc)
+#define HSCOEFF7	__REG_2700G(0x000021d0)
+#define HSCOEFF8	__REG_2700G(0x000021d4)
+
+#define SSSIZE		__REG_2700G(0x000021D8)
+
+/* 0x0000_2200 */
+/* 0x0000_2240 VIDGAM[0:16] Video Gamma LUT Index [0:16] 4.15.2 */
+#define VIDGAM0		__REG_2700G(0x00002200)
+#define VIDGAM1		__REG_2700G(0x00002204)
+#define VIDGAM2		__REG_2700G(0x00002208)
+#define VIDGAM3		__REG_2700G(0x0000220c)
+#define VIDGAM4		__REG_2700G(0x00002210)
+#define VIDGAM5		__REG_2700G(0x00002214)
+#define VIDGAM6		__REG_2700G(0x00002218)
+#define VIDGAM7		__REG_2700G(0x0000221c)
+#define VIDGAM8		__REG_2700G(0x00002220)
+#define VIDGAM9		__REG_2700G(0x00002224)
+#define VIDGAM10	__REG_2700G(0x00002228)
+#define VIDGAM11	__REG_2700G(0x0000222c)
+#define VIDGAM12	__REG_2700G(0x00002230)
+#define VIDGAM13	__REG_2700G(0x00002234)
+#define VIDGAM14	__REG_2700G(0x00002238)
+#define VIDGAM15	__REG_2700G(0x0000223c)
+#define VIDGAM16	__REG_2700G(0x00002240)
+
+/* 0x0000_2250 */
+/* 0x0000_2290 GFXGAM[0:16] Graphics Gamma LUT Index [0:16] 4.15.3 */
+#define GFXGAM0		__REG_2700G(0x00002250)
+#define GFXGAM1		__REG_2700G(0x00002254)
+#define GFXGAM2		__REG_2700G(0x00002258)
+#define GFXGAM3		__REG_2700G(0x0000225c)
+#define GFXGAM4		__REG_2700G(0x00002260)
+#define GFXGAM5		__REG_2700G(0x00002264)
+#define GFXGAM6		__REG_2700G(0x00002268)
+#define GFXGAM7		__REG_2700G(0x0000226c)
+#define GFXGAM8		__REG_2700G(0x00002270)
+#define GFXGAM9		__REG_2700G(0x00002274)
+#define GFXGAM10	__REG_2700G(0x00002278)
+#define GFXGAM11	__REG_2700G(0x0000227c)
+#define GFXGAM12	__REG_2700G(0x00002280)
+#define GFXGAM13	__REG_2700G(0x00002284)
+#define GFXGAM14	__REG_2700G(0x00002288)
+#define GFXGAM15	__REG_2700G(0x0000228c)
+#define GFXGAM16	__REG_2700G(0x00002290)
+
+#define DLSTS		__REG_2700G(0x00002300)
+#define DLLCTRL		__REG_2700G(0x00002304)
+#define DVLNUM		__REG_2700G(0x00002308)
+#define DUCTRL		__REG_2700G(0x0000230c)
+#define DVECTRL		__REG_2700G(0x00002310)
+#define DHDET		__REG_2700G(0x00002314)
+#define DVDET		__REG_2700G(0x00002318)
+#define DODMSK		__REG_2700G(0x0000231c)
+#define CSC01		__REG_2700G(0x00002330)
+#define CSC02		__REG_2700G(0x00002334)
+#define CSC03		__REG_2700G(0x00002338)
+#define CSC04		__REG_2700G(0x0000233c)
+#define CSC05		__REG_2700G(0x00002340)
+
+#endif /* __REGS_2700G_ */
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c
index 53ad61f..76675f6 100644
--- a/drivers/video/pxafb.c
+++ b/drivers/video/pxafb.c
@@ -48,6 +48,11 @@ #include <asm/arch/pxa-regs.h>
 #include <asm/arch/bitfield.h>
 #include <asm/arch/pxafb.h>
 
+#ifdef CONFIG_PXA27x
+#define LCCR4		__REG(0x44000010)  /* LCD Controller Control Register 3 */
+#endif
+
+
 /*
  * Complain if VAR is out of range.
  */
@@ -113,9 +118,15 @@ pxafb_setpalettereg(u_int regno, u_int r
 		if (fbi->fb.var.grayscale) {
 			val = ((blue >> 8) & 0x00ff);
 		} else {
+#ifdef CONFIG_ARMCORE_REV11
+			val  = (((red & 0xff)   <<  16) & 0xfc0000);
+			val |= (((green & 0xff) <<  8)  & 0xfc00);
+			val |= (((blue  & 0xff) <<  0)  & 0x00fc);
+#else
 			val  = ((red   >>  0) & 0xf800);
 			val |= ((green >>  5) & 0x07e0);
 			val |= ((blue  >> 11) & 0x001f);
+#endif
 		}
 		fbi->palette_cpu[regno] = val;
 		ret = 0;
@@ -426,6 +437,8 @@ static struct fb_ops pxafb_ops = {
  * We take account of the PPCR clock setting.
  * From PXA Developer's Manual:
  *
+ * If PCDDIV = 0 then:
+ *
  *   PixelClock =      LCLK
  *                -------------
  *                2 ( PCD + 1 )
@@ -434,6 +447,17 @@ static struct fb_ops pxafb_ops = {
  *         ------------- - 1
  *         2(PixelClock)
  *
+ *
+ * If PCDDIV = 1 then:
+ *
+ *   PixelClock =      LCLK
+ *                -------------
+ *                 ( PCD + 1 )
+ *
+ *   PCD =      LCLK
+ *         ------------- - 1
+ *           PixelClock
+ *
  * Where:
  *   LCLK = LCD/Memory Clock
  *   PCD = LCCR3[7:0]
@@ -448,22 +472,64 @@ static struct fb_ops pxafb_ops = {
  *    PCD = (lclk * 10^4 ) * ( pixclock * 10^-12 )
  *          -------------------------------------- - 1
  *                          2
+ * or
+ *    PCD = (lclk * 10^4 ) * ( pixclock * 10^-12 ) - 1
  *
  * Factoring the 10^4 and 10^-12 out gives 10^-8 == 1 / 100000000 as used below.
  */
-static inline unsigned int get_pcd(unsigned int pixclock)
+static inline unsigned int get_pcd(unsigned int pixclock, unsigned int *lccr4)
 {
-	unsigned long long pcd;
+	/* pcd1 is for PCDDIV=0 and pcd2 for PCDDIV=1 */
+	unsigned long long pcd1, pcd2;
+	unsigned long long clk1, clk2;
+	unsigned long long dif1, dif2;
+
+	*lccr4 = LCCR4;
 
 	/* FIXME: Need to take into account Double Pixel Clock mode
          * (DPC) bit? or perhaps set it based on the various clock
          * speeds */
 
-	pcd = (unsigned long long)get_lcdclk_frequency_10khz() * pixclock;
-	do_div(pcd, 100000000 * 2);
+	pcd1 = pcd2 = (unsigned long long)get_lcdclk_frequency_10khz() * pixclock;
+	do_div(pcd1, 100000000 * 2); /*	pcd1 /= 100000000 * 2; */
+	do_div(pcd2, 100000000); /* pcd2 /= 100000000; */
+
+/* 	clk1 = 100000000*(2 * (pcd1 + 1))/get_lcdclk_frequency_10khz(); */
+/* 	clk2 = 100000000*(pcd2 + 1)/get_lcdclk_frequency_10khz(); */
+
+	clk1 = 100000000*(2 * (pcd1 + 1));
+	clk2 = 100000000*(pcd2 + 1);
+	do_div(clk1, get_lcdclk_frequency_10khz());
+	do_div(clk2, get_lcdclk_frequency_10khz());
+
+	pr_debug("get_pcd: pcd1 = %lld, dotclock = %lld\n", pcd1, clk1);
+	pr_debug("get_pcd: pcd2 = %lld, dotclock = %lld\n", pcd2, clk2);
+
+	dif1 = pixclock - clk1;
+	if ( clk1 > pixclock ) 
+		dif1 *= -1;
+
+	dif2 = pixclock - clk2;
+	if ( clk2 > pixclock ) 
+		dif2 *= -1;
+
+	if ( dif1 > dif2 ) {
+		*lccr4 |= (1 << 31);
+		pr_debug(KERN_INFO "get_pcd: setting pixclock to high rate\n");
+		return (unsigned int)pcd2;
+	}
+	else {
+		*lccr4 &= ~(1 << 31);
+		pr_debug(KERN_INFO "get_pcd: setting pixclock to low rate\n");
+		return (unsigned int)pcd1;
+	}
+
 	/* no need for this, since we should subtract 1 anyway. they cancel */
 	/* pcd += 1; */ /* make up for integer math truncations */
-	return (unsigned int)pcd;
+/* 	return (unsigned int)pcd2; */
+
+	/* never get here */
+	return (unsigned int)0;
 }
 
 /*
@@ -505,7 +571,9 @@ static int pxafb_activate_var(struct fb_
 {
 	struct pxafb_lcd_reg new_regs;
 	u_long flags;
-	u_int lines_per_panel, pcd = get_pcd(var->pixclock);
+	u_int lines_per_panel;
+	u_int lccr4;
+	u_int pcd = get_pcd(var->pixclock, &lccr4);
 
 	pr_debug("pxafb: Configuring PXA LCD\n");
 
@@ -735,10 +803,18 @@ static void pxafb_setup_gpio(struct pxaf
 	pxa_gpio_mode(GPIO75_LCD_LCLK_MD);
 	pxa_gpio_mode(GPIO76_LCD_PCLK_MD);
 	pxa_gpio_mode(GPIO77_LCD_ACBIAS_MD);
+
+#ifdef CONFIG_ARMCORE_REV11
+	pxa_gpio_mode(86 | GPIO_ALT_FN_2_OUT);
+	pxa_gpio_mode(87 | GPIO_ALT_FN_2_OUT);
+#endif
 }
 
 static void pxafb_enable_controller(struct pxafb_info *fbi)
 {
+	unsigned int lccr4;
+	unsigned int pcd = get_pcd(fbi->fb.var.pixclock, &lccr4);
+
 	pr_debug("pxafb: Enabling LCD controller\n");
 	pr_debug("fdadr0 0x%08x\n", (unsigned int) fbi->fdadr0);
 	pr_debug("fdadr1 0x%08x\n", (unsigned int) fbi->fdadr1);
@@ -751,7 +827,20 @@ static void pxafb_enable_controller(stru
 	pxa_set_cken(CKEN16_LCD, 1);
 
 	/* Sequence from 11.7.10 */
-	LCCR3 = fbi->reg_lccr3;
+#ifdef CONFIG_ARMCORE_REV12
+	LCCR4 = lccr4;
+#else
+	LCCR4 = 0 | (2 << 15) | lccr4;
+#endif
+
+	fbi->reg_lccr3 = (fbi->reg_lccr3 & ~0xff) | LCCR3_PixClkDiv(pcd);
+
+#ifdef CONFIG_ARMCORE_REV12
+	LCCR3 = (fbi->reg_lccr3);//& (~(7 << 24))) | (3 << 24);
+#else
+	LCCR3 = (fbi->reg_lccr3 | (3 << 30)) ;//& (~(7 << 24))) | (3 << 24);
+#endif
+
 	LCCR2 = fbi->reg_lccr2;
 	LCCR1 = fbi->reg_lccr1;
 	LCCR0 = fbi->reg_lccr0 & ~LCCR0_ENB;
@@ -1083,6 +1172,7 @@ static struct pxafb_info * __init pxafb_
 	addr = addr + sizeof(struct pxafb_info);
 	fbi->fb.pseudo_palette	= addr;
 
+	fbi->fb.var.pixclock		= inf->pixclock;
 	fbi->max_xres			= inf->xres;
 	fbi->fb.var.xres		= inf->xres;
 	fbi->fb.var.xres_virtual	= inf->xres;
diff --git a/include/asm-arm/arch-pxa/cm-x270.h b/include/asm-arm/arch-pxa/cm-x270.h
new file mode 100644
index 0000000..7099ae7
--- /dev/null
+++ b/include/asm-arm/arch-pxa/cm-x270.h
@@ -0,0 +1,72 @@
+/*
+ *  linux/include/asm/arch-pxa/armcore.h
+ *
+ *  Compulab Ltd., 2003 
+ *
+ *  ARMCore registers
+ */
+
+#include <linux/config.h>
+
+#define CMX270_CS1_PHYS		(PXA_CS1_PHYS)
+#define MARATHON_PHYS		(PXA_CS2_PHYS)
+#define CMX270_IDE104_PHYS	(PXA_CS3_PHYS)
+#define CMX270_IT8152_PHYS	(PXA_CS4_PHYS)
+
+#define PXA_CS_SIZE		(64*1024*1024)
+
+/* Virtual map */
+
+#define CMX270_VIRT_BASE		(0xe8000000)
+
+#define CMX270_IT8152_VIRT		(CMX270_VIRT_BASE)
+#define CMX270_IDE104_VIRT		(CMX270_IT8152_VIRT + PXA_CS_SIZE)
+
+
+/* GPIO related definitions */
+#define GPIO_IT8152_IRQ			(22)
+#define GPIO_RED_LED			(93)
+#define GPIO_GREEN_LED			(94)
+
+
+#define IRQ_GPIO_IT8152_IRQ	IRQ_GPIO(GPIO_IT8152_IRQ)
+#define PME_IRQ			IRQ_GPIO(0)
+#define CMX270_IDE_IRQ		IRQ_GPIO(100)
+#define CMX270_GPIRQ1		IRQ_GPIO(101)
+#define CMX270_TOUCHIRQ		IRQ_GPIO(96)
+#define CMX270_ETHIRQ		IRQ_GPIO(10)
+#define CMX270_GFXIRQ		IRQ_GPIO(95)
+#define CMX270_NANDIRQ		IRQ_GPIO(89)
+#define CMX270_MMC_IRQ		IRQ_GPIO(83)
+
+/* LED macros */
+#define CMX270_RED_ON()		 GPCR(GPIO_RED_LED) = GPIO_bit(GPIO_RED_LED)
+#define CMX270_RED_OFF()		 GPSR(GPIO_RED_LED) = GPIO_bit(GPIO_RED_LED)
+#define CMX270_GREEN_ON()		 GPCR(GPIO_GREEN_LED) = GPIO_bit(GPIO_GREEN_LED)
+#define CMX270_GREEN_OFF()		 GPSR(GPIO_GREEN_LED) = GPIO_bit(GPIO_GREEN_LED)
+
+/* PCMCIA related definitions */
+#define PCC_DETECT(x)	(GPLR(84 - (x)) & GPIO_bit(84 - (x)))
+#define PCC_READY(x)	(GPLR(82 - (x)) & GPIO_bit(81 - (x)))
+
+#define PCMCIA_S0_CD_VALID		IRQ_GPIO(84)
+#define PCMCIA_S0_CD_VALID_EDGE		GPIO_BOTH_EDGES
+
+#define PCMCIA_S1_CD_VALID		IRQ_GPIO(83)
+#define PCMCIA_S1_CD_VALID_EDGE		GPIO_BOTH_EDGES
+
+#define PCMCIA_S0_RDYINT		IRQ_GPIO(82)
+#define PCMCIA_S1_RDYINT		IRQ_GPIO(81)
+
+#define PCMCIA_RESET_GPIO		53
+
+
+
+
+
+
+
+
+
+ 
+
diff --git a/include/asm-arm/arch-pxa/hardware.h b/include/asm-arm/arch-pxa/hardware.h
index 3e70bd9..cb4fb2f 100644
--- a/include/asm-arm/arch-pxa/hardware.h
+++ b/include/asm-arm/arch-pxa/hardware.h
@@ -80,4 +80,15 @@ extern unsigned int get_lcdclk_frequency
 
 #endif
 
+#if defined(CONFIG_MACH_ARMCORE) && defined(CONFIG_PCI)
+#define      HAVE_ARCH_PCI_SET_DMA_MASK
+#ifndef __ASSEMBLY__
+extern unsigned long armcore_pcibios_min_io;
+extern unsigned long armcore_pcibios_min_mem;
+#endif
+#define PCIBIOS_MIN_IO      (armcore_pcibios_min_io)
+#define PCIBIOS_MIN_MEM     (armcore_pcibios_min_mem)
+#define pcibios_assign_all_busses()	1
+#endif
+
 #endif  /* _ASM_ARCH_HARDWARE_H */
diff --git a/include/asm-arm/arch-pxa/irqs.h b/include/asm-arm/arch-pxa/irqs.h
index 05c4b70..f0259cd 100644
--- a/include/asm-arm/arch-pxa/irqs.h
+++ b/include/asm-arm/arch-pxa/irqs.h
@@ -176,7 +176,8 @@ #define NR_IRQS			(IRQ_S1_BVD1_STSCHG + 
 #elif defined(CONFIG_SHARP_LOCOMO)
 #define NR_IRQS			(IRQ_LOCOMO_SPI_TEND + 1)
 #elif defined(CONFIG_ARCH_LUBBOCK) || \
-      defined(CONFIG_MACH_MAINSTONE)
+      defined(CONFIG_MACH_MAINSTONE) || \
+      defined(CONFIG_MACH_ARMCORE)
 #define NR_IRQS			(IRQ_BOARD_END)
 #else
 #define NR_IRQS			(IRQ_BOARD_START)
@@ -217,3 +218,24 @@ #define IRQ_LOCOMO_KEY_BASE	(IRQ_BOARD_S
 #define IRQ_LOCOMO_GPIO_BASE	(IRQ_BOARD_START + 1)
 #define IRQ_LOCOMO_LT_BASE	(IRQ_BOARD_START + 2)
 #define IRQ_LOCOMO_SPI_BASE	(IRQ_BOARD_START + 3)
+
+/* ITE8152 irqs on CM-x2xx */
+#ifdef CONFIG_MACH_ARMCORE
+#define IT8152_IRQ(x)	(IRQ_BOARD_START + (x))
+#define PCISERR			IT8152_IRQ(0)
+#define H2PTADR			IT8152_IRQ(1)
+#define H2PMAR			IT8152_IRQ(2)
+#define PCI_INTA		IT8152_IRQ(3)
+#define PCI_INTB		IT8152_IRQ(4)
+#define PCI_INTC		IT8152_IRQ(5)
+#define PCI_INTD		IT8152_IRQ(6)
+#define USB_INT			IT8152_IRQ(7)
+#define AUDIO_INT		IT8152_IRQ(8)
+#define CDMA_INT		IT8152_IRQ(9)
+#define IRQ_ITESER		IT8152_IRQ(10)
+#define IT8152_IRQ_MAX		IT8152_IRQ(10)
+
+
+#undef NR_IRQS
+#define NR_IRQS IT8152_IRQ_MAX+1
+#endif
diff --git a/include/asm-arm/arch-pxa/marathonfb.h b/include/asm-arm/arch-pxa/marathonfb.h
new file mode 100644
index 0000000..97b69ef
--- /dev/null
+++ b/include/asm-arm/arch-pxa/marathonfb.h
@@ -0,0 +1,28 @@
+#ifndef __MARATHON_FB_H
+#define __MARATHON_FB_H
+
+struct mbxfb_val {
+	unsigned int	defval;
+	unsigned int	min;
+	unsigned int	max;
+};
+
+struct fb_info;
+
+struct mbxfb_platform_data {
+		/* Screen info */
+		struct mbxfb_val xres;
+		struct mbxfb_val yres;
+		struct mbxfb_val bpp;
+
+		/* Memory info */
+		unsigned long memsize; /* if 0 use ODFB? */
+		unsigned long timings1;
+		unsigned long timings2;
+		unsigned long timings3;
+
+		int (*probe)(struct fb_info *fb);
+		int (*remove)(struct fb_info *fb);
+};
+
+#endif /* __MARATHON_FB_H */
diff --git a/include/asm-arm/arch-pxa/memory.h b/include/asm-arm/arch-pxa/memory.h
index eaf6d43..98807e7 100644
--- a/include/asm-arm/arch-pxa/memory.h
+++ b/include/asm-arm/arch-pxa/memory.h
@@ -17,6 +17,19 @@ #define __ASM_ARCH_MEMORY_H
  */
 #define PHYS_OFFSET	UL(0xa0000000)
 
+
+#ifdef CONFIG_PCI_HOST_ITE8152
+#ifndef __ASSEMBLY__
+void it8152_adjust_zones(int node, unsigned long *size, unsigned long *holes);
+
+#define arch_adjust_zones(node, size, holes) \
+	it8152_adjust_zones(node, size, holes)
+
+#define ISA_DMA_THRESHOLD (SZ_64M - 1)
+#endif
+#endif
+
+
 /*
  * Virtual view <-> DMA view memory address translations
  * virt_to_bus: Used to translate the virtual address to an
diff --git a/include/asm-arm/arch-pxa/pxafbsetup.h b/include/asm-arm/arch-pxa/pxafbsetup.h
new file mode 100644
index 0000000..8a7c8de
--- /dev/null
+++ b/include/asm-arm/arch-pxa/pxafbsetup.h
@@ -0,0 +1,39 @@
+/*
+ Panel specific LCD controller setup
+ */
+
+#ifndef _PXAFBSETUP_H
+#define _PXAFBSETUP_H
+
+#define MTYPE_STN320x240	0
+#define MTYPE_TFT640x480	1
+#define MTYPE_CRT640x480	2
+#define MTYPE_CRT800x600	3
+#define MTYPE_CRT1024x768	4
+#define MTYPE_USER_DEFINED	5
+#define MTYPE_TFT320x240	6
+#define MTYPE_STN640x480	7
+
+#define	CMAP_GREYSCALE  	0
+#define CMAP_INVERSE		0
+#define CMAP_STATIC			0
+
+
+// Example for user defined display
+// Hitach SX19V-009
+#define LCD_PIXCLOCK			38461
+#define LCD_BPP				8
+#define LCD_XRES			640
+#define LCD_YRES			480
+#define LCD_HORIZONTAL_SYNC_PULSE_WIDTH 4
+#define LCD_VERTICAL_SYNC_PULSE_WIDTH	2
+#define LCD_BEGIN_OF_LINE_WAIT_COUNT	10
+#define LCD_BEGIN_FRAME_WAIT_COUNT	5
+#define LCD_END_OF_LINE_WAIT_COUNT	10
+#define LCD_END_OF_FRAME_WAIT_COUNT	5
+#define LCD_SYNC			(FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT)
+#define LCD_LCCR0			(LCCR0_LDM | LCCR0_IUM | LCCR0_QDM | LCCR0_BM  | LCCR0_OUM )
+#define LCD_LCCR3			(LCCR3_PixClkDiv(0x02) | LCCR3_Acb(0xff))
+#define LCD_NAME			"Hitachi SX19V-009-ZZA-1"
+
+#endif
diff --git a/include/asm-arm/hardware/it8152.h b/include/asm-arm/hardware/it8152.h
new file mode 100644
index 0000000..d28210d
--- /dev/null
+++ b/include/asm-arm/hardware/it8152.h
@@ -0,0 +1,104 @@
+/*
+ *  arch/arm/mach-pxa/it8152.h
+ *
+ *  Compulab Ltd., 2006
+ *
+ *  ITE 8152 companion chip definitions
+ */
+
+
+/* #define CMX270_IT8152_VIRT		(CMX270_VIRT_BASE) */
+
+
+extern unsigned long it8152_base_address;
+
+#define IT8152_IO_BASE			(it8152_base_address + 0x03e00000)
+#define IT8152_CFGREG_BASE		(it8152_base_address + 0x03f00000)
+
+/* #define IRQ_GPIO_IT8152_IRQ		IRQ_GPIO(GPIO_IT8152_IRQ) */
+
+#define IT8152_SHORT_IO(x)		(*((volatile unsigned short *)(IT8152_CFGREG_BASE+(x))))
+#define IT8152_LONG_IO(x)		(*((volatile unsigned long *)(IT8152_CFGREG_BASE+(x))))
+
+
+#define IT8152_PCI_MEMBASE		(*((volatile unsigned long *)(it8152_base_address)))
+/* #define IT8152_PCI_IOBASE		(*((volatile unsigned long *)(it8152_base_address + 0x3e00000))) */
+
+#define IT8152_PCI_IACK			(*((volatile unsigned long *)(it8152_base_address + 0x3f00808)))
+#define IT8152_PCI_CFG_ADDR		(*((volatile unsigned long *)(it8152_base_address + 0x3f00800)))
+#define IT8152_PCI_CFG_DATA		(*((volatile unsigned long *)(it8152_base_address + 0x3f00804)))
+
+#define IT_BUSNUM_SHF                   16
+#define IT_DEVNUM_SHF                   11
+#define IT_FUNCNUM_SHF                  8
+#define IT_REGNUM_SHF                   2
+
+/* Power management & PLL registers */
+#define IT8152_PMPLL_DSR		IT8152_LONG_IO(0x00)
+#define IT8152_PMPLL_DSSR		IT8152_LONG_IO(0x04)
+#define IT8152_PMPLL_PLLCR		IT8152_LONG_IO(0x20)
+#define IT8152_PMPLL_MFSR		IT8152_LONG_IO(0x24)
+
+/* Memory controller */
+#define IT8152_MC_REG_OFFSET		0x100
+
+#define IT8152_MC_SDCR			IT8152_LONG_IO(IT8152_MC_REG_OFFSET + 0x00)
+#define IT8152_MC_PCICR			IT8152_LONG_IO(IT8152_MC_REG_OFFSET + 0x04)
+
+/* Interrupt related definitions */
+#define IT8152_INTC_REG_OFFSET		0x300
+
+#define IT8152_INTC_LDCNIRR		IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0x00)
+#define IT8152_INTC_LDPNIRR		IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0x04)
+#define IT8152_INTC_LDCNIMR		IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0x08)
+#define IT8152_INTC_LDPNIMR		IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0x0C)
+#define IT8152_INTC_LDNITR		IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0x10)
+#define IT8152_INTC_LDNIAR		IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0x14)
+#define IT8152_INTC_LPCNIRR		IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0x20)
+#define IT8152_INTC_LPPNIRR		IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0x24)
+#define IT8152_INTC_LPCNIMR		IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0x28)
+#define IT8152_INTC_LPPNIMR		IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0x2C)
+#define IT8152_INTC_LPNITR		IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0x30)
+#define IT8152_INTC_LPNIAR		IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0x34)
+#define IT8152_INTC_PDCNIRR		IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0x40)
+#define IT8152_INTC_PDPNIRR		IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0x44)
+#define IT8152_INTC_PDCNIMR		IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0x48)
+#define IT8152_INTC_PDPNIMR		IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0x4C)
+#define IT8152_INTC_PDNITR		IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0x50)
+#define IT8152_INTC_PDNIAR		IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0x54)
+#define IT8152_INTC_INTC_TYPER	IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0xFC)
+
+#define IT8152_UART_BASE		IT8152_LONG_IO(0x200)
+
+#define IT8152_GPIO_REG_OFFSET		0x500
+
+#define IT8152_GPIO_GPLR		IT8152_LONG_IO(IT8152_GPIO_REG_OFFSET)
+#define IT8152_GPIO_GPCR12		IT8152_LONG_IO(IT8152_GPIO_REG_OFFSET + 0x04)
+#define IT8152_GPIO_GPCR34		IT8152_LONG_IO(IT8152_GPIO_REG_OFFSET + 0x08)
+
+
+/* Interrupt bit definitions */
+#define PCISERR_BIT		(1<<14)
+#define H2PTADR_BIT		(1<<13)
+#define H2PMAR_BIT		(1<<12)
+#define PCI_INTD_BIT	(1<<11)
+#define PCI_INTC_BIT	(1<<10)
+#define PCI_INTB_BIT	(1<<9)
+#define PCI_INTA_BIT	(1<<8)
+#define CDMA_INT_BIT	(1<<2)
+#define USB_INT_BIT		(1<<1)
+#define AUDIO_INT_BIT	(1<<0)
+
+/* IT8152 UART */
+#define ITESER_BIT		(1<<5)
+
+
+
+
+
+
+
+
+
+ 
+
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 751eea5..bc45d11 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -1568,6 +1568,7 @@ #define PCI_DEVICE_ID_EFFICEON		0x0060
 #define PCI_VENDOR_ID_ROCKWELL		0x127A
 
 #define PCI_VENDOR_ID_ITE		0x1283
+#define PCI_DEVICE_ID_ITE_IT8152	0x8152
 #define PCI_DEVICE_ID_ITE_IT8172G	0x8172
 #define PCI_DEVICE_ID_ITE_IT8172G_AUDIO 0x0801
 #define PCI_DEVICE_ID_ITE_8211		0x8211
diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c
index 3020ca2..ba1dc8a 100644
--- a/sound/pci/ac97/ac97_codec.c
+++ b/sound/pci/ac97/ac97_codec.c
@@ -150,7 +150,7 @@ static const struct ac97_codec_id snd_ac
 { 0x4e534300, 0xffffffff, "LM4540,43,45,46,48",	NULL,		NULL }, // only guess --jk
 { 0x4e534331, 0xffffffff, "LM4549",		NULL,		NULL },
 { 0x4e534350, 0xffffffff, "LM4550",		NULL,		NULL },
-{ 0x50534304, 0xffffffff, "UCB1400",		NULL,		NULL },
+{ 0x50534304, 0xffffffff, "UCB1400",		patch_ucb1400,	NULL },
 { 0x53494c20, 0xffffffe0, "Si3036,8",		mpatch_si3036,	mpatch_si3036, AC97_MODEM_PATCH },
 { 0x54524102, 0xffffffff, "TR28022",		NULL,		NULL },
 { 0x54524106, 0xffffffff, "TR28026",		NULL,		NULL },
diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c
index a444a78..0bb1d71 100644
--- a/sound/pci/ac97/ac97_patch.c
+++ b/sound/pci/ac97/ac97_patch.c
@@ -2823,3 +2823,33 @@ int mpatch_si3036(struct snd_ac97 * ac97
 	snd_ac97_write_cache(ac97, 0x68, 0);
 	return 0;
 }
+
+/* 
+ *  UCB1400 codec
+ */
+static const struct snd_kcontrol_new snd_ac97_controls_ucb1400[] = {
+AC97_SINGLE("Headphone driver", 0x6a, 6, 1, 0),
+AC97_SINGLE("DC filter", 0x6a, 4, 1, 0),
+AC97_SINGLE("Smart power mode", 0x6c, 4, 3, 0),
+};
+
+static int patch_ucb1400_specific(struct snd_ac97 * ac97)
+{
+	int idx, err;
+	for (idx = 0; idx < ARRAY_SIZE(snd_ac97_controls_ucb1400); idx++)
+		if ((err = snd_ctl_add(ac97->bus->card, snd_ctl_new1(&snd_ac97_controls_ucb1400[idx], ac97))) < 0)
+			return err;
+	return 0;
+}
+
+static struct snd_ac97_build_ops patch_ucb1400_ops = {
+	.build_specific	= patch_ucb1400_specific,
+};
+
+int patch_ucb1400(struct snd_ac97 * ac97)
+{
+	ac97->build_ops = &patch_ucb1400_ops;
+	snd_ac97_write(ac97, 0x6a, 0x0050);
+	snd_ac97_write(ac97, 0x6c, 0x0030);
+	return 0;
+}
diff --git a/sound/pci/ac97/ac97_patch.h b/sound/pci/ac97/ac97_patch.h
index 5060cb6..068b674 100644
--- a/sound/pci/ac97/ac97_patch.h
+++ b/sound/pci/ac97/ac97_patch.h
@@ -58,4 +58,5 @@ int patch_cm9780(struct snd_ac97 * ac97)
 int patch_vt1616(struct snd_ac97 * ac97);
 int patch_vt1617a(struct snd_ac97 * ac97);
 int patch_it2646(struct snd_ac97 * ac97);
+int patch_ucb1400(struct snd_ac97 * ac97);
 int mpatch_si3036(struct snd_ac97 * ac97);