Merge branch 'next' of git://git.denx.de/u-boot-coldfire into next
diff --git a/board/davinci/da830evm/da830evm.c b/board/davinci/da830evm/da830evm.c
index ed668af..6385443 100644
--- a/board/davinci/da830evm/da830evm.c
+++ b/board/davinci/da830evm/da830evm.c
@@ -150,7 +150,7 @@
 		DAVINCI_ABCR_RHOLD(0) |
 		DAVINCI_ABCR_TA(2) |
 		DAVINCI_ABCR_ASIZE_8BIT),
-	       &davinci_emif_regs->AB2CR);
+	       &davinci_emif_regs->ab2cr);
 #endif
 
 	/* arch number of the board */
diff --git a/common/cmd_nand.c b/common/cmd_nand.c
index 075a8af..9b0c930 100644
--- a/common/cmd_nand.c
+++ b/common/cmd_nand.c
@@ -327,8 +327,14 @@
 			     "are sure of what you are doing!\n"
 			     "\nReally scrub this NAND flash? <y/N>\n");
 
-			if (getc() == 'y' && getc() == '\r') {
-				opts.scrub = 1;
+			if (getc() == 'y') {
+				puts("y");
+				if (getc() == '\r')
+					opts.scrub = 1;
+				else {
+					puts("scrub aborted\n");
+					return -1;
+				}
 			} else {
 				puts("scrub aborted\n");
 				return -1;
diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c
index 40002be..d5eb54a 100644
--- a/drivers/mtd/nand/atmel_nand.c
+++ b/drivers/mtd/nand/atmel_nand.c
@@ -31,6 +31,209 @@
 
 #include <nand.h>
 
+#ifdef CONFIG_ATMEL_NAND_HWECC
+
+/* Register access macros */
+#define ecc_readl(add, reg)				\
+	readl(AT91_BASE_SYS + add + ATMEL_ECC_##reg)
+#define ecc_writel(add, reg, value)			\
+	writel((value), AT91_BASE_SYS + add + ATMEL_ECC_##reg)
+
+#include "atmel_nand_ecc.h"	/* Hardware ECC registers */
+
+/* oob layout for large page size
+ * bad block info is on bytes 0 and 1
+ * the bytes have to be consecutives to avoid
+ * several NAND_CMD_RNDOUT during read
+ */
+static struct nand_ecclayout atmel_oobinfo_large = {
+	.eccbytes = 4,
+	.eccpos = {60, 61, 62, 63},
+	.oobfree = {
+		{2, 58}
+	},
+};
+
+/* oob layout for small page size
+ * bad block info is on bytes 4 and 5
+ * the bytes have to be consecutives to avoid
+ * several NAND_CMD_RNDOUT during read
+ */
+static struct nand_ecclayout atmel_oobinfo_small = {
+	.eccbytes = 4,
+	.eccpos = {0, 1, 2, 3},
+	.oobfree = {
+		{6, 10}
+	},
+};
+
+/*
+ * Calculate HW ECC
+ *
+ * function called after a write
+ *
+ * mtd:        MTD block structure
+ * dat:        raw data (unused)
+ * ecc_code:   buffer for ECC
+ */
+static int atmel_nand_calculate(struct mtd_info *mtd,
+		const u_char *dat, unsigned char *ecc_code)
+{
+	struct nand_chip *nand_chip = mtd->priv;
+	unsigned int ecc_value;
+
+	/* get the first 2 ECC bytes */
+	ecc_value = ecc_readl(CONFIG_SYS_NAND_ECC_BASE, PR);
+
+	ecc_code[0] = ecc_value & 0xFF;
+	ecc_code[1] = (ecc_value >> 8) & 0xFF;
+
+	/* get the last 2 ECC bytes */
+	ecc_value = ecc_readl(CONFIG_SYS_NAND_ECC_BASE, NPR) & ATMEL_ECC_NPARITY;
+
+	ecc_code[2] = ecc_value & 0xFF;
+	ecc_code[3] = (ecc_value >> 8) & 0xFF;
+
+	return 0;
+}
+
+/*
+ * HW ECC read page function
+ *
+ * mtd:        mtd info structure
+ * chip:       nand chip info structure
+ * buf:        buffer to store read data
+ */
+static int atmel_nand_read_page(struct mtd_info *mtd,
+		struct nand_chip *chip, uint8_t *buf, int page)
+{
+	int eccsize = chip->ecc.size;
+	int eccbytes = chip->ecc.bytes;
+	uint32_t *eccpos = chip->ecc.layout->eccpos;
+	uint8_t *p = buf;
+	uint8_t *oob = chip->oob_poi;
+	uint8_t *ecc_pos;
+	int stat;
+
+	/* read the page */
+	chip->read_buf(mtd, p, eccsize);
+
+	/* move to ECC position if needed */
+	if (eccpos[0] != 0) {
+		/* This only works on large pages
+		 * because the ECC controller waits for
+		 * NAND_CMD_RNDOUTSTART after the
+		 * NAND_CMD_RNDOUT.
+		 * anyway, for small pages, the eccpos[0] == 0
+		 */
+		chip->cmdfunc(mtd, NAND_CMD_RNDOUT,
+				mtd->writesize + eccpos[0], -1);
+	}
+
+	/* the ECC controller needs to read the ECC just after the data */
+	ecc_pos = oob + eccpos[0];
+	chip->read_buf(mtd, ecc_pos, eccbytes);
+
+	/* check if there's an error */
+	stat = chip->ecc.correct(mtd, p, oob, NULL);
+
+	if (stat < 0)
+		mtd->ecc_stats.failed++;
+	else
+		mtd->ecc_stats.corrected += stat;
+
+	/* get back to oob start (end of page) */
+	chip->cmdfunc(mtd, NAND_CMD_RNDOUT, mtd->writesize, -1);
+
+	/* read the oob */
+	chip->read_buf(mtd, oob, mtd->oobsize);
+
+	return 0;
+}
+
+/*
+ * HW ECC Correction
+ *
+ * function called after a read
+ *
+ * mtd:        MTD block structure
+ * dat:        raw data read from the chip
+ * read_ecc:   ECC from the chip (unused)
+ * isnull:     unused
+ *
+ * Detect and correct a 1 bit error for a page
+ */
+static int atmel_nand_correct(struct mtd_info *mtd, u_char *dat,
+		u_char *read_ecc, u_char *isnull)
+{
+	struct nand_chip *nand_chip = mtd->priv;
+	unsigned int ecc_status, ecc_parity, ecc_mode;
+	unsigned int ecc_word, ecc_bit;
+
+	/* get the status from the Status Register */
+	ecc_status = ecc_readl(CONFIG_SYS_NAND_ECC_BASE, SR);
+
+	/* if there's no error */
+	if (likely(!(ecc_status & ATMEL_ECC_RECERR)))
+		return 0;
+
+	/* get error bit offset (4 bits) */
+	ecc_bit = ecc_readl(CONFIG_SYS_NAND_ECC_BASE, PR) & ATMEL_ECC_BITADDR;
+	/* get word address (12 bits) */
+	ecc_word = ecc_readl(CONFIG_SYS_NAND_ECC_BASE, PR) & ATMEL_ECC_WORDADDR;
+	ecc_word >>= 4;
+
+	/* if there are multiple errors */
+	if (ecc_status & ATMEL_ECC_MULERR) {
+		/* check if it is a freshly erased block
+		 * (filled with 0xff) */
+		if ((ecc_bit == ATMEL_ECC_BITADDR)
+				&& (ecc_word == (ATMEL_ECC_WORDADDR >> 4))) {
+			/* the block has just been erased, return OK */
+			return 0;
+		}
+		/* it doesn't seems to be a freshly
+		 * erased block.
+		 * We can't correct so many errors */
+		printk(KERN_WARNING "atmel_nand : multiple errors detected."
+				" Unable to correct.\n");
+		return -EIO;
+	}
+
+	/* if there's a single bit error : we can correct it */
+	if (ecc_status & ATMEL_ECC_ECCERR) {
+		/* there's nothing much to do here.
+		 * the bit error is on the ECC itself.
+		 */
+		printk(KERN_WARNING "atmel_nand : one bit error on ECC code."
+				" Nothing to correct\n");
+		return 0;
+	}
+
+	printk(KERN_WARNING "atmel_nand : one bit error on data."
+			" (word offset in the page :"
+			" 0x%x bit offset : 0x%x)\n",
+			ecc_word, ecc_bit);
+	/* correct the error */
+	if (nand_chip->options & NAND_BUSWIDTH_16) {
+		/* 16 bits words */
+		((unsigned short *) dat)[ecc_word] ^= (1 << ecc_bit);
+	} else {
+		/* 8 bits words */
+		dat[ecc_word] ^= (1 << ecc_bit);
+	}
+	printk(KERN_WARNING "atmel_nand : error corrected\n");
+	return 1;
+}
+
+/*
+ * Enable HW ECC : unused on most chips
+ */
+static void atmel_nand_hwctl(struct mtd_info *mtd, int mode)
+{
+}
+#endif
+
 static void at91_nand_hwcontrol(struct mtd_info *mtd,
 					 int cmd, unsigned int ctrl)
 {
@@ -64,6 +267,11 @@
 
 int board_nand_init(struct nand_chip *nand)
 {
+#ifdef CONFIG_ATMEL_NAND_HWECC
+	static int chip_nr = 0;
+	struct mtd_info *mtd;
+#endif
+
 	nand->ecc.mode = NAND_ECC_SOFT;
 #ifdef CONFIG_SYS_NAND_DBW_16
 	nand->options = NAND_BUSWIDTH_16;
@@ -74,5 +282,62 @@
 #endif
 	nand->chip_delay = 20;
 
+#ifdef CONFIG_ATMEL_NAND_HWECC
+	nand->ecc.mode = NAND_ECC_HW;
+	nand->ecc.calculate = atmel_nand_calculate;
+	nand->ecc.correct = atmel_nand_correct;
+	nand->ecc.hwctl = atmel_nand_hwctl;
+	nand->ecc.read_page = atmel_nand_read_page;
+	nand->ecc.bytes = 4;
+#endif
+
+#ifdef CONFIG_ATMEL_NAND_HWECC
+	mtd = &nand_info[chip_nr++];
+	mtd->priv = nand;
+
+	/* Detect NAND chips */
+	if (nand_scan_ident(mtd, 1)) {
+		printk(KERN_WARNING "NAND Flash not found !\n");
+		return -ENXIO;
+	}
+
+	if (nand->ecc.mode == NAND_ECC_HW) {
+		/* ECC is calculated for the whole page (1 step) */
+		nand->ecc.size = mtd->writesize;
+
+		/* set ECC page size and oob layout */
+		switch (mtd->writesize) {
+		case 512:
+			nand->ecc.layout = &atmel_oobinfo_small;
+			ecc_writel(CONFIG_SYS_NAND_ECC_BASE, MR, ATMEL_ECC_PAGESIZE_528);
+			break;
+		case 1024:
+			nand->ecc.layout = &atmel_oobinfo_large;
+			ecc_writel(CONFIG_SYS_NAND_ECC_BASE, MR, ATMEL_ECC_PAGESIZE_1056);
+			break;
+		case 2048:
+			nand->ecc.layout = &atmel_oobinfo_large;
+			ecc_writel(CONFIG_SYS_NAND_ECC_BASE, MR, ATMEL_ECC_PAGESIZE_2112);
+			break;
+		case 4096:
+			nand->ecc.layout = &atmel_oobinfo_large;
+			ecc_writel(CONFIG_SYS_NAND_ECC_BASE, MR, ATMEL_ECC_PAGESIZE_4224);
+			break;
+		default:
+			/* page size not handled by HW ECC */
+			/* switching back to soft ECC */
+			nand->ecc.mode = NAND_ECC_SOFT;
+			nand->ecc.calculate = NULL;
+			nand->ecc.correct = NULL;
+			nand->ecc.hwctl = NULL;
+			nand->ecc.read_page = NULL;
+			nand->ecc.postpad = 0;
+			nand->ecc.prepad = 0;
+			nand->ecc.bytes = 0;
+			break;
+		}
+	}
+#endif
+
 	return 0;
 }
diff --git a/drivers/mtd/nand/atmel_nand_ecc.h b/drivers/mtd/nand/atmel_nand_ecc.h
new file mode 100644
index 0000000..1ee7f99
--- /dev/null
+++ b/drivers/mtd/nand/atmel_nand_ecc.h
@@ -0,0 +1,36 @@
+/*
+ * Error Corrected Code Controller (ECC) - System peripherals regsters.
+ * Based on AT91SAM9260 datasheet revision B.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#ifndef ATMEL_NAND_ECC_H
+#define ATMEL_NAND_ECC_H
+
+#define ATMEL_ECC_CR		0x00			/* Control register */
+#define		ATMEL_ECC_RST		(1 << 0)		/* Reset parity */
+
+#define ATMEL_ECC_MR		0x04			/* Mode register */
+#define		ATMEL_ECC_PAGESIZE	(3 << 0)		/* Page Size */
+#define			ATMEL_ECC_PAGESIZE_528		(0)
+#define			ATMEL_ECC_PAGESIZE_1056		(1)
+#define			ATMEL_ECC_PAGESIZE_2112		(2)
+#define			ATMEL_ECC_PAGESIZE_4224		(3)
+
+#define ATMEL_ECC_SR		0x08			/* Status register */
+#define		ATMEL_ECC_RECERR		(1 << 0)		/* Recoverable Error */
+#define		ATMEL_ECC_ECCERR		(1 << 1)		/* ECC Single Bit Error */
+#define		ATMEL_ECC_MULERR		(1 << 2)		/* Multiple Errors */
+
+#define ATMEL_ECC_PR		0x0c			/* Parity register */
+#define		ATMEL_ECC_BITADDR	(0xf << 0)		/* Bit Error Address */
+#define		ATMEL_ECC_WORDADDR	(0xfff << 4)		/* Word Error Address */
+
+#define ATMEL_ECC_NPR		0x10			/* NParity register */
+#define		ATMEL_ECC_NPARITY	(0xffff << 0)		/* NParity */
+
+#endif
diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c
index bfc2acf..4ca738e 100644
--- a/drivers/mtd/nand/davinci_nand.c
+++ b/drivers/mtd/nand/davinci_nand.c
@@ -57,8 +57,6 @@
 #define ECC_STATE_ERR_CORR_COMP_P	0x2
 #define ECC_STATE_ERR_CORR_COMP_N	0x3
 
-static emif_registers *const emif_regs = (void *) DAVINCI_ASYNC_EMIF_CNTRL_BASE;
-
 /*
  * Exploit the little endianness of the ARM to do multi-byte transfers
  * per device read. This can perform over twice as quickly as individual
@@ -93,7 +91,7 @@
 
 	/* copy aligned data */
 	while (len >= 4) {
-		*(u32 *)buf = readl(nand);
+		*(u32 *)buf = __raw_readl(nand);
 		buf += 4;
 		len -= 4;
 	}
@@ -138,7 +136,7 @@
 
 	/* copy aligned data */
 	while (len >= 4) {
-		writel(*(u32 *)buf, nand);
+		__raw_writel(*(u32 *)buf, nand);
 		buf += 4;
 		len -= 4;
 	}
@@ -156,7 +154,8 @@
 	}
 }
 
-static void nand_davinci_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
+static void nand_davinci_hwcontrol(struct mtd_info *mtd, int cmd,
+		unsigned int ctrl)
 {
 	struct		nand_chip *this = mtd->priv;
 	u_int32_t	IO_ADDR_W = (u_int32_t)this->IO_ADDR_W;
@@ -164,9 +163,9 @@
 	if (ctrl & NAND_CTRL_CHANGE) {
 		IO_ADDR_W &= ~(MASK_ALE|MASK_CLE);
 
-		if ( ctrl & NAND_CLE )
+		if (ctrl & NAND_CLE)
 			IO_ADDR_W |= MASK_CLE;
-		if ( ctrl & NAND_ALE )
+		if (ctrl & NAND_ALE)
 			IO_ADDR_W |= MASK_ALE;
 		this->IO_ADDR_W = (void __iomem *) IO_ADDR_W;
 	}
@@ -181,24 +180,26 @@
 {
 	u_int32_t	val;
 
-	(void)readl(&(emif_regs->NANDFECC[CONFIG_SYS_NAND_CS - 2]));
+	(void)__raw_readl(&(davinci_emif_regs->nandfecc[
+				CONFIG_SYS_NAND_CS - 2]));
 
-	val = readl(&emif_regs->NANDFCR);
+	val = __raw_readl(&davinci_emif_regs->nandfcr);
 	val |= DAVINCI_NANDFCR_NAND_ENABLE(CONFIG_SYS_NAND_CS);
 	val |= DAVINCI_NANDFCR_1BIT_ECC_START(CONFIG_SYS_NAND_CS);
-	writel(val, &emif_regs->NANDFCR);
+	__raw_writel(val, &davinci_emif_regs->nandfcr);
 }
 
 static u_int32_t nand_davinci_readecc(struct mtd_info *mtd, u_int32_t region)
 {
 	u_int32_t	ecc = 0;
 
-	ecc = readl(&(emif_regs->NANDFECC[region - 1]));
+	ecc = __raw_readl(&(davinci_emif_regs->nandfecc[region - 1]));
 
-	return(ecc);
+	return ecc;
 }
 
-static int nand_davinci_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code)
+static int nand_davinci_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
+		u_char *ecc_code)
 {
 	u_int32_t		tmp;
 	const int region = 1;
@@ -232,7 +233,8 @@
 	return 0;
 }
 
-static int nand_davinci_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc)
+static int nand_davinci_correct_data(struct mtd_info *mtd, u_char *dat,
+		u_char *read_ecc, u_char *calc_ecc)
 {
 	struct nand_chip *this = mtd->priv;
 	u_int32_t ecc_nand = read_ecc[0] | (read_ecc[1] << 8) |
@@ -268,7 +270,7 @@
 			return -1;
 		}
 	}
-	return(0);
+	return 0;
 }
 #endif /* CONFIG_SYS_NAND_HW_ECC */
 
@@ -315,15 +317,15 @@
 		 * Start a new ECC calculation for reading or writing 512 bytes
 		 * of data.
 		 */
-		val = readl(&emif_regs->NANDFCR);
+		val = __raw_readl(&davinci_emif_regs->nandfcr);
 		val &= ~DAVINCI_NANDFCR_4BIT_ECC_SEL_MASK;
 		val |= DAVINCI_NANDFCR_NAND_ENABLE(CONFIG_SYS_NAND_CS);
 		val |= DAVINCI_NANDFCR_4BIT_ECC_SEL(CONFIG_SYS_NAND_CS);
 		val |= DAVINCI_NANDFCR_4BIT_ECC_START;
-		writel(val, &emif_regs->NANDFCR);
+		__raw_writel(val, &davinci_emif_regs->nandfcr);
 		break;
 	case NAND_ECC_READSYN:
-		val = emif_regs->NAND4BITECC1;
+		val = __raw_readl(&davinci_emif_regs->nand4bitecc[0]);
 		break;
 	default:
 		break;
@@ -332,10 +334,12 @@
 
 static u32 nand_davinci_4bit_readecc(struct mtd_info *mtd, unsigned int ecc[4])
 {
-	ecc[0] = emif_regs->NAND4BITECC1 & NAND_4BITECC_MASK;
-	ecc[1] = emif_regs->NAND4BITECC2 & NAND_4BITECC_MASK;
-	ecc[2] = emif_regs->NAND4BITECC3 & NAND_4BITECC_MASK;
-	ecc[3] = emif_regs->NAND4BITECC4 & NAND_4BITECC_MASK;
+	int i;
+
+	for (i = 0; i < 4; i++) {
+		ecc[i] = __raw_readl(&davinci_emif_regs->nand4bitecc[i]) &
+			NAND_4BITECC_MASK;
+	}
 
 	return 0;
 }
@@ -418,32 +422,36 @@
 	 */
 
 	/*Take 2 bits from 8th byte and 8 bits from 9th byte */
-	writel(((ecc16[4]) >> 6) & 0x3FF, &emif_regs->NAND4BITECCLOAD);
+	__raw_writel(((ecc16[4]) >> 6) & 0x3FF,
+			&davinci_emif_regs->nand4biteccload);
 
 	/* Take 4 bits from 7th byte and 6 bits from 8th byte */
-	writel((((ecc16[3]) >> 12) & 0xF) | ((((ecc16[4])) << 4) & 0x3F0),
-	       &emif_regs->NAND4BITECCLOAD);
+	__raw_writel((((ecc16[3]) >> 12) & 0xF) | ((((ecc16[4])) << 4) & 0x3F0),
+			&davinci_emif_regs->nand4biteccload);
 
 	/* Take 6 bits from 6th byte and 4 bits from 7th byte */
-	writel((ecc16[3] >> 2) & 0x3FF, &emif_regs->NAND4BITECCLOAD);
+	__raw_writel((ecc16[3] >> 2) & 0x3FF,
+			&davinci_emif_regs->nand4biteccload);
 
 	/* Take 8 bits from 5th byte and 2 bits from 6th byte */
-	writel(((ecc16[2]) >> 8) | ((((ecc16[3])) << 8) & 0x300),
-	       &emif_regs->NAND4BITECCLOAD);
+	__raw_writel(((ecc16[2]) >> 8) | ((((ecc16[3])) << 8) & 0x300),
+			&davinci_emif_regs->nand4biteccload);
 
 	/*Take 2 bits from 3rd byte and 8 bits from 4th byte */
-	writel((((ecc16[1]) >> 14) & 0x3) | ((((ecc16[2])) << 2) & 0x3FC),
-	       &emif_regs->NAND4BITECCLOAD);
+	__raw_writel((((ecc16[1]) >> 14) & 0x3) | ((((ecc16[2])) << 2) & 0x3FC),
+			&davinci_emif_regs->nand4biteccload);
 
 	/* Take 4 bits form 2nd bytes and 6 bits from 3rd bytes */
-	writel(((ecc16[1]) >> 4) & 0x3FF, &emif_regs->NAND4BITECCLOAD);
+	__raw_writel(((ecc16[1]) >> 4) & 0x3FF,
+			&davinci_emif_regs->nand4biteccload);
 
 	/* Take 6 bits from 1st byte and 4 bits from 2nd byte */
-	writel((((ecc16[0]) >> 10) & 0x3F) | (((ecc16[1]) << 6) & 0x3C0),
-	       &emif_regs->NAND4BITECCLOAD);
+	__raw_writel((((ecc16[0]) >> 10) & 0x3F) | (((ecc16[1]) << 6) & 0x3C0),
+			&davinci_emif_regs->nand4biteccload);
 
 	/* Take 10 bits from 0th and 1st bytes */
-	writel((ecc16[0]) & 0x3FF, &emif_regs->NAND4BITECCLOAD);
+	__raw_writel((ecc16[0]) & 0x3FF,
+			&davinci_emif_regs->nand4biteccload);
 
 	/*
 	 * Perform a dummy read to the EMIF Revision Code and Status register.
@@ -451,7 +459,7 @@
 	 * writing the ECC values in previous step.
 	 */
 
-	val = emif_regs->NANDFSR;
+	val = __raw_readl(&davinci_emif_regs->nandfsr);
 
 	/*
 	 * Read the syndrome from the NAND Flash 4-Bit ECC 1-4 registers.
@@ -467,13 +475,13 @@
 	 * Clear any previous address calculation by doing a dummy read of an
 	 * error address register.
 	 */
-	val = emif_regs->NANDERRADD1;
+	val = __raw_readl(&davinci_emif_regs->nanderradd1);
 
 	/*
 	 * Set the addr_calc_st bit(bit no 13) in the NAND Flash Control
 	 * register to 1.
 	 */
-	emif_regs->NANDFCR |= 1 << 13;
+	__raw_writel(1 << 13, &davinci_emif_regs->nandfcr);
 
 	/*
 	 * Wait for the corr_state field (bits 8 to 11)in the
@@ -481,12 +489,12 @@
 	 */
 	i = NAND_TIMEOUT;
 	do {
-		val = emif_regs->NANDFSR;
+		val = __raw_readl(&davinci_emif_regs->nandfsr);
 		val &= 0xc00;
 		i--;
 	} while ((i > 0) && val);
 
-	iserror = emif_regs->NANDFSR;
+	iserror = __raw_readl(&davinci_emif_regs->nandfsr);
 	iserror &= EMIF_NANDFSR_ECC_STATE_MASK;
 	iserror = iserror >> 8;
 
@@ -501,32 +509,33 @@
 	 */
 
 	if (iserror == ECC_STATE_NO_ERR) {
-		val = emif_regs->NANDERRVAL1;
+		val = __raw_readl(&davinci_emif_regs->nanderrval1);
 		return 0;
 	} else if (iserror == ECC_STATE_TOO_MANY_ERRS) {
-		val = emif_regs->NANDERRVAL1;
+		val = __raw_readl(&davinci_emif_regs->nanderrval1);
 		return -1;
 	}
 
-	numerrors = ((emif_regs->NANDFSR >> 16) & 0x3) + 1;
+	numerrors = ((__raw_readl(&davinci_emif_regs->nandfsr) >> 16)
+			& 0x3) + 1;
 
 	/* Read the error address, error value and correct */
 	for (i = 0; i < numerrors; i++) {
 		if (i > 1) {
 			erroraddress =
-			    ((emif_regs->NANDERRADD2 >>
+			    ((__raw_readl(&davinci_emif_regs->nanderradd2) >>
 			      (16 * (i & 1))) & 0x3FF);
 			erroraddress = ((512 + 7) - erroraddress);
 			errorvalue =
-			    ((emif_regs->NANDERRVAL2 >>
+			    ((__raw_readl(&davinci_emif_regs->nanderrval2) >>
 			      (16 * (i & 1))) & 0xFF);
 		} else {
 			erroraddress =
-			    ((emif_regs->NANDERRADD1 >>
+			    ((__raw_readl(&davinci_emif_regs->nanderradd1) >>
 			      (16 * (i & 1))) & 0x3FF);
 			erroraddress = ((512 + 7) - erroraddress);
 			errorvalue =
-			    ((emif_regs->NANDERRVAL1 >>
+			    ((__raw_readl(&davinci_emif_regs->nanderrval1) >>
 			      (16 * (i & 1))) & 0xFF);
 		}
 		/* xor the corrupt data with error value */
@@ -540,7 +549,7 @@
 
 static int nand_davinci_dev_ready(struct mtd_info *mtd)
 {
-	return emif_regs->NANDFSR & 0x1;
+	return __raw_readl(&davinci_emif_regs->nandfsr) & 0x1;
 }
 
 static void nand_flash_init(void)
@@ -561,21 +570,22 @@
 	 *                                                                  *
 	 *------------------------------------------------------------------*/
 	 acfg1 = 0
-		| (0 << 31 )	/* selectStrobe */
-		| (0 << 30 )	/* extWait */
-		| (1 << 26 )	/* writeSetup	10 ns */
-		| (3 << 20 )	/* writeStrobe	40 ns */
-		| (1 << 17 )	/* writeHold	10 ns */
-		| (1 << 13 )	/* readSetup	10 ns */
-		| (5 << 7 )	/* readStrobe	60 ns */
-		| (1 << 4 )	/* readHold	10 ns */
-		| (3 << 2 )	/* turnAround	?? ns */
-		| (0 << 0 )	/* asyncSize	8-bit bus */
+		| (0 << 31)	/* selectStrobe */
+		| (0 << 30)	/* extWait */
+		| (1 << 26)	/* writeSetup	10 ns */
+		| (3 << 20)	/* writeStrobe	40 ns */
+		| (1 << 17)	/* writeHold	10 ns */
+		| (1 << 13)	/* readSetup	10 ns */
+		| (5 << 7)	/* readStrobe	60 ns */
+		| (1 << 4)	/* readHold	10 ns */
+		| (3 << 2)	/* turnAround	?? ns */
+		| (0 << 0)	/* asyncSize	8-bit bus */
 		;
 
-	emif_regs->AB1CR = acfg1; /* CS2 */
+	__raw_writel(acfg1, &davinci_emif_regs->ab1cr); /* CS2 */
 
-	emif_regs->NANDFCR = 0x00000101; /* NAND flash on CS2 */
+	/* NAND flash on CS2 */
+	__raw_writel(0x00000101, &davinci_emif_regs->nandfcr);
 #endif
 }
 
diff --git a/include/asm-arm/arch-davinci/emif_defs.h b/include/asm-arm/arch-davinci/emif_defs.h
index aa57703..b48ec17 100644
--- a/include/asm-arm/arch-davinci/emif_defs.h
+++ b/include/asm-arm/arch-davinci/emif_defs.h
@@ -24,47 +24,42 @@
 
 #include <asm/arch/hardware.h>
 
-typedef struct davinci_emif_regs {
-	dv_reg		ERCSR;
-	dv_reg		AWCCR;
-	dv_reg		SDBCR;
-	dv_reg		SDRCR;
-	dv_reg		AB1CR;
-	dv_reg		AB2CR;
-	dv_reg		AB3CR;
-	dv_reg		AB4CR;
-	dv_reg		SDTIMR;
-	dv_reg		DDRSR;
-	dv_reg		DDRPHYCR;
-	dv_reg		DDRPHYSR;
-	dv_reg		TOTAR;
-	dv_reg		TOTACTR;
-	dv_reg		DDRPHYID_REV;
-	dv_reg		SDSRETR;
-	dv_reg		EIRR;
-	dv_reg		EIMR;
-	dv_reg		EIMSR;
-	dv_reg		EIMCR;
-	dv_reg		IOCTRLR;
-	dv_reg		IOSTATR;
-	u_int8_t	RSVD0[8];
-	dv_reg		NANDFCR;
-	dv_reg		NANDFSR;
-	u_int8_t	RSVD1[8];
-	dv_reg		NANDFECC[4];
-	u_int8_t	RSVD2[60];
-	dv_reg		NAND4BITECCLOAD;
-	dv_reg		NAND4BITECC1;
-	dv_reg		NAND4BITECC2;
-	dv_reg		NAND4BITECC3;
-	dv_reg		NAND4BITECC4;
-	dv_reg		NANDERRADD1;
-	dv_reg		NANDERRADD2;
-	dv_reg		NANDERRVAL1;
-	dv_reg		NANDERRVAL2;
-} emif_registers;
-
-typedef emif_registers	*emifregs;
+struct davinci_emif_regs {
+	u_int32_t	ercsr;
+	u_int32_t	awccr;
+	u_int32_t	sdbcr;
+	u_int32_t	sdrcr;
+	u_int32_t	ab1cr;
+	u_int32_t	ab2cr;
+	u_int32_t	ab3cr;
+	u_int32_t	ab4cr;
+	u_int32_t	sdtimr;
+	u_int32_t	ddrsr;
+	u_int32_t	ddrphycr;
+	u_int32_t	ddrphysr;
+	u_int32_t	totar;
+	u_int32_t	totactr;
+	u_int32_t	ddrphyid_rev;
+	u_int32_t	sdsretr;
+	u_int32_t	eirr;
+	u_int32_t	eimr;
+	u_int32_t	eimsr;
+	u_int32_t	eimcr;
+	u_int32_t	ioctrlr;
+	u_int32_t	iostatr;
+	u_int8_t	rsvd0[8];
+	u_int32_t	nandfcr;
+	u_int32_t	nandfsr;
+	u_int8_t	rsvd1[8];
+	u_int32_t	nandfecc[4];
+	u_int8_t	rsvd2[60];
+	u_int32_t	nand4biteccload;
+	u_int32_t	nand4bitecc[4];
+	u_int32_t	nanderradd1;
+	u_int32_t	nanderradd2;
+	u_int32_t	nanderrval1;
+	u_int32_t	nanderrval2;
+};
 
 #define davinci_emif_regs \
 	((struct davinci_emif_regs *)DAVINCI_ASYNC_EMIF_CNTRL_BASE)