 drivers/ide/Kconfig           |   14 +++++
 drivers/ide/arm/Makefile      |    2 +
 drivers/ide/arm/cm-x255-ide.c |   98 ++++++++++++++++++++++++++++++++++
 drivers/ide/arm/cm-x270-ide.c |  117 +++++++++++++++++++++++++++++++++++++++++
 4 files changed, 231 insertions(+), 0 deletions(-)

diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig
index d1266fe..709368c 100644
--- a/drivers/ide/Kconfig
+++ b/drivers/ide/Kconfig
@@ -857,6 +857,20 @@ 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_X255
+	tristate "CompuLab CM-X255 IDE support"
+	depends on ARM && (CM_X255)
+	help
+	  Say Y here if you want to support the onboard IDE channels on the
+	  CompuLab CM-X255 module
+
+config BLK_DEV_IDE_CM_X270
+	tristate "CompuLab CM-X270 IDE support"
+	depends on ARM && (CM_X270)
+	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..9ad6778 100644
--- a/drivers/ide/arm/Makefile
+++ b/drivers/ide/arm/Makefile
@@ -2,5 +2,7 @@
 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_X255)	+= cm-x255-ide.o
+obj-$(CONFIG_BLK_DEV_IDE_CM_X270)	+= cm-x270-ide.o
 
 EXTRA_CFLAGS	:= -Idrivers/ide
diff --git a/drivers/ide/arm/cm-x255-ide.c b/drivers/ide/arm/cm-x255-ide.c
new file mode 100644
index 0000000..e442a05
--- /dev/null
+++ b/drivers/ide/arm/cm-x255-ide.c
@@ -0,0 +1,98 @@
+/* 
+ * linux/drivers/ide/arm/cm-x255-ide.c
+ *
+ * Copyright (C) 2003, 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 <linux/irq.h>
+
+#include <asm/mach-types.h>
+
+#include <asm/io.h>
+#include <asm/arch/pxa-regs.h>
+#include <asm/arch/cm-x255.h>
+
+/* list of registered interfaces */
+static ide_hwif_t *ifs[1];
+
+static int __init
+cmx255_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 == CMX255_IDECS0_VIRT) {
+		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;
+		hw.io_ports[IDE_STATUS_OFFSET]= base + 14;
+		hw.io_ports[IDE_CONTROL_OFFSET] = (aux+0x6);
+	} else {
+		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;
+
+	ide_register_hw(&hw, hwif);
+
+	return 0;
+}
+
+static int __init cmx255_init(void)
+{
+	if (!(machine_is_armcore()))
+		return 0;
+
+	printk("CM-X255: IDE driver, (c) 2003-2006 CompuLab Ltd\n");
+
+	MSC1 = 0x7ffc7ff4;
+
+	/* Interrupts on rising edge: lines are inverted before they get to
+           the PXA */
+	pxa_gpio_mode(IRQ_TO_GPIO(CMX255_IDE_IRQ));
+	set_irq_type(CMX255_IDE_IRQ, IRQT_FALLING);
+
+	return cmx255_register(CMX255_IDECS0_VIRT, CMX255_IDECS1_VIRT, CMX255_IDE_IRQ, &ifs[0]);
+	return 0;
+}
+
+module_init(cmx255_init);
+
+MODULE_AUTHOR("CompuLab");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("CompuLab CM-X255 IDE driver");
diff --git a/drivers/ide/arm/cm-x270-ide.c b/drivers/ide/arm/cm-x270-ide.c
new file mode 100644
index 0000000..d989b79
--- /dev/null
+++ b/drivers/ide/arm/cm-x270-ide.c
@@ -0,0 +1,117 @@
+/* 
+ * linux/drivers/ide/arm/cm-x270-ide.c
+ *
+ * Copyright (C) 2003, 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 <linux/irq.h>
+
+#include <asm/mach-types.h>
+
+#include <asm/io.h>
+#include <asm/arch/cm-x270.h>
+
+/* list of registered interfaces */
+static ide_hwif_t *ifs[1];
+
+static int __init
+cmx270_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_IDECS0_VIRT) {
+#ifdef CONFIG_CM_X270_SB270
+		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
+		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);
+#endif
+	} 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;
+
+	ide_register_hw(&hw, hwif);
+
+	return 0;
+}
+
+static int __init cmx270_init(void)
+{
+	if (!(machine_is_armcore()))
+		return 0;
+
+	printk("CM-X270: IDE driver, (c) 2003-2006 CompuLab Ltd\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));
+
+#ifdef CONFIG_CM_X270_SB270
+	set_irq_type(CMX270_IDE_IRQ, IRQT_RISING);
+#else
+	set_irq_type(CMX270_IDE_IRQ, IRQT_FALLING);
+#endif
+
+	return cmx270_register(CMX270_IDECS0_VIRT, CMX270_IDECS1_VIRT, CMX270_IDE_IRQ, &ifs[0]);
+	return 0;
+}
+
+module_init(cmx270_init);
+
+MODULE_AUTHOR("CompuLab");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("CompuLab CM-X270 IDE driver");

