Merge branch 'u-boot-samsung/master' into 'u-boot-arm/master'
diff --git a/arch/arm/cpu/armv7/exynos/clock.c b/arch/arm/cpu/armv7/exynos/clock.c
index 1fea4d6..400d134 100644
--- a/arch/arm/cpu/armv7/exynos/clock.c
+++ b/arch/arm/cpu/armv7/exynos/clock.c
@@ -869,7 +869,7 @@
 {
 	struct exynos4_clock *clk =
 		(struct exynos4_clock *)samsung_get_base_clock();
-	unsigned int addr;
+	unsigned int addr, clear_bit, set_bit;
 
 	/*
 	 * CLK_DIV_FSYS1
@@ -877,44 +877,26 @@
 	 * CLK_DIV_FSYS2
 	 * MMC2_PRE_RATIO [15:8], MMC3_PRE_RATIO [31:24]
 	 * CLK_DIV_FSYS3
-	 * MMC4_PRE_RATIO [15:8]
+	 * MMC4_RATIO [3:0]
 	 */
 	if (dev_index < 2) {
 		addr = (unsigned int)&clk->div_fsys1;
-	}  else if (dev_index == 4) {
+		clear_bit = MASK_PRE_RATIO(dev_index);
+		set_bit = SET_PRE_RATIO(dev_index, div);
+	} else if (dev_index == 4) {
 		addr = (unsigned int)&clk->div_fsys3;
 		dev_index -= 4;
+		/* MMC4 is controlled with the MMC4_RATIO value */
+		clear_bit = MASK_RATIO(dev_index);
+		set_bit = SET_RATIO(dev_index, div);
 	} else {
 		addr = (unsigned int)&clk->div_fsys2;
 		dev_index -= 2;
+		clear_bit = MASK_PRE_RATIO(dev_index);
+		set_bit = SET_PRE_RATIO(dev_index, div);
 	}
 
-	clrsetbits_le32(addr, 0xff << ((dev_index << 4) + 8),
-			(div & 0xff) << ((dev_index << 4) + 8));
-}
-
-/* exynos4x12: set the mmc clock */
-static void exynos4x12_set_mmc_clk(int dev_index, unsigned int div)
-{
-	struct exynos4x12_clock *clk =
-		(struct exynos4x12_clock *)samsung_get_base_clock();
-	unsigned int addr;
-
-	/*
-	 * CLK_DIV_FSYS1
-	 * MMC0_PRE_RATIO [15:8], MMC1_PRE_RATIO [31:24]
-	 * CLK_DIV_FSYS2
-	 * MMC2_PRE_RATIO [15:8], MMC3_PRE_RATIO [31:24]
-	 */
-	if (dev_index < 2) {
-		addr = (unsigned int)&clk->div_fsys1;
-	} else {
-		addr = (unsigned int)&clk->div_fsys2;
-		dev_index -= 2;
-	}
-
-	clrsetbits_le32(addr, 0xff << ((dev_index << 4) + 8),
-			(div & 0xff) << ((dev_index << 4) + 8));
+	clrsetbits_le32(addr, clear_bit, set_bit);
 }
 
 /* exynos5: set the mmc clock */
@@ -1612,10 +1594,7 @@
 		else
 			exynos5_set_mmc_clk(dev_index, div);
 	} else {
-		if (proid_is_exynos4412())
-			exynos4x12_set_mmc_clk(dev_index, div);
-		else
-			exynos4_set_mmc_clk(dev_index, div);
+		exynos4_set_mmc_clk(dev_index, div);
 	}
 }
 
diff --git a/arch/arm/cpu/armv7/exynos/lowlevel_init.c b/arch/arm/cpu/armv7/exynos/lowlevel_init.c
index 11fe5b8..dcc270f 100644
--- a/arch/arm/cpu/armv7/exynos/lowlevel_init.c
+++ b/arch/arm/cpu/armv7/exynos/lowlevel_init.c
@@ -39,6 +39,7 @@
 	DO_CLOCKS	= 1 << 1,
 	DO_MEM_RESET	= 1 << 2,
 	DO_UART		= 1 << 3,
+	DO_POWER	= 1 << 4,
 };
 
 int do_lowlevel_init(void)
@@ -48,6 +49,8 @@
 
 	arch_cpu_init();
 
+	set_ps_hold_ctrl();
+
 	reset_status = get_reset_status();
 
 	switch (reset_status) {
@@ -60,9 +63,12 @@
 		break;
 	default:
 		/* This is a normal boot (not a wake from sleep) */
-		actions = DO_CLOCKS | DO_MEM_RESET;
+		actions = DO_CLOCKS | DO_MEM_RESET | DO_POWER;
 	}
 
+	if (actions & DO_POWER)
+		set_ps_hold_ctrl();
+
 	if (actions & DO_CLOCKS) {
 		system_clock_init();
 		mem_ctrl_init(actions & DO_MEM_RESET);
diff --git a/arch/arm/cpu/armv7/exynos/pinmux.c b/arch/arm/cpu/armv7/exynos/pinmux.c
index ee7c2e5..86a0c75 100644
--- a/arch/arm/cpu/armv7/exynos/pinmux.c
+++ b/arch/arm/cpu/armv7/exynos/pinmux.c
@@ -573,15 +573,26 @@
 static int exynos4_mmc_config(int peripheral, int flags)
 {
 	int i, start = 0, start_ext = 0;
+	unsigned int func, ext_func;
 
 	switch (peripheral) {
 	case PERIPH_ID_SDMMC0:
 		start = EXYNOS4_GPIO_K00;
 		start_ext = EXYNOS4_GPIO_K13;
+		func = S5P_GPIO_FUNC(0x2);
+		ext_func = S5P_GPIO_FUNC(0x3);
 		break;
 	case PERIPH_ID_SDMMC2:
 		start = EXYNOS4_GPIO_K20;
 		start_ext = EXYNOS4_GPIO_K33;
+		func = S5P_GPIO_FUNC(0x2);
+		ext_func = S5P_GPIO_FUNC(0x3);
+		break;
+	case PERIPH_ID_SDMMC4:
+		start = EXYNOS4_GPIO_K00;
+		start_ext = EXYNOS4_GPIO_K13;
+		func = S5P_GPIO_FUNC(0x3);
+		ext_func = S5P_GPIO_FUNC(0x4);
 		break;
 	default:
 		return -1;
@@ -589,13 +600,14 @@
 	for (i = start; i < (start + 7); i++) {
 		if (i == (start + 2))
 			continue;
-		gpio_cfg_pin(i,  S5P_GPIO_FUNC(0x2));
+		gpio_cfg_pin(i,  func);
 		gpio_set_pull(i, S5P_GPIO_PULL_NONE);
 		gpio_set_drv(i, S5P_GPIO_DRV_4X);
 	}
+	/* SDMMC2 do not use 8bit mode at exynos4 */
 	if (flags & PINMUX_FLAG_8BIT_MODE) {
 		for (i = start_ext; i < (start_ext + 4); i++) {
-			gpio_cfg_pin(i,  S5P_GPIO_FUNC(0x3));
+			gpio_cfg_pin(i,  ext_func);
 			gpio_set_pull(i, S5P_GPIO_PULL_NONE);
 			gpio_set_drv(i, S5P_GPIO_DRV_4X);
 		}
@@ -676,15 +688,26 @@
 static int exynos4x12_mmc_config(int peripheral, int flags)
 {
 	int i, start = 0, start_ext = 0;
+	unsigned int func, ext_func;
 
 	switch (peripheral) {
 	case PERIPH_ID_SDMMC0:
 		start = EXYNOS4X12_GPIO_K00;
 		start_ext = EXYNOS4X12_GPIO_K13;
+		func = S5P_GPIO_FUNC(0x2);
+		ext_func = S5P_GPIO_FUNC(0x3);
 		break;
 	case PERIPH_ID_SDMMC2:
 		start = EXYNOS4X12_GPIO_K20;
 		start_ext = EXYNOS4X12_GPIO_K33;
+		func = S5P_GPIO_FUNC(0x2);
+		ext_func = S5P_GPIO_FUNC(0x3);
+		break;
+	case PERIPH_ID_SDMMC4:
+		start = EXYNOS4_GPIO_K00;
+		start_ext = EXYNOS4_GPIO_K13;
+		func = S5P_GPIO_FUNC(0x3);
+		ext_func = S5P_GPIO_FUNC(0x4);
 		break;
 	default:
 		return -1;
@@ -692,13 +715,13 @@
 	for (i = start; i < (start + 7); i++) {
 		if (i == (start + 2))
 			continue;
-		gpio_cfg_pin(i,  S5P_GPIO_FUNC(0x2));
+		gpio_cfg_pin(i,  func);
 		gpio_set_pull(i, S5P_GPIO_PULL_NONE);
 		gpio_set_drv(i, S5P_GPIO_DRV_4X);
 	}
 	if (flags & PINMUX_FLAG_8BIT_MODE) {
 		for (i = start_ext; i < (start_ext + 4); i++) {
-			gpio_cfg_pin(i,  S5P_GPIO_FUNC(0x3));
+			gpio_cfg_pin(i,  ext_func);
 			gpio_set_pull(i, S5P_GPIO_PULL_NONE);
 			gpio_set_drv(i, S5P_GPIO_DRV_4X);
 		}
@@ -759,10 +782,10 @@
 		break;
 	case PERIPH_ID_SDMMC0:
 	case PERIPH_ID_SDMMC2:
+	case PERIPH_ID_SDMMC4:
 		return exynos4_mmc_config(peripheral, flags);
 	case PERIPH_ID_SDMMC1:
 	case PERIPH_ID_SDMMC3:
-	case PERIPH_ID_SDMMC4:
 		debug("SDMMC device %d not implemented\n", peripheral);
 		return -1;
 	default:
@@ -794,10 +817,10 @@
 		break;
 	case PERIPH_ID_SDMMC0:
 	case PERIPH_ID_SDMMC2:
+	case PERIPH_ID_SDMMC4:
 		return exynos4x12_mmc_config(peripheral, flags);
 	case PERIPH_ID_SDMMC1:
 	case PERIPH_ID_SDMMC3:
-	case PERIPH_ID_SDMMC4:
 		debug("SDMMC device %d not implemented\n", peripheral);
 		return -1;
 	default:
diff --git a/arch/arm/cpu/armv7/exynos/power.c b/arch/arm/cpu/armv7/exynos/power.c
index 563abd7..638ee0b 100644
--- a/arch/arm/cpu/armv7/exynos/power.c
+++ b/arch/arm/cpu/armv7/exynos/power.c
@@ -112,6 +112,12 @@
 			EXYNOS_PS_HOLD_CONTROL_DATA_HIGH);
 }
 
+/*
+ * Set ps_hold data driving value high
+ * This enables the machine to stay powered on
+ * after the initial power-on condition goes away
+ * (e.g. power button).
+ */
 void set_ps_hold_ctrl(void)
 {
 	if (cpu_is_exynos5())
diff --git a/arch/arm/dts/exynos4.dtsi b/arch/arm/dts/exynos4.dtsi
index 71dc7eb..110eb43 100644
--- a/arch/arm/dts/exynos4.dtsi
+++ b/arch/arm/dts/exynos4.dtsi
@@ -128,6 +128,14 @@
 		interrupts = <0 78 0>;
 	};
 
+	dwmmc@12550000 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		compatible = "samsung,exynos-dwmmc";
+		reg = <0x12550000 0x1000>;
+		interrupts = <0 131 0>;
+	};
+
 	gpio: gpio {
 		gpio-controller;
 		#gpio-cells = <2>;
diff --git a/arch/arm/dts/exynos4412-trats2.dts b/arch/arm/dts/exynos4412-trats2.dts
index 1596f83..cc58c87 100644
--- a/arch/arm/dts/exynos4412-trats2.dts
+++ b/arch/arm/dts/exynos4412-trats2.dts
@@ -31,6 +31,7 @@
 		console = "/serial@13820000";
 		mmc0 = "sdhci@12510000";
 		mmc2 = "sdhci@12530000";
+		mmc4 = "dwmmc@12550000";
 	};
 
 	i2c@138d0000 {
@@ -416,6 +417,7 @@
 		samsung,bus-width = <8>;
 		samsung,timing = <1 3 3>;
 		pwr-gpios = <&gpio 0xB2 0>;
+		status = "disabled";
 	};
 
 	sdhci@12520000 {
@@ -431,4 +433,14 @@
 	sdhci@12540000 {
 		status = "disabled";
 	};
+
+	dwmmc@12550000 {
+		samsung,bus-width = <8>;
+		samsung,timing = <2 1 0>;
+		pwr-gpios = <&gpio 0xB2 0>;
+		fifoth_val = <0x203f0040>;
+		bus_hz = <400000000>;
+		div = <0x3>;
+		index = <4>;
+	};
 };
diff --git a/arch/arm/dts/exynos5.dtsi b/arch/arm/dts/exynos5.dtsi
index f8c8741..a2b533a 100644
--- a/arch/arm/dts/exynos5.dtsi
+++ b/arch/arm/dts/exynos5.dtsi
@@ -136,7 +136,7 @@
 	mmc@12200000 {
 		#address-cells = <1>;
 		#size-cells = <0>;
-		compatible = "samsung,exynos5250-dwmmc";
+		compatible = "samsung,exynos-dwmmc";
 		reg = <0x12200000 0x1000>;
 		interrupts = <0 75 0>;
 	};
@@ -144,7 +144,7 @@
 	mmc@12210000 {
 		#address-cells = <1>;
 		#size-cells = <0>;
-		compatible = "samsung,exynos5250-dwmmc";
+		compatible = "samsung,exynos-dwmmc";
 		reg = <0x12210000 0x1000>;
 		interrupts = <0 76 0>;
 	};
@@ -152,7 +152,7 @@
 	mmc@12220000 {
 		#address-cells = <1>;
 		#size-cells = <0>;
-		compatible = "samsung,exynos5250-dwmmc";
+		compatible = "samsung,exynos-dwmmc";
 		reg = <0x12220000 0x1000>;
 		interrupts = <0 77 0>;
 	};
@@ -160,7 +160,7 @@
 	mmc@12230000 {
 		#address-cells = <1>;
 		#size-cells = <0>;
-		compatible = "samsung,exynos5250-dwmmc";
+		compatible = "samsung,exynos-dwmmc";
 		reg = <0x12230000 0x1000>;
 		interrupts = <0 78 0>;
 	};
diff --git a/arch/arm/dts/exynos5250-snow.dts b/arch/arm/dts/exynos5250-snow.dts
index 9b48a0c..ab4f2f8 100644
--- a/arch/arm/dts/exynos5250-snow.dts
+++ b/arch/arm/dts/exynos5250-snow.dts
@@ -44,7 +44,7 @@
 			reg = <0x1e>;
 			compatible = "google,cros-ec";
 			i2c-max-frequency = <100000>;
-			ec-interrupt = <&gpio 782 1>;
+			ec-interrupt = <&gpio 182 1>;
 		};
 
 		power-regulator@48 {
@@ -60,7 +60,7 @@
 			reg = <0>;
 			compatible = "google,cros-ec";
 			spi-max-frequency = <5000000>;
-			ec-interrupt = <&gpio 782 1>;
+			ec-interrupt = <&gpio 182 1>;
 			optimise-flash-write;
 			status = "disabled";
 		};
@@ -80,6 +80,19 @@
 			reg = <0x22>;
 			compatible = "maxim,max98095-codec";
 		};
+
+		ptn3460-bridge@20 {
+			compatible = "nxp,ptn3460";
+			reg = <0x20>;
+			/*
+			 * TODO(sjg@chromium.org): Use GPIOs here
+			 * powerdown-gpio = <&gpy2 5 0>;
+			 * reset-gpio = <&gpx1 5 0>;
+			 * edid-emulation = <5>;
+			 * pinctrl-names = "default";
+			 * pinctrl-0 = <&ptn3460_gpios>;
+			 */
+		};
 	};
 
 	i2c@12c60000 {
@@ -184,4 +197,48 @@
 			/* UP      LEFT    */
 			0x070b0067 0x070c0069>;
 	};
+
+	fimd@14400000 {
+		samsung,vl-freq = <60>;
+		samsung,vl-col = <1366>;
+		samsung,vl-row = <768>;
+		samsung,vl-width = <1366>;
+		samsung,vl-height = <768>;
+
+		samsung,vl-clkp;
+		samsung,vl-dp;
+		samsung,vl-hsp;
+		samsung,vl-vsp;
+
+		samsung,vl-bpix = <4>;
+
+		samsung,vl-hspw = <32>;
+		samsung,vl-hbpd = <80>;
+		samsung,vl-hfpd = <48>;
+		samsung,vl-vspw = <5>;
+		samsung,vl-vbpd = <14>;
+		samsung,vl-vfpd = <3>;
+		samsung,vl-cmd-allow-len = <0xf>;
+
+		samsung,winid = <0>;
+		samsung,interface-mode = <1>;
+		samsung,dp-enabled = <1>;
+		samsung,dual-lcd-enabled = <0>;
+	};
+
+	dp@145b0000 {
+		samsung,lt-status = <0>;
+
+		samsung,master-mode = <0>;
+		samsung,bist-mode = <0>;
+		samsung,bist-pattern = <0>;
+		samsung,h-sync-polarity = <0>;
+		samsung,v-sync-polarity = <0>;
+		samsung,interlaced = <0>;
+		samsung,color-space = <0>;
+		samsung,dynamic-range = <0>;
+		samsung,ycbcr-coeff = <0>;
+		samsung,color-depth = <1>;
+	};
+
 };
diff --git a/arch/arm/include/asm/arch-exynos/clk.h b/arch/arm/include/asm/arch-exynos/clk.h
index cdeef32..ffbc07e 100644
--- a/arch/arm/include/asm/arch-exynos/clk.h
+++ b/arch/arm/include/asm/arch-exynos/clk.h
@@ -16,6 +16,11 @@
 #define BPLL	5
 #define RPLL	6
 
+#define MASK_PRE_RATIO(x)	(0xff << ((x << 4) + 8))
+#define MASK_RATIO(x)		(0xf << (x << 4))
+#define SET_PRE_RATIO(x, y)	((y & 0xff) << ((x << 4) + 8))
+#define SET_RATIO(x, y)		((y & 0xf) << (x << 4))
+
 enum pll_src_bit {
 	EXYNOS_SRC_MPLL = 6,
 	EXYNOS_SRC_EPLL,
diff --git a/arch/arm/include/asm/arch-exynos/power.h b/arch/arm/include/asm/arch-exynos/power.h
index c9609a2..a4b41ad 100644
--- a/arch/arm/include/asm/arch-exynos/power.h
+++ b/arch/arm/include/asm/arch-exynos/power.h
@@ -1726,4 +1726,5 @@
 
 /* Read the resume function and call it */
 void power_exit_wakeup(void);
+
 #endif
diff --git a/board/samsung/common/board.c b/board/samsung/common/board.c
index de154e0..9dc7c83 100644
--- a/board/samsung/common/board.c
+++ b/board/samsung/common/board.c
@@ -243,13 +243,6 @@
 int board_mmc_init(bd_t *bis)
 {
 	int ret;
-
-#ifdef CONFIG_SDHCI
-	/* mmc initializattion for available channels */
-	ret = exynos_mmc_init(gd->fdt_blob);
-	if (ret)
-		debug("mmc init failed\n");
-#endif
 #ifdef CONFIG_DWMMC
 	/* dwmmc initializattion for available channels */
 	ret = exynos_dwmmc_init(gd->fdt_blob);
@@ -257,6 +250,12 @@
 		debug("dwmmc init failed\n");
 #endif
 
+#ifdef CONFIG_SDHCI
+	/* mmc initializattion for available channels */
+	ret = exynos_mmc_init(gd->fdt_blob);
+	if (ret)
+		debug("mmc init failed\n");
+#endif
 	return ret;
 }
 #endif
diff --git a/board/samsung/goni/goni.c b/board/samsung/goni/goni.c
index 4cea63b..eb0f9bf 100644
--- a/board/samsung/goni/goni.c
+++ b/board/samsung/goni/goni.c
@@ -14,6 +14,8 @@
 #include <asm/arch/cpu.h>
 #include <power/max8998_pmic.h>
 #include <samsung/misc.h>
+#include <usb.h>
+#include <usb_mass_storage.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -175,6 +177,12 @@
 	.regs_otg = S5PC110_OTG_BASE,
 	.usb_phy_ctrl = S5PC110_USB_PHY_CONTROL,
 };
+
+int board_usb_init(int index, enum usb_init_type init)
+{
+	debug("USB_udc_probe\n");
+	return s3c_udc_probe(&s5pc110_otg_data);
+}
 #endif
 
 #ifdef CONFIG_MISC_INIT_R
diff --git a/board/samsung/smdk5250/Makefile b/board/samsung/smdk5250/Makefile
index 6a58655..3d96b07 100644
--- a/board/samsung/smdk5250/Makefile
+++ b/board/samsung/smdk5250/Makefile
@@ -7,9 +7,5 @@
 obj-y	+= smdk5250_spl.o
 
 ifndef CONFIG_SPL_BUILD
-ifdef CONFIG_OF_CONTROL
 obj-y	+= exynos5-dt.o
-else
-obj-y	+= smdk5250.o
-endif
 endif
diff --git a/board/samsung/smdk5250/exynos5-dt.c b/board/samsung/smdk5250/exynos5-dt.c
index 58821c4..d6ce133 100644
--- a/board/samsung/smdk5250/exynos5-dt.c
+++ b/board/samsung/smdk5250/exynos5-dt.c
@@ -11,15 +11,16 @@
 #include <i2c.h>
 #include <netdev.h>
 #include <spi.h>
+#include <asm/gpio.h>
 #include <asm/arch/cpu.h>
 #include <asm/arch/dwmmc.h>
-#include <asm/arch/gpio.h>
 #include <asm/arch/mmc.h>
 #include <asm/arch/pinmux.h>
 #include <asm/arch/power.h>
 #include <asm/arch/sromc.h>
 #include <power/pmic.h>
 #include <power/max77686_pmic.h>
+#include <power/tps65090_pmic.h>
 #include <tmu.h>
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -41,7 +42,197 @@
 	return 0;
 }
 
+#if defined(CONFIG_POWER)
+#ifdef CONFIG_POWER_MAX77686
+static int pmic_reg_update(struct pmic *p, int reg, uint regval)
+{
+	u32 val;
+	int ret = 0;
+
+	ret = pmic_reg_read(p, reg, &val);
+	if (ret) {
+		debug("%s: PMIC %d register read failed\n", __func__, reg);
+		return -1;
+	}
+	val |= regval;
+	ret = pmic_reg_write(p, reg, val);
+	if (ret) {
+		debug("%s: PMIC %d register write failed\n", __func__, reg);
+		return -1;
+	}
+	return 0;
+}
+
+static int max77686_init(void)
+{
+	struct pmic *p;
+
+	if (pmic_init(I2C_PMIC))
+		return -1;
+
+	p = pmic_get("MAX77686_PMIC");
+	if (!p)
+		return -ENODEV;
+
+	if (pmic_probe(p))
+		return -1;
+
+	if (pmic_reg_update(p, MAX77686_REG_PMIC_32KHZ, MAX77686_32KHCP_EN))
+		return -1;
+
+	if (pmic_reg_update(p, MAX77686_REG_PMIC_BBAT,
+			    MAX77686_BBCHOSTEN | MAX77686_BBCVS_3_5V))
+		return -1;
+
+	/* VDD_MIF */
+	if (pmic_reg_write(p, MAX77686_REG_PMIC_BUCK1OUT,
+			   MAX77686_BUCK1OUT_1V)) {
+		debug("%s: PMIC %d register write failed\n", __func__,
+		      MAX77686_REG_PMIC_BUCK1OUT);
+		return -1;
+	}
+
+	if (pmic_reg_update(p, MAX77686_REG_PMIC_BUCK1CRTL,
+			    MAX77686_BUCK1CTRL_EN))
+		return -1;
+
+	/* VDD_ARM */
+	if (pmic_reg_write(p, MAX77686_REG_PMIC_BUCK2DVS1,
+			   MAX77686_BUCK2DVS1_1_3V)) {
+		debug("%s: PMIC %d register write failed\n", __func__,
+		      MAX77686_REG_PMIC_BUCK2DVS1);
+		return -1;
+	}
+
+	if (pmic_reg_update(p, MAX77686_REG_PMIC_BUCK2CTRL1,
+			    MAX77686_BUCK2CTRL_ON))
+		return -1;
+
+	/* VDD_INT */
+	if (pmic_reg_write(p, MAX77686_REG_PMIC_BUCK3DVS1,
+			   MAX77686_BUCK3DVS1_1_0125V)) {
+		debug("%s: PMIC %d register write failed\n", __func__,
+		      MAX77686_REG_PMIC_BUCK3DVS1);
+		return -1;
+	}
+
+	if (pmic_reg_update(p, MAX77686_REG_PMIC_BUCK3CTRL,
+			    MAX77686_BUCK3CTRL_ON))
+		return -1;
+
+	/* VDD_G3D */
+	if (pmic_reg_write(p, MAX77686_REG_PMIC_BUCK4DVS1,
+			   MAX77686_BUCK4DVS1_1_2V)) {
+		debug("%s: PMIC %d register write failed\n", __func__,
+		      MAX77686_REG_PMIC_BUCK4DVS1);
+		return -1;
+	}
+
+	if (pmic_reg_update(p, MAX77686_REG_PMIC_BUCK4CTRL1,
+			    MAX77686_BUCK3CTRL_ON))
+		return -1;
+
+	/* VDD_LDO2 */
+	if (pmic_reg_update(p, MAX77686_REG_PMIC_LDO2CTRL1,
+			    MAX77686_LD02CTRL1_1_5V | EN_LDO))
+		return -1;
+
+	/* VDD_LDO3 */
+	if (pmic_reg_update(p, MAX77686_REG_PMIC_LDO3CTRL1,
+			    MAX77686_LD03CTRL1_1_8V | EN_LDO))
+		return -1;
+
+	/* VDD_LDO5 */
+	if (pmic_reg_update(p, MAX77686_REG_PMIC_LDO5CTRL1,
+			    MAX77686_LD05CTRL1_1_8V | EN_LDO))
+		return -1;
+
+	/* VDD_LDO10 */
+	if (pmic_reg_update(p, MAX77686_REG_PMIC_LDO10CTRL1,
+			    MAX77686_LD10CTRL1_1_8V | EN_LDO))
+		return -1;
+
+	return 0;
+}
+#endif	/* CONFIG_POWER_MAX77686 */
+
+int exynos_power_init(void)
+{
+	int ret = 0;
+
+#ifdef CONFIG_POWER_MAX77686
+	ret = max77686_init();
+	if (ret)
+		return ret;
+#endif
+#ifdef CONFIG_POWER_TPS65090
+	/*
+	 * The TPS65090 may not be in the device tree. If so, it is not
+	 * an error.
+	 */
+	ret = tps65090_init();
+	if (ret == 0 || ret == -ENODEV)
+		return 0;
+#endif
+
+	return ret;
+}
+#endif	/* CONFIG_POWER */
+
 #ifdef CONFIG_LCD
+static int board_dp_bridge_setup(void)
+{
+	const int max_tries = 10;
+	int num_tries, node;
+
+	/*
+	 * TODO(sjg): Use device tree for GPIOs when exynos GPIO
+	 * numbering patch is in mainline.
+	 */
+	debug("%s\n", __func__);
+	node = fdtdec_next_compatible(gd->fdt_blob, 0, COMPAT_NXP_PTN3460);
+	if (node < 0) {
+		debug("%s: No node for DP bridge in device tree\n", __func__);
+		return -ENODEV;
+	}
+
+	/* Setup the GPIOs */
+
+	/* PD is ACTIVE_LOW, and initially de-asserted */
+	gpio_set_pull(EXYNOS5_GPIO_Y25, S5P_GPIO_PULL_NONE);
+	gpio_direction_output(EXYNOS5_GPIO_Y25, 1);
+
+	/* Reset is ACTIVE_LOW */
+	gpio_set_pull(EXYNOS5_GPIO_X15, S5P_GPIO_PULL_NONE);
+	gpio_direction_output(EXYNOS5_GPIO_X15, 0);
+
+	udelay(10);
+	gpio_set_value(EXYNOS5_GPIO_X15, 1);
+
+	gpio_direction_input(EXYNOS5_GPIO_X07);
+
+	/*
+	 * We need to wait for 90ms after bringing up the bridge since there
+	 * is a phantom "high" on the HPD chip during its bootup.  The phantom
+	 * high comes within 7ms of de-asserting PD and persists for at least
+	 * 15ms.  The real high comes roughly 50ms after PD is de-asserted. The
+	 * phantom high makes it hard for us to know when the NXP chip is up.
+	 */
+	mdelay(90);
+
+	for (num_tries = 0; num_tries < max_tries; num_tries++) {
+		/* Check HPD.  If it's high, we're all good. */
+		if (gpio_get_value(EXYNOS5_GPIO_X07))
+				return 0;
+
+		debug("%s: eDP bridge failed to come up; try %d of %d\n",
+		      __func__, num_tries, max_tries);
+	}
+
+	/* Immediately go into bridge reset if the hp line is not high */
+	return -ENODEV;
+}
+
 void exynos_cfg_lcd_gpio(void)
 {
 	/* For Backlight */
@@ -60,4 +251,49 @@
 {
 	set_dp_phy_ctrl(onoff);
 }
+
+void exynos_backlight_on(unsigned int on)
+{
+	debug("%s(%u)\n", __func__, on);
+
+	if (!on)
+		return;
+
+#ifdef CONFIG_POWER_TPS65090
+	int ret;
+
+	ret = tps65090_fet_enable(1); /* Enable FET1, backlight */
+	if (ret)
+		return;
+
+	/* T5 in the LCD timing spec (defined as > 10ms) */
+	mdelay(10);
+
+	/* board_dp_backlight_pwm */
+	gpio_direction_output(EXYNOS5_GPIO_B20, 1);
+
+	/* T6 in the LCD timing spec (defined as > 10ms) */
+	mdelay(10);
+
+	/* board_dp_backlight_en */
+	gpio_direction_output(EXYNOS5_GPIO_X30, 1);
+#endif
+}
+
+void exynos_lcd_power_on(void)
+{
+	int ret;
+
+	debug("%s\n", __func__);
+
+#ifdef CONFIG_POWER_TPS65090
+	/* board_dp_lcd_vdd */
+	tps65090_fet_enable(6); /* Enable FET6, lcd panel */
+#endif
+
+	ret = board_dp_bridge_setup();
+	if (ret && ret != -ENODEV)
+		printf("LCD bridge failed to enable: %d\n", ret);
+}
+
 #endif
diff --git a/board/samsung/smdk5250/smdk5250.c b/board/samsung/smdk5250/smdk5250.c
deleted file mode 100644
index 014b7bd..0000000
--- a/board/samsung/smdk5250/smdk5250.c
+++ /dev/null
@@ -1,363 +0,0 @@
-/*
- * Copyright (C) 2012 Samsung Electronics
- *
- * SPDX-License-Identifier:	GPL-2.0+
- */
-
-#include <common.h>
-#include <cros_ec.h>
-#include <fdtdec.h>
-#include <asm/io.h>
-#include <errno.h>
-#include <i2c.h>
-#include <lcd.h>
-#include <netdev.h>
-#include <spi.h>
-#include <asm/arch/cpu.h>
-#include <asm/arch/dwmmc.h>
-#include <asm/arch/gpio.h>
-#include <asm/arch/mmc.h>
-#include <asm/arch/pinmux.h>
-#include <asm/arch/power.h>
-#include <asm/arch/sromc.h>
-#include <asm/arch/dp_info.h>
-#include <power/pmic.h>
-#include <power/max77686_pmic.h>
-
-DECLARE_GLOBAL_DATA_PTR;
-
-#ifdef CONFIG_SOUND_MAX98095
-static void  board_enable_audio_codec(void)
-{
-	/* Enable MAX98095 Codec */
-	gpio_direction_output(EXYNOS5_GPIO_X17, 1);
-	gpio_set_pull(EXYNOS5_GPIO_X17, S5P_GPIO_PULL_NONE);
-}
-#endif
-
-int exynos_init(void)
-{
-#ifdef CONFIG_SOUND_MAX98095
-	board_enable_audio_codec();
-#endif
-	return 0;
-}
-
-int board_eth_init(bd_t *bis)
-{
-#ifdef CONFIG_SMC911X
-	u32 smc_bw_conf, smc_bc_conf;
-	struct fdt_sromc config;
-	fdt_addr_t base_addr;
-
-	/* Non-FDT configuration - bank number and timing parameters*/
-	config.bank = CONFIG_ENV_SROM_BANK;
-	config.width = 2;
-
-	config.timing[FDT_SROM_TACS] = 0x01;
-	config.timing[FDT_SROM_TCOS] = 0x01;
-	config.timing[FDT_SROM_TACC] = 0x06;
-	config.timing[FDT_SROM_TCOH] = 0x01;
-	config.timing[FDT_SROM_TAH] = 0x0C;
-	config.timing[FDT_SROM_TACP] = 0x09;
-	config.timing[FDT_SROM_PMC] = 0x01;
-	base_addr = CONFIG_SMC911X_BASE;
-
-	/* Ethernet needs data bus width of 16 bits */
-	if (config.width != 2) {
-		debug("%s: Unsupported bus width %d\n", __func__,
-			config.width);
-		return -1;
-	}
-	smc_bw_conf = SROMC_DATA16_WIDTH(config.bank)
-			| SROMC_BYTE_ENABLE(config.bank);
-
-	smc_bc_conf = SROMC_BC_TACS(config.timing[FDT_SROM_TACS])   |\
-			SROMC_BC_TCOS(config.timing[FDT_SROM_TCOS]) |\
-			SROMC_BC_TACC(config.timing[FDT_SROM_TACC]) |\
-			SROMC_BC_TCOH(config.timing[FDT_SROM_TCOH]) |\
-			SROMC_BC_TAH(config.timing[FDT_SROM_TAH])   |\
-			SROMC_BC_TACP(config.timing[FDT_SROM_TACP]) |\
-			SROMC_BC_PMC(config.timing[FDT_SROM_PMC]);
-
-	/* Select and configure the SROMC bank */
-	exynos_pinmux_config(PERIPH_ID_SROMC, config.bank);
-	s5p_config_sromc(config.bank, smc_bw_conf, smc_bc_conf);
-	return smc911x_initialize(0, base_addr);
-#endif
-	return 0;
-}
-
-#ifdef CONFIG_DISPLAY_BOARDINFO
-int checkboard(void)
-{
-	printf("\nBoard: SMDK5250\n");
-	return 0;
-}
-#endif
-
-#ifdef CONFIG_GENERIC_MMC
-int board_mmc_init(bd_t *bis)
-{
-	int err, ret = 0, index, bus_width;
-	u32 base;
-
-	err = exynos_pinmux_config(PERIPH_ID_SDMMC0, PINMUX_FLAG_8BIT_MODE);
-	if (err)
-		debug("SDMMC0 not configured\n");
-	ret |= err;
-
-	/*EMMC: dwmmc Channel-0 with 8 bit bus width */
-	index = 0;
-	base =  samsung_get_base_mmc() + (0x10000 * index);
-	bus_width = 8;
-	err = exynos_dwmci_add_port(index, base, bus_width, (u32)NULL);
-	if (err)
-		debug("dwmmc Channel-0 init failed\n");
-	ret |= err;
-
-	err = exynos_pinmux_config(PERIPH_ID_SDMMC2, PINMUX_FLAG_NONE);
-	if (err)
-		debug("SDMMC2 not configured\n");
-	ret |= err;
-
-	/*SD: dwmmc Channel-2 with 4 bit bus width */
-	index = 2;
-	base = samsung_get_base_mmc() + (0x10000 * index);
-	bus_width = 4;
-	err = exynos_dwmci_add_port(index, base, bus_width, (u32)NULL);
-	if (err)
-		debug("dwmmc Channel-2 init failed\n");
-	ret |= err;
-
-	return ret;
-}
-#endif
-
-void board_i2c_init(const void *blob)
-{
-	int i;
-
-	for (i = 0; i < CONFIG_MAX_I2C_NUM; i++) {
-		exynos_pinmux_config((PERIPH_ID_I2C0 + i),
-				     PINMUX_FLAG_NONE);
-	}
-}
-
-#if defined(CONFIG_POWER)
-#ifdef CONFIG_POWER_MAX77686
-static int pmic_reg_update(struct pmic *p, int reg, uint regval)
-{
-	u32 val;
-	int ret = 0;
-
-	ret = pmic_reg_read(p, reg, &val);
-	if (ret) {
-		debug("%s: PMIC %d register read failed\n", __func__, reg);
-		return -1;
-	}
-	val |= regval;
-	ret = pmic_reg_write(p, reg, val);
-	if (ret) {
-		debug("%s: PMIC %d register write failed\n", __func__, reg);
-		return -1;
-	}
-	return 0;
-}
-
-static int max77686_init(void)
-{
-	struct pmic *p;
-
-	if (pmic_init(I2C_PMIC))
-		return -1;
-
-	p = pmic_get("MAX77686_PMIC");
-	if (!p)
-		return -ENODEV;
-
-	if (pmic_probe(p))
-		return -1;
-
-	if (pmic_reg_update(p, MAX77686_REG_PMIC_32KHZ, MAX77686_32KHCP_EN))
-		return -1;
-
-	if (pmic_reg_update(p, MAX77686_REG_PMIC_BBAT,
-			    MAX77686_BBCHOSTEN | MAX77686_BBCVS_3_5V))
-		return -1;
-
-	/* VDD_MIF */
-	if (pmic_reg_write(p, MAX77686_REG_PMIC_BUCK1OUT,
-			   MAX77686_BUCK1OUT_1V)) {
-		debug("%s: PMIC %d register write failed\n", __func__,
-		      MAX77686_REG_PMIC_BUCK1OUT);
-		return -1;
-	}
-
-	if (pmic_reg_update(p, MAX77686_REG_PMIC_BUCK1CRTL,
-			    MAX77686_BUCK1CTRL_EN))
-		return -1;
-
-	/* VDD_ARM */
-	if (pmic_reg_write(p, MAX77686_REG_PMIC_BUCK2DVS1,
-			   MAX77686_BUCK2DVS1_1_3V)) {
-		debug("%s: PMIC %d register write failed\n", __func__,
-		      MAX77686_REG_PMIC_BUCK2DVS1);
-		return -1;
-	}
-
-	if (pmic_reg_update(p, MAX77686_REG_PMIC_BUCK2CTRL1,
-			    MAX77686_BUCK2CTRL_ON))
-		return -1;
-
-	/* VDD_INT */
-	if (pmic_reg_write(p, MAX77686_REG_PMIC_BUCK3DVS1,
-			   MAX77686_BUCK3DVS1_1_0125V)) {
-		debug("%s: PMIC %d register write failed\n", __func__,
-		      MAX77686_REG_PMIC_BUCK3DVS1);
-		return -1;
-	}
-
-	if (pmic_reg_update(p, MAX77686_REG_PMIC_BUCK3CTRL,
-			    MAX77686_BUCK3CTRL_ON))
-		return -1;
-
-	/* VDD_G3D */
-	if (pmic_reg_write(p, MAX77686_REG_PMIC_BUCK4DVS1,
-			   MAX77686_BUCK4DVS1_1_2V)) {
-		debug("%s: PMIC %d register write failed\n", __func__,
-		      MAX77686_REG_PMIC_BUCK4DVS1);
-		return -1;
-	}
-
-	if (pmic_reg_update(p, MAX77686_REG_PMIC_BUCK4CTRL1,
-			    MAX77686_BUCK3CTRL_ON))
-		return -1;
-
-	/* VDD_LDO2 */
-	if (pmic_reg_update(p, MAX77686_REG_PMIC_LDO2CTRL1,
-			    MAX77686_LD02CTRL1_1_5V | EN_LDO))
-		return -1;
-
-	/* VDD_LDO3 */
-	if (pmic_reg_update(p, MAX77686_REG_PMIC_LDO3CTRL1,
-			    MAX77686_LD03CTRL1_1_8V | EN_LDO))
-		return -1;
-
-	/* VDD_LDO5 */
-	if (pmic_reg_update(p, MAX77686_REG_PMIC_LDO5CTRL1,
-			    MAX77686_LD05CTRL1_1_8V | EN_LDO))
-		return -1;
-
-	/* VDD_LDO10 */
-	if (pmic_reg_update(p, MAX77686_REG_PMIC_LDO10CTRL1,
-			    MAX77686_LD10CTRL1_1_8V | EN_LDO))
-		return -1;
-
-	return 0;
-}
-#endif	/* CONFIG_POWER_MAX77686 */
-
-int exynos_power_init(void)
-{
-	int ret = 0;
-
-#ifdef CONFIG_POWER_MAX77686
-	ret = max77686_init();
-#endif
-	return ret;
-}
-#endif	/* CONFIG_POWER */
-
-#ifdef CONFIG_LCD
-void exynos_cfg_lcd_gpio(void)
-{
-
-	/* For Backlight */
-	gpio_cfg_pin(EXYNOS5_GPIO_B20, S5P_GPIO_OUTPUT);
-	gpio_set_value(EXYNOS5_GPIO_B20, 1);
-
-	/* LCD power on */
-	gpio_cfg_pin(EXYNOS5_GPIO_X15, S5P_GPIO_OUTPUT);
-	gpio_set_value(EXYNOS5_GPIO_X15, 1);
-
-	/* Set Hotplug detect for DP */
-	gpio_cfg_pin(EXYNOS5_GPIO_X07, S5P_GPIO_FUNC(0x3));
-}
-
-void exynos_set_dp_phy(unsigned int onoff)
-{
-	set_dp_phy_ctrl(onoff);
-}
-
-vidinfo_t panel_info = {
-	.vl_freq	= 60,
-	.vl_col		= 2560,
-	.vl_row		= 1600,
-	.vl_width	= 2560,
-	.vl_height	= 1600,
-	.vl_clkp	= CONFIG_SYS_LOW,
-	.vl_hsp		= CONFIG_SYS_LOW,
-	.vl_vsp		= CONFIG_SYS_LOW,
-	.vl_dp		= CONFIG_SYS_LOW,
-	.vl_bpix	= 4,	/* LCD_BPP = 2^4, for output conosle on LCD */
-
-	/* wDP panel timing infomation */
-	.vl_hspw	= 32,
-	.vl_hbpd	= 80,
-	.vl_hfpd	= 48,
-
-	.vl_vspw	= 6,
-	.vl_vbpd	= 37,
-	.vl_vfpd	= 3,
-	.vl_cmd_allow_len = 0xf,
-
-	.win_id		= 3,
-	.dual_lcd_enabled = 0,
-
-	.init_delay	= 0,
-	.power_on_delay = 0,
-	.reset_delay	= 0,
-	.interface_mode = FIMD_RGB_INTERFACE,
-	.dp_enabled	= 1,
-};
-
-static struct edp_device_info edp_info = {
-	.disp_info = {
-		.h_res = 2560,
-		.h_sync_width = 32,
-		.h_back_porch = 80,
-		.h_front_porch = 48,
-		.v_res = 1600,
-		.v_sync_width  = 6,
-		.v_back_porch = 37,
-		.v_front_porch = 3,
-		.v_sync_rate = 60,
-	},
-	.lt_info = {
-		.lt_status = DP_LT_NONE,
-	},
-	.video_info = {
-		.master_mode = 0,
-		.bist_mode = DP_DISABLE,
-		.bist_pattern = NO_PATTERN,
-		.h_sync_polarity = 0,
-		.v_sync_polarity = 0,
-		.interlaced = 0,
-		.color_space = COLOR_RGB,
-		.dynamic_range = VESA,
-		.ycbcr_coeff = COLOR_YCBCR601,
-		.color_depth = COLOR_8,
-	},
-};
-
-static struct exynos_dp_platform_data dp_platform_data = {
-	.edp_dev_info	= &edp_info,
-};
-
-void init_panel_info(vidinfo_t *vid)
-{
-	vid->rgb_mode   = MODE_RGB_P;
-	exynos_set_dp_platform_data(&dp_platform_data);
-}
-#endif
diff --git a/board/samsung/smdk5420/smdk5420.c b/board/samsung/smdk5420/smdk5420.c
index 9207522..183c522 100644
--- a/board/samsung/smdk5420/smdk5420.c
+++ b/board/samsung/smdk5420/smdk5420.c
@@ -42,9 +42,6 @@
 #ifdef CONFIG_LCD
 void cfg_lcd_gpio(void)
 {
-	struct exynos5_gpio_part1 *gpio1 =
-		(struct exynos5_gpio_part1 *)samsung_get_base_gpio_part1();
-
 	/* For Backlight */
 	gpio_cfg_pin(EXYNOS5420_GPIO_B20, S5P_GPIO_OUTPUT);
 	gpio_set_value(EXYNOS5420_GPIO_B20, 1);
diff --git a/doc/device-tree-bindings/exynos/dwmmc.txt b/doc/device-tree-bindings/exynos/dwmmc.txt
index 566da3b..694d195 100644
--- a/doc/device-tree-bindings/exynos/dwmmc.txt
+++ b/doc/device-tree-bindings/exynos/dwmmc.txt
@@ -1,18 +1,18 @@
-* Exynos 5250 DWC_mobile_storage
+* Exynos DWC_mobile_storage
 
-The Exynos 5250 provides DWC_mobile_storage interface which supports
+The Exynos provides DWC_mobile_storage interface which supports
 . Embedded Multimedia Cards (EMMC-version 4.5)
 . Secure Digital memory (SD mem-version 2.0)
 . Secure Digital I/O (SDIO-version 3.0)
 . Consumer Electronics Advanced Transport Architecture (CE-ATA-version 1.1)
 
-The Exynos 5250 DWC_mobile_storage provides four channels.
+The Exynos DWC_mobile_storage provides four channels.
 SOC specific and Board specific properties are channel specific.
 
 Required SoC Specific Properties:
 
 - compatible: should be
-	- samsung,exynos5250-dwmmc: for exynos5250 platforms
+	- samsung,exynos-dwmmc: for exynos platforms
 
 - reg: physical base address of the controller and length of memory mapped
 	region.
diff --git a/doc/device-tree-bindings/power/tps65090.txt b/doc/device-tree-bindings/power/tps65090.txt
new file mode 100644
index 0000000..8e5e0d3
--- /dev/null
+++ b/doc/device-tree-bindings/power/tps65090.txt
@@ -0,0 +1,17 @@
+TPS65090 Frontend PMU with Switchmode Charger
+
+Required Properties:
+-compatible: "ti,tps65090-charger"
+
+Optional Properties:
+-ti,enable-low-current-chrg: Enables charging when a low current is detected
+ while the default logic is to stop charging.
+
+This node is a subnode of the tps65090 PMIC.
+
+Example:
+
+	tps65090-charger {
+		compatible = "ti,tps65090-charger";
+		ti,enable-low-current-chrg;
+	};
diff --git a/doc/device-tree-bindings/regulator/tps65090.txt b/doc/device-tree-bindings/regulator/tps65090.txt
new file mode 100644
index 0000000..313a60b
--- /dev/null
+++ b/doc/device-tree-bindings/regulator/tps65090.txt
@@ -0,0 +1,122 @@
+TPS65090 regulators
+
+Required properties:
+- compatible: "ti,tps65090"
+- reg: I2C slave address
+- interrupts: the interrupt outputs of the controller
+- regulators: A node that houses a sub-node for each regulator within the
+  device. Each sub-node is identified using the node's name, with valid
+  values listed below. The content of each sub-node is defined by the
+  standard binding for regulators; see regulator.txt.
+  dcdc[1-3], fet[1-7] and ldo[1-2] respectively.
+- vsys[1-3]-supply: The input supply for DCDC[1-3] respectively.
+- infet[1-7]-supply: The input supply for FET[1-7] respectively.
+- vsys-l[1-2]-supply: The input supply for LDO[1-2] respectively.
+
+Optional properties:
+- ti,enable-ext-control: This is applicable for DCDC1, DCDC2 and DCDC3.
+  If DCDCs are externally controlled then this property should be there.
+- "dcdc-ext-control-gpios: This is applicable for DCDC1, DCDC2 and DCDC3.
+  If DCDCs are externally controlled and if it is from GPIO then GPIO
+  number should be provided. If it is externally controlled and no GPIO
+  entry then driver will just configure this rails as external control
+  and will not provide any enable/disable APIs.
+
+Each regulator is defined using the standard binding for regulators.
+
+Example:
+
+	tps65090@48 {
+		compatible = "ti,tps65090";
+		reg = <0x48>;
+		interrupts = <0 88 0x4>;
+
+		vsys1-supply = <&some_reg>;
+		vsys2-supply = <&some_reg>;
+		vsys3-supply = <&some_reg>;
+		infet1-supply = <&some_reg>;
+		infet2-supply = <&some_reg>;
+		infet3-supply = <&some_reg>;
+		infet4-supply = <&some_reg>;
+		infet5-supply = <&some_reg>;
+		infet6-supply = <&some_reg>;
+		infet7-supply = <&some_reg>;
+		vsys_l1-supply = <&some_reg>;
+		vsys_l2-supply = <&some_reg>;
+
+		regulators {
+			dcdc1 {
+				regulator-name = "dcdc1";
+				regulator-boot-on;
+				regulator-always-on;
+				ti,enable-ext-control;
+				dcdc-ext-control-gpios = <&gpio 10 0>;
+			};
+
+			dcdc2 {
+				regulator-name = "dcdc2";
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			dcdc3 {
+				regulator-name = "dcdc3";
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			fet1 {
+				regulator-name = "fet1";
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			fet2 {
+				regulator-name = "fet2";
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			fet3 {
+				regulator-name = "fet3";
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			fet4 {
+				regulator-name = "fet4";
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			fet5 {
+				regulator-name = "fet5";
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			fet6 {
+				regulator-name = "fet6";
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			fet7 {
+				regulator-name = "fet7";
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			ldo1 {
+				regulator-name = "ldo1";
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			ldo2 {
+				regulator-name = "ldo2";
+				regulator-boot-on;
+				regulator-always-on;
+			};
+		};
+	};
diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c
index eb4e2be..5bf36a0 100644
--- a/drivers/mmc/dw_mmc.c
+++ b/drivers/mmc/dw_mmc.c
@@ -284,8 +284,8 @@
 
 static void dwmci_set_ios(struct mmc *mmc)
 {
-	struct dwmci_host *host = mmc->priv;
-	u32 ctype;
+	struct dwmci_host *host = (struct dwmci_host *)mmc->priv;
+	u32 ctype, regs;
 
 	debug("Buswidth = %d, clock: %d\n",mmc->bus_width, mmc->clock);
 
@@ -304,6 +304,14 @@
 
 	dwmci_writel(host, DWMCI_CTYPE, ctype);
 
+	regs = dwmci_readl(host, DWMCI_UHS_REG);
+	if (mmc->card_caps & MMC_MODE_DDR_52MHz)
+		regs |= DWMCI_DDR_MODE;
+	else
+		regs &= DWMCI_DDR_MODE;
+
+	dwmci_writel(host, DWMCI_UHS_REG, regs);
+
 	if (host->clksel)
 		host->clksel(host);
 }
diff --git a/drivers/mmc/exynos_dw_mmc.c b/drivers/mmc/exynos_dw_mmc.c
index de8cdcc..d96dfe1 100644
--- a/drivers/mmc/exynos_dw_mmc.c
+++ b/drivers/mmc/exynos_dw_mmc.c
@@ -13,6 +13,8 @@
 #include <asm/arch/dwmmc.h>
 #include <asm/arch/clk.h>
 #include <asm/arch/pinmux.h>
+#include <asm/gpio.h>
+#include <asm-generic/errno.h>
 
 #define	DWMMC_MAX_CH_NUM		4
 #define	DWMMC_MAX_FREQ			52000000
@@ -44,7 +46,11 @@
 			& DWMCI_DIVRATIO_MASK) + 1;
 	sclk = get_mmc_clk(host->dev_index);
 
-	return sclk / clk_div;
+	/*
+	 * Assume to know divider value.
+	 * When clock unit is broken, need to set "host->div"
+	 */
+	return sclk / clk_div / (host->div + 1);
 }
 
 static void exynos_dwmci_board_init(struct dwmci_host *host)
@@ -60,48 +66,36 @@
 	}
 }
 
-/*
- * This function adds the mmc channel to be registered with mmc core.
- * index -	mmc channel number.
- * regbase -	register base address of mmc channel specified in 'index'.
- * bus_width -	operating bus width of mmc channel specified in 'index'.
- * clksel -	value to be written into CLKSEL register in case of FDT.
- *		NULL in case od non-FDT.
- */
-int exynos_dwmci_add_port(int index, u32 regbase, int bus_width, u32 clksel)
+static int exynos_dwmci_core_init(struct dwmci_host *host, int index)
 {
-	struct dwmci_host *host = NULL;
 	unsigned int div;
 	unsigned long freq, sclk;
-	host = malloc(sizeof(struct dwmci_host));
-	if (!host) {
-		printf("dwmci_host malloc fail!\n");
-		return 1;
-	}
+
+	if (host->bus_hz)
+		freq = host->bus_hz;
+	else
+		freq = DWMMC_MAX_FREQ;
+
 	/* request mmc clock vlaue of 52MHz.  */
-	freq = 52000000;
 	sclk = get_mmc_clk(index);
 	div = DIV_ROUND_UP(sclk, freq);
 	/* set the clock divisor for mmc */
 	set_mmc_clk(index, div);
 
 	host->name = "EXYNOS DWMMC";
-	host->ioaddr = (void *)regbase;
-	host->buswidth = bus_width;
 #ifdef CONFIG_EXYNOS5420
 	host->quirks = DWMCI_QUIRK_DISABLE_SMU;
 #endif
 	host->board_init = exynos_dwmci_board_init;
 
-	if (clksel) {
-		host->clksel_val = clksel;
-	} else {
-		if (0 == index)
+	if (!host->clksel_val) {
+		if (index == 0)
 			host->clksel_val = DWMMC_MMC0_CLKSEL_VAL;
-		if (2 == index)
+		else if (index == 2)
 			host->clksel_val = DWMMC_MMC2_CLKSEL_VAL;
 	}
 
+	host->caps = MMC_MODE_DDR_52MHz;
 	host->clksel = exynos_dwmci_clksel;
 	host->dev_index = index;
 	host->get_mmc_clk = exynos_dwmci_get_clk;
@@ -113,69 +107,134 @@
 	return 0;
 }
 
-#ifdef CONFIG_OF_CONTROL
-int exynos_dwmmc_init(const void *blob)
+/*
+ * This function adds the mmc channel to be registered with mmc core.
+ * index -	mmc channel number.
+ * regbase -	register base address of mmc channel specified in 'index'.
+ * bus_width -	operating bus width of mmc channel specified in 'index'.
+ * clksel -	value to be written into CLKSEL register in case of FDT.
+ *		NULL in case od non-FDT.
+ */
+int exynos_dwmci_add_port(int index, u32 regbase, int bus_width, u32 clksel)
 {
-	int index, bus_width;
-	int node_list[DWMMC_MAX_CH_NUM];
-	int err = 0, dev_id, flag, count, i;
-	u32 clksel_val, base, timing[3];
+	struct dwmci_host *host = NULL;
 
-	count = fdtdec_find_aliases_for_id(blob, "mmc",
-				COMPAT_SAMSUNG_EXYNOS5_DWMMC, node_list,
-				DWMMC_MAX_CH_NUM);
+	host = malloc(sizeof(struct dwmci_host));
+	if (!host) {
+		error("dwmci_host malloc fail!\n");
+		return -ENOMEM;
+	}
+
+	host->ioaddr = (void *)regbase;
+	host->buswidth = bus_width;
+
+	if (clksel)
+		host->clksel_val = clksel;
+
+	return exynos_dwmci_core_init(host, index);
+}
+
+#ifdef CONFIG_OF_CONTROL
+static struct dwmci_host dwmci_host[DWMMC_MAX_CH_NUM];
+
+static int do_dwmci_init(struct dwmci_host *host)
+{
+	int index, flag, err;
+
+	index = host->dev_index;
+
+	flag = host->buswidth == 8 ? PINMUX_FLAG_8BIT_MODE : PINMUX_FLAG_NONE;
+	err = exynos_pinmux_config(host->dev_id, flag);
+	if (err) {
+		debug("DWMMC not configure\n");
+		return err;
+	}
+
+	return exynos_dwmci_core_init(host, index);
+}
+
+static int exynos_dwmci_get_config(const void *blob, int node,
+					struct dwmci_host *host)
+{
+	int err = 0;
+	u32 base, clksel_val, timing[3];
+
+	/* Extract device id for each mmc channel */
+	host->dev_id = pinmux_decode_periph_id(blob, node);
+
+	/* Get the bus width from the device node */
+	host->buswidth = fdtdec_get_int(blob, node, "samsung,bus-width", 0);
+	if (host->buswidth <= 0) {
+		debug("DWMMC: Can't get bus-width\n");
+		return -EINVAL;
+	}
+
+	host->dev_index = fdtdec_get_int(blob, node, "index", host->dev_id);
+	if (host->dev_index == host->dev_id)
+		host->dev_index = host->dev_id - PERIPH_ID_SDMMC0;
+
+	/* Set the base address from the device node */
+	base = fdtdec_get_addr(blob, node, "reg");
+	if (!base) {
+		debug("DWMMC: Can't get base address\n");
+		return -EINVAL;
+	}
+	host->ioaddr = (void *)base;
+
+	/* Extract the timing info from the node */
+	err =  fdtdec_get_int_array(blob, node, "samsung,timing", timing, 3);
+	if (err) {
+		debug("Can't get sdr-timings for devider\n");
+		return -EINVAL;
+	}
+
+	clksel_val = (DWMCI_SET_SAMPLE_CLK(timing[0]) |
+			DWMCI_SET_DRV_CLK(timing[1]) |
+			DWMCI_SET_DIV_RATIO(timing[2]));
+	if (clksel_val)
+		host->clksel_val = clksel_val;
+
+	host->fifoth_val = fdtdec_get_int(blob, node, "fifoth_val", 0);
+	host->bus_hz = fdtdec_get_int(blob, node, "bus_hz", 0);
+	host->div = fdtdec_get_int(blob, node, "div", 0);
+
+	return 0;
+}
+
+static int exynos_dwmci_process_node(const void *blob,
+					int node_list[], int count)
+{
+	struct dwmci_host *host;
+	int i, node, err;
 
 	for (i = 0; i < count; i++) {
-		int node = node_list[i];
-
+		node = node_list[i];
 		if (node <= 0)
 			continue;
-
-		/* Extract device id for each mmc channel */
-		dev_id = pinmux_decode_periph_id(blob, node);
-
-		/* Get the bus width from the device node */
-		bus_width = fdtdec_get_int(blob, node, "samsung,bus-width", 0);
-		if (bus_width <= 0) {
-			debug("DWMMC: Can't get bus-width\n");
-			return -1;
-		}
-		if (8 == bus_width)
-			flag = PINMUX_FLAG_8BIT_MODE;
-		else
-			flag = PINMUX_FLAG_NONE;
-
-		/* config pinmux for each mmc channel */
-		err = exynos_pinmux_config(dev_id, flag);
+		host = &dwmci_host[i];
+		err = exynos_dwmci_get_config(blob, node, host);
 		if (err) {
-			debug("DWMMC not configured\n");
+			debug("%s: failed to decode dev %d\n", __func__, i);
 			return err;
 		}
 
-		index = dev_id - PERIPH_ID_SDMMC0;
-
-		/* Get the base address from the device node */
-		base = fdtdec_get_addr(blob, node, "reg");
-		if (!base) {
-			debug("DWMMC: Can't get base address\n");
-			return -1;
-		}
-		/* Extract the timing info from the node */
-		err = fdtdec_get_int_array(blob, node, "samsung,timing",
-					timing, 3);
-		if (err) {
-			debug("Can't get sdr-timings for divider\n");
-			return -1;
-		}
-
-		clksel_val = (DWMCI_SET_SAMPLE_CLK(timing[0]) |
-				DWMCI_SET_DRV_CLK(timing[1]) |
-				DWMCI_SET_DIV_RATIO(timing[2]));
-		/* Initialise each mmc channel */
-		err = exynos_dwmci_add_port(index, base, bus_width, clksel_val);
-		if (err)
-			debug("dwmmc Channel-%d init failed\n", index);
+		do_dwmci_init(host);
 	}
 	return 0;
 }
+
+int exynos_dwmmc_init(const void *blob)
+{
+	int compat_id;
+	int node_list[DWMMC_MAX_CH_NUM];
+	int err = 0, count;
+
+	compat_id = COMPAT_SAMSUNG_EXYNOS_DWMMC;
+
+	count = fdtdec_find_aliases_for_id(blob, "mmc",
+				compat_id, node_list, DWMMC_MAX_CH_NUM);
+	err = exynos_dwmci_process_node(blob, node_list, count);
+
+	return err;
+}
 #endif
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 8b53ead..55c2c68 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -160,6 +160,9 @@
 {
 	struct mmc_cmd cmd;
 
+	if (mmc->card_caps & MMC_MODE_DDR_52MHz)
+		return 0;
+
 	cmd.cmdidx = MMC_CMD_SET_BLOCKLEN;
 	cmd.resp_type = MMC_RSP_R1;
 	cmd.cmdarg = len;
@@ -516,10 +519,13 @@
 		return 0;
 
 	/* High Speed is set, there are two types: 52MHz and 26MHz */
-	if (cardtype & MMC_HS_52MHZ)
+	if (cardtype & EXT_CSD_CARD_TYPE_52) {
+		if (cardtype & EXT_CSD_CARD_TYPE_DDR_52)
+			mmc->card_caps |= MMC_MODE_DDR_52MHz;
 		mmc->card_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
-	else
+	} else {
 		mmc->card_caps |= MMC_MODE_HS;
+	}
 
 	return 0;
 }
@@ -1082,6 +1088,8 @@
 
 		/* An array of possible bus widths in order of preference */
 		static unsigned ext_csd_bits[] = {
+			EXT_CSD_DDR_BUS_WIDTH_8,
+			EXT_CSD_DDR_BUS_WIDTH_4,
 			EXT_CSD_BUS_WIDTH_8,
 			EXT_CSD_BUS_WIDTH_4,
 			EXT_CSD_BUS_WIDTH_1,
@@ -1089,13 +1097,15 @@
 
 		/* An array to map CSD bus widths to host cap bits */
 		static unsigned ext_to_hostcaps[] = {
+			[EXT_CSD_DDR_BUS_WIDTH_4] = MMC_MODE_DDR_52MHz,
+			[EXT_CSD_DDR_BUS_WIDTH_8] = MMC_MODE_DDR_52MHz,
 			[EXT_CSD_BUS_WIDTH_4] = MMC_MODE_4BIT,
 			[EXT_CSD_BUS_WIDTH_8] = MMC_MODE_8BIT,
 		};
 
 		/* An array to map chosen bus width to an integer */
 		static unsigned widths[] = {
-			8, 4, 1,
+			8, 4, 8, 4, 1,
 		};
 
 		for (idx=0; idx < ARRAY_SIZE(ext_csd_bits); idx++) {
diff --git a/drivers/mmc/s5p_sdhci.c b/drivers/mmc/s5p_sdhci.c
index ccae4cc..2ff0ec2 100644
--- a/drivers/mmc/s5p_sdhci.c
+++ b/drivers/mmc/s5p_sdhci.c
@@ -65,17 +65,9 @@
 	sdhci_writel(host, ctrl, SDHCI_CONTROL2);
 }
 
-int s5p_sdhci_init(u32 regbase, int index, int bus_width)
+static int s5p_sdhci_core_init(struct sdhci_host *host)
 {
-	struct sdhci_host *host = NULL;
-	host = (struct sdhci_host *)malloc(sizeof(struct sdhci_host));
-	if (!host) {
-		printf("sdhci__host malloc fail!\n");
-		return 1;
-	}
-
 	host->name = S5P_NAME;
-	host->ioaddr = (void *)regbase;
 
 	host->quirks = SDHCI_QUIRK_NO_HISPD_BIT | SDHCI_QUIRK_BROKEN_VOLTAGE |
 		SDHCI_QUIRK_BROKEN_R1B | SDHCI_QUIRK_32BIT_DMA_ADDR |
@@ -85,15 +77,28 @@
 
 	host->set_control_reg = &s5p_sdhci_set_control_reg;
 	host->set_clock = set_mmc_clk;
-	host->index = index;
 
 	host->host_caps = MMC_MODE_HC;
-	if (bus_width == 8)
+	if (host->bus_width == 8)
 		host->host_caps |= MMC_MODE_8BIT;
 
 	return add_sdhci(host, 52000000, 400000);
 }
 
+int s5p_sdhci_init(u32 regbase, int index, int bus_width)
+{
+	struct sdhci_host *host = malloc(sizeof(struct sdhci_host));
+	if (!host) {
+		printf("sdhci__host malloc fail!\n");
+		return 1;
+	}
+	host->ioaddr = (void *)regbase;
+	host->index = index;
+	host->bus_width = bus_width;
+
+	return s5p_sdhci_core_init(host);
+}
+
 #ifdef CONFIG_OF_CONTROL
 struct sdhci_host sdhci_host[SDHCI_MAX_HOSTS];
 
@@ -126,20 +131,7 @@
 		}
 	}
 
-	host->name = S5P_NAME;
-
-	host->quirks = SDHCI_QUIRK_NO_HISPD_BIT | SDHCI_QUIRK_BROKEN_VOLTAGE |
-		SDHCI_QUIRK_BROKEN_R1B | SDHCI_QUIRK_32BIT_DMA_ADDR |
-		SDHCI_QUIRK_WAIT_SEND_CMD;
-	host->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
-	host->version = sdhci_readw(host, SDHCI_HOST_VERSION);
-
-	host->set_control_reg = &s5p_sdhci_set_control_reg;
-	host->set_clock = set_mmc_clk;
-
-	host->host_caps = MMC_MODE_HC;
-
-	return add_sdhci(host, 52000000, 400000);
+	return s5p_sdhci_core_init(host);
 }
 
 static int sdhci_get_config(const void *blob, int node, struct sdhci_host *host)
diff --git a/drivers/power/battery/bat_trats.c b/drivers/power/battery/bat_trats.c
index 41b179f..bfde692 100644
--- a/drivers/power/battery/bat_trats.c
+++ b/drivers/power/battery/bat_trats.c
@@ -19,7 +19,7 @@
 	struct battery *battery = p_bat->bat;
 	int k;
 
-	if (bat->chrg->chrg_state(p_bat->chrg, CHARGER_ENABLE, 450))
+	if (bat->chrg->chrg_state(p_bat->chrg, PMIC_CHARGER_ENABLE, 450))
 		return -1;
 
 	for (k = 0; bat->chrg->chrg_bat_present(p_bat->chrg) &&
@@ -42,7 +42,7 @@
 		}
 	}
  exit:
-	bat->chrg->chrg_state(p_bat->chrg, CHARGER_DISABLE, 0);
+	bat->chrg->chrg_state(p_bat->chrg, PMIC_CHARGER_DISABLE, 0);
 
 	return 0;
 }
diff --git a/drivers/power/battery/bat_trats2.c b/drivers/power/battery/bat_trats2.c
index 94015aa..57221ad 100644
--- a/drivers/power/battery/bat_trats2.c
+++ b/drivers/power/battery/bat_trats2.c
@@ -17,7 +17,7 @@
 {
 	struct power_battery *p_bat = bat->pbat;
 
-	if (bat->chrg->chrg_state(p_bat->chrg, CHARGER_ENABLE, 450))
+	if (bat->chrg->chrg_state(p_bat->chrg, PMIC_CHARGER_ENABLE, 450))
 		return -1;
 
 	return 0;
diff --git a/drivers/power/mfd/pmic_max77693.c b/drivers/power/mfd/pmic_max77693.c
index 1a4416b..6b28e28 100644
--- a/drivers/power/mfd/pmic_max77693.c
+++ b/drivers/power/mfd/pmic_max77693.c
@@ -22,7 +22,7 @@
 	val = MAX77693_CHG_UNLOCK;
 	pmic_reg_write(p, MAX77693_CHG_CNFG_06, val);
 
-	if (state == CHARGER_DISABLE) {
+	if (state == PMIC_CHARGER_DISABLE) {
 		puts("Disable the charger.\n");
 		pmic_reg_read(p, MAX77693_CHG_CNFG_00, &val);
 		val &= ~0x01;
diff --git a/drivers/power/pmic/Makefile b/drivers/power/pmic/Makefile
index 920bbdc..9a8bfe0 100644
--- a/drivers/power/pmic/Makefile
+++ b/drivers/power/pmic/Makefile
@@ -11,5 +11,6 @@
 obj-$(CONFIG_POWER_MUIC_MAX8997) += muic_max8997.o
 obj-$(CONFIG_POWER_MAX77686) += pmic_max77686.o
 obj-$(CONFIG_POWER_PFUZE100) += pmic_pfuze100.o
+obj-$(CONFIG_POWER_TPS65090) += pmic_tps65090.o
 obj-$(CONFIG_POWER_TPS65217) += pmic_tps65217.o
 obj-$(CONFIG_POWER_TPS65910) += pmic_tps65910.o
diff --git a/drivers/power/pmic/pmic_max8997.c b/drivers/power/pmic/pmic_max8997.c
index ba01692..a36a9a0 100644
--- a/drivers/power/pmic/pmic_max8997.c
+++ b/drivers/power/pmic/pmic_max8997.c
@@ -35,7 +35,7 @@
 	if (pmic_probe(p))
 		return -1;
 
-	if (state == CHARGER_DISABLE) {
+	if (state == PMIC_CHARGER_DISABLE) {
 		puts("Disable the charger.\n");
 		pmic_reg_read(p, MAX8997_REG_MBCCTRL2, &val);
 		val &= ~(MBCHOSTEN | VCHGR_FC);
diff --git a/drivers/power/pmic/pmic_tps65090.c b/drivers/power/pmic/pmic_tps65090.c
new file mode 100644
index 0000000..c5b3966
--- /dev/null
+++ b/drivers/power/pmic/pmic_tps65090.c
@@ -0,0 +1,310 @@
+/*
+ * Copyright (c) 2012 The Chromium OS Authors.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <fdtdec.h>
+#include <i2c.h>
+#include <power/pmic.h>
+#include <power/tps65090_pmic.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define TPS65090_NAME "TPS65090_PMIC"
+
+/* TPS65090 register addresses */
+enum {
+	REG_IRQ1 = 0,
+	REG_CG_CTRL0 = 4,
+	REG_CG_STATUS1 = 0xa,
+	REG_FET1_CTRL = 0x0f,
+	REG_FET2_CTRL,
+	REG_FET3_CTRL,
+	REG_FET4_CTRL,
+	REG_FET5_CTRL,
+	REG_FET6_CTRL,
+	REG_FET7_CTRL,
+	TPS65090_NUM_REGS,
+};
+
+enum {
+	IRQ1_VBATG = 1 << 3,
+	CG_CTRL0_ENC_MASK	= 0x01,
+
+	MAX_FET_NUM	= 7,
+	MAX_CTRL_READ_TRIES = 5,
+
+	/* TPS65090 FET_CTRL register values */
+	FET_CTRL_TOFET		= 1 << 7,  /* Timeout, startup, overload */
+	FET_CTRL_PGFET		= 1 << 4,  /* Power good for FET status */
+	FET_CTRL_WAIT		= 3 << 2,  /* Overcurrent timeout max */
+	FET_CTRL_ADENFET	= 1 << 1,  /* Enable output auto discharge */
+	FET_CTRL_ENFET		= 1 << 0,  /* Enable FET */
+};
+
+/**
+ * Checks for a valid FET number
+ *
+ * @param fet_id	FET number to check
+ * @return 0 if ok, -EINVAL if FET value is out of range
+ */
+static int tps65090_check_fet(unsigned int fet_id)
+{
+	if (fet_id == 0 || fet_id > MAX_FET_NUM) {
+		debug("parameter fet_id is out of range, %u not in 1 ~ %u\n",
+		      fet_id, MAX_FET_NUM);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/**
+ * Set the power state for a FET
+ *
+ * @param pmic		pmic structure for the tps65090
+ * @param fet_id	Fet number to set (1..MAX_FET_NUM)
+ * @param set		1 to power on FET, 0 to power off
+ * @return -EIO if we got a comms error, -EAGAIN if the FET failed to
+ * change state. If all is ok, returns 0.
+ */
+static int tps65090_fet_set(struct pmic *pmic, int fet_id, bool set)
+{
+	int retry;
+	u32 reg, value;
+
+	value = FET_CTRL_ADENFET | FET_CTRL_WAIT;
+	if (set)
+		value |= FET_CTRL_ENFET;
+
+	if (pmic_reg_write(pmic, REG_FET1_CTRL + fet_id - 1, value))
+		return -EIO;
+
+	/* Try reading until we get a result */
+	for (retry = 0; retry < MAX_CTRL_READ_TRIES; retry++) {
+		if (pmic_reg_read(pmic, REG_FET1_CTRL + fet_id - 1, &reg))
+			return -EIO;
+
+		/* Check that the fet went into the expected state */
+		if (!!(reg & FET_CTRL_PGFET) == set)
+			return 0;
+
+		/* If we got a timeout, there is no point in waiting longer */
+		if (reg & FET_CTRL_TOFET)
+			break;
+
+		mdelay(1);
+	}
+
+	debug("FET %d: Power good should have set to %d but reg=%#02x\n",
+	      fet_id, set, reg);
+	return -EAGAIN;
+}
+
+int tps65090_fet_enable(unsigned int fet_id)
+{
+	struct pmic *pmic;
+	ulong start;
+	int loops;
+	int ret;
+
+	ret = tps65090_check_fet(fet_id);
+	if (ret)
+		return ret;
+
+	pmic = pmic_get(TPS65090_NAME);
+	if (!pmic)
+		return -EACCES;
+
+	start = get_timer(0);
+	for (loops = 0;; loops++) {
+		ret = tps65090_fet_set(pmic, fet_id, true);
+		if (!ret)
+			break;
+
+		if (get_timer(start) > 100)
+			break;
+
+		/* Turn it off and try again until we time out */
+		tps65090_fet_set(pmic, fet_id, false);
+	}
+
+	if (ret)
+		debug("%s: FET%d failed to power on: time=%lums, loops=%d\n",
+		      __func__, fet_id, get_timer(start), loops);
+	else if (loops)
+		debug("%s: FET%d powered on after %lums, loops=%d\n",
+		      __func__, fet_id, get_timer(start), loops);
+
+	/*
+	 * Unfortunately, there are some conditions where the power
+	 * good bit will be 0, but the fet still comes up. One such
+	 * case occurs with the lcd backlight. We'll just return 0 here
+	 * and assume that the fet will eventually come up.
+	 */
+	if (ret == -EAGAIN)
+		ret = 0;
+
+	return ret;
+}
+
+int tps65090_fet_disable(unsigned int fet_id)
+{
+	struct pmic *pmic;
+	int ret;
+
+	ret = tps65090_check_fet(fet_id);
+	if (ret)
+		return ret;
+
+	pmic = pmic_get(TPS65090_NAME);
+	if (!pmic)
+		return -EACCES;
+	ret = tps65090_fet_set(pmic, fet_id, false);
+
+	return ret;
+}
+
+int tps65090_fet_is_enabled(unsigned int fet_id)
+{
+	struct pmic *pmic;
+	u32 reg;
+	int ret;
+
+	ret = tps65090_check_fet(fet_id);
+	if (ret)
+		return ret;
+
+	pmic = pmic_get(TPS65090_NAME);
+	if (!pmic)
+		return -ENODEV;
+	ret = pmic_reg_read(pmic, REG_FET1_CTRL + fet_id - 1, &reg);
+	if (ret) {
+		debug("fail to read FET%u_CTRL register over I2C", fet_id);
+		return -EIO;
+	}
+
+	return reg & FET_CTRL_ENFET;
+}
+
+int tps65090_get_charging(void)
+{
+	struct pmic *pmic;
+	u32 val;
+	int ret;
+
+	pmic = pmic_get(TPS65090_NAME);
+	if (!pmic)
+		return -EACCES;
+
+	ret = pmic_reg_read(pmic, REG_CG_CTRL0, &val);
+	if (ret)
+		return ret;
+
+	return !!(val & CG_CTRL0_ENC_MASK);
+}
+
+static int tps65090_charger_state(struct pmic *pmic, int state,
+				  int current)
+{
+	u32 val;
+	int ret;
+
+	ret = pmic_reg_read(pmic, REG_CG_CTRL0, &val);
+	if (!ret) {
+		if (state == PMIC_CHARGER_ENABLE)
+			val |= CG_CTRL0_ENC_MASK;
+		else
+			val &= ~CG_CTRL0_ENC_MASK;
+		ret = pmic_reg_write(pmic, REG_CG_CTRL0, val);
+	}
+	if (ret) {
+		debug("%s: Failed to read/write register\n", __func__);
+		return ret;
+	}
+
+	return 0;
+}
+
+int tps65090_get_status(void)
+{
+	struct pmic *pmic;
+	u32 val;
+	int ret;
+
+	pmic = pmic_get(TPS65090_NAME);
+	if (!pmic)
+		return -EACCES;
+
+	ret = pmic_reg_read(pmic, REG_CG_STATUS1, &val);
+	if (ret)
+		return ret;
+
+	return val;
+}
+
+static int tps65090_charger_bat_present(struct pmic *pmic)
+{
+	u32 val;
+	int ret;
+
+	ret = pmic_reg_read(pmic, REG_IRQ1, &val);
+	if (ret)
+		return ret;
+
+	return !!(val & IRQ1_VBATG);
+}
+
+static struct power_chrg power_chrg_pmic_ops = {
+	.chrg_bat_present = tps65090_charger_bat_present,
+	.chrg_state = tps65090_charger_state,
+};
+
+int tps65090_init(void)
+{
+	struct pmic *p;
+	int bus;
+	int addr;
+	const void *blob = gd->fdt_blob;
+	int node, parent;
+
+	node = fdtdec_next_compatible(blob, 0, COMPAT_TI_TPS65090);
+	if (node < 0) {
+		debug("PMIC: No node for PMIC Chip in device tree\n");
+		debug("node = %d\n", node);
+		return -ENODEV;
+	}
+
+	parent = fdt_parent_offset(blob, node);
+	if (parent < 0) {
+		debug("%s: Cannot find node parent\n", __func__);
+		return -EINVAL;
+	}
+
+	bus = i2c_get_bus_num_fdt(parent);
+	if (p->bus < 0) {
+		debug("%s: Cannot find I2C bus\n", __func__);
+		return -ENOENT;
+	}
+	addr = fdtdec_get_int(blob, node, "reg", TPS65090_I2C_ADDR);
+	p = pmic_alloc();
+	if (!p) {
+		printf("%s: POWER allocation error!\n", __func__);
+		return -ENOMEM;
+	}
+
+	p->name = TPS65090_NAME;
+	p->bus = bus;
+	p->interface = PMIC_I2C;
+	p->number_of_regs = TPS65090_NUM_REGS;
+	p->hw.i2c.addr = addr;
+	p->hw.i2c.tx_num = 1;
+	p->chrg = &power_chrg_pmic_ops;
+
+	puts("TPS65090 PMIC init\n");
+
+	return 0;
+}
diff --git a/drivers/power/power_fsl.c b/drivers/power/power_fsl.c
index ac0b541..a64161b 100644
--- a/drivers/power/power_fsl.c
+++ b/drivers/power/power_fsl.c
@@ -11,9 +11,9 @@
 #include <fsl_pmic.h>
 #include <errno.h>
 
-#if defined(CONFIG_PMIC_FSL_MC13892)
+#if defined(CONFIG_POWER_FSL_MC13892)
 #define FSL_PMIC_I2C_LENGTH	3
-#elif defined(CONFIG_PMIC_FSL_MC34704)
+#elif defined(CONFIG_POWER_FSL_MC34704)
 #define FSL_PMIC_I2C_LENGTH	1
 #endif
 
@@ -51,7 +51,7 @@
 	p->hw.i2c.addr = CONFIG_SYS_FSL_PMIC_I2C_ADDR;
 	p->hw.i2c.tx_num = FSL_PMIC_I2C_LENGTH;
 #else
-#error "You must select CONFIG_POWER_SPI or CONFIG_PMIC_I2C"
+#error "You must select CONFIG_POWER_SPI or CONFIG_POWER_I2C"
 #endif
 
 	return 0;
diff --git a/drivers/power/power_i2c.c b/drivers/power/power_i2c.c
index ac76870..594cd11 100644
--- a/drivers/power/power_i2c.c
+++ b/drivers/power/power_i2c.c
@@ -23,6 +23,8 @@
 	if (check_reg(p, reg))
 		return -1;
 
+	I2C_SET_BUS(p->bus);
+
 	switch (pmic_i2c_tx_num) {
 	case 3:
 		if (p->sensor_byte_order == PMIC_SENSOR_BYTE_ORDER_BIG) {
@@ -66,6 +68,8 @@
 	if (check_reg(p, reg))
 		return -1;
 
+	I2C_SET_BUS(p->bus);
+
 	if (i2c_read(pmic_i2c_addr, reg, 1, buf, pmic_i2c_tx_num))
 		return -1;
 
diff --git a/include/configs/arndale.h b/include/configs/arndale.h
index 515facf..30ecd45 100644
--- a/include/configs/arndale.h
+++ b/include/configs/arndale.h
@@ -224,8 +224,8 @@
 
 /* PMIC */
 #define CONFIG_PMIC
-#define CONFIG_PMIC_I2C
-#define CONFIG_PMIC_MAX77686
+#define CONFIG_POWER_I2C
+#define CONFIG_POWER_MAX77686
 
 #define CONFIG_DEFAULT_DEVICE_TREE	exynos5250-arndale
 
diff --git a/include/configs/exynos4-dt.h b/include/configs/exynos4-dt.h
index cbd2d20..44e6ab4 100644
--- a/include/configs/exynos4-dt.h
+++ b/include/configs/exynos4-dt.h
@@ -20,6 +20,7 @@
 #define CONFIG_DISPLAY_CPUINFO
 #define CONFIG_DISPLAY_BOARDINFO
 #define CONFIG_BOARD_COMMON
+#define CONFIG_SYS_GENERIC_BOARD
 
 /* Enable fdt support */
 #define CONFIG_OF_CONTROL
@@ -44,6 +45,9 @@
 #define CONFIG_S5P_SDHCI
 #define CONFIG_SDHCI
 #define CONFIG_MMC_SDMA
+#define CONFIG_DWMMC
+#define CONFIG_EXYNOS_DWMMC
+#define CONFIG_BOUNCE_BUFFER
 #define CONFIG_MMC_DEFAULT_DEV	0
 
 /* PWM */
diff --git a/include/configs/exynos5-dt.h b/include/configs/exynos5-dt.h
index 5a9b1b4..b830495 100644
--- a/include/configs/exynos5-dt.h
+++ b/include/configs/exynos5-dt.h
@@ -259,6 +259,7 @@
 /* PMIC */
 #define CONFIG_POWER
 #define CONFIG_POWER_I2C
+#define CONFIG_POWER_TPS65090
 
 /* Ethernet Controllor Driver */
 #ifdef CONFIG_CMD_NET
diff --git a/include/configs/exynos5250-dt.h b/include/configs/exynos5250-dt.h
index b7ff472..9d1d56a 100644
--- a/include/configs/exynos5250-dt.h
+++ b/include/configs/exynos5250-dt.h
@@ -45,7 +45,7 @@
 #define CONFIG_SYS_INIT_SP_ADDR	CONFIG_IRAM_STACK
 
 /* PMIC */
-#define CONFIG_PMIC_MAX77686
+#define CONFIG_POWER_MAX77686
 
 /* Sound */
 #define CONFIG_CMD_SOUND
diff --git a/include/configs/mx25pdk.h b/include/configs/mx25pdk.h
index aff2419..d464ad9 100644
--- a/include/configs/mx25pdk.h
+++ b/include/configs/mx25pdk.h
@@ -107,7 +107,7 @@
 #define CONFIG_POWER
 #define CONFIG_POWER_I2C
 #define CONFIG_POWER_FSL
-#define CONFIG_PMIC_FSL_MC34704
+#define CONFIG_POWER_FSL_MC34704
 #define CONFIG_SYS_FSL_PMIC_I2C_ADDR	0x54
 
 #define CONFIG_DOS_PARTITION
diff --git a/include/configs/mx35pdk.h b/include/configs/mx35pdk.h
index 0a46f4c..ab48144 100644
--- a/include/configs/mx35pdk.h
+++ b/include/configs/mx35pdk.h
@@ -52,7 +52,7 @@
 #define CONFIG_POWER
 #define CONFIG_POWER_I2C
 #define CONFIG_POWER_FSL
-#define CONFIG_PMIC_FSL_MC13892
+#define CONFIG_POWER_FSL_MC13892
 #define CONFIG_SYS_FSL_PMIC_I2C_ADDR	0x08
 #define CONFIG_RTC_MC13XXX
 
diff --git a/include/configs/mx53evk.h b/include/configs/mx53evk.h
index 5bbae8c..fb2072d 100644
--- a/include/configs/mx53evk.h
+++ b/include/configs/mx53evk.h
@@ -47,7 +47,7 @@
 #define CONFIG_POWER_I2C
 #define CONFIG_POWER_FSL
 #define CONFIG_SYS_FSL_PMIC_I2C_ADDR    8
-#define CONFIG_PMIC_FSL_MC13892
+#define CONFIG_POWER_FSL_MC13892
 #define CONFIG_RTC_MC13XXX
 
 /* MMC Configs */
diff --git a/include/configs/mx53loco.h b/include/configs/mx53loco.h
index 12d79b4..a74508c 100644
--- a/include/configs/mx53loco.h
+++ b/include/configs/mx53loco.h
@@ -82,7 +82,7 @@
 #define CONFIG_POWER_I2C
 #define CONFIG_DIALOG_POWER
 #define CONFIG_POWER_FSL
-#define CONFIG_PMIC_FSL_MC13892
+#define CONFIG_POWER_FSL_MC13892
 #define CONFIG_SYS_DIALOG_PMIC_I2C_ADDR	0x48
 #define CONFIG_SYS_FSL_PMIC_I2C_ADDR	0x8
 
diff --git a/include/configs/s5p_goni.h b/include/configs/s5p_goni.h
index 799d4fe..fce1716 100644
--- a/include/configs/s5p_goni.h
+++ b/include/configs/s5p_goni.h
@@ -17,6 +17,7 @@
 #define CONFIG_S5PC110		1	/* which is in a S5PC110 */
 #define CONFIG_MACH_GONI	1	/* working with Goni */
 
+#include <linux/sizes.h>
 #include <asm/arch/cpu.h>		/* get chip and board defs */
 
 #define CONFIG_ARCH_CPU_INIT
@@ -38,11 +39,9 @@
 #define CONFIG_INITRD_TAG
 #define CONFIG_CMDLINE_EDITING
 
-/*
- * Size of malloc() pool
- * 1MB = 0x100000, 0x100000 = 1024 * 1024
- */
-#define CONFIG_SYS_MALLOC_LEN		(CONFIG_ENV_SIZE + (1 << 20))
+/* Size of malloc() pool.*/
+#define CONFIG_SYS_MALLOC_LEN		(CONFIG_ENV_SIZE + 80 * SZ_1M)
+
 /*
  * select serial console configuration
  */
@@ -72,14 +71,19 @@
 #define CONFIG_CMD_CACHE
 #define CONFIG_CMD_REGINFO
 #define CONFIG_CMD_ONENAND
-#define CONFIG_CMD_MTDPARTS
 #define CONFIG_CMD_MMC
+#define CONFIG_CMD_DFU
+#define CONFIG_CMD_GPT
 
-#define CONFIG_BOOTDELAY		1
-#define CONFIG_ZERO_BOOTDELAY_CHECK
+/* USB Composite download gadget - g_dnl */
+#define CONFIG_USBDOWNLOAD_GADGET
+#define CONFIG_DFU_FUNCTION
+#define CONFIG_DFU_MMC
 
-#define CONFIG_MTD_DEVICE
-#define CONFIG_MTD_PARTITIONS
+/* USB Samsung's IDs */
+#define CONFIG_G_DNL_VENDOR_NUM 0x04E8
+#define CONFIG_G_DNL_PRODUCT_NUM 0x6601
+#define CONFIG_G_DNL_MANUFACTURER "Samsung"
 
 /* Actual modem binary size is 16MiB. Add 2MiB for bad block handling */
 #define MTDIDS_DEFAULT		"onenand0=samsung-onenand"
@@ -90,30 +94,52 @@
 				",7m(kernel)"\
 				",1m(log)"\
 				",12m(modem)"\
-				",60m(qboot)"\
-				",-(UBI)\0"
+				",60m(qboot)\0"
 
-#define NORMAL_MTDPARTS_DEFAULT MTDPARTS_DEFAULT
+#define CONFIG_BOOTDELAY		1
+#define CONFIG_ZERO_BOOTDELAY_CHECK
 
-#define CONFIG_BOOTCOMMAND	"run ubifsboot"
+/* partitions definitions */
+#define PARTS_CSA			"csa-mmc"
+#define PARTS_BOOTLOADER	"u-boot"
+#define PARTS_BOOT			"boot"
+#define PARTS_ROOT			"platform"
+#define PARTS_DATA			"data"
+#define PARTS_CSC			"csc"
+#define PARTS_UMS			"ums"
+
+#define CONFIG_DFU_ALT \
+	"u-boot raw 0x80 0x400;" \
+	"uImage ext4 0 2;" \
+	"exynos3-goni.dtb ext4 0 2;" \
+	""PARTS_ROOT" part 0 5\0"
+
+#define PARTS_DEFAULT \
+	"uuid_disk=${uuid_gpt_disk};" \
+	"name="PARTS_CSA",size=8MiB,uuid=${uuid_gpt_"PARTS_CSA"};" \
+	"name="PARTS_BOOTLOADER",size=60MiB," \
+	"uuid=${uuid_gpt_"PARTS_BOOTLOADER"};" \
+	"name="PARTS_BOOT",size=100MiB,uuid=${uuid_gpt_"PARTS_BOOT"};" \
+	"name="PARTS_ROOT",size=1GiB,uuid=${uuid_gpt_"PARTS_ROOT"};" \
+	"name="PARTS_DATA",size=3GiB,uuid=${uuid_gpt_"PARTS_DATA"};" \
+	"name="PARTS_CSC",size=150MiB,uuid=${uuid_gpt_"PARTS_CSC"};" \
+	"name="PARTS_UMS",size=-,uuid=${uuid_gpt_"PARTS_UMS"}\0" \
+
+#define CONFIG_BOOTCOMMAND	"run mmcboot"
 
 #define CONFIG_DEFAULT_CONSOLE	"console=ttySAC2,115200n8\0"
 
-#define CONFIG_RAMDISK_BOOT	"root=/dev/ram0 rw rootfstype=ext2" \
+#define CONFIG_RAMDISK_BOOT	"root=/dev/ram0 rw rootfstype=ext4" \
 		" ${console} ${meminfo}"
 
 #define CONFIG_COMMON_BOOT	"${console} ${meminfo} ${mtdparts}"
 
-#define CONFIG_BOOTARGS	"root=/dev/mtdblock8 ubi.mtd=8 ubi.mtd=3 ubi.mtd=6" \
-		" rootfstype=cramfs " CONFIG_COMMON_BOOT
+#define CONFIG_BOOTARGS	"root=/dev/mtdblock8 rootfstype=ext4 " \
+			CONFIG_COMMON_BOOT
 
 #define CONFIG_UPDATEB	"updateb=onenand erase 0x0 0x100000;" \
 			" onenand write 0x32008000 0x0 0x100000\0"
 
-#define CONFIG_UBI_MTD	" ubi.mtd=${ubiblock} ubi.mtd=3 ubi.mtd=6"
-
-#define CONFIG_UBIFS_OPTION	"rootflags=bulk_read,no_chk_data_crc"
-
 #define CONFIG_MISC_COMMON
 #define CONFIG_MISC_INIT_R
 
@@ -130,42 +156,44 @@
 		"onenand erase 0x01560000 0x1eaa0000;" \
 		"onenand write 0x32000000 0x1260000 0x8C0000\0" \
 	"bootk=" \
-		"onenand read 0x30007FC0 0xc00000 0x600000;" \
+		"run loaduimage;" \
 		"bootm 0x30007FC0\0" \
 	"flashboot=" \
 		"set bootargs root=/dev/mtdblock${bootblock} " \
-		"rootfstype=${rootfstype}" CONFIG_UBI_MTD " ${opts} " \
+		"rootfstype=${rootfstype} ${opts} " \
 		"${lcdinfo} " CONFIG_COMMON_BOOT "; run bootk\0" \
 	"ubifsboot=" \
 		"set bootargs root=ubi0!rootfs rootfstype=ubifs " \
-		CONFIG_UBIFS_OPTION CONFIG_UBI_MTD " ${opts} ${lcdinfo} " \
+		"${opts} ${lcdinfo} " \
 		CONFIG_COMMON_BOOT "; run bootk\0" \
 	"tftpboot=" \
 		"set bootargs root=ubi0!rootfs rootfstype=ubifs " \
-		CONFIG_UBIFS_OPTION CONFIG_UBI_MTD " ${opts} ${lcdinfo} " \
-		CONFIG_COMMON_BOOT "; tftp 0x30007FC0 uImage; " \
-		"bootm 0x30007FC0\0" \
+		"${opts} ${lcdinfo} " CONFIG_COMMON_BOOT \
+		"; tftp 0x30007FC0 uImage; bootm 0x30007FC0\0" \
 	"ramboot=" \
 		"set bootargs " CONFIG_RAMDISK_BOOT \
-		" initrd=0x33000000,8M ramdisk=8192\0" \
+		"initrd=0x33000000,8M ramdisk=8192\0" \
 	"mmcboot=" \
-		"set bootargs root=${mmcblk} rootfstype=${rootfstype}" \
-		CONFIG_UBI_MTD " ${opts} ${lcdinfo} " \
+		"set bootargs root=/dev/mmcblk${mmcdev}p${mmcrootpart} " \
+		"rootfstype=${rootfstype} ${opts} ${lcdinfo} " \
 		CONFIG_COMMON_BOOT "; run bootk\0" \
 	"boottrace=setenv opts initcall_debug; run bootcmd\0" \
 	"bootchart=set opts init=/sbin/bootchartd; run bootcmd\0" \
 	"verify=n\0" \
-	"rootfstype=cramfs\0" \
+	"rootfstype=ext4\0" \
 	"console=" CONFIG_DEFAULT_CONSOLE \
-	"mtdparts=" MTDPARTS_DEFAULT \
 	"meminfo=mem=80M mem=256M@0x40000000 mem=128M@0x50000000\0" \
-	"mmcblk=/dev/mmcblk1p1\0" \
+	"loaduimage=ext4load mmc ${mmcdev}:${mmcbootpart} 0x30007FC0 uImage\0" \
+	"mmcdev=0\0" \
+	"mmcbootpart=2\0" \
+	"mmcrootpart=5\0" \
+	"partitions=" PARTS_DEFAULT \
 	"bootblock=9\0" \
 	"ubiblock=8\0" \
 	"ubi=enabled\0" \
-	"opts=always_resume=1"
+	"opts=always_resume=1\0" \
+	"dfu_alt_info=" CONFIG_DFU_ALT "\0"
 
-/* Miscellaneous configurable options */
 #define CONFIG_SYS_LONGHELP		/* undef to save memory */
 #define CONFIG_SYS_HUSH_PARSER		/* use "hush" command parser	*/
 #define CONFIG_SYS_PROMPT	"Goni # "
@@ -202,6 +230,18 @@
 
 #define CONFIG_DOS_PARTITION		1
 
+#define CONFIG_CMD_FAT
+#define CONFIG_CMD_EXT4
+#define CONFIG_CMD_EXT4_WRITE
+
+/* write support for filesystems */
+#define CONFIG_FAT_WRITE
+#define CONFIG_EXT4_WRITE
+
+/* GPT */
+#define CONFIG_EFI_PARTITION
+#define CONFIG_PARTITION_UUIDS
+
 #define CONFIG_SYS_INIT_SP_ADDR	(CONFIG_SYS_LOAD_ADDR - 0x1000000)
 
 #define CONFIG_SYS_CACHELINE_SIZE       64
@@ -226,5 +266,8 @@
 #define CONFIG_USB_GADGET
 #define CONFIG_USB_GADGET_S3C_UDC_OTG
 #define CONFIG_USB_GADGET_DUALSPEED
+#define CONFIG_USB_GADGET_VBUS_DRAW 2
+#define CONFIG_CMD_USB_MASS_STORAGE
+#define CONFIG_USB_GADGET_MASS_STORAGE
 
 #endif	/* __CONFIG_H */
diff --git a/include/configs/woodburn_common.h b/include/configs/woodburn_common.h
index 695bc23..259205e 100644
--- a/include/configs/woodburn_common.h
+++ b/include/configs/woodburn_common.h
@@ -55,7 +55,7 @@
 #define CONFIG_POWER
 #define CONFIG_POWER_I2C
 #define CONFIG_POWER_FSL
-#define CONFIG_PMIC_FSL_MC13892
+#define CONFIG_POWER_FSL_MC13892
 #define CONFIG_SYS_FSL_PMIC_I2C_ADDR	0x8
 #define CONFIG_RTC_MC13XXX
 
diff --git a/include/dwmmc.h b/include/dwmmc.h
index c9bdf51..b67f11b 100644
--- a/include/dwmmc.h
+++ b/include/dwmmc.h
@@ -123,6 +123,9 @@
 #define DWMCI_BMOD_IDMAC_FB	(1 << 1)
 #define DWMCI_BMOD_IDMAC_EN	(1 << 7)
 
+/* UHS register */
+#define DWMCI_DDR_MODE	(1 << 16)
+
 /* quirks */
 #define DWMCI_QUIRK_DISABLE_SMU		(1 << 0)
 
@@ -134,7 +137,9 @@
 	unsigned int version;
 	unsigned int clock;
 	unsigned int bus_hz;
+	unsigned int div;
 	int dev_index;
+	int dev_id;
 	int buswidth;
 	u32 clksel_val;
 	u32 fifoth_val;
diff --git a/include/fdtdec.h b/include/fdtdec.h
index 3196cf6..a7e6ee7 100644
--- a/include/fdtdec.h
+++ b/include/fdtdec.h
@@ -81,7 +81,7 @@
 	COMPAT_SAMSUNG_EXYNOS_FIMD,	/* Exynos Display controller */
 	COMPAT_SAMSUNG_EXYNOS_MIPI_DSI,	/* Exynos mipi dsi */
 	COMPAT_SAMSUNG_EXYNOS5_DP,	/* Exynos Display port controller */
-	COMPAT_SAMSUNG_EXYNOS5_DWMMC,	/* Exynos5 DWMMC controller */
+	COMPAT_SAMSUNG_EXYNOS_DWMMC,	/* Exynos DWMMC controller */
 	COMPAT_SAMSUNG_EXYNOS_MMC,	/* Exynos MMC controller */
 	COMPAT_SAMSUNG_EXYNOS_SERIAL,	/* Exynos UART */
 	COMPAT_MAXIM_MAX77686_PMIC,	/* MAX77686 PMIC */
@@ -92,6 +92,8 @@
 	COMPAT_SAMSUNG_EXYNOS5_I2C,	/* Exynos5 High Speed I2C Controller */
 	COMPAT_SANDBOX_HOST_EMULATION,	/* Sandbox emulation of a function */
 	COMPAT_SANDBOX_LCD_SDL,		/* Sandbox LCD emulation with SDL */
+	COMPAT_TI_TPS65090,		/* Texas Instrument TPS65090 */
+	COMPAT_NXP_PTN3460,		/* NXP PTN3460 DP/LVDS bridge */
 
 	COMPAT_COUNT,
 };
diff --git a/include/initcall.h b/include/initcall.h
index 2378077..65f67dc 100644
--- a/include/initcall.h
+++ b/include/initcall.h
@@ -6,4 +6,4 @@
 
 typedef int (*init_fnc_t)(void);
 
-int initcall_run_list(init_fnc_t init_sequence[]);
+int initcall_run_list(const init_fnc_t init_sequence[]);
diff --git a/include/mmc.h b/include/mmc.h
index a3a100b..f46572e 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -32,15 +32,13 @@
 #define MMC_VERSION_4_41	(MMC_VERSION_MMC | 0x429)
 #define MMC_VERSION_4_5		(MMC_VERSION_MMC | 0x405)
 
-#define MMC_MODE_HS		0x001
-#define MMC_MODE_HS_52MHz	0x010
-#define MMC_MODE_4BIT		0x100
-#define MMC_MODE_8BIT		0x200
-#define MMC_MODE_SPI		0x400
-#define MMC_MODE_HC		0x800
-
-#define MMC_MODE_MASK_WIDTH_BITS (MMC_MODE_4BIT | MMC_MODE_8BIT)
-#define MMC_MODE_WIDTH_BITS_SHIFT 8
+#define MMC_MODE_HS		(1 << 0)
+#define MMC_MODE_HS_52MHz	(1 << 1)
+#define MMC_MODE_4BIT		(1 << 2)
+#define MMC_MODE_8BIT		(1 << 3)
+#define MMC_MODE_SPI		(1 << 4)
+#define MMC_MODE_HC		(1 << 5)
+#define MMC_MODE_DDR_52MHz	(1 << 6)
 
 #define SD_DATA_4BIT	0x00040000
 
@@ -100,9 +98,6 @@
 #define SD_HIGHSPEED_BUSY	0x00020000
 #define SD_HIGHSPEED_SUPPORTED	0x00020000
 
-#define MMC_HS_TIMING		0x00000100
-#define MMC_HS_52MHZ		0x2
-
 #define OCR_BUSY		0x80000000
 #define OCR_HCS			0x40000000
 #define OCR_VOLTAGE_MASK	0x007FFF80
@@ -178,10 +173,16 @@
 
 #define EXT_CSD_CARD_TYPE_26	(1 << 0)	/* Card can run at 26MHz */
 #define EXT_CSD_CARD_TYPE_52	(1 << 1)	/* Card can run at 52MHz */
+#define EXT_CSD_CARD_TYPE_DDR_1_8V	(1 << 2)
+#define EXT_CSD_CARD_TYPE_DDR_1_2V	(1 << 3)
+#define EXT_CSD_CARD_TYPE_DDR_52	(EXT_CSD_CARD_TYPE_DDR_1_8V \
+					| EXT_CSD_CARD_TYPE_DDR_1_2V)
 
 #define EXT_CSD_BUS_WIDTH_1	0	/* Card is in 1 bit mode */
 #define EXT_CSD_BUS_WIDTH_4	1	/* Card is in 4 bit mode */
 #define EXT_CSD_BUS_WIDTH_8	2	/* Card is in 8 bit mode */
+#define EXT_CSD_DDR_BUS_WIDTH_4	5	/* Card is in 4 bit DDR mode */
+#define EXT_CSD_DDR_BUS_WIDTH_8	6	/* Card is in 8 bit DDR mode */
 
 #define EXT_CSD_BOOT_ACK_ENABLE			(1 << 6)
 #define EXT_CSD_BOOT_PARTITION_ENABLE		(1 << 3)
diff --git a/include/power/max77693_pmic.h b/include/power/max77693_pmic.h
index 616d051..3d59e59 100644
--- a/include/power/max77693_pmic.h
+++ b/include/power/max77693_pmic.h
@@ -10,8 +10,6 @@
 
 #include <power/power_chrg.h>
 
-enum {CHARGER_ENABLE, CHARGER_DISABLE};
-
 #define CHARGER_MIN_CURRENT 200
 #define CHARGER_MAX_CURRENT 2000
 
diff --git a/include/power/max8997_pmic.h b/include/power/max8997_pmic.h
index 74c5d54..728d60a 100644
--- a/include/power/max8997_pmic.h
+++ b/include/power/max8997_pmic.h
@@ -170,7 +170,6 @@
 #define SAFEOUT_3_30V 0x03
 
 /* Charger */
-enum {CHARGER_ENABLE, CHARGER_DISABLE};
 #define DETBAT                  (1 << 2)
 #define MBCICHFCSET             (1 << 4)
 #define MBCHOSTEN               (1 << 6)
diff --git a/include/power/pmic.h b/include/power/pmic.h
index 8f282dd..a62e6c9 100644
--- a/include/power/pmic.h
+++ b/include/power/pmic.h
@@ -17,6 +17,11 @@
 enum { PMIC_READ, PMIC_WRITE, };
 enum { PMIC_SENSOR_BYTE_ORDER_LITTLE, PMIC_SENSOR_BYTE_ORDER_BIG, };
 
+enum {
+	PMIC_CHARGER_DISABLE,
+	PMIC_CHARGER_ENABLE,
+};
+
 struct p_i2c {
 	unsigned char addr;
 	unsigned char *buf;
diff --git a/include/power/tps65090_pmic.h b/include/power/tps65090_pmic.h
new file mode 100644
index 0000000..dcf99c9
--- /dev/null
+++ b/include/power/tps65090_pmic.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2012 The Chromium OS Authors.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __TPS65090_PMIC_H_
+#define __TPS65090_PMIC_H_
+
+/* I2C device address for TPS65090 PMU */
+#define TPS65090_I2C_ADDR	0x48
+
+enum {
+	/* Status register fields */
+	TPS65090_ST1_OTC	= 1 << 0,
+	TPS65090_ST1_OCC	= 1 << 1,
+	TPS65090_ST1_STATE_SHIFT = 4,
+	TPS65090_ST1_STATE_MASK	= 0xf << TPS65090_ST1_STATE_SHIFT,
+};
+
+/**
+ * Enable FET
+ *
+ * @param	fet_id	FET ID, value between 1 and 7
+ * @return	0 on success, non-0 on failure
+ */
+int tps65090_fet_enable(unsigned int fet_id);
+
+/**
+ * Disable FET
+ *
+ * @param	fet_id	FET ID, value between 1 and 7
+ * @return	0 on success, non-0 on failure
+ */
+int tps65090_fet_disable(unsigned int fet_id);
+
+/**
+ * Is FET enabled?
+ *
+ * @param	fet_id	FET ID, value between 1 and 7
+ * @return	1 enabled, 0 disabled, negative value on failure
+ */
+int tps65090_fet_is_enabled(unsigned int fet_id);
+
+/**
+ * Enable / disable the battery charger
+ *
+ * @param enable	0 to disable charging, non-zero to enable
+ */
+int tps65090_set_charge_enable(int enable);
+
+/**
+ * Check whether we have enabled battery charging
+ *
+ * @return 1 if enabled, 0 if disabled
+ */
+int tps65090_get_charging(void);
+
+/**
+ * Return the value of the status register
+ *
+ * @return status register value, or -1 on error
+ */
+int tps65090_get_status(void);
+
+/**
+ * Initialize the TPS65090 PMU.
+ *
+ * @return	0 on success, non-0 on failure
+ */
+int tps65090_init(void);
+
+#endif /* __TPS65090_PMIC_H_ */
diff --git a/lib/fdtdec.c b/lib/fdtdec.c
index 8ecb80f..13d3d2f 100644
--- a/lib/fdtdec.c
+++ b/lib/fdtdec.c
@@ -55,7 +55,7 @@
 	COMPAT(SAMSUNG_EXYNOS_FIMD, "samsung,exynos-fimd"),
 	COMPAT(SAMSUNG_EXYNOS_MIPI_DSI, "samsung,exynos-mipi-dsi"),
 	COMPAT(SAMSUNG_EXYNOS5_DP, "samsung,exynos5-dp"),
-	COMPAT(SAMSUNG_EXYNOS5_DWMMC, "samsung,exynos5250-dwmmc"),
+	COMPAT(SAMSUNG_EXYNOS_DWMMC, "samsung,exynos-dwmmc"),
 	COMPAT(SAMSUNG_EXYNOS_MMC, "samsung,exynos-mmc"),
 	COMPAT(SAMSUNG_EXYNOS_SERIAL, "samsung,exynos4210-uart"),
 	COMPAT(MAXIM_MAX77686_PMIC, "maxim,max77686_pmic"),
@@ -66,6 +66,8 @@
 	COMPAT(SAMSUNG_EXYNOS5_I2C, "samsung,exynos5-hsi2c"),
 	COMPAT(SANDBOX_HOST_EMULATION, "sandbox,host-emulation"),
 	COMPAT(SANDBOX_LCD_SDL, "sandbox,lcd-sdl"),
+	COMPAT(TI_TPS65090, "ti,tps65090"),
+	COMPAT(COMPAT_NXP_PTN3460, "nxp,ptn3460"),
 };
 
 const char *fdtdec_get_compatible(enum fdt_compat_id id)
diff --git a/lib/initcall.c b/lib/initcall.c
index fa76dd7..7597bad 100644
--- a/lib/initcall.c
+++ b/lib/initcall.c
@@ -7,15 +7,22 @@
 #include <common.h>
 #include <initcall.h>
 
-int initcall_run_list(init_fnc_t init_sequence[])
+DECLARE_GLOBAL_DATA_PTR;
+
+int initcall_run_list(const init_fnc_t init_sequence[])
 {
-	init_fnc_t *init_fnc_ptr;
+	const init_fnc_t *init_fnc_ptr;
 
 	for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
-		debug("initcall: %p\n", *init_fnc_ptr);
+		unsigned long reloc_ofs = 0;
+
+		if (gd->flags & GD_FLG_RELOC)
+			reloc_ofs = gd->reloc_off;
+		debug("initcall: %p\n", (char *)*init_fnc_ptr - reloc_ofs);
 		if ((*init_fnc_ptr)()) {
-			debug("initcall sequence %p failed at call %p\n",
-			      init_sequence, *init_fnc_ptr);
+			printf("initcall sequence %p failed at call %p\n",
+			       init_sequence,
+			       (char *)*init_fnc_ptr - reloc_ofs);
 			return -1;
 		}
 	}