Merge branch 'master' of git://git.denx.de/u-boot-mpc85xx

* 'master' of git://git.denx.de/u-boot-mpc85xx:
  fsl_lbc: add printout of LCRR and LBCR to local bus regs
  sbc8548: Fix up local bus init to be frequency aware
  sbc8548: enable support for hardware SPD errata workaround
  sbc8548: relocate fixed ddr init code to ddr.c file
  sbc8548: Make enabling SPD RAM configuration work
  sbc8548: Fix LBC SDRAM initialization settings
  sbc8548: enable ability to boot from alternate flash
  sbc8548: relocate 64MB user flash to sane boundary
  Revert "SBC8548: fix address mask to allow 64M flash"
  MPC85xxCDS: Fix missing LCRR_DBYP bits for 66-133MHz LBC
  eXMeritus HWW-1U-1A: Add support for the AT24C128N I2C EEPROM
  eXMeritus HWW-1U-1A: Minor environment variable tweaks
diff --git a/MAINTAINERS b/MAINTAINERS
index 4bf12b5..28729d0 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -436,11 +436,13 @@
 	municse		MPC5200
 	sc3		PPC405GP
 	suvd3		MPC8321
-	tuda1		MPC8321
-	tuxa1		MPC8321
 	uc101		MPC5200
 	ve8313		MPC8313
 
+Holger Brunck <holger.brunck@keymile.com>
+	tuge1		MPC8321
+	tuxx1		MPC8321
+
 Peter De Schrijver <p2@mind.be>
 
 	ML2		PPC4xx
diff --git a/arch/arm/cpu/armv7/omap-common/gpio.c b/arch/arm/cpu/armv7/omap-common/gpio.c
index 75a02da..fc89f2a 100644
--- a/arch/arm/cpu/armv7/omap-common/gpio.c
+++ b/arch/arm/cpu/armv7/omap-common/gpio.c
@@ -36,7 +36,7 @@
  * published by the Free Software Foundation.
  */
 #include <common.h>
-#include <asm/arch/gpio.h>
+#include <asm/gpio.h>
 #include <asm/io.h>
 #include <asm/errno.h>
 
@@ -56,17 +56,17 @@
 static inline int gpio_valid(int gpio)
 {
 	if (gpio < 0)
-		return -EINVAL;
+		return -1;
 	if (gpio < 192)
 		return 0;
-	return -EINVAL;
+	return -1;
 }
 
 static int check_gpio(int gpio)
 {
 	if (gpio_valid(gpio) < 0) {
 		printf("ERROR : check_gpio: invalid GPIO %d\n", gpio);
-		return -EINVAL;
+		return -1;
 	}
 	return 0;
 }
@@ -106,7 +106,7 @@
 		reg += OMAP_GPIO_OE;
 		break;
 	default:
-		return -EINVAL;
+		return -1;
 	}
 
 	v = __raw_readl(reg);
@@ -142,27 +142,29 @@
 /**
  * Set value of the specified gpio
  */
-void gpio_set_value(int gpio, int value)
+int gpio_set_value(unsigned gpio, int value)
 {
 	const struct gpio_bank *bank;
 
 	if (check_gpio(gpio) < 0)
-		return;
+		return -1;
 	bank = get_gpio_bank(gpio);
 	_set_gpio_dataout(bank, get_gpio_index(gpio), value);
+
+	return 0;
 }
 
 /**
  * Get value of the specified gpio
  */
-int gpio_get_value(int gpio)
+int gpio_get_value(unsigned gpio)
 {
 	const struct gpio_bank *bank;
 	void *reg;
 	int input;
 
 	if (check_gpio(gpio) < 0)
-		return -EINVAL;
+		return -1;
 	bank = get_gpio_bank(gpio);
 	reg = bank->base;
 	switch (bank->method) {
@@ -176,11 +178,11 @@
 			reg += OMAP_GPIO_DATAOUT;
 			break;
 		default:
-			return -EINVAL;
+			return -1;
 		}
 		break;
 	default:
-		return -EINVAL;
+		return -1;
 	}
 	return (__raw_readl(reg)
 			& (1 << get_gpio_index(gpio))) != 0;
@@ -194,7 +196,7 @@
 	const struct gpio_bank *bank;
 
 	if (check_gpio(gpio) < 0)
-		return -EINVAL;
+		return -1;
 
 	bank = get_gpio_bank(gpio);
 	_set_gpio_direction(bank, get_gpio_index(gpio), 1);
@@ -210,7 +212,7 @@
 	const struct gpio_bank *bank;
 
 	if (check_gpio(gpio) < 0)
-		return -EINVAL;
+		return -1;
 
 	bank = get_gpio_bank(gpio);
 	_set_gpio_dataout(bank, get_gpio_index(gpio), value);
@@ -224,10 +226,10 @@
  *
  * NOTE: Argument 'label' is unused.
  */
-int gpio_request(int gpio, const char *label)
+int gpio_request(unsigned gpio, const char *label)
 {
 	if (check_gpio(gpio) < 0)
-		return -EINVAL;
+		return -1;
 
 	return 0;
 }
@@ -235,6 +237,7 @@
 /**
  * Reset and free the gpio after using it.
  */
-void gpio_free(unsigned gpio)
+int gpio_free(unsigned gpio)
 {
+	return 0;
 }
diff --git a/arch/arm/include/asm/gpio.h b/arch/arm/include/asm/gpio.h
index eb071d1..d49ad08 100644
--- a/arch/arm/include/asm/gpio.h
+++ b/arch/arm/include/asm/gpio.h
@@ -1,38 +1,2 @@
-/*
- * Copyright (c) 2011, NVIDIA Corp. All rights reserved.
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#ifndef _GPIO_H_
-#define _GPIO_H_
-
 #include <asm/arch/gpio.h>
-/*
- * Generic GPIO API
- */
-
-int gpio_request(int gp, const char *label);
-void gpio_free(int gp);
-void gpio_toggle_value(int gp);
-int gpio_direction_input(int gp);
-int gpio_direction_output(int gp, int value);
-int gpio_get_value(int gp);
-void gpio_set_value(int gp, int value);
-
-#endif	/* _GPIO_H_ */
+#include <asm-generic/gpio.h>
diff --git a/arch/powerpc/include/asm/arch-mpc83xx/gpio.h b/arch/powerpc/include/asm/arch-mpc83xx/gpio.h
new file mode 100644
index 0000000..036f51e
--- /dev/null
+++ b/arch/powerpc/include/asm/arch-mpc83xx/gpio.h
@@ -0,0 +1,38 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _MPC83XX_GPIO_H_
+#define _MPC83XX_GPIO_H_
+
+/*
+ * The MCP83xx's 1-2 GPIO controllers each with 32 bits.
+ */
+#if defined(CONFIG_MPC8313) || defined(CONFIG_MPC8308) || \
+	defined(CONFIG_MPC8315)
+#define MPC83XX_GPIO_CTRLRS 1
+#elif defined(CONFIG_MPC834x) || defined(CONFIG_MPC837x)
+#define MPC83XX_GPIO_CTRLRS 2
+#else
+#define MPC83XX_GPIO_CTRLRS 0
+#endif
+
+#define MAX_NUM_GPIOS (32 * MPC83XX_GPIO_CTRLRS)
+
+void mpc83xx_gpio_init_f(void);
+void mpc83xx_gpio_init_r(void);
+
+#endif	/* MPC83XX_GPIO_H_ */
diff --git a/arch/powerpc/include/asm/gpio.h b/arch/powerpc/include/asm/gpio.h
new file mode 100644
index 0000000..d49ad08
--- /dev/null
+++ b/arch/powerpc/include/asm/gpio.h
@@ -0,0 +1,2 @@
+#include <asm/arch/gpio.h>
+#include <asm-generic/gpio.h>
diff --git a/board/efikamx/efikamx.c b/board/efikamx/efikamx.c
index 1f6c457..e88b2ed 100644
--- a/board/efikamx/efikamx.c
+++ b/board/efikamx/efikamx.c
@@ -314,17 +314,18 @@
 		return MX51_PIN_EIM_CS2;
 }
 
-int board_mmc_getcd(u8 *absent, struct mmc *mmc)
+int board_mmc_getcd(struct mmc *mmc)
 {
 	struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
 	uint32_t cd = efika_mmc_cd();
+	int ret;
 
 	if (cfg->esdhc_base == MMC_SDHC1_BASE_ADDR)
-		*absent = gpio_get_value(IOMUX_TO_GPIO(cd));
+		ret = !gpio_get_value(IOMUX_TO_GPIO(cd));
 	else
-		*absent = gpio_get_value(IOMUX_TO_GPIO(MX51_PIN_GPIO1_8));
+		ret = !gpio_get_value(IOMUX_TO_GPIO(MX51_PIN_GPIO1_8));
 
-	return 0;
+	return ret;
 }
 
 int board_mmc_init(bd_t *bis)
diff --git a/board/emk/top9000/top9000.c b/board/emk/top9000/top9000.c
index 6f5662a..e0b4cf2 100644
--- a/board/emk/top9000/top9000.c
+++ b/board/emk/top9000/top9000.c
@@ -108,17 +108,9 @@
 }
 
 /* this is a weak define that we are overriding */
-int board_mmc_getcd(u8 *cd, struct mmc *mmc)
+int board_mmc_getcd(struct mmc *mmc)
 {
-	/*
-	 * the only currently existing use of this function
-	 * (fsl_esdhc.c) suggests this function must return
-	 * *cs = TRUE if a card is NOT detected -> in most
-	 * cases the value of the pin when the detect switch
-	 * closes to GND
-	 */
-	*cd = at91_get_gpio_value(CONFIG_SYS_MMC_CD_PIN) ? 1 : 0;
-	return 0;
+	return !at91_get_gpio_value(CONFIG_SYS_MMC_CD_PIN);
 }
 
 #endif
diff --git a/board/freescale/mpc8313erdb/mpc8313erdb.c b/board/freescale/mpc8313erdb/mpc8313erdb.c
index 08f873d..730ec4e 100644
--- a/board/freescale/mpc8313erdb/mpc8313erdb.c
+++ b/board/freescale/mpc8313erdb/mpc8313erdb.c
@@ -31,6 +31,9 @@
 #include <vsc7385.h>
 #include <ns16550.h>
 #include <nand.h>
+#if defined(CONFIG_MPC83XX_GPIO) && !defined(CONFIG_NAND_SPL)
+#include <asm/gpio.h>
+#endif
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -42,6 +45,18 @@
 	if (im->pmc.pmccr1 & PMCCR1_POWER_OFF)
 		gd->flags |= GD_FLG_SILENT;
 #endif
+#if defined(CONFIG_MPC83XX_GPIO) && !defined(CONFIG_NAND_SPL)
+	mpc83xx_gpio_init_f();
+#endif
+
+	return 0;
+}
+
+int board_early_init_r(void)
+{
+#if defined(CONFIG_MPC83XX_GPIO) && !defined(CONFIG_NAND_SPL)
+	mpc83xx_gpio_init_r();
+#endif
 
 	return 0;
 }
diff --git a/board/freescale/mx51evk/mx51evk.c b/board/freescale/mx51evk/mx51evk.c
index e43aaf7..8d1f6a3 100644
--- a/board/freescale/mx51evk/mx51evk.c
+++ b/board/freescale/mx51evk/mx51evk.c
@@ -321,19 +321,20 @@
 }
 
 #ifdef CONFIG_FSL_ESDHC
-int board_mmc_getcd(u8 *cd, struct mmc *mmc)
+int board_mmc_getcd(struct mmc *mmc)
 {
 	struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
+	int ret;
 
 	mxc_request_iomux(MX51_PIN_GPIO1_0, IOMUX_CONFIG_ALT1);
 	mxc_request_iomux(MX51_PIN_GPIO1_6, IOMUX_CONFIG_ALT0);
 
 	if (cfg->esdhc_base == MMC_SDHC1_BASE_ADDR)
-		*cd = gpio_get_value(0);
+		ret = !gpio_get_value(0);
 	else
-		*cd = gpio_get_value(6);
+		ret = !gpio_get_value(6);
 
-	return 0;
+	return ret;
 }
 
 int board_mmc_init(bd_t *bis)
diff --git a/board/freescale/mx53ard/mx53ard.c b/board/freescale/mx53ard/mx53ard.c
index e5a1142..40b5c19 100644
--- a/board/freescale/mx53ard/mx53ard.c
+++ b/board/freescale/mx53ard/mx53ard.c
@@ -83,19 +83,20 @@
 	{MMC_SDHC2_BASE_ADDR, 1 },
 };
 
-int board_mmc_getcd(u8 *cd, struct mmc *mmc)
+int board_mmc_getcd(struct mmc *mmc)
 {
 	struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
+	int ret;
 
 	mxc_request_iomux(MX53_PIN_GPIO_1, IOMUX_CONFIG_ALT1);
 	mxc_request_iomux(MX53_PIN_GPIO_4, IOMUX_CONFIG_ALT1);
 
 	if (cfg->esdhc_base == MMC_SDHC1_BASE_ADDR)
-		*cd = gpio_get_value(1); /*GPIO1_1*/
+		ret = !gpio_get_value(1); /* GPIO1_1 */
 	else
-		*cd = gpio_get_value(4); /*GPIO1_4*/
+		ret = !gpio_get_value(4); /* GPIO1_4 */
 
-	return 0;
+	return ret;
 }
 
 int board_mmc_init(bd_t *bis)
diff --git a/board/freescale/mx53evk/mx53evk.c b/board/freescale/mx53evk/mx53evk.c
index aa4a2c9..e976ae1 100644
--- a/board/freescale/mx53evk/mx53evk.c
+++ b/board/freescale/mx53evk/mx53evk.c
@@ -208,19 +208,20 @@
 	{MMC_SDHC3_BASE_ADDR, 1},
 };
 
-int board_mmc_getcd(u8 *cd, struct mmc *mmc)
+int board_mmc_getcd(struct mmc *mmc)
 {
 	struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
+	int ret;
 
 	mxc_request_iomux(MX53_PIN_EIM_DA11, IOMUX_CONFIG_ALT1);
 	mxc_request_iomux(MX53_PIN_EIM_DA13, IOMUX_CONFIG_ALT1);
 
 	if (cfg->esdhc_base == MMC_SDHC1_BASE_ADDR)
-		*cd = gpio_get_value(77); /*GPIO3_13*/
+		ret = !gpio_get_value(77); /* GPIO3_13 */
 	else
-		*cd = gpio_get_value(75); /*GPIO3_11*/
+		ret = !gpio_get_value(75); /* GPIO3_11 */
 
-	return 0;
+	return ret;
 }
 
 int board_mmc_init(bd_t *bis)
diff --git a/board/freescale/mx53loco/mx53loco.c b/board/freescale/mx53loco/mx53loco.c
index ea4d354..e6345e7 100644
--- a/board/freescale/mx53loco/mx53loco.c
+++ b/board/freescale/mx53loco/mx53loco.c
@@ -147,19 +147,20 @@
 	{MMC_SDHC3_BASE_ADDR, 1},
 };
 
-int board_mmc_getcd(u8 *cd, struct mmc *mmc)
+int board_mmc_getcd(struct mmc *mmc)
 {
 	struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
+	int ret;
 
 	mxc_request_iomux(MX53_PIN_EIM_DA11, IOMUX_CONFIG_ALT1);
 	mxc_request_iomux(MX53_PIN_EIM_DA13, IOMUX_CONFIG_ALT1);
 
 	if (cfg->esdhc_base == MMC_SDHC1_BASE_ADDR)
-		*cd = gpio_get_value(77); /*GPIO3_13*/
+		ret = !gpio_get_value(77); /* GPIO3_13 */
 	else
-		*cd = gpio_get_value(75); /*GPIO3_11*/
+		ret = !gpio_get_value(75); /* GPIO3_11 */
 
-	return 0;
+	return ret;
 }
 
 int board_mmc_init(bd_t *bis)
diff --git a/board/freescale/mx53smd/mx53smd.c b/board/freescale/mx53smd/mx53smd.c
index 55af4e4..e273192 100644
--- a/board/freescale/mx53smd/mx53smd.c
+++ b/board/freescale/mx53smd/mx53smd.c
@@ -132,12 +132,10 @@
 	{MMC_SDHC1_BASE_ADDR, 1},
 };
 
-int board_mmc_getcd(u8 *cd, struct mmc *mmc)
+int board_mmc_getcd(struct mmc *mmc)
 {
 	mxc_request_iomux(MX53_PIN_EIM_DA13, IOMUX_CONFIG_ALT1);
-	*cd = gpio_get_value(77); /*GPIO3_13*/
-
-	return 0;
+	return !gpio_get_value(77); /* GPIO3_13 */
 }
 
 int board_mmc_init(bd_t *bis)
diff --git a/board/gdsys/405ex/io64.c b/board/gdsys/405ex/io64.c
index a997571..177141d 100644
--- a/board/gdsys/405ex/io64.c
+++ b/board/gdsys/405ex/io64.c
@@ -249,6 +249,7 @@
 	char str_serdes[] = "Start SERDES blocks";
 	char str_channels[] = "Start FPGA channels";
 	char str_locks[] = "Verify SERDES locks";
+	char str_hicb[] = "Verify HICB status";
 	char str_status[] = "Verify PHY status -";
 	char slash[] = "\\|/-\\|/-";
 
@@ -312,6 +313,21 @@
 	}
 	blank_string(strlen(str_locks));
 
+	/* verify hicb_status */
+	puts(str_hicb);
+	for (fpga = 0; fpga < 2; ++fpga) {
+		u16 *ch0_hicb_status_int = &(fpga ? fpga1 : fpga0)->ch0_hicb_status_int;
+		for (k = 0; k < 32; ++k) {
+			u16 status = in_le16(ch0_hicb_status_int + 4*k);
+			if (status)
+				printf("fpga %d hicb %d: hicb status %04x\n",
+					fpga, k, status);
+			/* reset events */
+			out_le16(ch0_hicb_status_int + 4*k, status);
+		}
+	}
+	blank_string(strlen(str_hicb));
+
 	/* verify phy status */
 	puts(str_status);
 	for (k = 0; k < 32; ++k) {
diff --git a/board/mpl/common/common_util.c b/board/mpl/common/common_util.c
index d3300ed..a61a98c 100644
--- a/board/mpl/common/common_util.c
+++ b/board/mpl/common/common_util.c
@@ -53,13 +53,156 @@
 #define I2C_BACKUP_ADDR 0x7C00		/* 0x200 bytes for backup */
 #define IMAGE_SIZE CONFIG_SYS_MONITOR_LEN	/* ugly, but it works for now */
 
-extern flash_info_t flash_info[];	/* info for FLASH chips */
+#if defined(CONFIG_PIP405) || defined(CONFIG_MIP405)
+/*-----------------------------------------------------------------------
+ * On PIP/MIP405 we have 3 (4) possible boot mode
+ *
+ * - Boot from Flash (Flash CS = CS0, MPS CS = CS1)
+ * - Boot from MPS   (Flash CS = CS1, MPS CS = CS0)
+ * - Boot from PCI with Flash map (Flash CS = CS0, MPS CS = CS1)
+ * - Boot from PCI with MPS map   (Flash CS = CS1, MPS CS = CS0)
+ * The flash init is the first board specific routine which is called
+ * after code relocation (running from SDRAM)
+ * The first thing we do is to map the Flash CS to the Flash area and
+ * the MPS CS to the MPS area. Since the flash size is unknown at this
+ * point, we use the max flash size and the lowest flash address as base.
+ *
+ * After flash detection we adjust the size of the CS area accordingly.
+ * update_flash_size() will fix in wrong values in the flash_info structure,
+ * misc_init_r() will fix the values in the board info structure
+ */
+int get_boot_mode(void)
+{
+	unsigned long pbcr;
+	int res = 0;
+	pbcr = mfdcr(CPC0_PSR);
+	if ((pbcr & PSR_ROM_WIDTH_MASK) == 0)
+		/* boot via MPS or MPS mapping */
+		res = BOOT_MPS;
+	if (pbcr & PSR_ROM_LOC)
+		/* boot via PCI.. */
+		res |= BOOT_PCI;
+	 return res;
+}
+
+/* Map the flash high (in boot area)
+   This code can only be executed from SDRAM (after relocation).
+*/
+void setup_cs_reloc(void)
+{
+	int mode;
+	/*
+	 * since we are relocated, we can set-up the CS finaly
+	 * but first of all, switch off PCI mapping (in case it
+	 * was a PCI boot)
+	 */
+	out32r(PMM0MA, 0L);
+	/* get boot mode */
+	mode = get_boot_mode();
+	/*
+	 * we map the flash high in every case
+	 * first find out to which CS the flash is attached to
+	 */
+	if (mode & BOOT_MPS) {
+		/* map flash high on CS1 and MPS on CS0 */
+		mtdcr(EBC0_CFGADDR, PB0AP);
+		mtdcr(EBC0_CFGDATA, MPS_AP);
+		mtdcr(EBC0_CFGADDR, PB0CR);
+		mtdcr(EBC0_CFGDATA, MPS_CR);
+		/*
+		 * we use the default values (max values) for the flash
+		 * because its real size is not yet known
+		 */
+		mtdcr(EBC0_CFGADDR, PB1AP);
+		mtdcr(EBC0_CFGDATA, FLASH_AP);
+		mtdcr(EBC0_CFGADDR, PB1CR);
+		mtdcr(EBC0_CFGDATA, FLASH_CR_B);
+	} else {
+		/* map flash high on CS0 and MPS on CS1 */
+		mtdcr(EBC0_CFGADDR, PB1AP);
+		mtdcr(EBC0_CFGDATA, MPS_AP);
+		mtdcr(EBC0_CFGADDR, PB1CR);
+		mtdcr(EBC0_CFGDATA, MPS_CR);
+		/*
+		 * we use the default values (max values) for the flash
+		 * because its real size is not yet known
+		 */
+		mtdcr(EBC0_CFGADDR, PB0AP);
+		mtdcr(EBC0_CFGDATA, FLASH_AP);
+		mtdcr(EBC0_CFGADDR, PB0CR);
+		mtdcr(EBC0_CFGDATA, FLASH_CR_B);
+	}
+}
+#endif /* #if defined(CONFIG_PIP405) || defined(CONFIG_MIP405) */
+
+#ifdef CONFIG_SYS_UPDATE_FLASH_SIZE
+/* adjust flash start and protection info */
+int update_flash_size(int flash_size)
+{
+	int i = 0, mode;
+	flash_info_t *info = &flash_info[0];
+	unsigned long flashcr;
+	unsigned long flash_base = (0 - flash_size) & 0xFFF00000;
+
+	if (flash_size > 128*1024*1024) {
+		printf("\n ### ERROR, wrong flash size: %X, reset board ###\n",
+		       flash_size);
+		hang();
+	}
+
+	if ((flash_size >> 20) != 0)
+		i = __ilog2(flash_size >> 20);
+
+	/* set up flash CS according to the size */
+	mode = get_boot_mode();
+	if (mode & BOOT_MPS) {
+		/* flash is on CS1 */
+		mtdcr(EBC0_CFGADDR, PB1CR);
+		flashcr = mfdcr(EBC0_CFGDATA);
+		/* we map the flash high in every case */
+		flashcr &= 0x0001FFFF; /* mask out address bits */
+		flashcr |= flash_base; /* start addr */
+		flashcr |= (i << 17); /* size addr */
+		mtdcr(EBC0_CFGADDR, PB1CR);
+		mtdcr(EBC0_CFGDATA, flashcr);
+	} else {
+		/* flash is on CS0 */
+		mtdcr(EBC0_CFGADDR, PB0CR);
+		flashcr = mfdcr(EBC0_CFGDATA);
+		/* we map the flash high in every case */
+		flashcr &= 0x0001FFFF; /* mask out address bits */
+		flashcr |= flash_base; /* start addr */
+		flashcr |= (i << 17); /* size addr */
+		mtdcr(EBC0_CFGADDR, PB0CR);
+		mtdcr(EBC0_CFGDATA, flashcr);
+	}
+
+	for (i = 0; i < info->sector_count; i++)
+		/* adjust sector start address */
+		info->start[i] = flash_base +
+				(info->start[i] - CONFIG_SYS_FLASH_BASE);
+
+	/* unprotect all sectors */
+	flash_protect(FLAG_PROTECT_CLEAR,
+		      info->start[0],
+		      0xFFFFFFFF,
+		      info);
+	flash_protect_default();
+	/* protect reset vector too*/
+	flash_protect(FLAG_PROTECT_SET,
+		      info->start[info->sector_count-1],
+		      0xFFFFFFFF,
+		      info);
+
+	return 0;
+}
+#endif
 
 static int
 mpl_prg(uchar *src, ulong size)
 {
 	ulong start;
-	flash_info_t *info;
+	flash_info_t *info = &flash_info[0];
 	int i, rc;
 #if defined(CONFIG_PATI)
 	int start_sect;
@@ -69,8 +212,6 @@
 	ulong *magic = (ulong *)src;
 #endif
 
-	info = &flash_info[0];
-
 #if defined(CONFIG_PIP405) || defined(CONFIG_MIP405) || defined(CONFIG_PATI)
 	if (uimage_to_cpu (magic[0]) != IH_MAGIC) {
 		puts("Bad Magic number\n");
@@ -96,12 +237,18 @@
 	}
 #if !defined(CONFIG_PATI)
 	start = 0 - size;
-	for (i = info->sector_count-1; i > 0; i--) {
-		info->protect[i] = 0; /* unprotect this sector */
+
+	/* unprotect sectors used by u-boot */
+	flash_protect(FLAG_PROTECT_CLEAR,
+		      start,
+		      0xFFFFFFFF,
+		      info);
+
+	/* search start sector */
+	for (i = info->sector_count-1; i > 0; i--)
 		if (start >= info->start[i])
 			break;
-	}
-	/* set-up flash location */
+
 	/* now erase flash */
 	printf("Erasing at %lx (sector %d) (start %lx)\n",
 				start,i,info->start[i]);
@@ -114,22 +261,24 @@
 #else /* #if !defined(CONFIG_PATI */
 	start = FIRM_START;
 	start_sect = -1;
-	for (i = 0; i < info->sector_count; i++) {
-		if (start < info->start[i]) {
-			start_sect = i - 1;
-			break;
-		}
-	}
 
-	info->protect[i - 1] = 0;	/* unprotect this sector */
-	for (; i < info->sector_count; i++) {
-		if ((start + size) < info->start[i])
+	/* search start sector */
+	for (i = info->sector_count-1; i > 0; i--)
+		if (start >= info->start[i])
 			break;
-		info->protect[i] = 0;	/* unprotect this sector */
-	}
 
-	i--;
-	/* set-up flash location */
+	start_sect = i;
+
+	for (i = info->sector_count-1; i > 0; i--)
+		if ((start + size) >= info->start[i])
+			break;
+
+	/* unprotect sectors used by u-boot */
+	flash_protect(FLAG_PROTECT_CLEAR,
+		      start,
+		      start + size,
+		      info);
+
 	/* now erase flash */
 	printf ("Erasing at %lx to %lx (sector %d to %d) (%lx to %lx)\n",
 		start, start + size, start_sect, i,
@@ -143,12 +292,17 @@
 
 #elif defined(CONFIG_VCMA9)
 	start = 0;
-	for (i = 0; i <info->sector_count; i++) {
-		info->protect[i] = 0; /* unprotect this sector */
+
+	/* search end sector */
+	for (i = 0; i < info->sector_count; i++)
 		if (size < info->start[i])
 		    break;
-	}
-	/* set-up flash location */
+
+	flash_protect(FLAG_PROTECT_CLEAR,
+		      start,
+		      size,
+		      info);
+
 	/* now erase flash */
 	printf("Erasing at %lx (sector %d) (start %lx)\n",
 				start,0,info->start[0]);
diff --git a/board/mpl/common/common_util.h b/board/mpl/common/common_util.h
index 29cd14f..a0ea239 100644
--- a/board/mpl/common/common_util.h
+++ b/board/mpl/common/common_util.h
@@ -30,11 +30,15 @@
 	char eth_addr[21];	/* "00:60:C2:0a:00:00" */
 } backup_t;
 
+extern flash_info_t flash_info[];	/* info for FLASH chips */
+
 void get_backup_values(backup_t *buf);
 
 #if defined(CONFIG_PIP405) || defined(CONFIG_MIP405)
 #define BOOT_MPS	0x01
 #define BOOT_PCI	0x02
+int get_boot_mode(void);
+void setup_cs_reloc(void);
 #endif
 
 void check_env(void);
diff --git a/board/mpl/common/flash.c b/board/mpl/common/flash.c
deleted file mode 100644
index d5b63c0..0000000
--- a/board/mpl/common/flash.c
+++ /dev/null
@@ -1,872 +0,0 @@
-/*
- * (C) Copyright 2000, 2001
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-/*
- * Modified 4/5/2001
- * Wait for completion of each sector erase command issued
- * 4/5/2001
- * Chris Hallinan - DS4.COM, Inc. - clh@net1plus.com
- */
-
-/*
- * Modified 3/7/2001
- * - adapted for pip405, Denis Peter, MPL AG Switzerland
- * TODO:
- * clean-up
- */
-
-#include <common.h>
-
-#if !defined(CONFIG_PATI)
-#include <asm/ppc4xx.h>
-#include <asm/processor.h>
-#include "common_util.h"
-#if defined(CONFIG_MIP405)
-#include "../mip405/mip405.h"
-#endif
-#if defined(CONFIG_PIP405)
-#include "../pip405/pip405.h"
-#endif
-#include <asm/4xx_pci.h>
-#else /* defined(CONFIG_PATI) */
-#include <mpc5xx.h>
-#endif
-
-flash_info_t	flash_info[CONFIG_SYS_MAX_FLASH_BANKS]; /* info for FLASH chips	*/
-/*-----------------------------------------------------------------------
- * Functions
- */
-static ulong flash_get_size (vu_long *addr, flash_info_t *info);
-static int write_word (flash_info_t *info, ulong dest, ulong data);
-
-void unlock_intel_sectors(flash_info_t *info,ulong addr,ulong cnt);
-
-#define ADDR0           0x5555
-#define ADDR1           0x2aaa
-#define FLASH_WORD_SIZE unsigned short
-
-#define FALSE           0
-#define TRUE            1
-
-#if !defined(CONFIG_PATI)
-
-/*-----------------------------------------------------------------------
- * Some CS switching routines:
- *
- * On PIP/MIP405 we have 3 (4) possible boot mode
- *
- * - Boot from Flash (Flash CS = CS0, MPS CS = CS1)
- * - Boot from MPS   (Flash CS = CS1, MPS CS = CS0)
- * - Boot from PCI with Flash map (Flash CS = CS0, MPS CS = CS1)
- * - Boot from PCI with MPS map   (Flash CS = CS1, MPS CS = CS0)
- * The flash init is the first board specific routine which is called
- * after code relocation (running from SDRAM)
- * The first thing we do is to map the Flash CS to the Flash area and
- * the MPS CS to the MPS area. Since the flash size is unknown at this
- * point, we use the max flash size and the lowest flash address as base.
- *
- * After flash detection we adjust the size of the CS area accordingly.
- * The board_init_r will fill in wrong values in the board init structure,
- * but this will be fixed in the misc_init_r routine:
- * bd->bi_flashstart=0-flash_info[0].size
- * bd->bi_flashsize=flash_info[0].size-CONFIG_SYS_MONITOR_LEN
- * bd->bi_flashoffset=0
- *
- */
-int get_boot_mode(void)
-{
-	unsigned long pbcr;
-	int res = 0;
-	pbcr = mfdcr (CPC0_PSR);
-	if ((pbcr & PSR_ROM_WIDTH_MASK) == 0)
-		/* boot via MPS or MPS mapping */
-		res = BOOT_MPS;
-	if(pbcr & PSR_ROM_LOC)
-		/* boot via PCI.. */
-		res |= BOOT_PCI;
-	 return res;
-}
-
-/* Map the flash high (in boot area)
-   This code can only be executed from SDRAM (after relocation).
-*/
-void setup_cs_reloc(void)
-{
-	int mode;
-	/* Since we are relocated, we can set-up the CS finaly
-	 * but first of all, switch off PCI mapping (in case it was a PCI boot) */
-	out32r(PMM0MA,0L);
-	icache_enable (); /* we are relocated */
-	/* get boot mode */
-	mode=get_boot_mode();
-	/* we map the flash high in every case */
-	/* first findout on which cs the flash is */
-	if(mode & BOOT_MPS) {
-		/* map flash high on CS1 and MPS on CS0 */
-		mtdcr (EBC0_CFGADDR, PB0AP);
-		mtdcr (EBC0_CFGDATA, MPS_AP);
-		mtdcr (EBC0_CFGADDR, PB0CR);
-		mtdcr (EBC0_CFGDATA, MPS_CR);
-		/* we use the default values (max values) for the flash
-		 * because its real size is not yet known */
-		mtdcr (EBC0_CFGADDR, PB1AP);
-		mtdcr (EBC0_CFGDATA, FLASH_AP);
-		mtdcr (EBC0_CFGADDR, PB1CR);
-		mtdcr (EBC0_CFGDATA, FLASH_CR_B);
-	}
-	else {
-		/* map flash high on CS0 and MPS on CS1 */
-		mtdcr (EBC0_CFGADDR, PB1AP);
-		mtdcr (EBC0_CFGDATA, MPS_AP);
-		mtdcr (EBC0_CFGADDR, PB1CR);
-		mtdcr (EBC0_CFGDATA, MPS_CR);
-		/* we use the default values (max values) for the flash
-		 * because its real size is not yet known */
-		mtdcr (EBC0_CFGADDR, PB0AP);
-		mtdcr (EBC0_CFGDATA, FLASH_AP);
-		mtdcr (EBC0_CFGADDR, PB0CR);
-		mtdcr (EBC0_CFGDATA, FLASH_CR_B);
-	}
-}
-
-#endif /* #if !defined(CONFIG_PATI) */
-
-unsigned long flash_init (void)
-{
-	unsigned long size_b0;
-	int i;
-
-#if !defined(CONFIG_PATI)
-	unsigned long flashcr,size_reg;
-	int mode;
-	extern char version_string;
-	char *p = &version_string;
-
-	/* Since we are relocated, we can set-up the CS finally */
-	setup_cs_reloc();
-	/* get and display boot mode */
-	mode=get_boot_mode();
-	if(mode & BOOT_PCI)
-		printf("(PCI Boot %s Map) ",(mode & BOOT_MPS) ?
-			"MPS" : "Flash");
-	else
-		printf("(%s Boot) ",(mode & BOOT_MPS) ?
-			"MPS" : "Flash");
-#endif /* #if !defined(CONFIG_PATI) */
-	/* Init: no FLASHes known */
-	for (i=0; i<CONFIG_SYS_MAX_FLASH_BANKS; ++i) {
-		flash_info[i].flash_id = FLASH_UNKNOWN;
-	}
-
-	/* Static FLASH Bank configuration here - FIXME XXX */
-
-	size_b0 = flash_get_size((vu_long *)CONFIG_SYS_MONITOR_BASE, &flash_info[0]);
-
-	if (flash_info[0].flash_id == FLASH_UNKNOWN) {
-		printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
-			size_b0, size_b0<<20);
-	}
-	/* protect the bootloader */
-	/* Monitor protection ON by default */
-#if CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE
-	flash_protect(FLAG_PROTECT_SET,
-			CONFIG_SYS_MONITOR_BASE,
-			CONFIG_SYS_MONITOR_BASE+monitor_flash_len-1,
-			&flash_info[0]);
-#endif
-#if !defined(CONFIG_PATI)
-	/* protect reset vector */
-	flash_info[0].protect[flash_info[0].sector_count-1] = 1;
-	flash_info[0].size = size_b0;
-	/* set up flash cs according to the size */
-	size_reg=(flash_info[0].size >>20);
-	switch (size_reg) {
-		case 0:
-		case 1: i=0; break; /* <= 1MB */
-		case 2: i=1; break; /* = 2MB */
-		case 4: i=2; break; /* = 4MB */
-		case 8: i=3; break; /* = 8MB */
-		case 16: i=4; break; /* = 16MB */
-		case 32: i=5; break; /* = 32MB */
-		case 64: i=6; break; /* = 64MB */
-		case 128: i=7; break; /*= 128MB */
-		default:
-			printf("\n #### ERROR, wrong size %ld MByte reset board #####\n",size_reg);
-			while(1);
-	}
-	if(mode & BOOT_MPS) {
-		/* flash is on CS1 */
-		mtdcr(EBC0_CFGADDR, PB1CR);
-		flashcr = mfdcr (EBC0_CFGDATA);
-		/* we map the flash high in every case */
-		flashcr&=0x0001FFFF; /* mask out address bits */
-		flashcr|= ((0-flash_info[0].size) & 0xFFF00000); /* start addr */
-		flashcr|= (i << 17); /* size addr */
-		mtdcr(EBC0_CFGADDR, PB1CR);
-		mtdcr(EBC0_CFGDATA, flashcr);
-	}
-	else {
-		/* flash is on CS0 */
-		mtdcr(EBC0_CFGADDR, PB0CR);
-		flashcr = mfdcr (EBC0_CFGDATA);
-		/* we map the flash high in every case */
-		flashcr&=0x0001FFFF; /* mask out address bits */
-		flashcr|= ((0-flash_info[0].size) & 0xFFF00000); /* start addr */
-		flashcr|= (i << 17); /* size addr */
-		mtdcr(EBC0_CFGADDR, PB0CR);
-		mtdcr(EBC0_CFGDATA, flashcr);
-	}
-#if 0
-	/* enable this (PIP405/MIP405 only) if you want to test if
-	   the relocation has be done ok.
-	   This will disable both Chipselects */
-	mtdcr (EBC0_CFGADDR, PB0CR);
-	mtdcr (EBC0_CFGDATA, 0L);
-	mtdcr (EBC0_CFGADDR, PB1CR);
-	mtdcr (EBC0_CFGDATA, 0L);
-	printf("CS0 & CS1 switched off for test\n");
-#endif
-	/* patch version_string */
-	for(i=0;i<0x100;i++) {
-		if(*p=='\n') {
-			*p=0;
-			break;
-		}
-		p++;
-	}
-#else /* #if !defined(CONFIG_PATI) */
-#ifdef	CONFIG_ENV_IS_IN_FLASH
-	/* ENV protection ON by default */
-	flash_protect(FLAG_PROTECT_SET,
-		      CONFIG_ENV_ADDR,
-		      CONFIG_ENV_ADDR+CONFIG_ENV_SECT_SIZE-1,
-		      &flash_info[0]);
-#endif
-#endif /* #if !defined(CONFIG_PATI) */
-	return (size_b0);
-}
-
-
-/*-----------------------------------------------------------------------
- */
-void flash_print_info  (flash_info_t *info)
-{
-	int i;
-	int k;
-	int size;
-	int erased;
-	volatile unsigned long *flash;
-
-	if (info->flash_id == FLASH_UNKNOWN) {
-		printf ("missing or unknown FLASH type\n");
-		return;
-	}
-
-	switch (info->flash_id & FLASH_VENDMASK) {
-	case FLASH_MAN_AMD:	printf ("AMD ");		break;
-	case FLASH_MAN_FUJ:	printf ("FUJITSU ");		break;
-	case FLASH_MAN_SST:	printf ("SST ");		break;
-	case FLASH_MAN_INTEL:	printf ("Intel ");		break;
-	default:		printf ("Unknown Vendor ");	break;
-	}
-
-	switch (info->flash_id & FLASH_TYPEMASK) {
-	case FLASH_AM040:	printf ("AM29F040 (512 Kbit, uniform sector size)\n");
-				break;
-	case FLASH_AM400B:	printf ("AM29LV400B (4 Mbit, bottom boot sect)\n");
-				break;
-	case FLASH_AM400T:	printf ("AM29LV400T (4 Mbit, top boot sector)\n");
-				break;
-	case FLASH_AM800B:	printf ("AM29LV800B (8 Mbit, bottom boot sect)\n");
-				break;
-	case FLASH_AM800T:	printf ("AM29LV800T (8 Mbit, top boot sector)\n");
-				break;
-	case FLASH_AM160B:	printf ("AM29LV160B (16 Mbit, bottom boot sect)\n");
-				break;
-	case FLASH_AM160T:	printf ("AM29LV160T (16 Mbit, top boot sector)\n");
-				break;
-	case FLASH_AM320B:	printf ("AM29LV320B (32 Mbit, bottom boot sect)\n");
-				break;
-	case FLASH_AM320T:	printf ("AM29LV320T (32 Mbit, top boot sector)\n");
-				break;
-	case FLASH_SST800A:	printf ("SST39LF/VF800 (8 Mbit, uniform sector size)\n");
-				break;
-	case FLASH_SST160A:	printf ("SST39LF/VF160 (16 Mbit, uniform sector size)\n");
-				break;
-	case FLASH_INTEL320T:	printf ("TE28F320C3 (32 Mbit, top sector size)\n");
-				break;
-	case FLASH_AM640U:	printf ("AM29LV640U (64 Mbit, uniform sector size)\n");
-				break;
-	default:		printf ("Unknown Chip Type\n");
-				break;
-	}
-
-	printf ("  Size: %ld KB in %d Sectors\n",
-		info->size >> 10, info->sector_count);
-
-	printf ("  Sector Start Addresses:");
-	for (i=0; i<info->sector_count; ++i) {
-		/*
-		 * Check if whole sector is erased
-		*/
-		if (i != (info->sector_count-1))
-			size = info->start[i+1] - info->start[i];
-		else
-			size = info->start[0] + info->size - info->start[i];
-		erased = 1;
-		flash = (volatile unsigned long *)info->start[i];
-		size = size >> 2;        /* divide by 4 for longword access */
-		for (k=0; k<size; k++) {
-			if (*flash++ != 0xffffffff) {
-				erased = 0;
-				break;
-			}
-		}
-		if ((i % 5) == 0)
-			printf ("\n   ");
-		printf (" %08lX%s%s",
-			info->start[i],
-			erased ? " E" : "  ",
-			info->protect[i] ? "RO " : "   ");
-	}
-	printf ("\n");
-}
-
-/*-----------------------------------------------------------------------
- */
-
-
-/*-----------------------------------------------------------------------
-
-*/
-
-/*
- * The following code cannot be run from FLASH!
- */
-static ulong flash_get_size (vu_long *addr, flash_info_t *info)
-{
-	short i;
-	FLASH_WORD_SIZE value;
-	ulong base;
-	volatile FLASH_WORD_SIZE *addr2 = (FLASH_WORD_SIZE *)addr;
-
-	/* Write auto select command: read Manufacturer ID */
-	addr2[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA;
-	addr2[ADDR1] = (FLASH_WORD_SIZE)0x00550055;
-	addr2[ADDR0] = (FLASH_WORD_SIZE)0x00900090;
-
-	value = addr2[0];
-	/*	printf("flash_get_size value: %x\n",value); */
-	switch (value) {
-	case (FLASH_WORD_SIZE)AMD_MANUFACT:
-		info->flash_id = FLASH_MAN_AMD;
-		break;
-	case (FLASH_WORD_SIZE)FUJ_MANUFACT:
-		info->flash_id = FLASH_MAN_FUJ;
-		break;
-	case (FLASH_WORD_SIZE)INTEL_MANUFACT:
-		info->flash_id = FLASH_MAN_INTEL;
-		break;
-	case (FLASH_WORD_SIZE)SST_MANUFACT:
-		info->flash_id = FLASH_MAN_SST;
-		break;
-	default:
-		info->flash_id = FLASH_UNKNOWN;
-		info->sector_count = 0;
-		info->size = 0;
-		return (0);			/* no or unknown flash	*/
-	}
-	value = addr2[1];			/* device ID		*/
-	/*	printf("Device value %x\n",value);		    */
-	switch (value) {
-	case (FLASH_WORD_SIZE)AMD_ID_F040B:
-		info->flash_id += FLASH_AM040;
-		info->sector_count = 8;
-		info->size = 0x0080000; /* => 512 ko */
-		break;
-	case (FLASH_WORD_SIZE)AMD_ID_LV400T:
-		info->flash_id += FLASH_AM400T;
-		info->sector_count = 11;
-		info->size = 0x00080000;
-		break;				/* => 0.5 MB		*/
-
-	case (FLASH_WORD_SIZE)AMD_ID_LV400B:
-		info->flash_id += FLASH_AM400B;
-		info->sector_count = 11;
-		info->size = 0x00080000;
-		break;				/* => 0.5 MB		*/
-
-	case (FLASH_WORD_SIZE)AMD_ID_LV800T:
-		info->flash_id += FLASH_AM800T;
-		info->sector_count = 19;
-		info->size = 0x00100000;
-		break;				/* => 1 MB		*/
-
-	case (FLASH_WORD_SIZE)AMD_ID_LV800B:
-		info->flash_id += FLASH_AM800B;
-		info->sector_count = 19;
-		info->size = 0x00100000;
-		break;				/* => 1 MB		*/
-
-	case (FLASH_WORD_SIZE)AMD_ID_LV160T:
-		info->flash_id += FLASH_AM160T;
-		info->sector_count = 35;
-		info->size = 0x00200000;
-		break;				/* => 2 MB		*/
-
-	case (FLASH_WORD_SIZE)AMD_ID_LV160B:
-		info->flash_id += FLASH_AM160B;
-		info->sector_count = 35;
-		info->size = 0x00200000;
-		break;				/* => 2 MB		*/
-	case (FLASH_WORD_SIZE)AMD_ID_LV320T:
-		info->flash_id += FLASH_AM320T;
-		info->sector_count = 67;
-		info->size = 0x00400000;
-		break;				/* => 4 MB		*/
-	case (FLASH_WORD_SIZE)AMD_ID_LV640U:
-		info->flash_id += FLASH_AM640U;
-		info->sector_count = 128;
-		info->size = 0x00800000;
-		break;				/* => 8 MB		*/
-#if 0	/* enable when device IDs are available */
-
-	case (FLASH_WORD_SIZE)AMD_ID_LV320B:
-		info->flash_id += FLASH_AM320B;
-		info->sector_count = 67;
-		info->size = 0x00400000;
-		break;				/* => 4 MB		*/
-#endif
-	case (FLASH_WORD_SIZE)SST_ID_xF800A:
-		info->flash_id += FLASH_SST800A;
-		info->sector_count = 16;
-		info->size = 0x00100000;
-		break;				/* => 1 MB		*/
-	case (FLASH_WORD_SIZE)INTEL_ID_28F320C3T:
-		info->flash_id += FLASH_INTEL320T;
-		info->sector_count = 71;
-		info->size = 0x00400000;
-		break;				/* => 4 MB		*/
-
-
-	case (FLASH_WORD_SIZE)SST_ID_xF160A:
-		info->flash_id += FLASH_SST160A;
-		info->sector_count = 32;
-		info->size = 0x00200000;
-		break;				/* => 2 MB		*/
-
-	default:
-		info->flash_id = FLASH_UNKNOWN;
-		return (0);			/* => no or unknown flash */
-
-	}
-	/* base address calculation */
-	base=0-info->size;
-	/* set up sector start address table */
-	if (((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) ||
-	     (info->flash_id  == FLASH_AM040) ||
-	     (info->flash_id  == FLASH_AM640U)){
-		for (i = 0; i < info->sector_count; i++)
-			info->start[i] = base + (i * 0x00010000);
-	}
-	else {
-		if (info->flash_id & FLASH_BTYPE) {
-			/* set sector offsets for bottom boot block type	*/
-			info->start[0] = base + 0x00000000;
-			info->start[1] = base + 0x00004000;
-			info->start[2] = base + 0x00006000;
-			info->start[3] = base + 0x00008000;
-			for (i = 4; i < info->sector_count; i++)
-				info->start[i] = base + (i * 0x00010000) - 0x00030000;
-		}
-		else {
-			/* set sector offsets for top boot block type		*/
-			i = info->sector_count - 1;
-			if(info->sector_count==71) {
-
-				info->start[i--] = base + info->size - 0x00002000;
-				info->start[i--] = base + info->size - 0x00004000;
-				info->start[i--] = base + info->size - 0x00006000;
-				info->start[i--] = base + info->size - 0x00008000;
-				info->start[i--] = base + info->size - 0x0000A000;
-				info->start[i--] = base + info->size - 0x0000C000;
-				info->start[i--] = base + info->size - 0x0000E000;
-				for (; i >= 0; i--)
-					info->start[i] = base + i * 0x000010000;
-			}
-			else {
-				info->start[i--] = base + info->size - 0x00004000;
-				info->start[i--] = base + info->size - 0x00006000;
-				info->start[i--] = base + info->size - 0x00008000;
-				for (; i >= 0; i--)
-					info->start[i] = base + i * 0x00010000;
-			}
-		}
-	}
-
-	/* check for protected sectors */
-	for (i = 0; i < info->sector_count; i++) {
-		/* read sector protection at sector address, (A7 .. A0) = 0x02 */
-		/* D0 = 1 if protected */
-		addr2 = (volatile FLASH_WORD_SIZE *)(info->start[i]);
-		if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL)
-			info->protect[i] = 0;
-		else
-			info->protect[i] = addr2[2] & 1;
-	}
-
-	/*
-	 * Prevent writes to uninitialized FLASH.
-	 */
-	if (info->flash_id != FLASH_UNKNOWN) {
-		addr2 = (FLASH_WORD_SIZE *)info->start[0];
-		*addr2 = (FLASH_WORD_SIZE)0x00F000F0;	/* reset bank */
-	}
-	return (info->size);
-}
-
-
-int wait_for_DQ7(flash_info_t *info, int sect)
-{
-	ulong start, now, last;
-	volatile FLASH_WORD_SIZE *addr = (FLASH_WORD_SIZE *)(info->start[sect]);
-
-	start = get_timer (0);
-	last  = start;
-	while ((addr[0] & (FLASH_WORD_SIZE)0x00800080) != (FLASH_WORD_SIZE)0x00800080) {
-		if ((now = get_timer(start)) > CONFIG_SYS_FLASH_ERASE_TOUT) {
-			printf ("Timeout\n");
-			return ERR_TIMOUT;
-		}
-		/* show that we're waiting */
-		if ((now - last) > 1000) {  /* every second */
-			putc ('.');
-			last = now;
-		}
-	}
-	return ERR_OK;
-}
-
-int intel_wait_for_DQ7(flash_info_t *info, int sect)
-{
-	ulong start, now, last, status;
-	volatile FLASH_WORD_SIZE *addr = (FLASH_WORD_SIZE *)(info->start[sect]);
-
-	start = get_timer (0);
-	last  = start;
-	while ((addr[0] & (FLASH_WORD_SIZE)0x00800080) != (FLASH_WORD_SIZE)0x00800080) {
-		if ((now = get_timer(start)) > CONFIG_SYS_FLASH_ERASE_TOUT) {
-			printf ("Timeout\n");
-			return ERR_TIMOUT;
-		}
-		/* show that we're waiting */
-		if ((now - last) > 1000) {  /* every second */
-			putc ('.');
-			last = now;
-		}
-	}
-	status = addr[0] & (FLASH_WORD_SIZE)0x00280028;
-	/* clear status register */
-	addr[0] = (FLASH_WORD_SIZE)0x00500050;
-	/* check status for block erase fail and VPP low */
-	return (status == 0 ? ERR_OK : ERR_NOT_ERASED);
-}
-
-/*-----------------------------------------------------------------------
- */
-
-int	flash_erase (flash_info_t *info, int s_first, int s_last)
-{
-	volatile FLASH_WORD_SIZE *addr = (FLASH_WORD_SIZE *)(info->start[0]);
-	volatile FLASH_WORD_SIZE *addr2;
-	int flag, prot, sect;
-	int i, rcode = 0;
-
-
-	if ((s_first < 0) || (s_first > s_last)) {
-		if (info->flash_id == FLASH_UNKNOWN) {
-			printf ("- missing\n");
-		} else {
-			printf ("- no sectors to erase\n");
-		}
-		return 1;
-	}
-
-	if (info->flash_id == FLASH_UNKNOWN) {
-		printf ("Can't erase unknown flash type - aborted\n");
-		return 1;
-	}
-
-	prot = 0;
-	for (sect=s_first; sect<=s_last; ++sect) {
-		if (info->protect[sect]) {
-			prot++;
-		}
-	}
-
-	if (prot) {
-		printf ("- Warning: %d protected sectors will not be erased!\n",
-			prot);
-	} else {
-		printf ("\n");
-	}
-
-	/* Disable interrupts which might cause a timeout here */
-	flag = disable_interrupts();
-
-	/* Start erase on unprotected sectors */
-	for (sect = s_first; sect<=s_last; sect++) {
-		if (info->protect[sect] == 0) {	/* not protected */
-			addr2 = (FLASH_WORD_SIZE *)(info->start[sect]);
-			/*  printf("Erasing sector %p\n", addr2); */ /* CLH */
-			if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) {
-				addr[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA;
-				addr[ADDR1] = (FLASH_WORD_SIZE)0x00550055;
-				addr[ADDR0] = (FLASH_WORD_SIZE)0x00800080;
-				addr[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA;
-				addr[ADDR1] = (FLASH_WORD_SIZE)0x00550055;
-				addr2[0] = (FLASH_WORD_SIZE)0x00500050;  /* block erase */
-				for (i=0; i<50; i++)
-					udelay(1000);  /* wait 1 ms */
-				rcode |= wait_for_DQ7(info, sect);
-			}
-			else {
-				if((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL){
-					addr2[0] = (FLASH_WORD_SIZE)0x00600060;  /* unlock sector */
-					addr2[0] = (FLASH_WORD_SIZE)0x00D000D0;  /* sector erase */
-					intel_wait_for_DQ7(info, sect);
-					addr2[0] = (FLASH_WORD_SIZE)0x00200020;  /* sector erase */
-					addr2[0] = (FLASH_WORD_SIZE)0x00D000D0;  /* sector erase */
-					rcode |= intel_wait_for_DQ7(info, sect);
-				}
-				else {
-					addr[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA;
-					addr[ADDR1] = (FLASH_WORD_SIZE)0x00550055;
-					addr[ADDR0] = (FLASH_WORD_SIZE)0x00800080;
-					addr[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA;
-					addr[ADDR1] = (FLASH_WORD_SIZE)0x00550055;
-					addr2[0] = (FLASH_WORD_SIZE)0x00300030;  /* sector erase */
-					rcode |= wait_for_DQ7(info, sect);
-				}
-			}
-			/*
-			 * Wait for each sector to complete, it's more
-			 * reliable.  According to AMD Spec, you must
-			 * issue all erase commands within a specified
-			 * timeout.  This has been seen to fail, especially
-			 * if printf()s are included (for debug)!!
-			 */
-			/*   wait_for_DQ7(info, sect); */
-		}
-	}
-
-	/* re-enable interrupts if necessary */
-	if (flag)
-		enable_interrupts();
-
-	/* wait at least 80us - let's wait 1 ms */
-	udelay (1000);
-
-	/* reset to read mode */
-	addr = (FLASH_WORD_SIZE *)info->start[0];
-	addr[0] = (FLASH_WORD_SIZE)0x00F000F0;	/* reset bank */
-
-	if (!rcode)
-	    printf (" done\n");
-
-	return rcode;
-}
-
-
-void unlock_intel_sectors(flash_info_t *info,ulong addr,ulong cnt)
-{
-	int i;
-	volatile FLASH_WORD_SIZE *addr2;
-	long c;
-	c= (long)cnt;
-	for(i=info->sector_count-1;i>0;i--)
-	{
-		if(addr>=info->start[i])
-			break;
-	}
-	do {
-		addr2 = (FLASH_WORD_SIZE *)(info->start[i]);
-		addr2[0] = (FLASH_WORD_SIZE)0x00600060;  /* unlock sector setup */
-		addr2[0] = (FLASH_WORD_SIZE)0x00D000D0;  /* unlock sector */
-		intel_wait_for_DQ7(info, i);
-		i++;
-		c-=(info->start[i]-info->start[i-1]);
-	}while(c>0);
-}
-
-
-/*-----------------------------------------------------------------------
- * Copy memory to flash, returns:
- * 0 - OK
- * 1 - write timeout
- * 2 - Flash not erased
- */
-
-int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
-{
-	ulong cp, wp, data;
-	int i, l, rc;
-
-	if((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL){
-		unlock_intel_sectors(info,addr,cnt);
-	}
-	wp = (addr & ~3);	/* get lower word aligned address */
-	/*
-	 * handle unaligned start bytes
-	 */
-	if ((l = addr - wp) != 0) {
-		data = 0;
-		for (i=0, cp=wp; i<l; ++i, ++cp) {
-			data = (data << 8) | (*(uchar *)cp);
-		}
-		for (; i<4 && cnt>0; ++i) {
-			data = (data << 8) | *src++;
-			--cnt;
-			++cp;
-		}
-		for (; cnt==0 && i<4; ++i, ++cp) {
-			data = (data << 8) | (*(uchar *)cp);
-		}
-
-		if ((rc = write_word(info, wp, data)) != 0) {
-			return (rc);
-		}
-		wp += 4;
-	}
-
-	/*
-	 * handle word aligned part
-	 */
-	while (cnt >= 4) {
-		data = 0;
-		for (i=0; i<4; ++i) {
-			data = (data << 8) | *src++;
-		}
-		if ((rc = write_word(info, wp, data)) != 0) {
-			return (rc);
-		}
-		wp  += 4;
-		if((wp % 0x10000)==0)
-			printf("."); /* show Progress */
-		cnt -= 4;
-	}
-
-	if (cnt == 0) {
-		return (0);
-	}
-
-	/*
-	 * handle unaligned tail bytes
-	 */
-	data = 0;
-	for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) {
-		data = (data << 8) | *src++;
-		--cnt;
-	}
-	for (; i<4; ++i, ++cp) {
-		data = (data << 8) | (*(uchar *)cp);
-	}
-	rc=write_word(info, wp, data);
-	return rc;
-}
-
-/*-----------------------------------------------------------------------
- * Write a word to Flash, returns:
- * 0 - OK
- * 1 - write timeout
- * 2 - Flash not erased
- */
-static FLASH_WORD_SIZE *read_val = (FLASH_WORD_SIZE *)0x200000;
-
-static int write_word (flash_info_t *info, ulong dest, ulong data)
-{
-	volatile FLASH_WORD_SIZE *addr2 = (volatile FLASH_WORD_SIZE *)(info->start[0]);
-	volatile FLASH_WORD_SIZE *dest2 = (volatile FLASH_WORD_SIZE *)dest;
-	volatile FLASH_WORD_SIZE *data2;
-	ulong start;
-	ulong *data_p;
-	int flag;
-	int i;
-
-	data_p = &data;
-	data2 = (volatile FLASH_WORD_SIZE *)data_p;
-
-	/* Check if Flash is (sufficiently) erased */
-	if ((*((volatile FLASH_WORD_SIZE *)dest) &
-		(FLASH_WORD_SIZE)data) != (FLASH_WORD_SIZE)data) {
-		return (2);
-	}
-	/* Disable interrupts which might cause a timeout here */
-	flag = disable_interrupts();
-	for (i=0; i<4/sizeof(FLASH_WORD_SIZE); i++)
-	{
-		if((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL){
-			/* intel style writting */
-			dest2[i] = (FLASH_WORD_SIZE)0x00500050;
-			dest2[i] = (FLASH_WORD_SIZE)0x00400040;
-			*read_val++ = data2[i];
-			dest2[i] = data2[i];
-			if (flag)
-				enable_interrupts();
-			/* data polling for D7 */
-			start = get_timer (0);
-			udelay(10);
-			while ((dest2[i] & (FLASH_WORD_SIZE)0x00800080) != (FLASH_WORD_SIZE)0x00800080)
-			{
-				if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT)
-					return (1);
-			}
-			dest2[i] = (FLASH_WORD_SIZE)0x00FF00FF; /* return to read mode */
-			udelay(10);
-			dest2[i] = (FLASH_WORD_SIZE)0x00FF00FF; /* return to read mode */
-			if(dest2[i]!=data2[i])
-				printf("Error at %p 0x%04X != 0x%04X\n",&dest2[i],dest2[i],data2[i]);
-		}
-		else {
-			addr2[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA;
-			addr2[ADDR1] = (FLASH_WORD_SIZE)0x00550055;
-			addr2[ADDR0] = (FLASH_WORD_SIZE)0x00A000A0;
-			dest2[i] = data2[i];
-			/* re-enable interrupts if necessary */
-			if (flag)
-				enable_interrupts();
-			/* data polling for D7 */
-			start = get_timer (0);
-			while ((dest2[i] & (FLASH_WORD_SIZE)0x00800080) !=
-				(data2[i] & (FLASH_WORD_SIZE)0x00800080)) {
-				if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
-					return (1);
-				}
-			}
-		}
-	}
-	return (0);
-}
-
-/*-----------------------------------------------------------------------
- */
diff --git a/board/mpl/mip405/Makefile b/board/mpl/mip405/Makefile
index 5dd0b2f..9921545 100644
--- a/board/mpl/mip405/Makefile
+++ b/board/mpl/mip405/Makefile
@@ -28,8 +28,10 @@
 
 LIB	= $(obj)lib$(BOARD).o
 
-COBJS	= $(BOARD).o ../common/flash.o cmd_mip405.o ../common/pci.o \
-			../common/usb_uhci.o ../common/common_util.o
+COBJS	= $(BOARD).o cmd_mip405.o \
+		../common/pci.o \
+		../common/usb_uhci.o \
+		../common/common_util.o
 
 SOBJS	= init.o
 
diff --git a/board/mpl/mip405/mip405.c b/board/mpl/mip405/mip405.c
index 9d0db64..56a84e9 100644
--- a/board/mpl/mip405/mip405.c
+++ b/board/mpl/mip405/mip405.c
@@ -498,6 +498,27 @@
 	return 0;
 }
 
+int board_early_init_r(void)
+{
+	int mode;
+
+	/*
+	 * since we are relocated, we can finally enable i-cache
+	 * and set up the flash CS correctly
+	 */
+	icache_enable();
+	setup_cs_reloc();
+	/* get and display boot mode */
+	mode = get_boot_mode();
+	if (mode & BOOT_PCI)
+		printf("PCI Boot %s Map\n", (mode & BOOT_MPS) ?
+			"MPS" : "Flash");
+	else
+		printf("%s Boot\n", (mode & BOOT_MPS) ?
+			"MPS" : "Flash");
+
+	return 0;
+}
 
 /*
  * Get some PLD Registers
@@ -671,7 +692,6 @@
 /* used to check if the time in RTC is valid */
 static unsigned long start;
 static struct rtc_time tm;
-extern flash_info_t flash_info[];	/* info for FLASH chips */
 
 int misc_init_r (void)
 {
diff --git a/board/mpl/pati/Makefile b/board/mpl/pati/Makefile
index dae381d..0fe508c 100644
--- a/board/mpl/pati/Makefile
+++ b/board/mpl/pati/Makefile
@@ -28,8 +28,8 @@
 
 LIB	= $(obj)lib$(BOARD).o
 
-COBJS	:=  pati.o ../common/flash.o cmd_pati.o ../common/common_util.o
-#### cmd_pati.o
+COBJS	:=  $(BOARD).o cmd_pati.o \
+		../common/common_util.o
 
 SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
 OBJS	:= $(addprefix $(obj),$(COBJS))
diff --git a/board/mpl/pip405/Makefile b/board/mpl/pip405/Makefile
index 9aebb9a..48fe750 100644
--- a/board/mpl/pip405/Makefile
+++ b/board/mpl/pip405/Makefile
@@ -28,11 +28,12 @@
 
 LIB	= $(obj)lib$(BOARD).o
 
-COBJS	= $(BOARD).o \
-	  ../common/flash.o cmd_pip405.o ../common/pci.o \
-	  ../common/isa.o ../common/kbd.o \
-	  ../common/usb_uhci.o \
-	  ../common/common_util.o
+COBJS	= $(BOARD).o cmd_pip405.o \
+		../common/pci.o \
+		../common/isa.o \
+		../common/kbd.o \
+		../common/usb_uhci.o \
+		../common/common_util.o
 
 SOBJS	= init.o
 
diff --git a/board/mpl/pip405/pip405.c b/board/mpl/pip405/pip405.c
index a1f0b65..75f57ad 100644
--- a/board/mpl/pip405/pip405.c
+++ b/board/mpl/pip405/pip405.c
@@ -566,7 +566,27 @@
 	return 0;
 }
 
+int board_early_init_r(void)
+{
+	int mode;
 
+	/*
+	 * since we are relocated, we can finally enable i-cache
+	 * and set up the flash CS correctly
+	 */
+	icache_enable();
+	setup_cs_reloc();
+	/* get and display boot mode */
+	mode = get_boot_mode();
+	if (mode & BOOT_PCI)
+		printf("PCI Boot %s Map\n", (mode & BOOT_MPS) ?
+			"MPS" : "Flash");
+	else
+		printf("%s Boot\n", (mode & BOOT_MPS) ?
+			"MPS" : "Flash");
+
+	return 0;
+}
 /* ------------------------------------------------------------------------- */
 
 /*
@@ -660,9 +680,6 @@
 	return (1);
 }
 
-
-extern flash_info_t flash_info[];	/* info for FLASH chips */
-
 int misc_init_r (void)
 {
 	/* adjust flash start and size as well as the offset */
diff --git a/boards.cfg b/boards.cfg
index 0b32532..35bc525 100644
--- a/boards.cfg
+++ b/boards.cfg
@@ -593,8 +593,8 @@
 kmeter1                      powerpc     mpc83xx     km83xx              keymile
 kmsupx5                      powerpc     mpc83xx     km83xx              keymile
 suvd3                        powerpc     mpc83xx     km83xx              keymile
-tuda1                        powerpc     mpc83xx     km83xx              keymile
-tuxa1                        powerpc     mpc83xx     km83xx              keymile
+tuge1                        powerpc     mpc83xx     km83xx              keymile        -           tuxx1:KM_DISABLE_APP2
+tuxx1                        powerpc     mpc83xx     km83xx              keymile
 MERGERBOX                    powerpc     mpc83xx     mergerbox           matrix_vision
 MVBLM7                       powerpc     mpc83xx     mvblm7              matrix_vision
 SIMPC8313_LP                 powerpc     mpc83xx     simpc8313           sheldon        -           SIMPC8313:NAND_LP
diff --git a/doc/README.atmel_mci b/doc/README.atmel_mci
index dee0cf0..0cbd909 100644
--- a/doc/README.atmel_mci
+++ b/doc/README.atmel_mci
@@ -59,17 +59,9 @@
 }
 
 /* this is a weak define that we are overriding */
-int board_mmc_getcd(u8 *cd, struct mmc *mmc)
+int board_mmc_getcd(struct mmc *mmc)
 {
-	/*
-	 * the only currently existing use of this function
-	 * (fsl_esdhc.c) suggests this function must return
-	 * *cs = TRUE if a card is NOT detected -> in most
-	 * cases the value of the pin when the detect switch
-	 * closes to GND
-	 */
-	*cd = at91_get_gpio_value (CONFIG_SYS_MMC_CD_PIN) ? 1 : 0;
-	return 0;
+	return !at91_get_gpio_value(CONFIG_SYS_MMC_CD_PIN);
 }
 
 #endif
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index e22c096..4375a55 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -37,6 +37,7 @@
 COBJS-$(CONFIG_TEGRA2_GPIO)	+= tegra2_gpio.o
 COBJS-$(CONFIG_DA8XX_GPIO)	+= da8xx_gpio.o
 COBJS-$(CONFIG_ALTERA_PIO)	+= altera_pio.o
+COBJS-$(CONFIG_MPC83XX_GPIO)	+= mpc83xx_gpio.o
 
 COBJS	:= $(COBJS-y)
 SRCS 	:= $(COBJS:.o=.c)
diff --git a/drivers/gpio/da8xx_gpio.c b/drivers/gpio/da8xx_gpio.c
index 74b58e8..84d2b77 100644
--- a/drivers/gpio/da8xx_gpio.c
+++ b/drivers/gpio/da8xx_gpio.c
@@ -23,7 +23,6 @@
 #include <common.h>
 #include <asm/io.h>
 #include <asm/gpio.h>
-#include <asm/arch/gpio.h>
 #include <asm/arch/hardware.h>
 #include <asm/arch/davinci_misc.h>
 
@@ -181,87 +180,93 @@
 	{ pinmux(18), 8, 2 },
 };
 
-int gpio_request(int gp, const char *label)
+int gpio_request(unsigned gpio, const char *label)
 {
-	if (gp >= MAX_NUM_GPIOS)
+	if (gpio >= MAX_NUM_GPIOS)
 		return -1;
 
-	if (gpio_registry[gp].is_registered)
+	if (gpio_registry[gpio].is_registered)
 		return -1;
 
-	gpio_registry[gp].is_registered = 1;
-	strncpy(gpio_registry[gp].name, label, GPIO_NAME_SIZE);
-	gpio_registry[gp].name[GPIO_NAME_SIZE - 1] = 0;
+	gpio_registry[gpio].is_registered = 1;
+	strncpy(gpio_registry[gpio].name, label, GPIO_NAME_SIZE);
+	gpio_registry[gpio].name[GPIO_NAME_SIZE - 1] = 0;
 
-	davinci_configure_pin_mux(&gpio_pinmux[gp], 1);
+	davinci_configure_pin_mux(&gpio_pinmux[gpio], 1);
 
 	return 0;
 }
 
-void gpio_free(int gp)
+int gpio_free(unsigned gpio)
 {
-	gpio_registry[gp].is_registered = 0;
+	if (gpio >= MAX_NUM_GPIOS)
+		return -1;
+
+	if (!gpio_registry[gpio].is_registered)
+		return -1;
+
+	gpio_registry[gpio].is_registered = 0;
+	gpio_registry[gpio].name[0] = '\0';
+	/* Do not configure as input or change pin mux here */
+	return 0;
 }
 
-void gpio_toggle_value(int gp)
-{
-	gpio_set_value(gp, !gpio_get_value(gp));
-}
-
-int gpio_direction_input(int gp)
+int gpio_direction_input(unsigned gpio)
 {
 	struct davinci_gpio *bank;
 
-	bank = GPIO_BANK(gp);
-	setbits_le32(&bank->dir, 1U << GPIO_BIT(gp));
+	bank = GPIO_BANK(gpio);
+	setbits_le32(&bank->dir, 1U << GPIO_BIT(gpio));
 	return 0;
 }
 
-int gpio_direction_output(int gp, int value)
+int gpio_direction_output(unsigned gpio, int value)
 {
 	struct davinci_gpio *bank;
 
-	bank = GPIO_BANK(gp);
-	clrbits_le32(&bank->dir, 1U << GPIO_BIT(gp));
-	gpio_set_value(gp, value);
+	bank = GPIO_BANK(gpio);
+	clrbits_le32(&bank->dir, 1U << GPIO_BIT(gpio));
+	gpio_set_value(gpio, value);
 	return 0;
 }
 
-int gpio_get_value(int gp)
+int gpio_get_value(unsigned gpio)
 {
 	struct davinci_gpio *bank;
 	unsigned int ip;
 
-	bank = GPIO_BANK(gp);
-	ip = in_le32(&bank->in_data) & (1U << GPIO_BIT(gp));
+	bank = GPIO_BANK(gpio);
+	ip = in_le32(&bank->in_data) & (1U << GPIO_BIT(gpio));
 	return ip ? 1 : 0;
 }
 
-void gpio_set_value(int gp, int value)
+int gpio_set_value(unsigned gpio, int value)
 {
 	struct davinci_gpio *bank;
 
-	bank = GPIO_BANK(gp);
+	bank = GPIO_BANK(gpio);
 
 	if (value)
-		bank->set_data = 1U << GPIO_BIT(gp);
+		bank->set_data = 1U << GPIO_BIT(gpio);
 	else
-		bank->clr_data = 1U << GPIO_BIT(gp);
+		bank->clr_data = 1U << GPIO_BIT(gpio);
+
+	return 0;
 }
 
 void gpio_info(void)
 {
-	int gp, dir, val;
+	unsigned gpio, dir, val;
 	struct davinci_gpio *bank;
 
-	for (gp = 0; gp < MAX_NUM_GPIOS; ++gp) {
-		bank = GPIO_BANK(gp);
-		dir = in_le32(&bank->dir) & (1U << GPIO_BIT(gp));
-		val = gpio_get_value(gp);
+	for (gpio = 0; gpio < MAX_NUM_GPIOS; ++gpio) {
+		bank = GPIO_BANK(gpio);
+		dir = in_le32(&bank->dir) & (1U << GPIO_BIT(gpio));
+		val = gpio_get_value(gpio);
 
 		printf("% 4d: %s: %d [%c] %s\n",
-			gp, dir ? " in" : "out", val,
-			gpio_registry[gp].is_registered ? 'x' : ' ',
-			gpio_registry[gp].name);
+			gpio, dir ? " in" : "out", val,
+			gpio_registry[gpio].is_registered ? 'x' : ' ',
+			gpio_registry[gpio].name);
 	}
 }
diff --git a/drivers/gpio/mpc83xx_gpio.c b/drivers/gpio/mpc83xx_gpio.c
new file mode 100644
index 0000000..a9afcb2
--- /dev/null
+++ b/drivers/gpio/mpc83xx_gpio.c
@@ -0,0 +1,199 @@
+/*
+ * Freescale MPC83xx GPIO handling.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <mpc83xx.h>
+#include <asm/gpio.h>
+#include <asm/io.h>
+
+#ifndef CONFIG_MPC83XX_GPIO_0_INIT_DIRECTION
+#define CONFIG_MPC83XX_GPIO_0_INIT_DIRECTION 0
+#endif
+#ifndef CONFIG_MPC83XX_GPIO_1_INIT_DIRECTION
+#define CONFIG_MPC83XX_GPIO_1_INIT_DIRECTION 0
+#endif
+#ifndef CONFIG_MPC83XX_GPIO_0_INIT_OPEN_DRAIN
+#define CONFIG_MPC83XX_GPIO_0_INIT_OPEN_DRAIN 0
+#endif
+#ifndef CONFIG_MPC83XX_GPIO_1_INIT_OPEN_DRAIN
+#define CONFIG_MPC83XX_GPIO_1_INIT_OPEN_DRAIN 0
+#endif
+#ifndef CONFIG_MPC83XX_GPIO_0_INIT_VALUE
+#define CONFIG_MPC83XX_GPIO_0_INIT_VALUE 0
+#endif
+#ifndef CONFIG_MPC83XX_GPIO_1_INIT_VALUE
+#define CONFIG_MPC83XX_GPIO_1_INIT_VALUE 0
+#endif
+
+static unsigned int gpio_output_value[MPC83XX_GPIO_CTRLRS];
+
+/*
+ * Generic_GPIO primitives.
+ */
+
+int gpio_request(unsigned gpio, const char *label)
+{
+	if (gpio >= MAX_NUM_GPIOS)
+		return -1;
+
+	return 0;
+}
+
+int gpio_free(unsigned gpio)
+{
+	/* Do not set to input */
+	return 0;
+}
+
+/* set GPIO pin 'gpio' as an input */
+int gpio_direction_input(unsigned gpio)
+{
+	immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
+	unsigned int ctrlr;
+	unsigned int line;
+	unsigned int line_mask;
+
+	/* 32-bits per controller */
+	ctrlr = gpio >> 5;
+	line = gpio & (0x1F);
+
+	/* Big endian */
+	line_mask = 1 << (31 - line);
+
+	clrbits_be32(&im->gpio[ctrlr].dir, line_mask);
+
+	return 0;
+}
+
+/* set GPIO pin 'gpio' as an output, with polarity 'value' */
+int gpio_direction_output(unsigned gpio, int value)
+{
+	immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
+	unsigned int ctrlr;
+	unsigned int line;
+	unsigned int line_mask;
+
+	if (value != 0 && value != 1) {
+		printf("Error: Value parameter must be 0 or 1.\n");
+		return -1;
+	}
+
+	gpio_set_value(gpio, value);
+
+	/* 32-bits per controller */
+	ctrlr = gpio >> 5;
+	line = gpio & (0x1F);
+
+	/* Big endian */
+	line_mask = 1 << (31 - line);
+
+	/* Make the line output */
+	setbits_be32(&im->gpio[ctrlr].dir, line_mask);
+
+	return 0;
+}
+
+/* read GPIO IN value of pin 'gpio' */
+int gpio_get_value(unsigned gpio)
+{
+	immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
+	unsigned int ctrlr;
+	unsigned int line;
+	unsigned int line_mask;
+
+	/* 32-bits per controller */
+	ctrlr = gpio >> 5;
+	line = gpio & (0x1F);
+
+	/* Big endian */
+	line_mask = 1 << (31 - line);
+
+	/* Read the value and mask off the bit */
+	return (in_be32(&im->gpio[ctrlr].dat) & line_mask) != 0;
+}
+
+/* write GPIO OUT value to pin 'gpio' */
+int gpio_set_value(unsigned gpio, int value)
+{
+	immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
+	unsigned int ctrlr;
+	unsigned int line;
+	unsigned int line_mask;
+
+	if (value != 0 && value != 1) {
+		printf("Error: Value parameter must be 0 or 1.\n");
+		return -1;
+	}
+
+	/* 32-bits per controller */
+	ctrlr = gpio >> 5;
+	line = gpio & (0x1F);
+
+	/* Big endian */
+	line_mask = 1 << (31 - line);
+
+	/* Update the local output buffer soft copy */
+	gpio_output_value[ctrlr] =
+		(gpio_output_value[ctrlr] & ~line_mask) | \
+			(value ? line_mask : 0);
+
+	/* Write the output */
+	out_be32(&im->gpio[ctrlr].dat, gpio_output_value[ctrlr]);
+
+	return 0;
+}
+
+/* Configure GPIO registers early */
+void mpc83xx_gpio_init_f()
+{
+	immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
+
+#if MPC83XX_GPIO_CTRLRS >= 1
+	out_be32(&im->gpio[0].dir, CONFIG_MPC83XX_GPIO_0_INIT_DIRECTION);
+	out_be32(&im->gpio[0].odr, CONFIG_MPC83XX_GPIO_0_INIT_OPEN_DRAIN);
+	out_be32(&im->gpio[0].dat, CONFIG_MPC83XX_GPIO_0_INIT_VALUE);
+	out_be32(&im->gpio[0].ier, 0xFFFFFFFF); /* Clear all events */
+	out_be32(&im->gpio[0].imr, 0);
+	out_be32(&im->gpio[0].icr, 0);
+#endif
+
+#if MPC83XX_GPIO_CTRLRS >= 2
+	out_be32(&im->gpio[1].dir, CONFIG_MPC83XX_GPIO_1_INIT_DIRECTION);
+	out_be32(&im->gpio[1].odr, CONFIG_MPC83XX_GPIO_1_INIT_OPEN_DRAIN);
+	out_be32(&im->gpio[1].dat, CONFIG_MPC83XX_GPIO_1_INIT_VALUE);
+	out_be32(&im->gpio[1].ier, 0xFFFFFFFF); /* Clear all events */
+	out_be32(&im->gpio[1].imr, 0);
+	out_be32(&im->gpio[1].icr, 0);
+#endif
+}
+
+/* Initialize GPIO soft-copies */
+void mpc83xx_gpio_init_r()
+{
+#if MPC83XX_GPIO_CTRLRS >= 1
+	gpio_output_value[0] = CONFIG_MPC83XX_GPIO_0_INIT_VALUE;
+#endif
+
+#if MPC83XX_GPIO_CTRLRS >= 2
+	gpio_output_value[1] = CONFIG_MPC83XX_GPIO_1_INIT_VALUE;
+#endif
+}
diff --git a/drivers/gpio/mvgpio.c b/drivers/gpio/mvgpio.c
index 276f206..c80891c 100644
--- a/drivers/gpio/mvgpio.c
+++ b/drivers/gpio/mvgpio.c
@@ -35,81 +35,79 @@
 #define MV_MAX_GPIO	128
 #endif
 
-int gpio_request(int gp, const char *label)
+int gpio_request(unsigned gpio, const char *label)
 {
-	if (gp >= MV_MAX_GPIO) {
-		printf("%s: Invalid GPIO requested %d\n", __func__, gp);
-		return -EINVAL;
+	if (gpio >= MV_MAX_GPIO) {
+		printf("%s: Invalid GPIO requested %d\n", __func__, gpio);
+		return -1;
 	}
 	return 0;
 }
 
-void gpio_free(int gp)
+int gpio_free(unsigned gpio)
 {
-}
-
-void gpio_toggle_value(int gp)
-{
-	gpio_set_value(gp, !gpio_get_value(gp));
-}
-
-int gpio_direction_input(int gp)
-{
-	struct gpio_reg *gpio_reg_bank;
-
-	if (gp >= MV_MAX_GPIO) {
-		printf("%s: Invalid GPIO %d\n", __func__, gp);
-		return -EINVAL;
-	}
-
-	gpio_reg_bank = get_gpio_base(GPIO_TO_REG(gp));
-	writel(GPIO_TO_BIT(gp), &gpio_reg_bank->gcdr);
 	return 0;
 }
 
-int gpio_direction_output(int gp, int value)
+int gpio_direction_input(unsigned gpio)
 {
 	struct gpio_reg *gpio_reg_bank;
 
-	if (gp >= MV_MAX_GPIO) {
-		printf("%s: Invalid GPIO %d\n", __func__, gp);
-		return -EINVAL;
+	if (gpio >= MV_MAX_GPIO) {
+		printf("%s: Invalid GPIO %d\n", __func__, gpio);
+		return -1;
 	}
 
-	gpio_reg_bank = get_gpio_base(GPIO_TO_REG(gp));
-	writel(GPIO_TO_BIT(gp), &gpio_reg_bank->gsdr);
-	gpio_set_value(gp, value);
+	gpio_reg_bank = get_gpio_base(GPIO_TO_REG(gpio));
+	writel(GPIO_TO_BIT(gpio), &gpio_reg_bank->gcdr);
 	return 0;
 }
 
-int gpio_get_value(int gp)
+int gpio_direction_output(unsigned gpio, int value)
 {
 	struct gpio_reg *gpio_reg_bank;
-	u32 gp_val;
 
-	if (gp >= MV_MAX_GPIO) {
-		printf("%s: Invalid GPIO %d\n", __func__, gp);
-		return -EINVAL;
+	if (gpio >= MV_MAX_GPIO) {
+		printf("%s: Invalid GPIO %d\n", __func__, gpio);
+		return -1;
 	}
 
-	gpio_reg_bank = get_gpio_base(GPIO_TO_REG(gp));
-	gp_val = readl(&gpio_reg_bank->gplr);
-
-	return GPIO_VAL(gp, gp_val);
+	gpio_reg_bank = get_gpio_base(GPIO_TO_REG(gpio));
+	writel(GPIO_TO_BIT(gpio), &gpio_reg_bank->gsdr);
+	gpio_set_value(gpio, value);
+	return 0;
 }
 
-void gpio_set_value(int gp, int value)
+int gpio_get_value(unsigned gpio)
+{
+	struct gpio_reg *gpio_reg_bank;
+	u32 gpio_val;
+
+	if (gpio >= MV_MAX_GPIO) {
+		printf("%s: Invalid GPIO %d\n", __func__, gpio);
+		return -1;
+	}
+
+	gpio_reg_bank = get_gpio_base(GPIO_TO_REG(gpio));
+	gpio_val = readl(&gpio_reg_bank->gplr);
+
+	return GPIO_VAL(gpio, gpio_val);
+}
+
+int gpio_set_value(unsigned gpio, int value)
 {
 	struct gpio_reg *gpio_reg_bank;
 
-	if (gp >= MV_MAX_GPIO) {
-		printf("%s: Invalid GPIO %d\n", __func__, gp);
-		return;
+	if (gpio >= MV_MAX_GPIO) {
+		printf("%s: Invalid GPIO %d\n", __func__, gpio);
+		return -1;
 	}
 
-	gpio_reg_bank = get_gpio_base(GPIO_TO_REG(gp));
+	gpio_reg_bank = get_gpio_base(GPIO_TO_REG(gpio));
 	if (value)
-		writel(GPIO_TO_BIT(gp),	&gpio_reg_bank->gpsr);
+		writel(GPIO_TO_BIT(gpio), &gpio_reg_bank->gpsr);
 	else
-		writel(GPIO_TO_BIT(gp),	&gpio_reg_bank->gpcr);
+		writel(GPIO_TO_BIT(gpio), &gpio_reg_bank->gpcr);
+
+	return 0;
 }
diff --git a/drivers/gpio/mxc_gpio.c b/drivers/gpio/mxc_gpio.c
index 908808d..df6bbbb 100644
--- a/drivers/gpio/mxc_gpio.c
+++ b/drivers/gpio/mxc_gpio.c
@@ -58,7 +58,7 @@
 	u32 l;
 
 	if (port >= ARRAY_SIZE(gpio_ports))
-		return -EINVAL;
+		return -1;
 
 	gpio &= 0x1f;
 
@@ -78,14 +78,14 @@
 	return 0;
 }
 
-void gpio_set_value(int gpio, int value)
+int gpio_set_value(unsigned gpio, int value)
 {
 	unsigned int port = gpio >> 5;
 	struct gpio_regs *regs;
 	u32 l;
 
 	if (port >= ARRAY_SIZE(gpio_ports))
-		return;
+		return -1;
 
 	gpio &= 0x1f;
 
@@ -97,55 +97,53 @@
 	else
 		l &= ~(1 << gpio);
 	writel(l, &regs->gpio_dr);
+
+	return 0;
 }
 
-int gpio_get_value(int gpio)
+int gpio_get_value(unsigned gpio)
 {
 	unsigned int port = gpio >> 5;
 	struct gpio_regs *regs;
-	u32 l;
+	u32 val;
 
 	if (port >= ARRAY_SIZE(gpio_ports))
-		return -EINVAL;
+		return -1;
 
 	gpio &= 0x1f;
 
 	regs = (struct gpio_regs *)gpio_ports[port];
 
-	l = (readl(&regs->gpio_dr) >> gpio) & 0x01;
+	val = (readl(&regs->gpio_dr) >> gpio) & 0x01;
 
-	return l;
+	return val;
 }
 
-int gpio_request(int gp, const char *label)
+int gpio_request(unsigned gpio, const char *label)
 {
-	unsigned int port = gp >> 5;
+	unsigned int port = gpio >> 5;
 	if (port >= ARRAY_SIZE(gpio_ports))
-		return -EINVAL;
+		return -1;
 	return 0;
 }
 
-void gpio_free(int gp)
+int gpio_free(unsigned gpio)
 {
+	return 0;
 }
 
-void gpio_toggle_value(int gp)
+int gpio_direction_input(unsigned gpio)
 {
-	gpio_set_value(gp, !gpio_get_value(gp));
+	return mxc_gpio_direction(gpio, MXC_GPIO_DIRECTION_IN);
 }
 
-int gpio_direction_input(int gp)
+int gpio_direction_output(unsigned gpio, int value)
 {
-	return mxc_gpio_direction(gp, MXC_GPIO_DIRECTION_IN);
-}
-
-int gpio_direction_output(int gp, int value)
-{
-	int ret = mxc_gpio_direction(gp, MXC_GPIO_DIRECTION_OUT);
+	int ret = mxc_gpio_direction(gpio, MXC_GPIO_DIRECTION_OUT);
 
 	if (ret < 0)
 		return ret;
 
-	gpio_set_value(gp, value);
+	gpio_set_value(gpio, value);
 	return 0;
 }
diff --git a/drivers/gpio/mxs_gpio.c b/drivers/gpio/mxs_gpio.c
index 539738b..0365812 100644
--- a/drivers/gpio/mxs_gpio.c
+++ b/drivers/gpio/mxs_gpio.c
@@ -69,68 +69,64 @@
 	}
 }
 
-int gpio_get_value(int gp)
+int gpio_get_value(unsigned gpio)
 {
-	uint32_t bank = PAD_BANK(gp);
+	uint32_t bank = PAD_BANK(gpio);
 	uint32_t offset = PINCTRL_DIN(bank);
 	struct mx28_register *reg =
 		(struct mx28_register *)(MXS_PINCTRL_BASE + offset);
 
-	return (readl(&reg->reg) >> PAD_PIN(gp)) & 1;
+	return (readl(&reg->reg) >> PAD_PIN(gpio)) & 1;
 }
 
-void gpio_set_value(int gp, int value)
+void gpio_set_value(unsigned gpio, int value)
 {
-	uint32_t bank = PAD_BANK(gp);
+	uint32_t bank = PAD_BANK(gpio);
 	uint32_t offset = PINCTRL_DOUT(bank);
 	struct mx28_register *reg =
 		(struct mx28_register *)(MXS_PINCTRL_BASE + offset);
 
 	if (value)
-		writel(1 << PAD_PIN(gp), &reg->reg_set);
+		writel(1 << PAD_PIN(gpio), &reg->reg_set);
 	else
-		writel(1 << PAD_PIN(gp), &reg->reg_clr);
+		writel(1 << PAD_PIN(gpio), &reg->reg_clr);
 }
 
-int gpio_direction_input(int gp)
+int gpio_direction_input(unsigned gpio)
 {
-	uint32_t bank = PAD_BANK(gp);
+	uint32_t bank = PAD_BANK(gpio);
 	uint32_t offset = PINCTRL_DOE(bank);
 	struct mx28_register *reg =
 		(struct mx28_register *)(MXS_PINCTRL_BASE + offset);
 
-	writel(1 << PAD_PIN(gp), &reg->reg_clr);
+	writel(1 << PAD_PIN(gpio), &reg->reg_clr);
 
 	return 0;
 }
 
-int gpio_direction_output(int gp, int value)
+int gpio_direction_output(unsigned gpio, int value)
 {
-	uint32_t bank = PAD_BANK(gp);
+	uint32_t bank = PAD_BANK(gpio);
 	uint32_t offset = PINCTRL_DOE(bank);
 	struct mx28_register *reg =
 		(struct mx28_register *)(MXS_PINCTRL_BASE + offset);
 
-	writel(1 << PAD_PIN(gp), &reg->reg_set);
+	writel(1 << PAD_PIN(gpio), &reg->reg_set);
 
-	gpio_set_value(gp, value);
+	gpio_set_value(gpio, value);
 
 	return 0;
 }
 
-int gpio_request(int gp, const char *label)
+int gpio_request(unsigned gpio, const char *label)
 {
-	if (PAD_BANK(gp) >= PINCTRL_BANKS)
-		return -EINVAL;
+	if (PAD_BANK(gpio) >= PINCTRL_BANKS)
+		return -1;
 
 	return 0;
 }
 
-void gpio_free(int gp)
+int gpio_free(unsigned gpio)
 {
-}
-
-void gpio_toggle_value(int gp)
-{
-	gpio_set_value(gp, !gpio_get_value(gp));
+	return 0;
 }
diff --git a/drivers/gpio/s5p_gpio.c b/drivers/gpio/s5p_gpio.c
index 1edf9a2..47f3213 100644
--- a/drivers/gpio/s5p_gpio.c
+++ b/drivers/gpio/s5p_gpio.c
@@ -20,7 +20,7 @@
 
 #include <common.h>
 #include <asm/io.h>
-#include <asm/arch/gpio.h>
+#include <asm/gpio.h>
 
 #define CON_MASK(x)		(0xf << ((x) << 2))
 #define CON_SFR(x, v)		((v) << ((x) << 2))
@@ -142,46 +142,55 @@
 	writel(value, &bank->drv);
 }
 
-struct s5p_gpio_bank *s5p_gpio_get_bank(int nr)
+struct s5p_gpio_bank *s5p_gpio_get_bank(unsigned gpio)
 {
-	int bank = nr / GPIO_PER_BANK;
+	int bank = gpio / GPIO_PER_BANK;
 	bank *= sizeof(struct s5p_gpio_bank);
 
-	return (struct s5p_gpio_bank *) (s5p_gpio_base(nr) + bank);
+	return (struct s5p_gpio_bank *) (s5p_gpio_base(gpio) + bank);
 }
 
-int s5p_gpio_get_pin(int nr)
+int s5p_gpio_get_pin(unsigned gpio)
 {
-	return nr % GPIO_PER_BANK;
+	return gpio % GPIO_PER_BANK;
 }
 
-int gpio_request(int gpio, const char *label)
+/* Common GPIO API */
+
+int gpio_request(unsigned gpio, const char *label)
 {
 	return 0;
 }
 
-int gpio_direction_input(int nr)
+int gpio_free(unsigned gpio)
 {
-	s5p_gpio_direction_input(s5p_gpio_get_bank(nr),
-				s5p_gpio_get_pin(nr));
 	return 0;
 }
 
-int gpio_direction_output(int nr, int value)
+int gpio_direction_input(unsigned gpio)
 {
-	s5p_gpio_direction_output(s5p_gpio_get_bank(nr),
-				 s5p_gpio_get_pin(nr), value);
+	s5p_gpio_direction_input(s5p_gpio_get_bank(gpio),
+				s5p_gpio_get_pin(gpio));
 	return 0;
 }
 
-int gpio_get_value(int nr)
+int gpio_direction_output(unsigned gpio, int value)
 {
-	return (int) s5p_gpio_get_value(s5p_gpio_get_bank(nr),
-				       s5p_gpio_get_pin(nr));
+	s5p_gpio_direction_output(s5p_gpio_get_bank(gpio),
+				 s5p_gpio_get_pin(gpio), value);
+	return 0;
 }
 
-void gpio_set_value(int nr, int value)
+int gpio_get_value(unsigned gpio)
 {
-	s5p_gpio_set_value(s5p_gpio_get_bank(nr),
-			  s5p_gpio_get_pin(nr), value);
+	return (int) s5p_gpio_get_value(s5p_gpio_get_bank(gpio),
+				       s5p_gpio_get_pin(gpio));
+}
+
+int gpio_set_value(unsigned gpio, int value)
+{
+	s5p_gpio_set_value(s5p_gpio_get_bank(gpio),
+			  s5p_gpio_get_pin(gpio), value);
+
+	return 0;
 }
diff --git a/drivers/gpio/tegra2_gpio.c b/drivers/gpio/tegra2_gpio.c
index 22669b6..70ca46f 100644
--- a/drivers/gpio/tegra2_gpio.c
+++ b/drivers/gpio/tegra2_gpio.c
@@ -49,188 +49,192 @@
 	return *gpio_names[i].name ? gpio_names[i].name : "UNKNOWN";
 }
 
-/* Return config of pin 'gp' as GPIO (1) or SFPIO (0) */
-static int get_config(int gp)
+/* Return config of pin 'gpio' as GPIO (1) or SFPIO (0) */
+static int get_config(unsigned gpio)
 {
-	struct gpio_ctlr *gpio = (struct gpio_ctlr *)NV_PA_GPIO_BASE;
-	struct gpio_ctlr_bank *bank = &gpio->gpio_bank[GPIO_BANK(gp)];
+	struct gpio_ctlr *ctlr = (struct gpio_ctlr *)NV_PA_GPIO_BASE;
+	struct gpio_ctlr_bank *bank = &ctlr->gpio_bank[GPIO_BANK(gpio)];
 	u32 u;
 	int type;
 
-	u = readl(&bank->gpio_config[GPIO_PORT(gp)]);
-	type =  (u >> GPIO_BIT(gp)) & 1;
+	u = readl(&bank->gpio_config[GPIO_PORT(gpio)]);
+	type =  (u >> GPIO_BIT(gpio)) & 1;
 
 	debug("get_config: port = %d, bit = %d is %s\n",
-		GPIO_FULLPORT(gp), GPIO_BIT(gp), type ? "GPIO" : "SFPIO");
+		GPIO_FULLPORT(gpio), GPIO_BIT(gpio), type ? "GPIO" : "SFPIO");
 
 	return type;
 }
 
-/* Config pin 'gp' as GPIO or SFPIO, based on 'type' */
-static void set_config(int gp, int type)
+/* Config pin 'gpio' as GPIO or SFPIO, based on 'type' */
+static void set_config(unsigned gpio, int type)
 {
-	struct gpio_ctlr *gpio = (struct gpio_ctlr *)NV_PA_GPIO_BASE;
-	struct gpio_ctlr_bank *bank = &gpio->gpio_bank[GPIO_BANK(gp)];
+	struct gpio_ctlr *ctlr = (struct gpio_ctlr *)NV_PA_GPIO_BASE;
+	struct gpio_ctlr_bank *bank = &ctlr->gpio_bank[GPIO_BANK(gpio)];
 	u32 u;
 
 	debug("set_config: port = %d, bit = %d, %s\n",
-		GPIO_FULLPORT(gp), GPIO_BIT(gp), type ? "GPIO" : "SFPIO");
+		GPIO_FULLPORT(gpio), GPIO_BIT(gpio), type ? "GPIO" : "SFPIO");
 
-	u = readl(&bank->gpio_config[GPIO_PORT(gp)]);
+	u = readl(&bank->gpio_config[GPIO_PORT(gpio)]);
 	if (type)				/* GPIO */
-		u |= 1 << GPIO_BIT(gp);
+		u |= 1 << GPIO_BIT(gpio);
 	else
-		u &= ~(1 << GPIO_BIT(gp));
-	writel(u, &bank->gpio_config[GPIO_PORT(gp)]);
+		u &= ~(1 << GPIO_BIT(gpio));
+	writel(u, &bank->gpio_config[GPIO_PORT(gpio)]);
 }
 
-/* Return GPIO pin 'gp' direction - 0 = input or 1 = output */
-static int get_direction(int gp)
+/* Return GPIO pin 'gpio' direction - 0 = input or 1 = output */
+static int get_direction(unsigned gpio)
 {
-	struct gpio_ctlr *gpio = (struct gpio_ctlr *)NV_PA_GPIO_BASE;
-	struct gpio_ctlr_bank *bank = &gpio->gpio_bank[GPIO_BANK(gp)];
+	struct gpio_ctlr *ctlr = (struct gpio_ctlr *)NV_PA_GPIO_BASE;
+	struct gpio_ctlr_bank *bank = &ctlr->gpio_bank[GPIO_BANK(gpio)];
 	u32 u;
 	int dir;
 
-	u = readl(&bank->gpio_dir_out[GPIO_PORT(gp)]);
-	dir =  (u >> GPIO_BIT(gp)) & 1;
+	u = readl(&bank->gpio_dir_out[GPIO_PORT(gpio)]);
+	dir =  (u >> GPIO_BIT(gpio)) & 1;
 
 	debug("get_direction: port = %d, bit = %d, %s\n",
-		GPIO_FULLPORT(gp), GPIO_BIT(gp), dir ? "OUT" : "IN");
+		GPIO_FULLPORT(gpio), GPIO_BIT(gpio), dir ? "OUT" : "IN");
 
 	return dir;
 }
 
-/* Config GPIO pin 'gp' as input or output (OE) as per 'output' */
-static void set_direction(int gp, int output)
+/* Config GPIO pin 'gpio' as input or output (OE) as per 'output' */
+static void set_direction(unsigned gpio, int output)
 {
-	struct gpio_ctlr *gpio = (struct gpio_ctlr *)NV_PA_GPIO_BASE;
-	struct gpio_ctlr_bank *bank = &gpio->gpio_bank[GPIO_BANK(gp)];
+	struct gpio_ctlr *ctlr = (struct gpio_ctlr *)NV_PA_GPIO_BASE;
+	struct gpio_ctlr_bank *bank = &ctlr->gpio_bank[GPIO_BANK(gpio)];
 	u32 u;
 
 	debug("set_direction: port = %d, bit = %d, %s\n",
-		GPIO_FULLPORT(gp), GPIO_BIT(gp), output ? "OUT" : "IN");
+		GPIO_FULLPORT(gpio), GPIO_BIT(gpio), output ? "OUT" : "IN");
 
-	u = readl(&bank->gpio_dir_out[GPIO_PORT(gp)]);
+	u = readl(&bank->gpio_dir_out[GPIO_PORT(gpio)]);
 	if (output)
-		u |= 1 << GPIO_BIT(gp);
+		u |= 1 << GPIO_BIT(gpio);
 	else
-		u &= ~(1 << GPIO_BIT(gp));
-	writel(u, &bank->gpio_dir_out[GPIO_PORT(gp)]);
+		u &= ~(1 << GPIO_BIT(gpio));
+	writel(u, &bank->gpio_dir_out[GPIO_PORT(gpio)]);
 }
 
-/* set GPIO pin 'gp' output bit as 0 or 1 as per 'high' */
-static void set_level(int gp, int high)
+/* set GPIO pin 'gpio' output bit as 0 or 1 as per 'high' */
+static void set_level(unsigned gpio, int high)
 {
-	struct gpio_ctlr *gpio = (struct gpio_ctlr *)NV_PA_GPIO_BASE;
-	struct gpio_ctlr_bank *bank = &gpio->gpio_bank[GPIO_BANK(gp)];
+	struct gpio_ctlr *ctlr = (struct gpio_ctlr *)NV_PA_GPIO_BASE;
+	struct gpio_ctlr_bank *bank = &ctlr->gpio_bank[GPIO_BANK(gpio)];
 	u32 u;
 
 	debug("set_level: port = %d, bit %d == %d\n",
-		GPIO_FULLPORT(gp), GPIO_BIT(gp), high);
+		GPIO_FULLPORT(gpio), GPIO_BIT(gpio), high);
 
-	u = readl(&bank->gpio_out[GPIO_PORT(gp)]);
+	u = readl(&bank->gpio_out[GPIO_PORT(gpio)]);
 	if (high)
-		u |= 1 << GPIO_BIT(gp);
+		u |= 1 << GPIO_BIT(gpio);
 	else
-		u &= ~(1 << GPIO_BIT(gp));
-	writel(u, &bank->gpio_out[GPIO_PORT(gp)]);
+		u &= ~(1 << GPIO_BIT(gpio));
+	writel(u, &bank->gpio_out[GPIO_PORT(gpio)]);
 }
 
 /*
  * Generic_GPIO primitives.
  */
 
-int gpio_request(int gp, const char *label)
+int gpio_request(unsigned gpio, const char *label)
 {
-	if (gp >= MAX_NUM_GPIOS)
+	if (gpio >= MAX_NUM_GPIOS)
 		return -1;
 
 	if (label != NULL) {
-		strncpy(gpio_names[gp].name, label, GPIO_NAME_SIZE);
-		gpio_names[gp].name[GPIO_NAME_SIZE - 1] = '\0';
+		strncpy(gpio_names[gpio].name, label, GPIO_NAME_SIZE);
+		gpio_names[gpio].name[GPIO_NAME_SIZE - 1] = '\0';
 	}
 
 	/* Configure as a GPIO */
-	set_config(gp, 1);
+	set_config(gpio, 1);
 
 	return 0;
 }
 
-void gpio_free(int gp)
+int gpio_free(unsigned gpio)
 {
+	if (gpio >= MAX_NUM_GPIOS)
+		return -1;
+
+	gpio_names[gpio].name[0] = '\0';
+	/* Do not configure as input or change pin mux here */
+	return 0;
 }
 
-/* read GPIO OUT value of pin 'gp' */
-static int gpio_get_output_value(int gp)
+/* read GPIO OUT value of pin 'gpio' */
+static int gpio_get_output_value(unsigned gpio)
 {
-	struct gpio_ctlr *gpio = (struct gpio_ctlr *)NV_PA_GPIO_BASE;
-	struct gpio_ctlr_bank *bank = &gpio->gpio_bank[GPIO_BANK(gp)];
+	struct gpio_ctlr *ctlr = (struct gpio_ctlr *)NV_PA_GPIO_BASE;
+	struct gpio_ctlr_bank *bank = &ctlr->gpio_bank[GPIO_BANK(gpio)];
 	int val;
 
 	debug("gpio_get_output_value: pin = %d (port %d:bit %d)\n",
-		gp, GPIO_FULLPORT(gp), GPIO_BIT(gp));
+		gpio, GPIO_FULLPORT(gpio), GPIO_BIT(gpio));
 
-	val = readl(&bank->gpio_out[GPIO_PORT(gp)]);
+	val = readl(&bank->gpio_out[GPIO_PORT(gpio)]);
 
-	return (val >> GPIO_BIT(gp)) & 1;
+	return (val >> GPIO_BIT(gpio)) & 1;
 }
 
-void gpio_toggle_value(int gp)
-{
-	gpio_set_value(gp, !gpio_get_output_value(gp));
-}
-
-/* set GPIO pin 'gp' as an input */
-int gpio_direction_input(int gp)
+/* set GPIO pin 'gpio' as an input */
+int gpio_direction_input(unsigned gpio)
 {
 	debug("gpio_direction_input: pin = %d (port %d:bit %d)\n",
-		gp, GPIO_FULLPORT(gp), GPIO_BIT(gp));
+		gpio, GPIO_FULLPORT(gpio), GPIO_BIT(gpio));
 
 	/* Configure GPIO direction as input. */
-	set_direction(gp, 0);
+	set_direction(gpio, 0);
 
 	return 0;
 }
 
-/* set GPIO pin 'gp' as an output, with polarity 'value' */
-int gpio_direction_output(int gp, int value)
+/* set GPIO pin 'gpio' as an output, with polarity 'value' */
+int gpio_direction_output(unsigned gpio, int value)
 {
 	debug("gpio_direction_output: pin = %d (port %d:bit %d) = %s\n",
-		gp, GPIO_FULLPORT(gp), GPIO_BIT(gp), value ? "HIGH" : "LOW");
+		gpio, GPIO_FULLPORT(gpio), GPIO_BIT(gpio),
+		value ? "HIGH" : "LOW");
 
 	/* Configure GPIO output value. */
-	set_level(gp, value);
+	set_level(gpio, value);
 
 	/* Configure GPIO direction as output. */
-	set_direction(gp, 1);
+	set_direction(gpio, 1);
 
 	return 0;
 }
 
-/* read GPIO IN value of pin 'gp' */
-int gpio_get_value(int gp)
+/* read GPIO IN value of pin 'gpio' */
+int gpio_get_value(unsigned gpio)
 {
-	struct gpio_ctlr *gpio = (struct gpio_ctlr *)NV_PA_GPIO_BASE;
-	struct gpio_ctlr_bank *bank = &gpio->gpio_bank[GPIO_BANK(gp)];
+	struct gpio_ctlr *ctlr = (struct gpio_ctlr *)NV_PA_GPIO_BASE;
+	struct gpio_ctlr_bank *bank = &ctlr->gpio_bank[GPIO_BANK(gpio)];
 	int val;
 
 	debug("gpio_get_value: pin = %d (port %d:bit %d)\n",
-		gp, GPIO_FULLPORT(gp), GPIO_BIT(gp));
+		gpio, GPIO_FULLPORT(gpio), GPIO_BIT(gpio));
 
-	val = readl(&bank->gpio_in[GPIO_PORT(gp)]);
+	val = readl(&bank->gpio_in[GPIO_PORT(gpio)]);
 
-	return (val >> GPIO_BIT(gp)) & 1;
+	return (val >> GPIO_BIT(gpio)) & 1;
 }
 
-/* write GPIO OUT value to pin 'gp' */
-void gpio_set_value(int gp, int value)
+/* write GPIO OUT value to pin 'gpio' */
+int gpio_set_value(unsigned gpio, int value)
 {
 	debug("gpio_set_value: pin = %d (port %d:bit %d), value = %d\n",
-		gp, GPIO_FULLPORT(gp), GPIO_BIT(gp), value);
+		gpio, GPIO_FULLPORT(gpio), GPIO_BIT(gpio), value);
 
 	/* Configure GPIO output value. */
-	set_level(gp, value);
+	set_level(gpio, value);
+
+	return 0;
 }
 
 /*
@@ -238,7 +242,8 @@
  */
 void gpio_info(void)
 {
-	int c, type;
+	unsigned c;
+	int type;
 
 	for (c = 0; c < MAX_NUM_GPIOS; c++) {
 		type = get_config(c);		/* GPIO, not SFPIO */
diff --git a/drivers/mmc/arm_pl180_mmci.c b/drivers/mmc/arm_pl180_mmci.c
index e6467a2..09d443e 100644
--- a/drivers/mmc/arm_pl180_mmci.c
+++ b/drivers/mmc/arm_pl180_mmci.c
@@ -385,6 +385,7 @@
 	dev->send_cmd = host_request;
 	dev->set_ios = host_set_ios;
 	dev->init = mmc_host_reset;
+	dev->getcd = NULL;
 	dev->host_caps = 0;
 	dev->voltages = VOLTAGE_WINDOW_MMC;
 	dev->f_min = dev->clock;
diff --git a/drivers/mmc/bfin_sdh.c b/drivers/mmc/bfin_sdh.c
index bc9057f..08fc5c1 100644
--- a/drivers/mmc/bfin_sdh.c
+++ b/drivers/mmc/bfin_sdh.c
@@ -250,6 +250,7 @@
 	mmc->send_cmd = bfin_sdh_request;
 	mmc->set_ios = bfin_sdh_set_ios;
 	mmc->init = bfin_sdh_init;
+	mmc->getcd = NULL;
 	mmc->host_caps = MMC_MODE_4BIT;
 
 	mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
diff --git a/drivers/mmc/davinci_mmc.c b/drivers/mmc/davinci_mmc.c
index ce96736..ee8f261 100644
--- a/drivers/mmc/davinci_mmc.c
+++ b/drivers/mmc/davinci_mmc.c
@@ -387,6 +387,7 @@
 	mmc->send_cmd = dmmc_send_cmd;
 	mmc->set_ios = dmmc_set_ios;
 	mmc->init = dmmc_init;
+	mmc->getcd = NULL;
 
 	mmc->f_min = 200000;
 	mmc->f_max = 25000000;
diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c
index ec953f0..a2f35e3 100644
--- a/drivers/mmc/fsl_esdhc.c
+++ b/drivers/mmc/fsl_esdhc.c
@@ -58,7 +58,8 @@
 	uint	autoc12err;
 	uint	hostcapblt;
 	uint	wml;
-	char	reserved1[8];
+	uint    mixctrl;
+	char    reserved1[4];
 	uint	fevt;
 	char	reserved2[168];
 	uint	hostver;
@@ -113,7 +114,8 @@
 static void
 esdhc_pio_read_write(struct mmc *mmc, struct mmc_data *data)
 {
-	struct fsl_esdhc *regs = mmc->priv;
+	struct fsl_esdhc_cfg *cfg = mmc->priv;
+	struct fsl_esdhc *regs = (struct fsl_esdhc *)cfg->esdhc_base;
 	uint blocks;
 	char *buffer;
 	uint databuf;
@@ -298,8 +300,13 @@
 
 	/* Send the command */
 	esdhc_write32(&regs->cmdarg, cmd->cmdarg);
+#if defined(CONFIG_FSL_USDHC)
+	esdhc_write32(&regs->mixctrl,
+	(esdhc_read32(&regs->mixctrl) & 0xFFFFFF80) | (xfertyp & 0x7F));
+	esdhc_write32(&regs->xfertyp, xfertyp & 0xFFFF0000);
+#else
 	esdhc_write32(&regs->xfertyp, xfertyp);
-
+#endif
 	/* Wait for the command to complete */
 	while (!(esdhc_read32(&regs->irqstat) & IRQSTAT_CC))
 		;
@@ -412,8 +419,6 @@
 	struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
 	struct fsl_esdhc *regs = (struct fsl_esdhc *)cfg->esdhc_base;
 	int timeout = 1000;
-	int ret = 0;
-	u8 card_absent;
 
 	/* Reset the entire host controller */
 	esdhc_write32(&regs->sysctl, SYSCTL_RSTA);
@@ -440,21 +445,19 @@
 	/* Set timout to the maximum value */
 	esdhc_clrsetbits32(&regs->sysctl, SYSCTL_TIMEOUT_MASK, 14 << 16);
 
-	/* Check if there is a callback for detecting the card */
-	if (board_mmc_getcd(&card_absent, mmc)) {
-		timeout = 1000;
-		while (!(esdhc_read32(&regs->prsstat) & PRSSTAT_CINS) &&
-				--timeout)
-			udelay(1000);
+	return 0;
+}
 
-		if (timeout <= 0)
-			ret = NO_CARD_ERR;
-	} else {
-		if (card_absent)
-			ret = NO_CARD_ERR;
-	}
+static int esdhc_getcd(struct mmc *mmc)
+{
+	struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
+	struct fsl_esdhc *regs = (struct fsl_esdhc *)cfg->esdhc_base;
+	int timeout = 1000;
 
-	return ret;
+	while (!(esdhc_read32(&regs->prsstat) & PRSSTAT_CINS) && --timeout)
+		udelay(1000);
+
+	return timeout > 0;
 }
 
 static void esdhc_reset(struct fsl_esdhc *regs)
@@ -482,7 +485,7 @@
 
 	mmc = malloc(sizeof(struct mmc));
 
-	sprintf(mmc->name, "FSL_ESDHC");
+	sprintf(mmc->name, "FSL_SDHC");
 	regs = (struct fsl_esdhc *)cfg->esdhc_base;
 
 	/* First reset the eSDHC controller */
@@ -492,6 +495,7 @@
 	mmc->send_cmd = esdhc_send_cmd;
 	mmc->set_ios = esdhc_set_ios;
 	mmc->init = esdhc_init;
+	mmc->getcd = esdhc_getcd;
 
 	voltage_caps = 0;
 	caps = regs->hostcapblt;
diff --git a/drivers/mmc/ftsdc010_esdhc.c b/drivers/mmc/ftsdc010_esdhc.c
index e38dd87..f1702fe 100644
--- a/drivers/mmc/ftsdc010_esdhc.c
+++ b/drivers/mmc/ftsdc010_esdhc.c
@@ -90,8 +90,13 @@
 
 	while (size) {
 		status = readl(&host->reg->status);
+		debug("%s: size: %08x\n", __func__, size);
 
 		if (status & FTSDC010_STATUS_FIFO_ORUN) {
+
+			debug("%s: FIFO OVERRUN: sta: %08x\n",
+					__func__, status);
+
 			fifo = host->fifo_len > size ?
 				size : host->fifo_len;
 
@@ -146,7 +151,7 @@
 	while (size) {
 		status = readl(&host->reg->status);
 
-		if (status & FTSDC010_STATUS_FIFO_ORUN) {
+		if (status & FTSDC010_STATUS_FIFO_URUN) {
 			fifo = host->fifo_len > size ?
 				size : host->fifo_len;
 
@@ -158,7 +163,6 @@
 				writel(*ptr, &host->reg->dwr);
 				ptr++;
 			}
-
 		} else {
 			udelay(1);
 			if (++retry >= FTSDC010_PIO_RETRY) {
@@ -169,56 +173,19 @@
 	}
 }
 
-static int ftsdc010_pio_check_status(struct mmc *mmc, struct mmc_cmd *cmd,
+static int ftsdc010_check_rsp(struct mmc *mmc, struct mmc_cmd *cmd,
 			struct mmc_data *data)
 {
 	struct mmc_host *host = mmc->priv;
-
 	unsigned int sta, clear;
-	unsigned int i;
 
-	/* check response and hardware status */
-	clear = 0;
-
-	/* chech CMD_SEND */
-	for (i = 0; i < FTSDC010_CMD_RETRY; i++) {
-		sta = readl(&host->reg->status);
-		/* Command Complete */
-		if (sta & FTSDC010_STATUS_CMD_SEND) {
-			if (!data)
-				clear |= FTSDC010_CLR_CMD_SEND;
-			break;
-		}
-	}
-
-	if (i > FTSDC010_CMD_RETRY) {
-		printf("%s: send command timeout\n", __func__);
-		return TIMEOUT;
-	}
-
-	/* debug: print status register and command index*/
-	debug("sta: %08x cmd %d\n", sta, cmd->cmdidx);
-
-	/* handle data FIFO */
-	if ((sta & FTSDC010_STATUS_FIFO_ORUN) ||
-		(sta & FTSDC010_STATUS_FIFO_URUN)) {
-
-		/* Wrong DATA FIFO Flag */
-		if (data == NULL)
-			printf("%s, data fifo wrong: sta: %08x cmd %d\n",
-				__func__, sta, cmd->cmdidx);
-
-		if (sta & FTSDC010_STATUS_FIFO_ORUN)
-			clear |= FTSDC010_STATUS_FIFO_ORUN;
-		if (sta & FTSDC010_STATUS_FIFO_URUN)
-			clear |= FTSDC010_STATUS_FIFO_URUN;
-	}
+	sta = readl(&host->reg->status);
+	debug("%s: sta: %08x cmd %d\n", __func__, sta, cmd->cmdidx);
 
 	/* check RSP TIMEOUT or FAIL */
 	if (sta & FTSDC010_STATUS_RSP_TIMEOUT) {
 		/* RSP TIMEOUT */
-		debug("%s: RSP timeout: sta: %08x cmd %d\n",
-				__func__, sta, cmd->cmdidx);
+		debug("%s: RSP timeout: sta: %08x\n", __func__, sta);
 
 		clear |= FTSDC010_CLR_RSP_TIMEOUT;
 		writel(clear, &host->reg->clr);
@@ -226,47 +193,62 @@
 		return TIMEOUT;
 	} else if (sta & FTSDC010_STATUS_RSP_CRC_FAIL) {
 		/* clear response fail bit */
-		debug("%s: RSP CRC FAIL: sta: %08x cmd %d\n",
-				__func__, sta, cmd->cmdidx);
+		debug("%s: RSP CRC FAIL: sta: %08x\n", __func__, sta);
 
 		clear |= FTSDC010_CLR_RSP_CRC_FAIL;
 		writel(clear, &host->reg->clr);
 
-		return 0;
+		return COMM_ERR;
 	} else if (sta & FTSDC010_STATUS_RSP_CRC_OK) {
 
 		/* clear response CRC OK bit */
 		clear |= FTSDC010_CLR_RSP_CRC_OK;
 	}
 
+	writel(clear, &host->reg->clr);
+	return 0;
+}
+
+static int ftsdc010_check_data(struct mmc *mmc, struct mmc_cmd *cmd,
+			struct mmc_data *data)
+{
+	struct mmc_host *host = mmc->priv;
+	unsigned int sta, clear;
+
+	sta = readl(&host->reg->status);
+	debug("%s: sta: %08x cmd %d\n", __func__, sta, cmd->cmdidx);
+
 	/* check DATA TIMEOUT or FAIL */
 	if (data) {
+
+		/* Transfer Complete */
+		if (sta & FTSDC010_STATUS_DATA_END)
+			clear |= FTSDC010_STATUS_DATA_END;
+
+		/* Data CRC_OK */
+		if (sta & FTSDC010_STATUS_DATA_CRC_OK)
+			clear |= FTSDC010_STATUS_DATA_CRC_OK;
+
+		/* DATA TIMEOUT or DATA CRC FAIL */
 		if (sta & FTSDC010_STATUS_DATA_TIMEOUT) {
 			/* DATA TIMEOUT */
-			debug("%s: DATA TIMEOUT: sta: %08x\n",
-					__func__, sta);
+			debug("%s: DATA TIMEOUT: sta: %08x\n", __func__, sta);
 
 			clear |= FTSDC010_STATUS_DATA_TIMEOUT;
-			writel(sta, &host->reg->clr);
+			writel(clear, &host->reg->clr);
+
 			return TIMEOUT;
 		} else if (sta & FTSDC010_STATUS_DATA_CRC_FAIL) {
-			/* Error Interrupt */
-			debug("%s: DATA CRC FAIL: sta: %08x\n",
-					__func__, sta);
+			/* DATA CRC FAIL */
+			debug("%s: DATA CRC FAIL: sta: %08x\n", __func__, sta);
 
 			clear |= FTSDC010_STATUS_DATA_CRC_FAIL;
 			writel(clear, &host->reg->clr);
 
-			return 0;
-		} else if (sta & FTSDC010_STATUS_DATA_END) {
-			/* Transfer Complete */
-			clear |= FTSDC010_STATUS_DATA_END;
+			return COMM_ERR;
 		}
+		writel(clear, &host->reg->clr);
 	}
-
-	/* transaction is success and clear status register */
-	writel(clear, &host->reg->clr);
-
 	return 0;
 }
 
@@ -281,6 +263,9 @@
 	unsigned int ccon;
 	unsigned int mask, tmpmask;
 	unsigned int ret;
+	unsigned int sta, i;
+
+	ret = 0;
 
 	if (data)
 		mask = FTSDC010_INT_MASK_RSP_TIMEOUT;
@@ -290,13 +275,9 @@
 		mask = FTSDC010_INT_MASK_CMD_SEND;
 
 	/* write argu reg */
-	debug("%s: cmd->arg: %08x\n", __func__, cmd->cmdarg);
+	debug("%s: argu: %08x\n", __func__, host->reg->argu);
 	writel(cmd->cmdarg, &host->reg->argu);
 
-	/* setup cmd reg */
-	debug("cmd: %d\n", cmd->cmdidx);
-	debug("resp: %08x\n", cmd->resp_type);
-
 	/* setup commnad */
 	ccon = FTSDC010_CMD_IDX(cmd->cmdidx);
 
@@ -340,7 +321,51 @@
 	/* write cmd reg */
 	debug("%s: ccon: %08x\n", __func__, ccon);
 	writel(ccon, &host->reg->cmd);
-	udelay(4*FTSDC010_DELAY_UNIT);
+
+	/* check CMD_SEND */
+	for (i = 0; i < FTSDC010_CMD_RETRY; i++) {
+		/*
+		 * If we read status register too fast
+		 * will lead hardware error and the RSP_TIMEOUT
+		 * flag will be raised incorrectly.
+		 */
+		udelay(16*FTSDC010_DELAY_UNIT);
+		sta = readl(&host->reg->status);
+
+		/* Command Complete */
+		/*
+		 * Note:
+		 *	Do not clear FTSDC010_CLR_CMD_SEND flag.
+		 *	(by writing FTSDC010_CLR_CMD_SEND bit to clear register)
+		 *	It will make the driver becomes very slow.
+		 *	If the operation hasn't been finished, hardware will
+		 *	clear this bit automatically.
+		 *	In origin, the driver will clear this flag if there is
+		 *	no data need to be read.
+		 */
+		if (sta & FTSDC010_STATUS_CMD_SEND)
+			break;
+	}
+
+	if (i > FTSDC010_CMD_RETRY) {
+		printf("%s: send command timeout\n", __func__);
+		return TIMEOUT;
+	}
+
+	/* check rsp status */
+	ret = ftsdc010_check_rsp(mmc, cmd, data);
+	if (ret)
+		return ret;
+
+	/* read response if we have RSP_OK */
+	if (ccon & FTSDC010_CMD_LONG_RSP) {
+		cmd->response[0] = readl(&host->reg->rsp3);
+		cmd->response[1] = readl(&host->reg->rsp2);
+		cmd->response[2] = readl(&host->reg->rsp1);
+		cmd->response[3] = readl(&host->reg->rsp0);
+	} else {
+		cmd->response[0] = readl(&host->reg->rsp0);
+	}
 
 	/* read/write data */
 	if (data && (data->flags & MMC_DATA_READ)) {
@@ -351,19 +376,11 @@
 				data->blocksize * data->blocks);
 	}
 
-	/* pio check response status */
-	ret = ftsdc010_pio_check_status(mmc, cmd, data);
-	if (!ret) {
-		/* if it is long response */
-		if (ccon & FTSDC010_CMD_LONG_RSP) {
-			cmd->response[0] = readl(&host->reg->rsp3);
-			cmd->response[1] = readl(&host->reg->rsp2);
-			cmd->response[2] = readl(&host->reg->rsp1);
-			cmd->response[3] = readl(&host->reg->rsp0);
-
-		} else {
-			cmd->response[0] = readl(&host->reg->rsp0);
-		}
+	/* check data status */
+	if (data) {
+		ret = ftsdc010_check_data(mmc, cmd, data);
+		if (ret)
+			return ret;
 	}
 
 	udelay(FTSDC010_DELAY_UNIT);
@@ -431,8 +448,6 @@
 	/* always reset fifo since last transfer may fail */
 	dcon |= FTSDC010_DCR_FIFO_RST;
 
-	/* handle sdio */
-	dcon = data->blocksize | data->blocks << 15;
 	if (data->blocks > 1)
 		dcon |= FTSDC010_SDIO_CTRL1_SDIO_BLK_MODE;
 #endif
@@ -497,7 +512,7 @@
 {
 	struct mmc_host *host = mmc->priv;
 	unsigned char clk_div;
-	unsigned char real_rate;
+	unsigned int real_rate;
 	unsigned int clock;
 
 	debug("%s: mmc_set_clock: %x\n", __func__, mmc->clock);
@@ -518,7 +533,7 @@
 				break;
 		}
 
-		debug("%s: computed real_rete: %x, clk_div: %x\n",
+		debug("%s: computed real_rate: %x, clk_div: %x\n",
 			 __func__, real_rate, clk_div);
 
 		if (clk_div > 127)
@@ -579,6 +594,7 @@
 static void ftsdc010_reset(struct mmc_host *host)
 {
 	unsigned int timeout;
+	unsigned int sta;
 
 	/* Do SDC_RST: Software reset for all register */
 	writel(FTSDC010_CMD_SDC_RST, &host->reg->cmd);
@@ -598,6 +614,10 @@
 		timeout--;
 		udelay(10*FTSDC010_DELAY_UNIT);
 	}
+
+	sta = readl(&host->reg->status);
+	if (sta & FTSDC010_STATUS_CARD_CHANGE)
+		writel(FTSDC010_CLR_CARD_CHANGE, &host->reg->clr);
 }
 
 static int ftsdc010_core_init(struct mmc *mmc)
@@ -645,13 +665,12 @@
 	mmc->send_cmd = ftsdc010_request;
 	mmc->set_ios = ftsdc010_set_ios;
 	mmc->init = ftsdc010_core_init;
+	mmc->getcd = NULL;
 
 	mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
 
 	mmc->host_caps = MMC_MODE_4BIT | MMC_MODE_8BIT;
 
-	mmc->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
-
 	mmc->f_min = CONFIG_SYS_CLK_FREQ / 2 / (2*128);
 	mmc->f_max = CONFIG_SYS_CLK_FREQ / 2 / 2;
 
diff --git a/drivers/mmc/gen_atmel_mci.c b/drivers/mmc/gen_atmel_mci.c
index f346b24..4968c5e 100644
--- a/drivers/mmc/gen_atmel_mci.c
+++ b/drivers/mmc/gen_atmel_mci.c
@@ -337,6 +337,7 @@
 	mmc->send_cmd = mci_send_cmd;
 	mmc->set_ios = mci_set_ios;
 	mmc->init = mci_init;
+	mmc->getcd = NULL;
 
 	/* need to be able to pass these in on a board by board basis */
 	mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 21665ec..6db37b1 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -40,11 +40,11 @@
 static struct list_head mmc_devices;
 static int cur_dev_num = -1;
 
-int __board_mmc_getcd(u8 *cd, struct mmc *mmc) {
+int __board_mmc_getcd(struct mmc *mmc) {
 	return -1;
 }
 
-int board_mmc_getcd(u8 *cd, struct mmc *mmc)__attribute__((weak,
+int board_mmc_getcd(struct mmc *mmc)__attribute__((weak,
 	alias("__board_mmc_getcd")));
 
 int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
@@ -674,6 +674,18 @@
 			  | (part_num & PART_ACCESS_MASK));
 }
 
+int mmc_getcd(struct mmc *mmc)
+{
+	int cd;
+
+	cd = board_mmc_getcd(mmc);
+
+	if ((cd < 0) && mmc->getcd)
+		cd = mmc->getcd(mmc);
+
+	return cd;
+}
+
 int sd_switch(struct mmc *mmc, int mode, int group, u8 value, u8 *resp)
 {
 	struct mmc_cmd cmd;
@@ -785,6 +797,16 @@
 	if (!(__be32_to_cpu(switch_status[3]) & SD_HIGHSPEED_SUPPORTED))
 		return 0;
 
+	/*
+	 * If the host doesn't support SD_HIGHSPEED, do not switch card to
+	 * HIGHSPEED mode even if the card support SD_HIGHSPPED.
+	 * This can avoid furthur problem when the card runs in different
+	 * mode between the host.
+	 */
+	if (!((mmc->host_caps & MMC_MODE_HS_52MHz) &&
+		(mmc->host_caps & MMC_MODE_HS)))
+		return 0;
+
 	err = sd_switch(mmc, SD_SWITCH_SWITCH, 0, 1, (u8 *)switch_status);
 
 	if (err)
@@ -1192,6 +1214,12 @@
 {
 	int err;
 
+	if (mmc_getcd(mmc) == 0) {
+		mmc->has_init = 0;
+		printf("MMC: no card present\n");
+		return NO_CARD_ERR;
+	}
+
 	if (mmc->has_init)
 		return 0;
 
diff --git a/drivers/mmc/mmc_spi.c b/drivers/mmc/mmc_spi.c
index 49fb9e0..de43a85 100644
--- a/drivers/mmc/mmc_spi.c
+++ b/drivers/mmc/mmc_spi.c
@@ -272,6 +272,7 @@
 	mmc->send_cmd = mmc_spi_request;
 	mmc->set_ios = mmc_spi_set_ios;
 	mmc->init = mmc_spi_init_p;
+	mmc->getcd = NULL;
 	mmc->host_caps = MMC_MODE_SPI;
 
 	mmc->voltages = MMC_SPI_VOLTAGE;
diff --git a/drivers/mmc/mv_sdhci.c b/drivers/mmc/mv_sdhci.c
index 1501974..2fe34b6 100644
--- a/drivers/mmc/mv_sdhci.c
+++ b/drivers/mmc/mv_sdhci.c
@@ -44,8 +44,7 @@
 	host->quirks = quirks;
 #ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS
 	memset(&mv_ops, 0, sizeof(struct sdhci_ops));
-	if (mv_sdhci_writeb != NULL)
-		mv_ops.write_b = mv_sdhci_writeb;
+	mv_ops.write_b = mv_sdhci_writeb;
 	host->ops = &mv_ops;
 #endif
 	if (quirks & SDHCI_QUIRK_REG32_RW)
diff --git a/drivers/mmc/mxcmmc.c b/drivers/mmc/mxcmmc.c
index ab1fc82..8afb221 100644
--- a/drivers/mmc/mxcmmc.c
+++ b/drivers/mmc/mxcmmc.c
@@ -500,6 +500,7 @@
 	mmc->send_cmd = mxcmci_request;
 	mmc->set_ios = mxcmci_set_ios;
 	mmc->init = mxcmci_init;
+	mmc->getcd = NULL;
 	mmc->host_caps = MMC_MODE_4BIT;
 
 	host->base = (struct mxcmci_regs *)CONFIG_MXC_MCI_REGS_BASE;
diff --git a/drivers/mmc/mxsmmc.c b/drivers/mmc/mxsmmc.c
index 2a9949e..5f87a1e 100644
--- a/drivers/mmc/mxsmmc.c
+++ b/drivers/mmc/mxsmmc.c
@@ -329,6 +329,7 @@
 	mmc->send_cmd = mxsmmc_send_cmd;
 	mmc->set_ios = mxsmmc_set_ios;
 	mmc->init = mxsmmc_init;
+	mmc->getcd = NULL;
 	mmc->priv = priv;
 
 	mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c
index c38b9e6..ef64e37 100644
--- a/drivers/mmc/omap_hsmmc.c
+++ b/drivers/mmc/omap_hsmmc.c
@@ -472,6 +472,7 @@
 	mmc->send_cmd = mmc_send_cmd;
 	mmc->set_ios = mmc_set_ios;
 	mmc->init = mmc_init_setup;
+	mmc->getcd = NULL;
 
 	switch (dev_index) {
 	case 0:
diff --git a/drivers/mmc/pxa_mmc_gen.c b/drivers/mmc/pxa_mmc_gen.c
index 4a7c67a..2c5bf17 100644
--- a/drivers/mmc/pxa_mmc_gen.c
+++ b/drivers/mmc/pxa_mmc_gen.c
@@ -411,6 +411,7 @@
 	mmc->send_cmd	= pxa_mmc_request;
 	mmc->set_ios	= pxa_mmc_set_ios;
 	mmc->init	= pxa_mmc_init;
+	mmc->getcd	= NULL;
 
 	mmc->voltages	= MMC_VDD_32_33 | MMC_VDD_33_34;
 	mmc->f_max	= PXAMMC_MAX_SPEED;
diff --git a/drivers/mmc/s5p_mmc.c b/drivers/mmc/s5p_mmc.c
index 7786ecf..4ae3aaf 100644
--- a/drivers/mmc/s5p_mmc.c
+++ b/drivers/mmc/s5p_mmc.c
@@ -463,6 +463,7 @@
 	mmc->send_cmd = mmc_send_cmd;
 	mmc->set_ios = mmc_set_ios;
 	mmc->init = mmc_core_init;
+	mmc->getcd = NULL;
 
 	mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
 	if (bus_width == 8)
diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c
index fce0ef0..fc904b5 100644
--- a/drivers/mmc/sdhci.c
+++ b/drivers/mmc/sdhci.c
@@ -390,6 +390,7 @@
 	mmc->send_cmd = sdhci_send_command;
 	mmc->set_ios = sdhci_set_ios;
 	mmc->init = sdhci_init;
+	mmc->getcd = NULL;
 
 	caps = sdhci_readl(host, SDHCI_CAPABILITIES);
 #ifdef CONFIG_MMC_SDMA
diff --git a/drivers/mmc/sh_mmcif.c b/drivers/mmc/sh_mmcif.c
index 567e2cb..2835e24 100644
--- a/drivers/mmc/sh_mmcif.c
+++ b/drivers/mmc/sh_mmcif.c
@@ -598,6 +598,7 @@
 	mmc->send_cmd = sh_mmcif_request;
 	mmc->set_ios = sh_mmcif_set_ios;
 	mmc->init = sh_mmcif_init;
+	mmc->getcd = NULL;
 	host->regs = (struct sh_mmcif_regs *)CONFIG_SH_MMCIF_ADDR;
 	host->clk = CONFIG_SH_MMCIF_CLK;
 	mmc->priv = host;
diff --git a/drivers/mmc/tegra2_mmc.c b/drivers/mmc/tegra2_mmc.c
index 035a868..5b4c9f6 100644
--- a/drivers/mmc/tegra2_mmc.c
+++ b/drivers/mmc/tegra2_mmc.c
@@ -474,6 +474,18 @@
 	return 0;
 }
 
+int tegra2_mmc_getcd(struct mmc *mmc)
+{
+	struct mmc_host *host = (struct mmc_host *)mmc->priv;
+
+	debug("tegra2_mmc_getcd called\n");
+
+	if (host->cd_gpio >= 0)
+		return !gpio_get_value(host->cd_gpio);
+
+	return 1;
+}
+
 int tegra2_mmc_init(int dev_index, int bus_width, int pwr_gpio, int cd_gpio)
 {
 	struct mmc_host *host;
@@ -512,6 +524,7 @@
 	mmc->send_cmd = mmc_send_cmd;
 	mmc->set_ios = mmc_set_ios;
 	mmc->init = mmc_core_init;
+	mmc->getcd = tegra2_mmc_getcd;
 
 	mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
 	if (bus_width == 8)
@@ -535,22 +548,3 @@
 
 	return 0;
 }
-
-/* this is a weak define that we are overriding */
-int board_mmc_getcd(u8 *cd, struct mmc *mmc)
-{
-	struct mmc_host *host = (struct mmc_host *)mmc->priv;
-
-	debug("board_mmc_getcd called\n");
-
-	*cd = 1; /* Assume card is inserted, or eMMC */
-
-	if (IS_SD(mmc)) {
-		if (host->cd_gpio >= 0) {
-			if (gpio_get_value(host->cd_gpio))
-				*cd = 0;
-		}
-	}
-
-	return 0;
-}
diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h
index a1ebb28..c19e16c 100644
--- a/include/asm-generic/gpio.h
+++ b/include/asm-generic/gpio.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2011 The Chromium OS Authors.
+ * Copyright (c) 2011, NVIDIA Corp. All rights reserved.
  * See file CREDITS for list of people who contributed to this
  * project.
  *
@@ -19,6 +20,9 @@
  * MA 02111-1307 USA
  */
 
+#ifndef _ASM_GENERIC_GPIO_H_
+#define _ASM_GENERIC_GPIO_H_
+
 /*
  * Generic GPIO API for U-Boot
  *
@@ -38,37 +42,56 @@
  */
 
 /**
- * Make a GPIO an input.
+ * Request ownership of a GPIO.
  *
- * @param gp	GPIO number
+ * @param gpio	GPIO number
+ * @param label	Name given to the GPIO
  * @return 0 if ok, -1 on error
  */
-int gpio_direction_input(int gp);
+int gpio_request(unsigned gpio, const char *label);
+
+/**
+ * Stop using the GPIO.  This function should not alter pin configuration.
+ *
+ * @param gpio	GPIO number
+ * @return 0 if ok, -1 on error
+ */
+int gpio_free(unsigned gpio);
+
+/**
+ * Make a GPIO an input.
+ *
+ * @param gpio	GPIO number
+ * @return 0 if ok, -1 on error
+ */
+int gpio_direction_input(unsigned gpio);
 
 /**
  * Make a GPIO an output, and set its value.
  *
- * @param gp	GPIO number
+ * @param gpio	GPIO number
  * @param value	GPIO value (0 for low or 1 for high)
  * @return 0 if ok, -1 on error
  */
-int gpio_direction_output(int gp, int value);
+int gpio_direction_output(unsigned gpio, int value);
 
 /**
  * Get a GPIO's value. This will work whether the GPIO is an input
  * or an output.
  *
- * @param gp	GPIO number
+ * @param gpio	GPIO number
  * @return 0 if low, 1 if high, -1 on error
  */
-int gpio_get_value(int gp);
+int gpio_get_value(unsigned gpio);
 
 /**
- * Set an output GPIO's value. The GPIO must already be an output of
+ * Set an output GPIO's value. The GPIO must already be an output or
  * this function may have no effect.
  *
- * @param gp	GPIO number
+ * @param gpio	GPIO number
  * @param value	GPIO value (0 for low or 1 for high)
  * @return 0 if ok, -1 on error
  */
-int gpio_set_value(int gp, int value);
+int gpio_set_value(unsigned gpio, int value);
+
+#endif	/* _ASM_GENERIC_GPIO_H_ */
diff --git a/include/configs/MIP405.h b/include/configs/MIP405.h
index 247cd2f..9961fb5 100644
--- a/include/configs/MIP405.h
+++ b/include/configs/MIP405.h
@@ -239,11 +239,17 @@
 /*-----------------------------------------------------------------------
  * FLASH organization
  */
-#define CONFIG_SYS_MAX_FLASH_BANKS	1	/* max number of memory banks		*/
-#define CONFIG_SYS_MAX_FLASH_SECT	256	/* max number of sectors on one chip	*/
+#define CONFIG_SYS_UPDATE_FLASH_SIZE
+#define CONFIG_SYS_FLASH_PROTECTION
+#define CONFIG_SYS_FLASH_EMPTY_INFO
 
-#define CONFIG_SYS_FLASH_ERASE_TOUT	120000	/* Timeout for Flash Erase (in ms)	*/
-#define CONFIG_SYS_FLASH_WRITE_TOUT	500	/* Timeout for Flash Write (in ms)	*/
+#define CONFIG_SYS_FLASH_CFI
+#define CONFIG_FLASH_CFI_DRIVER
+
+#define CONFIG_FLASH_SHOW_PROGRESS	45
+
+#define CONFIG_SYS_MAX_FLASH_BANKS	1
+#define CONFIG_SYS_MAX_FLASH_SECT	256
 
 /*
  * JFFS2 partitions
@@ -291,6 +297,7 @@
 #define FLASH_SIZE_PRELIM	 3  /* maximal flash FLASH size bank #0	*/
 
 #define CONFIG_BOARD_EARLY_INIT_F 1
+#define CONFIG_BOARD_EARLY_INIT_R
 
 /* Peripheral Bus Mapping */
 #define PER_PLD_ADDR		0xF4000000 /* smallest window is 1MByte 0x10 0000*/
diff --git a/include/configs/MPC8313ERDB.h b/include/configs/MPC8313ERDB.h
index 31503af..863c9b9 100644
--- a/include/configs/MPC8313ERDB.h
+++ b/include/configs/MPC8313ERDB.h
@@ -82,7 +82,8 @@
 
 #define CONFIG_SYS_CLK_FREQ	CONFIG_83XX_CLKIN
 
-#define CONFIG_BOARD_EARLY_INIT_F		/* call board_pre_init */
+#define CONFIG_BOARD_EARLY_INIT_F		/* call board_early_init_f */
+#define CONFIG_BOARD_EARLY_INIT_R		/* call board_early_init_r */
 
 #define CONFIG_SYS_IMMR		0xE0000000
 
@@ -266,7 +267,7 @@
 #define CONFIG_CMD_MTDPARTS
 #define MTDIDS_DEFAULT			"nand0=e2800000.flash"
 #define MTDPARTS_DEFAULT		\
-	"mtdparts=e0600000.flash:512k(uboot),128k(env),3m@1m(kernel),-(fs)"
+	"mtdparts=e2800000.flash:512k(uboot),128k(env),3m@1m(kernel),-(fs)"
 
 #define CONFIG_SYS_MAX_NAND_DEVICE	1
 #define CONFIG_MTD_NAND_VERIFY_WRITE
@@ -363,6 +364,9 @@
 #define CONFIG_OF_BOARD_SETUP	1
 #define CONFIG_OF_STDOUT_VIA_ALIAS	1
 
+#define CONFIG_MPC83XX_GPIO 1
+#define CONFIG_CMD_GPIO 1
+
 /*
  * Serial Port
  */
@@ -581,7 +585,8 @@
 
 /* System IO Config */
 #define CONFIG_SYS_SICRH	(SICRH_TSOBI1 | SICRH_TSOBI2)	/* RGMII */
-#define CONFIG_SYS_SICRL	SICRL_USBDR_10	/* Enable Internal USB Phy  */
+			/* Enable Internal USB Phy and GPIO on LCD Connector */
+#define CONFIG_SYS_SICRL	(SICRL_USBDR_10 | SICRL_LBC)
 
 #define CONFIG_SYS_HID0_INIT	0x000000000
 #define CONFIG_SYS_HID0_FINAL	(HID0_ENABLE_MACHINE_CHECK | \
diff --git a/include/configs/PATI.h b/include/configs/PATI.h
index da2d602..bf39d00 100644
--- a/include/configs/PATI.h
+++ b/include/configs/PATI.h
@@ -168,11 +168,16 @@
  *
  */
 
-#define CONFIG_SYS_MAX_FLASH_BANKS		1		/* Max number of memory banks		*/
-#define CONFIG_SYS_MAX_FLASH_SECT		128		/* Max number of sectors on one chip	*/
-#define CONFIG_SYS_FLASH_ERASE_TOUT	180000		/* Timeout for Flash Erase (in ms)	*/
-#define CONFIG_SYS_FLASH_WRITE_TOUT	600		/* Timeout for Flash Write (in ms)	*/
+#define CONFIG_SYS_FLASH_PROTECTION
+#define CONFIG_SYS_FLASH_EMPTY_INFO
 
+#define CONFIG_SYS_FLASH_CFI
+#define CONFIG_FLASH_CFI_DRIVER
+
+#define CONFIG_FLASH_SHOW_PROGRESS	45
+
+#define CONFIG_SYS_MAX_FLASH_BANKS	1
+#define CONFIG_SYS_MAX_FLASH_SECT	128
 
 #define	CONFIG_ENV_IS_IN_EEPROM
 #ifdef	CONFIG_ENV_IS_IN_EEPROM
diff --git a/include/configs/PIP405.h b/include/configs/PIP405.h
index 07415f4..242aa31 100644
--- a/include/configs/PIP405.h
+++ b/include/configs/PIP405.h
@@ -113,6 +113,8 @@
 #define SPD_EEPROM_ADDRESS      0x50
 
 #define CONFIG_BOARD_EARLY_INIT_F
+#define CONFIG_BOARD_EARLY_INIT_R
+
 /**************************************************************
  * Environment definitions
  **************************************************************/
@@ -230,11 +232,17 @@
 /*-----------------------------------------------------------------------
  * FLASH organization
  */
-#define CONFIG_SYS_MAX_FLASH_BANKS	1	/* max number of memory banks		*/
-#define CONFIG_SYS_MAX_FLASH_SECT	256	/* max number of sectors on one chip	*/
+#define CONFIG_SYS_UPDATE_FLASH_SIZE
+#define CONFIG_SYS_FLASH_PROTECTION
+#define CONFIG_SYS_FLASH_EMPTY_INFO
 
-#define CONFIG_SYS_FLASH_ERASE_TOUT	120000	/* Timeout for Flash Erase (in ms)	*/
-#define CONFIG_SYS_FLASH_WRITE_TOUT	500	/* Timeout for Flash Write (in ms)	*/
+#define CONFIG_SYS_FLASH_CFI
+#define CONFIG_FLASH_CFI_DRIVER
+
+#define CONFIG_FLASH_SHOW_PROGRESS	45
+
+#define CONFIG_SYS_MAX_FLASH_BANKS	1
+#define CONFIG_SYS_MAX_FLASH_SECT	256
 
 /*
  * Init Memory Controller:
diff --git a/include/configs/km/km8321-common.h b/include/configs/km/km8321-common.h
index 902ae26..580b72f 100644
--- a/include/configs/km/km8321-common.h
+++ b/include/configs/km/km8321-common.h
@@ -70,7 +70,8 @@
 #define CONFIG_SYS_DDR_CS0_BNDS		0x0000007f
 #define CONFIG_SYS_DDR_SDRAM_CFG	(SDRAM_CFG_SDRAM_TYPE_DDR2 | \
 					 SDRAM_CFG_32_BE | \
-					 SDRAM_CFG_SREN)
+					 SDRAM_CFG_SREN | \
+					 SDRAM_CFG_HSE)
 
 #define CONFIG_SYS_DDR_SDRAM_CFG2	0x00401000
 #define CONFIG_SYS_DDR_CLK_CNTL		(DDR_SDRAM_CLK_CNTL_CLK_ADJUST_05)
@@ -82,7 +83,7 @@
 					 CSCONFIG_ROW_BIT_13 | \
 					 CSCONFIG_COL_BIT_10)
 
-#define CONFIG_SYS_DDR_MODE	0x47860252
+#define CONFIG_SYS_DDR_MODE	0x47860242
 #define CONFIG_SYS_DDR_MODE2	0x8080c000
 
 #define CONFIG_SYS_DDR_TIMING_0	((2 << TIMING_CFG0_MRS_CYC_SHIFT) | \
@@ -94,20 +95,20 @@
 				 (0 << TIMING_CFG0_WRT_SHIFT) | \
 				 (0 << TIMING_CFG0_RWT_SHIFT))
 
-#define CONFIG_SYS_DDR_TIMING_1	((TIMING_CFG1_CASLAT_50) | \
+#define CONFIG_SYS_DDR_TIMING_1	((TIMING_CFG1_CASLAT_40) | \
 				 (2 << TIMING_CFG1_WRTORD_SHIFT) | \
 				 (2 << TIMING_CFG1_ACTTOACT_SHIFT) | \
-				 (2 << TIMING_CFG1_WRREC_SHIFT) | \
-				 (6 << TIMING_CFG1_REFREC_SHIFT) | \
-				 (2 << TIMING_CFG1_ACTTORW_SHIFT) | \
-				 (6 << TIMING_CFG1_ACTTOPRE_SHIFT) | \
-				 (2 << TIMING_CFG1_PRETOACT_SHIFT))
+				 (3 << TIMING_CFG1_WRREC_SHIFT) | \
+				 (7 << TIMING_CFG1_REFREC_SHIFT) | \
+				 (3 << TIMING_CFG1_ACTTORW_SHIFT) | \
+				 (7 << TIMING_CFG1_ACTTOPRE_SHIFT) | \
+				 (3 << TIMING_CFG1_PRETOACT_SHIFT))
 
 #define CONFIG_SYS_DDR_TIMING_2	((8 << TIMING_CFG2_FOUR_ACT_SHIFT) | \
 				 (3 << TIMING_CFG2_CKE_PLS_SHIFT) | \
 				 (2 << TIMING_CFG2_WR_DATA_DELAY_SHIFT) | \
 				 (2 << TIMING_CFG2_RD_TO_PRE_SHIFT) | \
-				 (4 << TIMING_CFG2_WR_LAT_DELAY_SHIFT) | \
+				 (3 << TIMING_CFG2_WR_LAT_DELAY_SHIFT) | \
 				 (0 << TIMING_CFG2_ADD_LAT_SHIFT) | \
 				 (5 << TIMING_CFG2_CPO_SHIFT))
 
@@ -122,7 +123,10 @@
 /*
  * Local Bus Configuration & Clock Setup
  */
-#define CONFIG_SYS_LCRR		(LCRR_DBYP | LCRR_EADC_1 | LCRR_CLKDIV_2)
+#define CONFIG_SYS_LCRR_DBYP	0x80000000
+#define CONFIG_SYS_LCRR_EADC	0x00010000
+#define CONFIG_SYS_LCRR_CLKDIV	0x00000002
+
 #define CONFIG_SYS_LBC_LBCR	0x00000000
 
 /*
diff --git a/include/configs/tuxa1.h b/include/configs/tuxa1.h
deleted file mode 100644
index 2d9af3f..0000000
--- a/include/configs/tuxa1.h
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (C) 2006 Freescale Semiconductor, Inc.
- *                    Dave Liu <daveliu@freescale.com>
- *
- * Copyright (C) 2007 Logic Product Development, Inc.
- *                    Peter Barada <peterb@logicpd.com>
- *
- * Copyright (C) 2007 MontaVista Software, Inc.
- *                    Anton Vorontsov <avorontsov@ru.mvista.com>
- *
- * (C) Copyright 2008
- * Heiko Schocher, DENX Software Engineering, hs@denx.de.
- *
- * (C) Copyright 2010
- * Yan Bin, Lukas Roggli, KEYMILE Ltd, lukas.roggli@keymile.com
- *
- * 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 __CONFIG_H
-#define __CONFIG_H
-
-/*
- * High Level Configuration Options
- */
-#define CONFIG_TUXA1		/* TUXA1 board specific */
-#define CONFIG_HOSTNAME		tuxa1
-#define CONFIG_KM_BOARD_NAME   "tuxa1"
-
-#define	CONFIG_SYS_TEXT_BASE	0xF0000000
-
-/* include common defines/options for all 8321 Keymile boards */
-#include "km/km8321-common.h"
-
-#define	CONFIG_SYS_LPXF_BASE		0xA0000000    /* LPXF */
-#define	CONFIG_SYS_LPXF_SIZE		256 /* Megabytes */
-#define	CONFIG_SYS_PINC2_BASE		0xB0000000    /* PINC2 */
-#define	CONFIG_SYS_PINC2_SIZE		256 /* Megabytes */
-
-/*
- * Init Local Bus Memory Controller:
- *
- * Bank Bus     Machine PortSz  Size  Device
- * ---- ---     ------- ------  -----  ------
- *  2   Local   GPCM    8 bit  256MB	LPXF
- *  3   Local   GPCM    8 bit  256MB	PINC2
- *
- */
-
-/*
- * LPXF on the local bus CS2
- * Window base at flash base
- * Window size: 256 MB
- */
-#define CONFIG_SYS_LBLAWBAR2_PRELIM	CONFIG_SYS_LPXF_BASE
-#define CONFIG_SYS_LBLAWAR2_PRELIM	(LBLAWAR_EN | LBLAWAR_256MB)
-
-#define CONFIG_SYS_BR2_PRELIM       (CONFIG_SYS_LPXF_BASE | \
-				BR_PS_8 | \
-				BR_MS_GPCM | \
-				BR_V)
-
-#define CONFIG_SYS_OR2_PRELIM	(MEG_TO_AM(CONFIG_SYS_LPXF_SIZE) | \
-				 OR_GPCM_CSNT | \
-				 OR_GPCM_ACS_DIV4 | \
-				 OR_GPCM_SCY_2 | \
-				 OR_GPCM_TRLX_SET | \
-				 OR_GPCM_EHTR_CLEAR | \
-				 OR_GPCM_EAD)
-/*
- * PINC2 on the local bus CS3
- * Access window base at PINC2 base
- * Window size: 256 MB
- */
-#define CONFIG_SYS_LBLAWBAR3_PRELIM	CONFIG_SYS_PINC2_BASE
-#define CONFIG_SYS_LBLAWAR3_PRELIM	(LBLAWAR_EN | LBLAWAR_256MB)
-
-#define CONFIG_SYS_BR3_PRELIM	(CONFIG_SYS_PINC2_BASE | \
-				 BR_PS_8 | \
-				 BR_MS_GPCM | \
-				 BR_V)
-
-#define CONFIG_SYS_OR3_PRELIM	(MEG_TO_AM(CONFIG_SYS_PINC2_SIZE) | \
-				 OR_GPCM_CSNT | \
-				 OR_GPCM_ACS_DIV2 | \
-				 OR_GPCM_SCY_2 | \
-				 OR_GPCM_TRLX_SET | \
-				 OR_GPCM_EHTR_CLEAR)
-
-#define CONFIG_SYS_MAMR		(MxMR_GPL_x4DIS | \
-				 0x0000c000 | \
-				 MxMR_WLFx_2X)
-
-/*
- * MMU Setup
- */
-/* LPXF:  icache cacheable, but dcache-inhibit and guarded */
-#define CONFIG_SYS_IBAT5L	(CONFIG_SYS_LPXF_BASE | BATL_PP_RW | \
-				 BATL_MEMCOHERENCE)
-#define CONFIG_SYS_IBAT5U	(CONFIG_SYS_LPXF_BASE | BATU_BL_256M | \
-				 BATU_VS | BATU_VP)
-#define CONFIG_SYS_DBAT5L	(CONFIG_SYS_LPXF_BASE | BATL_PP_RW | \
-				 BATL_CACHEINHIBIT | BATL_GUARDEDSTORAGE)
-#define CONFIG_SYS_DBAT5U	CONFIG_SYS_IBAT5U
-
-/* PINC2:  icache cacheable, but dcache-inhibit and guarded */
-#define CONFIG_SYS_IBAT6L	(CONFIG_SYS_PINC2_BASE | BATL_PP_RW | \
-				 BATL_MEMCOHERENCE)
-#define CONFIG_SYS_IBAT6U	(CONFIG_SYS_PINC2_BASE | BATU_BL_256M | \
-				 BATU_VS | BATU_VP)
-#define CONFIG_SYS_DBAT6L	(CONFIG_SYS_PINC2_BASE | BATL_PP_RW | \
-				 BATL_CACHEINHIBIT | BATL_GUARDEDSTORAGE)
-#define CONFIG_SYS_DBAT6U	CONFIG_SYS_IBAT6U
-
-#define CONFIG_SYS_IBAT7L	(0)
-#define CONFIG_SYS_IBAT7U	(0)
-#define CONFIG_SYS_DBAT7L	CONFIG_SYS_IBAT7L
-#define CONFIG_SYS_DBAT7U	CONFIG_SYS_IBAT7U
-
-#endif /* __CONFIG_H */
diff --git a/include/configs/tuda1.h b/include/configs/tuxx1.h
similarity index 77%
rename from include/configs/tuda1.h
rename to include/configs/tuxx1.h
index 577bbd0..f6d2b17 100644
--- a/include/configs/tuda1.h
+++ b/include/configs/tuxx1.h
@@ -13,6 +13,7 @@
  *
  * (C) Copyright 2010-2011
  * Lukas Roggli, KEYMILE Ltd, lukas.roggli@keymile.com
+ * Holger Brunck,  Keymile GmbH, holger.bruncl@keymile.com
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -26,9 +27,13 @@
 /*
  * High Level Configuration Options
  */
-#define CONFIG_TUDA1		/* TUDA1 board specific */
-#define CONFIG_HOSTNAME		tuda1
-#define CONFIG_KM_BOARD_NAME   "tuda1"
+#define CONFIG_TUXXX		/* TUXX1 board (tuxa1/tuda1) specific */
+#define CONFIG_HOSTNAME		tuxx1
+#ifdef CONFIG_KM_DISABLE_APP2
+#define CONFIG_KM_BOARD_NAME   "tuge1"
+#else
+#define CONFIG_KM_BOARD_NAME   "tuxx1"
+#endif
 
 #define	CONFIG_SYS_TEXT_BASE	0xF0000000
 
@@ -37,27 +42,23 @@
 
 #define CONFIG_SYS_APP1_BASE	0xA0000000    /* PAXG */
 #define	CONFIG_SYS_APP1_SIZE	256 /* Megabytes */
+#ifndef CONFIG_KM_DISABLE_APP2
 #define CONFIG_SYS_APP2_BASE	0xB0000000    /* PINC3 */
 #define	CONFIG_SYS_APP2_SIZE	256 /* Megabytes */
-
-/*
- * Local Bus Configuration & Clock Setup
- */
-#define CONFIG_SYS_LCRR		(LCRR_DBYP | LCRR_EADC_1 | LCRR_CLKDIV_2)
-#define CONFIG_SYS_LBC_LBCR	0x00000000
+#endif
 
 /*
  * Init Local Bus Memory Controller:
  *
- * Bank Bus     Machine PortSz  Size  Device
- * ---- ---     ------- ------  -----  ------
- *  2   Local   GPCM    8 bit  256MB	PAXG
- *  3   Local   GPCM    8 bit  256MB	PINC3
+ * Bank Bus     Machine PortSz  Size  Device on TUDA1  TUXA1  TUGE1
+ * ---- ---     ------- ------  -----  ----------------------------
+ *  2   Local   GPCM    8 bit  256MB	         PAXG  LPXF   PAXI
+ *  3   Local   GPCM    8 bit  256MB	         PINC3 PINC2  unused
  *
  */
 
 /*
- * PAXG on the local bus CS2
+ * Configuration for C2 on the local bus
  */
 /* Window base at flash base */
 #define CONFIG_SYS_LBLAWBAR2_PRELIM	CONFIG_SYS_APP1_BASE
@@ -76,8 +77,9 @@
 				 OR_GPCM_TRLX_SET | \
 				 OR_GPCM_EHTR_CLEAR | \
 				 OR_GPCM_EAD)
+#ifndef CONFIG_KM_DISABLE_APP2
 /*
- * PINC3 on the local bus CS3
+ * Configuration for C3 on the local bus
  */
 /* Access window base at PINC3 base */
 #define CONFIG_SYS_LBLAWBAR3_PRELIM	CONFIG_SYS_APP2_BASE
@@ -99,11 +101,12 @@
 #define CONFIG_SYS_MAMR		(MxMR_GPL_x4DIS | \
 				 0x0000c000 | \
 				 MxMR_WLFx_2X)
+#endif
 
 /*
  * MMU Setup
  */
-/* PAXG:  icache cacheable, but dcache-inhibit and guarded */
+/* APP1: icache cacheable, but dcache-inhibit and guarded */
 #define CONFIG_SYS_IBAT5L	(CONFIG_SYS_APP1_BASE | \
 				 BATL_PP_RW | \
 				 BATL_MEMCOHERENCE)
@@ -118,7 +121,12 @@
 				 BATL_GUARDEDSTORAGE)
 #define CONFIG_SYS_DBAT5U	CONFIG_SYS_IBAT5U
 
-/* PINC3:  icache cacheable, but dcache-inhibit and guarded */
+#ifdef CONFIG_KM_DISABLE_APP2
+#define CONFIG_SYS_IBAT6L	(0)
+#define CONFIG_SYS_IBAT6U	(0)
+#define CONFIG_SYS_DBAT6L	CONFIG_SYS_IBAT6L
+#else
+/* APP2:  icache cacheable, but dcache-inhibit and guarded */
 #define CONFIG_SYS_IBAT6L	(CONFIG_SYS_APP2_BASE | \
 				 BATL_PP_RW | \
 				 BATL_MEMCOHERENCE)
@@ -130,6 +138,7 @@
 				 BATL_PP_RW | \
 				 BATL_CACHEINHIBIT | \
 				 BATL_GUARDEDSTORAGE)
+#endif
 #define CONFIG_SYS_DBAT6U	CONFIG_SYS_IBAT6U
 
 #define CONFIG_SYS_IBAT7L	(0)
diff --git a/include/gdsys_fpga.h b/include/gdsys_fpga.h
index e7a072b..949864c 100644
--- a/include/gdsys_fpga.h
+++ b/include/gdsys_fpga.h
@@ -82,7 +82,10 @@
 	u16 reserved_1[502];	/* 0x0014 */
 	u16 ch0_status_int;	/* 0x0400 */
 	u16 ch0_config_int;	/* 0x0402 */
-	u16 reserved_2[7677];	/* 0x0404 */
+	u16 reserved_2[126];	/* 0x0404 */
+	u16 ch0_hicb_status_int;/* 0x0500 */
+	u16 ch0_hicb_config_int;/* 0x0502 */
+	u16 reserved_3[7549];	/* 0x0504 */
 	u16 reflection_high;	/* 0x3ffe */
 } ihs_fpga_t;
 #endif
diff --git a/include/i2c.h b/include/i2c.h
index ee31034..1f35acf 100644
--- a/include/i2c.h
+++ b/include/i2c.h
@@ -78,7 +78,7 @@
 # elif (defined(CONFIG_AT91RM9200) || \
 	defined(CONFIG_AT91SAM9260) ||  defined(CONFIG_AT91SAM9261) || \
 	defined(CONFIG_AT91SAM9263)) && !defined(CONFIG_AT91_LEGACY)
-#  define I2C_SOFT_DECLARATIONS	at91_pio_t *pio	= (at91_pio_t *) AT91_PIO_BASE;
+#  define I2C_SOFT_DECLARATIONS	at91_pio_t *pio	= (at91_pio_t *) ATMEL_BASE_PIOA;
 # else
 #  define I2C_SOFT_DECLARATIONS
 # endif
diff --git a/include/mmc.h b/include/mmc.h
index 015a7f3..8744604 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -302,6 +302,7 @@
 			struct mmc_cmd *cmd, struct mmc_data *data);
 	void (*set_ios)(struct mmc *mmc);
 	int (*init)(struct mmc *mmc);
+	int (*getcd)(struct mmc *mmc);
 	uint b_max;
 };
 
@@ -314,8 +315,9 @@
 int mmc_set_dev(int dev_num);
 void print_mmc_devices(char separator);
 int get_mmc_num(void);
-int board_mmc_getcd(u8 *cd, struct mmc *mmc);
+int board_mmc_getcd(struct mmc *mmc);
 int mmc_switch_part(int dev_num, unsigned int part_num);
+int mmc_getcd(struct mmc *mmc);
 
 #ifdef CONFIG_GENERIC_MMC
 int atmel_mci_init(void *regs);