diff -uprN linux-2.6.20-at92_e1.5.1-spi/arch/arm/mach-at91rm9200/Makefile linux-2.6.20-at92_e1.5.1-4w/arch/arm/mach-at91rm9200/Makefile
--- linux-2.6.20-at92_e1.5.1-spi/arch/arm/mach-at91rm9200/Makefile	2008-02-06 12:51:27.000000000 -0500
+++ linux-2.6.20-at92_e1.5.1-4w/arch/arm/mach-at91rm9200/Makefile	2008-02-06 14:02:21.000000000 -0500
@@ -28,7 +28,7 @@ obj-$(CONFIG_MACH_ATEB9200)	+= board-eb9
 obj-$(CONFIG_MACH_KAFA)		+= board-kafa.o
 
 # AT91SAM9260 board-specific support
-obj-$(CONFIG_MACH_AT91SAM9260EK) += board-sam9260ek.o
+obj-$(CONFIG_MACH_AT91SAM9260EK) += board-sam9260ek.o atod-som9260m.o
 obj-$(CONFIG_MACH_SOM9260M) += board-som9260m.o atod-som9260m.o led-som9260m.o
 
 # AT91SAM9261 board-specific support
diff -uprN linux-2.6.20-at92_e1.5.1-spi/arch/arm/mach-at91rm9200/board-sam9260ek.c linux-2.6.20-at92_e1.5.1-4w/arch/arm/mach-at91rm9200/board-sam9260ek.c
--- linux-2.6.20-at92_e1.5.1-spi/arch/arm/mach-at91rm9200/board-sam9260ek.c	2008-02-06 13:09:17.000000000 -0500
+++ linux-2.6.20-at92_e1.5.1-4w/arch/arm/mach-at91rm9200/board-sam9260ek.c	2008-02-06 14:02:21.000000000 -0500
@@ -39,6 +39,8 @@
 #include <asm/arch/gpio.h>
 #include <asm/arch/at91sam926x_mc.h>
 
+#include "atod-som9260m.h"
+
 #include "generic.h"
 
 
@@ -194,15 +196,25 @@ static struct __initdata at91_eth_data e
 #if 0
 static struct mtd_partition __initdata ek_nand_partition[] = {
 	{
-		.name	= "Partition 1",
+		.name	= "Boot Partition",
 		.offset	= 0,
-		.size	= 256 * 1024,
+		.size	= 64 * 2 * 1024,
 	},
 	{
-		.name	= "Partition 2",
-		.offset	= 256 * 1024,
-		.size	= MTDPART_SIZ_FULL,
+		.name	= "UBoot Partition",
+		.offset	= 64 * 2 * 1024,
+		.size	= 64 * 14 * 1024,
 	},
+ 	{
+ 		.name	= "Kernel Partition",
+ 		.offset	= 64 * 16 * 1024,
+ 		.size	= 64 * 48 * 1024,
+ 	},
+ 	{
+ 		.name	= "Disk Partition",
+ 		.offset	= 64 * 64 * 1024,
+ 		.size	= 64 * 256 * 1024,
+ 	},
 };
 #endif
 
@@ -264,6 +276,39 @@ static struct at91_mmc_data __initdata e
 //	.vcc_pin	= ... not connected
 };
 
+/************************************************************
+ * device registrations from the arch go here, 
+ * which are called by the boardspec ioex driver
+ */
+static int som9260m_classes(void)
+{
+	som9260m_atod_init();
+	som9260m_atod_class_create("indexed_atod");
+	
+	//set wakeup mask to all uarts
+	set_irq_wake(AT91SAM9260_ID_US0,1);
+	set_irq_wake(AT91SAM9260_ID_US1,1);
+	set_irq_wake(AT91SAM9260_ID_US2,1);
+	set_irq_wake(AT91SAM9260_ID_US3,1);
+	set_irq_wake(AT91SAM9260_ID_US4,1);
+	set_irq_wake(AT91SAM9260_ID_US5,1);
+	
+	return 0;
+}
+
+static struct platform_device boardspec_device = {
+	.name = "boardspec",
+	.id = 1,
+	.dev		= {
+		.platform_data	= &som9260m_classes,
+	},
+};
+
+static inline void at91_add_device_boardspec(void){
+	platform_device_register(&boardspec_device);
+}
+
+
 static void __init ek_board_init(void)
 {
 	/* Serial */
@@ -280,6 +325,8 @@ static void __init ek_board_init(void)
 	at91_add_device_eth(&ek_macb_data);
 	/* MMC */
 	at91_add_device_mmc(0, &ek_mmc_data);
+	/* Board Specific */
+	at91_add_device_boardspec();
 	/* AT73C213 & SSC port */
 	at91_add_device_ssc_at73c213();
 }
diff -uprN linux-2.6.20-at92_e1.5.1-spi/drivers/mmc/at91_mci.c linux-2.6.20-at92_e1.5.1-4w/drivers/mmc/at91_mci.c
--- linux-2.6.20-at92_e1.5.1-spi/drivers/mmc/at91_mci.c	2008-02-06 12:51:28.000000000 -0500
+++ linux-2.6.20-at92_e1.5.1-4w/drivers/mmc/at91_mci.c	2008-02-06 14:02:21.000000000 -0500
@@ -1,5 +1,5 @@
 /*
- *  linux/drivers/mmc/at91_mci.c - ATMEL AT91 MCI Driver
+ *  linux/drivers/mmc/host/at91_mci.c - ATMEL AT91 MCI Driver
  *
  *  Copyright (C) 2005 Cougar Creek Computing Devices Ltd, All Rights Reserved
  *
@@ -67,7 +67,6 @@
 #include <linux/atmel_pdc.h>
 
 #include <linux/mmc/host.h>
-#include <linux/mmc/protocol.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
@@ -77,17 +76,14 @@
 #include <asm/arch/gpio.h>
 #include <asm/arch/at91_mci.h>
 
-
 #define DRIVER_NAME "at91_mci"
 
-#undef	SUPPORT_4WIRE
-
 #define FL_SENT_COMMAND	(1 << 0)
 #define FL_SENT_STOP	(1 << 1)
 
 #define AT91_MCI_ERRORS	(AT91_MCI_RINDE | AT91_MCI_RDIRE | AT91_MCI_RCRCE	\
-			| AT91_MCI_RENDE | AT91_MCI_RTOE | AT91_MCI_DCRCE	\
-			| AT91_MCI_DTOE | AT91_MCI_OVRE | AT91_MCI_UNRE)
+		| AT91_MCI_RENDE | AT91_MCI_RTOE | AT91_MCI_DCRCE		\
+		| AT91_MCI_DTOE | AT91_MCI_OVRE | AT91_MCI_UNRE)
 
 #define at91_mci_read(host, reg)	__raw_readl((host)->baseaddr + (reg))
 #define at91_mci_write(host, reg, val)	__raw_writel((val), (host)->baseaddr + (reg))
@@ -133,7 +129,7 @@ struct at91mci_host
 /*
  * Copy from sg to a dma block - used for transfers
  */
-static inline void at91mci_sg_to_dma(struct at91mci_host *host, struct mmc_data *data)
+static inline void at91_mci_sg_to_dma(struct at91mci_host *host, struct mmc_data *data)
 {
 	unsigned int len, i, size;
 	unsigned *dmabuf = host->buffer;
@@ -182,7 +178,7 @@ static inline void at91mci_sg_to_dma(str
 /*
  * Prepare a dma read
  */
-static void at91mci_pre_dma_read(struct at91mci_host *host)
+static void at91_mci_pre_dma_read(struct at91mci_host *host)
 {
 	int i;
 	struct scatterlist *sg;
@@ -250,7 +246,7 @@ static void at91mci_pre_dma_read(struct 
 /*
  * Handle after a dma read
  */
-static void at91mci_post_dma_read(struct at91mci_host *host)
+static void at91_mci_post_dma_read(struct at91mci_host *host)
 {
 	struct mmc_command *cmd;
 	struct mmc_data *data;
@@ -270,8 +266,6 @@ static void at91mci_post_dma_read(struct
 	}
 
 	while (host->in_use_index < host->transfer_index) {
-		unsigned int *buffer;
-
 		struct scatterlist *sg;
 
 		pr_debug("finishing index %d\n", host->in_use_index);
@@ -282,44 +276,105 @@ static void at91mci_post_dma_read(struct
 
 		dma_unmap_page(NULL, sg->dma_address, sg->length, DMA_FROM_DEVICE);
 
-		/* Swap the contents of the buffer */
-		buffer = kmap_atomic(sg->page, KM_BIO_SRC_IRQ) + sg->offset;
-		pr_debug("buffer = %p, length = %d\n", buffer, sg->length);
-
 		data->bytes_xfered += sg->length;
 
 		if (cpu_is_at91rm9200()) {	/* AT91RM9200 errata */
+			unsigned int *buffer;
 			int index;
 
+			/* Swap the contents of the buffer */
+			buffer = kmap_atomic(sg->page, KM_BIO_SRC_IRQ) + sg->offset;
+			pr_debug("buffer = %p, length = %d\n", buffer, sg->length);
+
 			for (index = 0; index < (sg->length / 4); index++)
 				buffer[index] = swab32(buffer[index]);
+
+			kunmap_atomic(buffer, KM_BIO_SRC_IRQ);
 		}
 
-		kunmap_atomic(buffer, KM_BIO_SRC_IRQ);
 		flush_dcache_page(sg->page);
 	}
 
 	/* Is there another transfer to trigger? */
 	if (host->transfer_index < data->sg_len)
-		at91mci_pre_dma_read(host);
+		at91_mci_pre_dma_read(host);
 	else {
+		at91_mci_write(host, AT91_MCI_IDR, AT91_MCI_ENDRX);
 		at91_mci_write(host, AT91_MCI_IER, AT91_MCI_RXBUFF);
-		at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_RXTDIS | ATMEL_PDC_TXTDIS);
 	}
 
 	pr_debug("post dma read done\n");
 }
 
+/*
+ * Handle transmitted data
+ */
+static void at91_mci_handle_transmitted(struct at91mci_host *host)
+{
+	struct mmc_command *cmd;
+	struct mmc_data *data;
+
+	pr_debug("Handling the transmit\n");
+
+	/* Disable the transfer */
+	at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_RXTDIS | ATMEL_PDC_TXTDIS);
+
+	/* Now wait for cmd ready */
+	at91_mci_write(host, AT91_MCI_IDR, AT91_MCI_TXBUFE);
+
+	cmd = host->cmd;
+	if (!cmd) return;
+
+	data = cmd->data;
+	if (!data) return;
+
+	if (cmd->data->flags & MMC_DATA_MULTI) {
+		pr_debug("multiple write : wait for BLKE...\n");
+		at91_mci_write(host, AT91_MCI_IER, AT91_MCI_BLKE);
+	} else
+		at91_mci_write(host, AT91_MCI_IER, AT91_MCI_NOTBUSY);
+
+	data->bytes_xfered = host->total_length;
+}
+
+/*Handle after command sent ready*/
+static int at91_mci_handle_cmdrdy(struct at91mci_host *host)
+{
+	if (!host->cmd)
+		return 1;
+	else if (!host->cmd->data) {
+		if (host->flags & FL_SENT_STOP) {
+			/*After multi block write, we must wait for NOTBUSY*/
+			at91_mci_write(host, AT91_MCI_IER, AT91_MCI_NOTBUSY);
+		} else return 1;
+	} else if (host->cmd->data->flags & MMC_DATA_WRITE) {
+		/*After sendding multi-block-write command, start DMA transfer*/
+		at91_mci_write(host, AT91_MCI_IER, AT91_MCI_TXBUFE);
+		at91_mci_write(host, AT91_MCI_IER, AT91_MCI_BLKE);
+		at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_TXTEN);
+	}
+
+	/* command not completed, have to wait */
+	return 0;
+}
+
 
 /*
  * Enable the controller
  */
 static void at91_mci_enable(struct at91mci_host *host)
 {
+	unsigned int mr;
+
 	at91_mci_write(host, AT91_MCI_CR, AT91_MCI_MCIEN);
 	at91_mci_write(host, AT91_MCI_IDR, 0xffffffff);
 	at91_mci_write(host, AT91_MCI_DTOR, AT91_MCI_DTOMUL_1M | AT91_MCI_DTOCYC);
-	at91_mci_write(host, AT91_MCI_MR, AT91_MCI_PDCMODE | 0x34a);
+	mr = AT91_MCI_PDCMODE | 0x34a;
+
+	if (cpu_is_at91sam9260() || cpu_is_at91sam9263())
+		mr |= AT91_MCI_RDPROOF | AT91_MCI_WRPROOF;
+
+	at91_mci_write(host, AT91_MCI_MR, mr);
 
 	/* use Slot A or B (only one at same time) */
 	at91_mci_write(host, AT91_MCI_SDCR, host->board->slot_b);
@@ -335,9 +390,8 @@ static void at91_mci_disable(struct at91
 
 /*
  * Send a command
- * return the interrupts to enable
  */
-static unsigned int at91_mci_send_command(struct at91mci_host *host, struct mmc_command *cmd)
+static void at91_mci_send_command(struct at91mci_host *host, struct mmc_command *cmd)
 {
 	unsigned int cmdr, mr;
 	unsigned int block_length;
@@ -348,8 +402,7 @@ static unsigned int at91_mci_send_comman
 
 	host->cmd = cmd;
 
-	/* Not sure if this is needed */
-#if 0
+	/* Needed for leaving busy state before CMD1 */
 	if ((at91_mci_read(host, AT91_MCI_SR) & AT91_MCI_RTOE) && (cmd->opcode == 1)) {
 		pr_debug("Clearing timeout\n");
 		at91_mci_write(host, AT91_MCI_ARGR, 0);
@@ -359,7 +412,7 @@ static unsigned int at91_mci_send_comman
 			pr_debug("Clearing: SR = %08X\n", at91_mci_read(host, AT91_MCI_SR));
 		}
 	}
-#endif
+
 	cmdr = cmd->opcode;
 
 	if (mmc_resp_type(cmd) == MMC_RSP_NONE)
@@ -394,7 +447,7 @@ static unsigned int at91_mci_send_comman
 		blocks = 0;
 	}
 
-	if (cmd->opcode == MMC_STOP_TRANSMISSION)
+	if (host->flags & FL_SENT_STOP)
 		cmdr |= AT91_MCI_TRCMD_STOP;
 
 	if (host->bus_mode == MMC_BUSMODE_OPENDRAIN)
@@ -416,50 +469,48 @@ static unsigned int at91_mci_send_comman
 		at91_mci_write(host, ATMEL_PDC_TCR, 0);
 		at91_mci_write(host, ATMEL_PDC_TNPR, 0);
 		at91_mci_write(host, ATMEL_PDC_TNCR, 0);
+		ier = AT91_MCI_CMDRDY;
+	} else {
+		/* zero block length and PDC mode */
+		mr = at91_mci_read(host, AT91_MCI_MR) & 0x7fff;
+		at91_mci_write(host, AT91_MCI_MR, mr | (block_length << 16) | AT91_MCI_PDCMODE);
+
+		/*
+		 * Disable the PDC controller
+		 */
+		at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_RXTDIS | ATMEL_PDC_TXTDIS);
 
-		at91_mci_write(host, AT91_MCI_ARGR, cmd->arg);
-		at91_mci_write(host, AT91_MCI_CMDR, cmdr);
-		return AT91_MCI_CMDRDY;
-	}
-
-	mr = at91_mci_read(host, AT91_MCI_MR) & 0x7fff;	/* zero block length and PDC mode */
-	at91_mci_write(host, AT91_MCI_MR, mr | (block_length << 16) | AT91_MCI_PDCMODE);
-
-	/*
-	 * Disable the PDC controller
-	 */
-	at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_RXTDIS | ATMEL_PDC_TXTDIS);
-
-	if (cmdr & AT91_MCI_TRCMD_START) {
-		data->bytes_xfered = 0;
-		host->transfer_index = 0;
-		host->in_use_index = 0;
-		if (cmdr & AT91_MCI_TRDIR) {
-			/*
-			 * Handle a read
-			 */
-			host->buffer = NULL;
-			host->total_length = 0;
+		if (cmdr & AT91_MCI_TRCMD_START) {
+			data->bytes_xfered = 0;
+			host->transfer_index = 0;
+			host->in_use_index = 0;
+			if (cmdr & AT91_MCI_TRDIR) {
+				/*
+				 * Handle a read
+				 */
+				host->buffer = NULL;
+				host->total_length = 0;
 
-			at91mci_pre_dma_read(host);
-			ier = AT91_MCI_ENDRX /* | AT91_MCI_RXBUFF */;
-		}
-		else {
-			/*
-			 * Handle a write
-			 */
-			host->total_length = block_length * blocks;
-			host->buffer = dma_alloc_coherent(NULL,
+				at91_mci_pre_dma_read(host);
+				ier = AT91_MCI_ENDRX /* | AT91_MCI_RXBUFF */;
+			}
+			else {
+				/*
+				 * Handle a write
+				 */
+				host->total_length = block_length * blocks;
+				host->buffer = dma_alloc_coherent(NULL,
 						host->total_length,
 						&host->physical_address, GFP_KERNEL);
 
-			at91mci_sg_to_dma(host, data);
+				at91_mci_sg_to_dma(host, data);
 
-			pr_debug("Transmitting %d bytes\n", host->total_length);
+				pr_debug("Transmitting %d bytes\n", host->total_length);
 
-			at91_mci_write(host, ATMEL_PDC_TPR, host->physical_address);
-			at91_mci_write(host, ATMEL_PDC_TCR, host->total_length / 4);
-			ier = AT91_MCI_TXBUFE;
+				at91_mci_write(host, ATMEL_PDC_TPR, host->physical_address);
+				at91_mci_write(host, ATMEL_PDC_TCR, host->total_length / 4);
+				ier = AT91_MCI_CMDRDY;
+			}
 		}
 	}
 
@@ -474,39 +525,24 @@ static unsigned int at91_mci_send_comman
 	if (cmdr & AT91_MCI_TRCMD_START) {
 		if (cmdr & AT91_MCI_TRDIR)
 			at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_RXTEN);
-		else
-			at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_TXTEN);
 	}
-	return ier;
-}
 
-/*
- * Wait for a command to complete
- */
-static void at91mci_process_command(struct at91mci_host *host, struct mmc_command *cmd)
-{
-	unsigned int ier;
-
-	ier = at91_mci_send_command(host, cmd);
-
-	pr_debug("setting ier to %08X\n", ier);
-
-	/* Stop on errors or the required value */
+	/* Enable selected interrupts */
 	at91_mci_write(host, AT91_MCI_IER, AT91_MCI_ERRORS | ier);
 }
 
 /*
  * Process the next step in the request
  */
-static void at91mci_process_next(struct at91mci_host *host)
+static void at91_mci_process_next(struct at91mci_host *host)
 {
 	if (!(host->flags & FL_SENT_COMMAND)) {
 		host->flags |= FL_SENT_COMMAND;
-		at91mci_process_command(host, host->request->cmd);
+		at91_mci_send_command(host, host->request->cmd);
 	}
 	else if ((!(host->flags & FL_SENT_STOP)) && host->request->stop) {
 		host->flags |= FL_SENT_STOP;
-		at91mci_process_command(host, host->request->stop);
+		at91_mci_send_command(host, host->request->stop);
 	}
 	else
 		mmc_request_done(host->mmc, host->request);
@@ -515,7 +551,7 @@ static void at91mci_process_next(struct 
 /*
  * Handle a command that has been completed
  */
-static void at91mci_completed_command(struct at91mci_host *host)
+static void at91_mci_completed_command(struct at91mci_host *host)
 {
 	struct mmc_command *cmd = host->cmd;
 	unsigned int status;
@@ -536,10 +572,8 @@ static void at91mci_completed_command(st
 
 	pr_debug("Status = %08X [%08X %08X %08X %08X]\n",
 		 status, cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3]);
-
 	if (status & AT91_MCI_ERRORS) {
-		if ((status & AT91_MCI_RCRCE) &&
-			((cmd->opcode == MMC_SEND_OP_COND) || (cmd->opcode == SD_APP_OP_COND))) {
+		if ((status & AT91_MCI_RCRCE) && !(mmc_resp_type(cmd) & MMC_RSP_CRC)) {
 			cmd->error = MMC_ERR_NONE;
 		}
 		else {
@@ -559,7 +593,7 @@ static void at91mci_completed_command(st
 	else
 		cmd->error = MMC_ERR_NONE;
 
-	at91mci_process_next(host);
+	at91_mci_process_next(host);
 }
 
 /*
@@ -571,33 +605,7 @@ static void at91_mci_request(struct mmc_
 	host->request = mrq;
 	host->flags = 0;
 
-	at91mci_process_next(host);
-}
-
-/*
- * Handle transmitted data
- */
-static void at91_mci_handle_transmitted(struct at91mci_host *host)
-{
-	struct mmc_command *cmd;
-	struct mmc_data *data;
-
-	pr_debug("Handling the transmit\n");
-
-	/* Disable the transfer */
-	at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_RXTDIS | ATMEL_PDC_TXTDIS);
-
-	/* Now wait for cmd ready */
-	at91_mci_write(host, AT91_MCI_IDR, AT91_MCI_TXBUFE);
-	at91_mci_write(host, AT91_MCI_IER, AT91_MCI_NOTBUSY);
-
-	cmd = host->cmd;
-	if (!cmd) return;
-
-	data = cmd->data;
-	if (!data) return;
-
-	data->bytes_xfered = host->total_length;
+	at91_mci_process_next(host);
 }
 
 /*
@@ -700,29 +708,33 @@ static irqreturn_t at91_mci_irq(int irq,
 			at91_mci_handle_transmitted(host);
 		}
 
+		if (int_status & AT91_MCI_ENDRX) {
+			pr_debug("ENDRX\n");
+			at91_mci_post_dma_read(host);
+		}
+
 		if (int_status & AT91_MCI_RXBUFF) {
 			pr_debug("RX buffer full\n");
-			at91_mci_write(host, AT91_MCI_IER, AT91_MCI_CMDRDY);
+			at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_RXTDIS | ATMEL_PDC_TXTDIS);
+			at91_mci_write(host, AT91_MCI_IDR, AT91_MCI_RXBUFF | AT91_MCI_ENDRX);
+			completed = 1;
 		}
 
 		if (int_status & AT91_MCI_ENDTX)
 			pr_debug("Transmit has ended\n");
 
-		if (int_status & AT91_MCI_ENDRX) {
-			pr_debug("Receive has ended\n");
-			at91mci_post_dma_read(host);
-		}
-
 		if (int_status & AT91_MCI_NOTBUSY) {
 			pr_debug("Card is ready\n");
-			at91_mci_write(host, AT91_MCI_IER, AT91_MCI_CMDRDY);
+			completed = 1;
 		}
 
 		if (int_status & AT91_MCI_DTIP)
 			pr_debug("Data transfer in progress\n");
 
-		if (int_status & AT91_MCI_BLKE)
+		if (int_status & AT91_MCI_BLKE) {
 			pr_debug("Block transfer has ended\n");
+			completed = 1;
+		}
 
 		if (int_status & AT91_MCI_TXRDY)
 			pr_debug("Ready to transmit\n");
@@ -732,14 +744,14 @@ static irqreturn_t at91_mci_irq(int irq,
 
 		if (int_status & AT91_MCI_CMDRDY) {
 			pr_debug("Command ready\n");
-			completed = 1;
+			completed = at91_mci_handle_cmdrdy(host);
 		}
 	}
 
 	if (completed) {
 		pr_debug("Completed command\n");
 		at91_mci_write(host, AT91_MCI_IDR, 0xffffffff);
-		at91mci_completed_command(host);
+		at91_mci_completed_command(host);
 	} else
 		at91_mci_write(host, AT91_MCI_IDR, int_status);
 
@@ -821,7 +833,10 @@ static int __init at91_mci_probe(struct 
 	mmc->f_min = 375000;
 	mmc->f_max = 25000000;
 	mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
-	mmc->caps = MMC_CAP_BYTEBLOCK | MMC_CAP_MULTIWRITE;
+	mmc->caps = MMC_CAP_BYTEBLOCK;
+
+	mmc->max_blk_size = 4095;
+	mmc->max_blk_count = mmc->max_req_size;
 
 	host = mmc_priv(mmc);
 	host->mmc = mmc;
@@ -829,11 +844,11 @@ static int __init at91_mci_probe(struct 
 	host->bus_mode = 0;
 	host->board = pdev->dev.platform_data;
 	if (host->board->wire4) {
-#ifdef SUPPORT_4WIRE
-		mmc->caps |= MMC_CAP_4_BIT_DATA;
-#else
-		printk("AT91 MMC: 4 wire bus mode not supported by this driver - using 1 wire\n");
-#endif
+		if (cpu_is_at91sam9260() || cpu_is_at91sam9263())
+			mmc->caps |= MMC_CAP_4_BIT_DATA;
+		else
+			printk("AT91 MMC: 4 wire bus mode not supported"
+				" - using 1 wire\n");
 	}
 
 	/*
@@ -853,15 +868,15 @@ static int __init at91_mci_probe(struct 
 	host->baseaddr = ioremap(res->start, res->end - res->start + 1);
 	if (!host->baseaddr) {
 		clk_put(host->mci_clk);
-		release_mem_region(res->start, res->end - res->start + 1);
 		mmc_free_host(mmc);
+		release_mem_region(res->start, res->end - res->start + 1);
 		return -ENOMEM;
 	}
 
 	/*
 	 * Reset hardware
 	 */
-	clk_enable(host->mci_clk);	/* Enable the peripheral clock */
+	clk_enable(host->mci_clk);		/* Enable the peripheral clock */
 	at91_mci_disable(host);
 	at91_mci_enable(host);
 
@@ -874,9 +889,9 @@ static int __init at91_mci_probe(struct 
 		printk(KERN_ERR "AT91 MMC: Failed to request MCI interrupt\n");
 		clk_disable(host->mci_clk);
 		clk_put(host->mci_clk);
+		mmc_free_host(mmc);
 		iounmap(host->baseaddr);
 		release_mem_region(res->start, res->end - res->start + 1);
-		mmc_free_host(mmc);
 		return ret;
 	}
 
@@ -885,8 +900,10 @@ static int __init at91_mci_probe(struct 
 	/*
 	 * Add host to MMC layer
 	 */
-	if (host->board->det_pin)
+	if (host->board->det_pin) {
 		host->present = !at91_get_gpio_value(host->board->det_pin);
+		device_init_wakeup(&pdev->dev, 1);
+	}
 	else
 		host->present = -1;
 
@@ -921,7 +938,8 @@ static int __exit at91_mci_remove(struct
 
 	host = mmc_priv(mmc);
 
-	if (host->present != -1) {
+	if (host->board->det_pin) {
+		device_init_wakeup(&pdev->dev, 0);
 		free_irq(host->board->det_pin, host);
 		cancel_delayed_work(&host->mmc->detect);
 	}
@@ -930,13 +948,13 @@ static int __exit at91_mci_remove(struct
 	mmc_remove_host(mmc);
 	free_irq(host->irq, host);
 
+	clk_disable(host->mci_clk);			/* Disable the peripheral clock */
+	clk_put(host->mci_clk);
+
 	iounmap(host->baseaddr);
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	release_mem_region(res->start, res->end - res->start + 1);
 
-	clk_disable(host->mci_clk);			/* Disable the peripheral clock */
-	clk_put(host->mci_clk);
-
 	mmc_free_host(mmc);
 	platform_set_drvdata(pdev, NULL);
 	pr_debug("MCI Removed\n");
@@ -948,8 +966,12 @@ static int __exit at91_mci_remove(struct
 static int at91_mci_suspend(struct platform_device *pdev, pm_message_t state)
 {
 	struct mmc_host *mmc = platform_get_drvdata(pdev);
+	struct at91mci_host *host = mmc_priv(mmc);
 	int ret = 0;
 
+	if (host->board->det_pin && device_may_wakeup(&pdev->dev))
+		enable_irq_wake(host->board->det_pin);
+
 	if (mmc)
 		ret = mmc_suspend_host(mmc, state);
 
@@ -959,8 +981,12 @@ static int at91_mci_suspend(struct platf
 static int at91_mci_resume(struct platform_device *pdev)
 {
 	struct mmc_host *mmc = platform_get_drvdata(pdev);
+	struct at91mci_host *host = mmc_priv(mmc);
 	int ret = 0;
 
+	if (host->board->det_pin && device_may_wakeup(&pdev->dev))
+		disable_irq_wake(host->board->det_pin);
+
 	if (mmc)
 		ret = mmc_resume_host(mmc);
 
diff -uprN linux-2.6.20-at92_e1.5.1-spi/include/linux/mmc/host.h linux-2.6.20-at92_e1.5.1-4w/include/linux/mmc/host.h
--- linux-2.6.20-at92_e1.5.1-spi/include/linux/mmc/host.h	2007-02-04 13:44:54.000000000 -0500
+++ linux-2.6.20-at92_e1.5.1-4w/include/linux/mmc/host.h	2008-02-06 14:02:21.000000000 -0500
@@ -94,6 +94,10 @@ struct mmc_host {
 	unsigned short		max_phys_segs;	/* see blk_queue_max_phys_segments */
 	unsigned short		max_sectors;	/* see blk_queue_max_sectors */
 	unsigned short		unused;
+	unsigned int		max_blk_size;	/* maximum size of one mmc block */
+	unsigned int		max_blk_count;	/* maximum number of blocks in one req */
+	unsigned int		max_req_size;	/* maximum number of bytes in one req */
+
 
 	/* private data */
 	struct mmc_ios		ios;		/* current io bus settings */
