diff --git a/Makefile b/Makefile
index 26dacee98e07d0c203e0156bae557ea95a006d29..9c8a58013145dccef1e8a5f429bf1eba932d3bd7 100644
--- a/Makefile
+++ b/Makefile
@@ -946,7 +946,8 @@ u-boot-nand.gph: u-boot.bin FORCE
 ifneq ($(CONFIG_SUNXI),)
 OBJCOPYFLAGS_u-boot-sunxi-with-spl.bin = -I binary -O binary \
 				   --pad-to=$(CONFIG_SPL_PAD_TO) --gap-fill=0xff
-u-boot-sunxi-with-spl.bin: spl/sunxi-spl.bin u-boot.img FORCE
+u-boot-sunxi-with-spl.bin: spl/sunxi-spl.bin \
+			u-boot$(if $(CONFIG_OF_CONTROL),-dtb,).img FORCE
 	$(call if_changed,pad_cat)
 endif
 
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 43700c32eea9c7c4730105d384f799684b3289af..bd774d42a89fa7c05a14616a35b5adf2acdd49de 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -663,30 +663,8 @@ config TARGET_SOCFPGA_CYCLONE5
 	select CPU_V7
 	select SUPPORT_SPL
 
-config TARGET_SUN4I
-	bool "Support sun4i"
-	select CPU_V7
-	select SUPPORT_SPL
-
-config TARGET_SUN5I
-	bool "Support sun5i"
-	select CPU_V7
-	select SUPPORT_SPL
-
-config TARGET_SUN6I
-	bool "Support sun6i"
-	select CPU_V7
-	select SUPPORT_SPL
-
-config TARGET_SUN7I
-	bool "Support sun7i"
-	select CPU_V7
-	select SUPPORT_SPL
-
-config TARGET_SUN8I
-	bool "Support sun8i"
-	select CPU_V7
-	select SUPPORT_SPL
+config ARCH_SUNXI
+	bool "Support sunxi (Allwinner) SoCs"
 
 config TARGET_SNOWBALL
 	bool "Support snowball"
diff --git a/arch/arm/cpu/armv7/sunxi/Makefile b/arch/arm/cpu/armv7/sunxi/Makefile
index 24f1daee64766d1631122a65dcb13dcb88dbc8ea..82dbf764e438adc16c84d231cc910a875aa9e01a 100644
--- a/arch/arm/cpu/armv7/sunxi/Makefile
+++ b/arch/arm/cpu/armv7/sunxi/Makefile
@@ -11,13 +11,13 @@ obj-y	+= timer.o
 obj-y	+= board.o
 obj-y	+= clock.o
 obj-y	+= pinmux.o
-obj-$(CONFIG_SUN6I)	+= prcm.o
-obj-$(CONFIG_SUN8I)	+= prcm.o
-obj-$(CONFIG_SUN4I)	+= clock_sun4i.o
-obj-$(CONFIG_SUN5I)	+= clock_sun4i.o
-obj-$(CONFIG_SUN6I)	+= clock_sun6i.o
-obj-$(CONFIG_SUN7I)	+= clock_sun4i.o
-obj-$(CONFIG_SUN8I)	+= clock_sun6i.o
+obj-$(CONFIG_MACH_SUN6I)	+= prcm.o
+obj-$(CONFIG_MACH_SUN8I)	+= prcm.o
+obj-$(CONFIG_MACH_SUN4I)	+= clock_sun4i.o
+obj-$(CONFIG_MACH_SUN5I)	+= clock_sun4i.o
+obj-$(CONFIG_MACH_SUN6I)	+= clock_sun6i.o
+obj-$(CONFIG_MACH_SUN7I)	+= clock_sun4i.o
+obj-$(CONFIG_MACH_SUN8I)	+= clock_sun6i.o
 
 ifndef CONFIG_SPL_BUILD
 obj-y	+= cpu_info.o
@@ -27,9 +27,9 @@ endif
 endif
 
 ifdef CONFIG_SPL_BUILD
-obj-$(CONFIG_SUN4I)	+= dram.o
-obj-$(CONFIG_SUN5I)	+= dram.o
-obj-$(CONFIG_SUN7I)	+= dram.o
+obj-$(CONFIG_MACH_SUN4I)	+= dram.o
+obj-$(CONFIG_MACH_SUN5I)	+= dram.o
+obj-$(CONFIG_MACH_SUN7I)	+= dram.o
 ifdef CONFIG_SPL_FEL
 obj-y	+= start.o
 endif
diff --git a/arch/arm/cpu/armv7/sunxi/board.c b/arch/arm/cpu/armv7/sunxi/board.c
index 06eb6768e8f2b58ddbe1b2408157f8e4e89ccaab..6c812fc6e9ce351c4dddf910a978c5c3ffe442d9 100644
--- a/arch/arm/cpu/armv7/sunxi/board.c
+++ b/arch/arm/cpu/armv7/sunxi/board.c
@@ -51,7 +51,7 @@ u32 spl_boot_mode(void)
 int gpio_init(void)
 {
 #if CONFIG_CONS_INDEX == 1 && defined(CONFIG_UART0_PORT_F)
-#if defined(CONFIG_SUN4I) || defined(CONFIG_SUN7I)
+#if defined(CONFIG_MACH_SUN4I) || defined(CONFIG_MACH_SUN7I)
 	/* disable GPB22,23 as uart0 tx,rx to avoid conflict */
 	sunxi_gpio_set_cfgpin(SUNXI_GPB(22), SUNXI_GPIO_INPUT);
 	sunxi_gpio_set_cfgpin(SUNXI_GPB(23), SUNXI_GPIO_INPUT);
@@ -59,23 +59,23 @@ int gpio_init(void)
 	sunxi_gpio_set_cfgpin(SUNXI_GPF(2), SUNXI_GPF2_UART0_TX);
 	sunxi_gpio_set_cfgpin(SUNXI_GPF(4), SUNXI_GPF4_UART0_RX);
 	sunxi_gpio_set_pull(SUNXI_GPF(4), 1);
-#elif CONFIG_CONS_INDEX == 1 && (defined(CONFIG_SUN4I) || defined(CONFIG_SUN7I))
+#elif CONFIG_CONS_INDEX == 1 && (defined(CONFIG_MACH_SUN4I) || defined(CONFIG_MACH_SUN7I))
 	sunxi_gpio_set_cfgpin(SUNXI_GPB(22), SUN4I_GPB22_UART0_TX);
 	sunxi_gpio_set_cfgpin(SUNXI_GPB(23), SUN4I_GPB23_UART0_RX);
 	sunxi_gpio_set_pull(SUNXI_GPB(23), SUNXI_GPIO_PULL_UP);
-#elif CONFIG_CONS_INDEX == 1 && defined(CONFIG_SUN5I)
+#elif CONFIG_CONS_INDEX == 1 && defined(CONFIG_MACH_SUN5I)
 	sunxi_gpio_set_cfgpin(SUNXI_GPB(19), SUN5I_GPB19_UART0_TX);
 	sunxi_gpio_set_cfgpin(SUNXI_GPB(20), SUN5I_GPB20_UART0_RX);
 	sunxi_gpio_set_pull(SUNXI_GPB(20), SUNXI_GPIO_PULL_UP);
-#elif CONFIG_CONS_INDEX == 1 && defined(CONFIG_SUN6I)
+#elif CONFIG_CONS_INDEX == 1 && defined(CONFIG_MACH_SUN6I)
 	sunxi_gpio_set_cfgpin(SUNXI_GPH(20), SUN6I_GPH20_UART0_TX);
 	sunxi_gpio_set_cfgpin(SUNXI_GPH(21), SUN6I_GPH21_UART0_RX);
 	sunxi_gpio_set_pull(SUNXI_GPH(21), SUNXI_GPIO_PULL_UP);
-#elif CONFIG_CONS_INDEX == 2 && defined(CONFIG_SUN5I)
+#elif CONFIG_CONS_INDEX == 2 && defined(CONFIG_MACH_SUN5I)
 	sunxi_gpio_set_cfgpin(SUNXI_GPG(3), SUN5I_GPG3_UART1_TX);
 	sunxi_gpio_set_cfgpin(SUNXI_GPG(4), SUN5I_GPG4_UART1_RX);
 	sunxi_gpio_set_pull(SUNXI_GPG(4), SUNXI_GPIO_PULL_UP);
-#elif CONFIG_CONS_INDEX == 5 && defined(CONFIG_SUN8I)
+#elif CONFIG_CONS_INDEX == 5 && defined(CONFIG_MACH_SUN8I)
 	sunxi_gpio_set_cfgpin(SUNXI_GPL(2), SUN8I_GPL2_R_UART_TX);
 	sunxi_gpio_set_cfgpin(SUNXI_GPL(3), SUN8I_GPL3_R_UART_RX);
 	sunxi_gpio_set_pull(SUNXI_GPL(3), SUNXI_GPIO_PULL_UP);
@@ -88,7 +88,7 @@ int gpio_init(void)
 
 void reset_cpu(ulong addr)
 {
-#if defined(CONFIG_SUN4I) || defined(CONFIG_SUN5I) || defined(CONFIG_SUN7I)
+#if defined(CONFIG_MACH_SUN4I) || defined(CONFIG_MACH_SUN5I) || defined(CONFIG_MACH_SUN7I)
 	static const struct sunxi_wdog *wdog =
 		 &((struct sunxi_timer_reg *)SUNXI_TIMER_BASE)->wdog;
 
@@ -100,7 +100,7 @@ void reset_cpu(ulong addr)
 		/* sun5i sometimes gets stuck without this */
 		writel(WDT_MODE_RESET_EN | WDT_MODE_EN, &wdog->mode);
 	}
-#else /* CONFIG_SUN6I || CONFIG_SUN8I || .. */
+#else /* CONFIG_MACH_SUN6I || CONFIG_MACH_SUN8I || .. */
 	static const struct sunxi_wdog *wdog =
 		 ((struct sunxi_timer_reg *)SUNXI_TIMER_BASE)->wdog;
 
@@ -114,8 +114,8 @@ void reset_cpu(ulong addr)
 /* do some early init */
 void s_init(void)
 {
-#if !defined CONFIG_SPL_BUILD && (defined CONFIG_SUN7I || \
-		defined CONFIG_SUN6I || defined CONFIG_SUN8I)
+#if !defined CONFIG_SPL_BUILD && (defined CONFIG_MACH_SUN7I || \
+		defined CONFIG_MACH_SUN6I || defined CONFIG_MACH_SUN8I)
 	/* Enable SMP mode for CPU0, by setting bit 6 of Auxiliary Ctl reg */
 	asm volatile(
 		"mrc p15, 0, r0, c1, c0, 1\n"
diff --git a/arch/arm/cpu/armv7/sunxi/clock_sun4i.c b/arch/arm/cpu/armv7/sunxi/clock_sun4i.c
index 4a0d64fb30e64db6b996d35e4134469a0ccfd385..a0e49d179feff469f212f479925bc6ab881b3585 100644
--- a/arch/arm/cpu/armv7/sunxi/clock_sun4i.c
+++ b/arch/arm/cpu/armv7/sunxi/clock_sun4i.c
@@ -35,7 +35,7 @@ void clock_init_safe(void)
 	       APB0_DIV_1 << APB0_DIV_SHIFT |
 	       CPU_CLK_SRC_PLL1 << CPU_CLK_SRC_SHIFT,
 	       &ccm->cpu_ahb_apb0_cfg);
-#ifdef CONFIG_SUN7I
+#ifdef CONFIG_MACH_SUN7I
 	setbits_le32(&ccm->ahb_gate0, 0x1 << AHB_GATE_OFFSET_DMA);
 #endif
 	writel(PLL6_CFG_DEFAULT, &ccm->pll6_cfg);
diff --git a/arch/arm/cpu/armv7/sunxi/cpu_info.c b/arch/arm/cpu/armv7/sunxi/cpu_info.c
index 4f2a09cd2e28cbd69a498bab61c06341f4235473..41b9add297a2362732c360a6b51ec893735f06a7 100644
--- a/arch/arm/cpu/armv7/sunxi/cpu_info.c
+++ b/arch/arm/cpu/armv7/sunxi/cpu_info.c
@@ -13,9 +13,9 @@
 #ifdef CONFIG_DISPLAY_CPUINFO
 int print_cpuinfo(void)
 {
-#ifdef CONFIG_SUN4I
+#ifdef CONFIG_MACH_SUN4I
 	puts("CPU:   Allwinner A10 (SUN4I)\n");
-#elif defined CONFIG_SUN5I
+#elif defined CONFIG_MACH_SUN5I
 	u32 val = readl(SUNXI_SID_BASE + 0x08);
 	switch ((val >> 12) & 0xf) {
 	case 0: puts("CPU:   Allwinner A12 (SUN5I)\n"); break;
@@ -23,11 +23,11 @@ int print_cpuinfo(void)
 	case 7: puts("CPU:   Allwinner A10s (SUN5I)\n"); break;
 	default: puts("CPU:   Allwinner A1X (SUN5I)\n");
 	}
-#elif defined CONFIG_SUN6I
+#elif defined CONFIG_MACH_SUN6I
 	puts("CPU:   Allwinner A31 (SUN6I)\n");
-#elif defined CONFIG_SUN7I
+#elif defined CONFIG_MACH_SUN7I
 	puts("CPU:   Allwinner A20 (SUN7I)\n");
-#elif defined CONFIG_SUN8I
+#elif defined CONFIG_MACH_SUN8I
 	puts("CPU:   Allwinner A23 (SUN8I)\n");
 #else
 #warning Please update cpu_info.c with correct CPU information
diff --git a/arch/arm/cpu/armv7/sunxi/dram.c b/arch/arm/cpu/armv7/sunxi/dram.c
index 3cf3cbf19adb25fce553a4f88a8d35ca6909999a..dc9fdb930b6e5c51c2d7252f7b4511439c3f33a2 100644
--- a/arch/arm/cpu/armv7/sunxi/dram.c
+++ b/arch/arm/cpu/armv7/sunxi/dram.c
@@ -74,7 +74,7 @@ static void mctl_ddr3_reset(void)
 	struct sunxi_dram_reg *dram =
 			(struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
 
-#ifdef CONFIG_SUN4I
+#ifdef CONFIG_MACH_SUN4I
 	struct sunxi_timer_reg *timer =
 			(struct sunxi_timer_reg *)SUNXI_TIMER_BASE;
 	u32 reg_val;
@@ -113,7 +113,7 @@ static void mctl_set_drive(void)
 {
 	struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
 
-#ifdef CONFIG_SUN7I
+#ifdef CONFIG_MACH_SUN7I
 	clrsetbits_le32(&dram->mcr, DRAM_MCR_MODE_NORM(0x3) | (0x3 << 28),
 #else
 	clrsetbits_le32(&dram->mcr, DRAM_MCR_MODE_NORM(0x3),
@@ -202,7 +202,7 @@ static void mctl_enable_dllx(u32 phase)
 }
 
 static u32 hpcr_value[32] = {
-#ifdef CONFIG_SUN5I
+#ifdef CONFIG_MACH_SUN5I
 	0, 0, 0, 0,
 	0, 0, 0, 0,
 	0, 0, 0, 0,
@@ -212,7 +212,7 @@ static u32 hpcr_value[32] = {
 	0x0301, 0x0301, 0x0301, 0x0301,
 	0x0301, 0x0301, 0x0301, 0
 #endif
-#ifdef CONFIG_SUN4I
+#ifdef CONFIG_MACH_SUN4I
 	0x0301, 0x0301, 0x0301, 0x0301,
 	0x0301, 0x0301, 0, 0,
 	0, 0, 0, 0,
@@ -222,7 +222,7 @@ static u32 hpcr_value[32] = {
 	0x1035, 0x1031, 0x0731, 0x1035,
 	0x1031, 0x0301, 0x0301, 0x0731
 #endif
-#ifdef CONFIG_SUN7I
+#ifdef CONFIG_MACH_SUN7I
 	0x0301, 0x0301, 0x0301, 0x0301,
 	0x0301, 0x0301, 0x0301, 0x0301,
 	0, 0, 0, 0,
@@ -304,7 +304,7 @@ static void mctl_setup_dram_clock(u32 clk, u32 mbus_clk)
 
 	setbits_le32(&ccm->pll5_cfg, CCM_PLL5_CTRL_DDR_CLK);
 
-#if defined(CONFIG_SUN4I) || defined(CONFIG_SUN7I)
+#if defined(CONFIG_MACH_SUN4I) || defined(CONFIG_MACH_SUN7I)
 	/* reset GPS */
 	clrbits_le32(&ccm->gps_clk_cfg, CCM_GPS_CTRL_RESET | CCM_GPS_CTRL_GATE);
 	setbits_le32(&ccm->ahb_gate0, CCM_AHB_GATE_GPS);
@@ -318,7 +318,7 @@ static void mctl_setup_dram_clock(u32 clk, u32 mbus_clk)
 
 	/* PLL5P and PLL6 are the potential clock sources for MBUS */
 	pll6x_clk = clock_get_pll6() / 1000000;
-#ifdef CONFIG_SUN7I
+#ifdef CONFIG_MACH_SUN7I
 	pll6x_clk *= 2; /* sun7i uses PLL6*2, sun5i uses just PLL6 */
 #endif
 	pll5p_clk = clock_get_pll5p() / 1000000;
@@ -348,7 +348,7 @@ static void mctl_setup_dram_clock(u32 clk, u32 mbus_clk)
 	 * open DRAMC AHB & DLL register clock
 	 * close it first
 	 */
-#if defined(CONFIG_SUN5I) || defined(CONFIG_SUN7I)
+#if defined(CONFIG_MACH_SUN5I) || defined(CONFIG_MACH_SUN7I)
 	clrbits_le32(&ccm->ahb_gate0, CCM_AHB_GATE_SDRAM | CCM_AHB_GATE_DLL);
 #else
 	clrbits_le32(&ccm->ahb_gate0, CCM_AHB_GATE_SDRAM);
@@ -356,7 +356,7 @@ static void mctl_setup_dram_clock(u32 clk, u32 mbus_clk)
 	udelay(22);
 
 	/* then open it */
-#if defined(CONFIG_SUN5I) || defined(CONFIG_SUN7I)
+#if defined(CONFIG_MACH_SUN5I) || defined(CONFIG_MACH_SUN7I)
 	setbits_le32(&ccm->ahb_gate0, CCM_AHB_GATE_SDRAM | CCM_AHB_GATE_DLL);
 #else
 	setbits_le32(&ccm->ahb_gate0, CCM_AHB_GATE_SDRAM);
@@ -417,7 +417,7 @@ static int dramc_scan_readpipe(void)
 
 static void dramc_clock_output_en(u32 on)
 {
-#if defined(CONFIG_SUN5I) || defined(CONFIG_SUN7I)
+#if defined(CONFIG_MACH_SUN5I) || defined(CONFIG_MACH_SUN7I)
 	struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
 
 	if (on)
@@ -425,7 +425,7 @@ static void dramc_clock_output_en(u32 on)
 	else
 		clrbits_le32(&dram->mcr, DRAM_MCR_DCLK_OUT);
 #endif
-#ifdef CONFIG_SUN4I
+#ifdef CONFIG_MACH_SUN4I
 	struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
 	if (on)
 		setbits_le32(&ccm->dram_clk_cfg, CCM_DRAM_CTRL_DCLK_OUT);
@@ -527,7 +527,7 @@ static void mctl_set_impedance(u32 zq, u32 odt_en)
 	u32 reg_val;
 	u32 zprog = zq & 0xFF, zdata = (zq >> 8) & 0xFFFFF;
 
-#ifndef CONFIG_SUN7I
+#ifndef CONFIG_MACH_SUN7I
 	/* Appears that some kind of automatically initiated default
 	 * ZQ calibration is already in progress at this point on sun4i/sun5i
 	 * hardware, but not on sun7i. So it is reasonable to wait for its
@@ -539,7 +539,7 @@ static void mctl_set_impedance(u32 zq, u32 odt_en)
 	if (!odt_en)
 		return;
 
-#ifdef CONFIG_SUN7I
+#ifdef CONFIG_MACH_SUN7I
 	/* Enabling ODT in SDR_IOCR on sun7i hardware results in a deadlock
 	 * unless bit 24 is set in SDR_ZQCR1. Not much is known about the
 	 * SDR_ZQCR1 register, but there are hints indicating that it might
@@ -597,7 +597,7 @@ static unsigned long dramc_init_helper(struct dram_para *para)
 	/* dram clock off */
 	dramc_clock_output_en(0);
 
-#ifdef CONFIG_SUN4I
+#ifdef CONFIG_MACH_SUN4I
 	/* select dram controller 1 */
 	writel(DRAM_CSEL_MAGIC, &dram->csel);
 #endif
@@ -654,7 +654,7 @@ static unsigned long dramc_init_helper(struct dram_para *para)
 	writel(para->tpr2, &dram->tpr2);
 
 	reg_val = DRAM_MR_BURST_LENGTH(0x0);
-#if (defined(CONFIG_SUN5I) || defined(CONFIG_SUN7I))
+#if (defined(CONFIG_MACH_SUN5I) || defined(CONFIG_MACH_SUN7I))
 	reg_val |= DRAM_MR_POWER_DOWN;
 #endif
 	reg_val |= DRAM_MR_CAS_LAT(para->cas - 4);
@@ -668,7 +668,7 @@ static unsigned long dramc_init_helper(struct dram_para *para)
 	/* disable drift compensation and set passive DQS window mode */
 	clrsetbits_le32(&dram->ccr, DRAM_CCR_DQS_DRIFT_COMP, DRAM_CCR_DQS_GATE);
 
-#ifdef CONFIG_SUN7I
+#ifdef CONFIG_MACH_SUN7I
 	/* Command rate timing mode 2T & 1T */
 	if (para->tpr4 & 0x1)
 		setbits_le32(&dram->ccr, DRAM_CCR_COMMAND_RATE_1T);
@@ -718,7 +718,7 @@ unsigned long dramc_init(struct dram_para *para)
 	/* try to autodetect the DRAM bus width and density */
 	para->io_width  = 16;
 	para->bus_width = 32;
-#if defined(CONFIG_SUN4I) || defined(CONFIG_SUN5I)
+#if defined(CONFIG_MACH_SUN4I) || defined(CONFIG_MACH_SUN5I)
 	/* only A0-A14 address lines on A10/A13, limiting max density to 4096 */
 	para->density = 4096;
 #else
diff --git a/arch/arm/cpu/armv7/sunxi/pinmux.c b/arch/arm/cpu/armv7/sunxi/pinmux.c
index 1f2843fcac4577ebcfa45212b27c9238399e7347..b026f78ca50785a198e68295496093d1ab67a06b 100644
--- a/arch/arm/cpu/armv7/sunxi/pinmux.c
+++ b/arch/arm/cpu/armv7/sunxi/pinmux.c
@@ -10,32 +10,42 @@
 #include <asm/io.h>
 #include <asm/arch/gpio.h>
 
-int sunxi_gpio_set_cfgpin(u32 pin, u32 val)
+void sunxi_gpio_set_cfgbank(struct sunxi_gpio *pio, int bank_offset, u32 val)
 {
-	u32 bank = GPIO_BANK(pin);
-	u32 index = GPIO_CFG_INDEX(pin);
-	u32 offset = GPIO_CFG_OFFSET(pin);
-	struct sunxi_gpio *pio = BANK_TO_GPIO(bank);
+	u32 index = GPIO_CFG_INDEX(bank_offset);
+	u32 offset = GPIO_CFG_OFFSET(bank_offset);
 
 	clrsetbits_le32(&pio->cfg[0] + index, 0xf << offset, val << offset);
-
-	return 0;
 }
 
-int sunxi_gpio_get_cfgpin(u32 pin)
+void sunxi_gpio_set_cfgpin(u32 pin, u32 val)
 {
-	u32 cfg;
 	u32 bank = GPIO_BANK(pin);
-	u32 index = GPIO_CFG_INDEX(pin);
-	u32 offset = GPIO_CFG_OFFSET(pin);
 	struct sunxi_gpio *pio = BANK_TO_GPIO(bank);
 
+	sunxi_gpio_set_cfgbank(pio, pin, val);
+}
+
+int sunxi_gpio_get_cfgbank(struct sunxi_gpio *pio, int bank_offset)
+{
+	u32 index = GPIO_CFG_INDEX(bank_offset);
+	u32 offset = GPIO_CFG_OFFSET(bank_offset);
+	u32 cfg;
+
 	cfg = readl(&pio->cfg[0] + index);
 	cfg >>= offset;
 
 	return cfg & 0xf;
 }
 
+int sunxi_gpio_get_cfgpin(u32 pin)
+{
+	u32 bank = GPIO_BANK(pin);
+	struct sunxi_gpio *pio = BANK_TO_GPIO(bank);
+
+	return sunxi_gpio_get_cfgbank(pio, pin);
+}
+
 int sunxi_gpio_set_drv(u32 pin, u32 val)
 {
 	u32 bank = GPIO_BANK(pin);
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index c34606334dbea34363aba579097eed3bc8a20200..52f89268940020a2e1389ce37ae99637878a52e3 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -1,3 +1,4 @@
+dtb-$(CONFIG_MACH_SUN7I) +=  sun7i-a20-pcduino3.dtb
 dtb-$(CONFIG_S5PC100) += s5pc1xx-smdkc100.dtb
 dtb-$(CONFIG_S5PC110) += s5pc1xx-goni.dtb
 dtb-$(CONFIG_EXYNOS4) += exynos4210-origen.dtb \
diff --git a/arch/arm/dts/sun7i-a20-pcduino3.dts b/arch/arm/dts/sun7i-a20-pcduino3.dts
new file mode 100644
index 0000000000000000000000000000000000000000..f7cc8e7a09c2e5ece889bb364f47488eb9287bef
--- /dev/null
+++ b/arch/arm/dts/sun7i-a20-pcduino3.dts
@@ -0,0 +1,177 @@
+/*
+ * Copyright 2014 Zoltan HERPAI
+ * Zoltan HERPAI <wigyori@uid0.hu>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+/include/ "sun7i-a20.dtsi"
+/include/ "sunxi-common-regulators.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	model = "LinkSprite pcDuino3";
+	compatible = "linksprite,pcduino3", "allwinner,sun7i-a20";
+
+	chosen {
+		stdout-path = &uart0;
+	};
+
+	soc@01c00000 {
+		mmc0: mmc@01c0f000 {
+			pinctrl-names = "default";
+			pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>;
+			vmmc-supply = <&reg_vcc3v3>;
+			bus-width = <4>;
+			cd-gpios = <&pio 7 1 0>; /* PH1 */
+			cd-inverted;
+			status = "okay";
+		};
+
+		usbphy: phy@01c13400 {
+			usb1_vbus-supply = <&reg_usb1_vbus>;
+			usb2_vbus-supply = <&reg_usb2_vbus>;
+			status = "okay";
+		};
+
+		ehci0: usb@01c14000 {
+			status = "okay";
+		};
+
+		ohci0: usb@01c14400 {
+			status = "okay";
+		};
+
+		ahci: sata@01c18000 {
+			target-supply = <&reg_ahci_5v>;
+			status = "okay";
+		};
+
+		ehci1: usb@01c1c000 {
+			status = "okay";
+		};
+
+		ohci1: usb@01c1c400 {
+			status = "okay";
+		};
+
+		pinctrl@01c20800 {
+			ahci_pwr_pin_a: ahci_pwr_pin@0 {
+				allwinner,pins = "PH2";
+			};
+
+			led_pins_pcduino3: led_pins@0 {
+				allwinner,pins = "PH15", "PH16";
+				allwinner,function = "gpio_out";
+				allwinner,drive = <0>;
+				allwinner,pull = <0>;
+			};
+
+			key_pins_pcduino3: key_pins@0 {
+				allwinner,pins = "PH17", "PH18", "PH19";
+				allwinner,function = "gpio_in";
+				allwinner,drive = <0>;
+				allwinner,pull = <0>;
+			};
+		};
+
+		ir0: ir@01c21800 {
+			pinctrl-names = "default";
+			pinctrl-0 = <&ir0_pins_a>;
+			status = "okay";
+		};
+
+		uart0: serial@01c28000 {
+			pinctrl-names = "default";
+			pinctrl-0 = <&uart0_pins_a>;
+			status = "okay";
+		};
+
+		i2c0: i2c@01c2ac00 {
+			pinctrl-names = "default";
+			pinctrl-0 = <&i2c0_pins_a>;
+			status = "okay";
+
+			axp209: pmic@34 {
+				compatible = "x-powers,axp209";
+				reg = <0x34>;
+				interrupt-parent = <&nmi_intc>;
+				interrupts = <0 8>;
+
+				interrupt-controller;
+				#interrupt-cells = <1>;
+			};
+		};
+
+		gmac: ethernet@01c50000 {
+			pinctrl-names = "default";
+			pinctrl-0 = <&gmac_pins_mii_a>;
+			phy = <&phy1>;
+			phy-mode = "mii";
+			status = "okay";
+
+			phy1: ethernet-phy@1 {
+				reg = <1>;
+			};
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+		pinctrl-names = "default";
+		pinctrl-0 = <&led_pins_pcduino3>;
+
+		tx {
+			label = "pcduino3:green:tx";
+			gpios = <&pio 7 15 GPIO_ACTIVE_LOW>;
+		};
+
+		rx {
+			label = "pcduino3:green:rx";
+			gpios = <&pio 7 16 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	gpio_keys {
+		compatible = "gpio-keys";
+		pinctrl-names = "default";
+		pinctrl-0 = <&key_pins_pcduino3>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		button@0 {
+			label = "Key Back";
+			linux,code = <KEY_BACK>;
+			gpios = <&pio 7 17 GPIO_ACTIVE_LOW>;
+		};
+		button@1 {
+			label = "Key Home";
+			linux,code = <KEY_HOME>;
+			gpios = <&pio 7 18 GPIO_ACTIVE_LOW>;
+		};
+		button@2 {
+			label = "Key Menu";
+			linux,code = <KEY_MENU>;
+			gpios = <&pio 7 19 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	reg_usb1_vbus: usb1-vbus {
+		status = "okay";
+	};
+
+	reg_usb2_vbus: usb2-vbus {
+		status = "okay";
+	};
+
+	reg_ahci_5v: ahci-5v {
+		gpio = <&pio 7 2 0>;
+		status = "okay";
+	};
+};
diff --git a/arch/arm/dts/sun7i-a20.dtsi b/arch/arm/dts/sun7i-a20.dtsi
new file mode 100644
index 0000000000000000000000000000000000000000..4011628c738101b0004b6bb9da7f4c0ee3fa1e70
--- /dev/null
+++ b/arch/arm/dts/sun7i-a20.dtsi
@@ -0,0 +1,988 @@
+/*
+ * Copyright 2013 Maxime Ripard
+ *
+ * Maxime Ripard <maxime.ripard@free-electrons.com>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/include/ "skeleton.dtsi"
+
+/ {
+	interrupt-parent = <&gic>;
+
+	aliases {
+		ethernet0 = &gmac;
+		serial0 = &uart0;
+		serial1 = &uart1;
+		serial2 = &uart2;
+		serial3 = &uart3;
+		serial4 = &uart4;
+		serial5 = &uart5;
+		serial6 = &uart6;
+		serial7 = &uart7;
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu@0 {
+			compatible = "arm,cortex-a7";
+			device_type = "cpu";
+			reg = <0>;
+		};
+
+		cpu@1 {
+			compatible = "arm,cortex-a7";
+			device_type = "cpu";
+			reg = <1>;
+		};
+	};
+
+	memory {
+		reg = <0x40000000 0x80000000>;
+	};
+
+	timer {
+		compatible = "arm,armv7-timer";
+		interrupts = <1 13 0xf08>,
+			     <1 14 0xf08>,
+			     <1 11 0xf08>,
+			     <1 10 0xf08>;
+	};
+
+	pmu {
+		compatible = "arm,cortex-a7-pmu", "arm,cortex-a15-pmu";
+		interrupts = <0 120 4>,
+			     <0 121 4>;
+	};
+
+	clocks {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		osc24M: clk@01c20050 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-a10-osc-clk";
+			reg = <0x01c20050 0x4>;
+			clock-frequency = <24000000>;
+			clock-output-names = "osc24M";
+		};
+
+		osc32k: clk@0 {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <32768>;
+			clock-output-names = "osc32k";
+		};
+
+		pll1: clk@01c20000 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-a10-pll1-clk";
+			reg = <0x01c20000 0x4>;
+			clocks = <&osc24M>;
+			clock-output-names = "pll1";
+		};
+
+		pll4: clk@01c20018 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun7i-a20-pll4-clk";
+			reg = <0x01c20018 0x4>;
+			clocks = <&osc24M>;
+			clock-output-names = "pll4";
+		};
+
+		pll5: clk@01c20020 {
+			#clock-cells = <1>;
+			compatible = "allwinner,sun4i-a10-pll5-clk";
+			reg = <0x01c20020 0x4>;
+			clocks = <&osc24M>;
+			clock-output-names = "pll5_ddr", "pll5_other";
+		};
+
+		pll6: clk@01c20028 {
+			#clock-cells = <1>;
+			compatible = "allwinner,sun4i-a10-pll6-clk";
+			reg = <0x01c20028 0x4>;
+			clocks = <&osc24M>;
+			clock-output-names = "pll6_sata", "pll6_other", "pll6";
+		};
+
+		pll8: clk@01c20040 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun7i-a20-pll4-clk";
+			reg = <0x01c20040 0x4>;
+			clocks = <&osc24M>;
+			clock-output-names = "pll8";
+		};
+
+		cpu: cpu@01c20054 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-a10-cpu-clk";
+			reg = <0x01c20054 0x4>;
+			clocks = <&osc32k>, <&osc24M>, <&pll1>, <&pll6 1>;
+			clock-output-names = "cpu";
+		};
+
+		axi: axi@01c20054 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-a10-axi-clk";
+			reg = <0x01c20054 0x4>;
+			clocks = <&cpu>;
+			clock-output-names = "axi";
+		};
+
+		ahb: ahb@01c20054 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-a10-ahb-clk";
+			reg = <0x01c20054 0x4>;
+			clocks = <&axi>;
+			clock-output-names = "ahb";
+		};
+
+		ahb_gates: clk@01c20060 {
+			#clock-cells = <1>;
+			compatible = "allwinner,sun7i-a20-ahb-gates-clk";
+			reg = <0x01c20060 0x8>;
+			clocks = <&ahb>;
+			clock-output-names = "ahb_usb0", "ahb_ehci0",
+				"ahb_ohci0", "ahb_ehci1", "ahb_ohci1",
+				"ahb_ss", "ahb_dma", "ahb_bist", "ahb_mmc0",
+				"ahb_mmc1", "ahb_mmc2", "ahb_mmc3", "ahb_ms",
+				"ahb_nand", "ahb_sdram", "ahb_ace",
+				"ahb_emac", "ahb_ts", "ahb_spi0", "ahb_spi1",
+				"ahb_spi2", "ahb_spi3", "ahb_sata",
+				"ahb_hstimer", "ahb_ve", "ahb_tvd", "ahb_tve0",
+				"ahb_tve1", "ahb_lcd0", "ahb_lcd1", "ahb_csi0",
+				"ahb_csi1", "ahb_hdmi1", "ahb_hdmi0",
+				"ahb_de_be0", "ahb_de_be1", "ahb_de_fe0",
+				"ahb_de_fe1", "ahb_gmac", "ahb_mp",
+				"ahb_mali";
+		};
+
+		apb0: apb0@01c20054 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-a10-apb0-clk";
+			reg = <0x01c20054 0x4>;
+			clocks = <&ahb>;
+			clock-output-names = "apb0";
+		};
+
+		apb0_gates: clk@01c20068 {
+			#clock-cells = <1>;
+			compatible = "allwinner,sun7i-a20-apb0-gates-clk";
+			reg = <0x01c20068 0x4>;
+			clocks = <&apb0>;
+			clock-output-names = "apb0_codec", "apb0_spdif",
+				"apb0_ac97", "apb0_iis0", "apb0_iis1",
+				"apb0_pio", "apb0_ir0", "apb0_ir1",
+				"apb0_iis2", "apb0_keypad";
+		};
+
+		apb1_mux: apb1_mux@01c20058 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-a10-apb1-mux-clk";
+			reg = <0x01c20058 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&osc32k>;
+			clock-output-names = "apb1_mux";
+		};
+
+		apb1: apb1@01c20058 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-a10-apb1-clk";
+			reg = <0x01c20058 0x4>;
+			clocks = <&apb1_mux>;
+			clock-output-names = "apb1";
+		};
+
+		apb1_gates: clk@01c2006c {
+			#clock-cells = <1>;
+			compatible = "allwinner,sun7i-a20-apb1-gates-clk";
+			reg = <0x01c2006c 0x4>;
+			clocks = <&apb1>;
+			clock-output-names = "apb1_i2c0", "apb1_i2c1",
+				"apb1_i2c2", "apb1_i2c3", "apb1_can",
+				"apb1_scr", "apb1_ps20", "apb1_ps21",
+				"apb1_i2c4", "apb1_uart0", "apb1_uart1",
+				"apb1_uart2", "apb1_uart3", "apb1_uart4",
+				"apb1_uart5", "apb1_uart6", "apb1_uart7";
+		};
+
+		nand_clk: clk@01c20080 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-a10-mod0-clk";
+			reg = <0x01c20080 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+			clock-output-names = "nand";
+		};
+
+		ms_clk: clk@01c20084 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-a10-mod0-clk";
+			reg = <0x01c20084 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+			clock-output-names = "ms";
+		};
+
+		mmc0_clk: clk@01c20088 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-a10-mod0-clk";
+			reg = <0x01c20088 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+			clock-output-names = "mmc0";
+		};
+
+		mmc1_clk: clk@01c2008c {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-a10-mod0-clk";
+			reg = <0x01c2008c 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+			clock-output-names = "mmc1";
+		};
+
+		mmc2_clk: clk@01c20090 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-a10-mod0-clk";
+			reg = <0x01c20090 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+			clock-output-names = "mmc2";
+		};
+
+		mmc3_clk: clk@01c20094 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-a10-mod0-clk";
+			reg = <0x01c20094 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+			clock-output-names = "mmc3";
+		};
+
+		ts_clk: clk@01c20098 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-a10-mod0-clk";
+			reg = <0x01c20098 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+			clock-output-names = "ts";
+		};
+
+		ss_clk: clk@01c2009c {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-a10-mod0-clk";
+			reg = <0x01c2009c 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+			clock-output-names = "ss";
+		};
+
+		spi0_clk: clk@01c200a0 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-a10-mod0-clk";
+			reg = <0x01c200a0 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+			clock-output-names = "spi0";
+		};
+
+		spi1_clk: clk@01c200a4 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-a10-mod0-clk";
+			reg = <0x01c200a4 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+			clock-output-names = "spi1";
+		};
+
+		spi2_clk: clk@01c200a8 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-a10-mod0-clk";
+			reg = <0x01c200a8 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+			clock-output-names = "spi2";
+		};
+
+		pata_clk: clk@01c200ac {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-a10-mod0-clk";
+			reg = <0x01c200ac 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+			clock-output-names = "pata";
+		};
+
+		ir0_clk: clk@01c200b0 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-a10-mod0-clk";
+			reg = <0x01c200b0 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+			clock-output-names = "ir0";
+		};
+
+		ir1_clk: clk@01c200b4 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-a10-mod0-clk";
+			reg = <0x01c200b4 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+			clock-output-names = "ir1";
+		};
+
+		usb_clk: clk@01c200cc {
+			#clock-cells = <1>;
+		        #reset-cells = <1>;
+			compatible = "allwinner,sun4i-a10-usb-clk";
+			reg = <0x01c200cc 0x4>;
+			clocks = <&pll6 1>;
+			clock-output-names = "usb_ohci0", "usb_ohci1", "usb_phy";
+		};
+
+		spi3_clk: clk@01c200d4 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-a10-mod0-clk";
+			reg = <0x01c200d4 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+			clock-output-names = "spi3";
+		};
+
+		mbus_clk: clk@01c2015c {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-a10-mod0-clk";
+			reg = <0x01c2015c 0x4>;
+			clocks = <&osc24M>, <&pll6 2>, <&pll5 1>;
+			clock-output-names = "mbus";
+		};
+
+		/*
+		 * The following two are dummy clocks, placeholders used in the gmac_tx
+		 * clock. The gmac driver will choose one parent depending on the PHY
+		 * interface mode, using clk_set_rate auto-reparenting.
+		 * The actual TX clock rate is not controlled by the gmac_tx clock.
+		 */
+		mii_phy_tx_clk: clk@2 {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <25000000>;
+			clock-output-names = "mii_phy_tx";
+		};
+
+		gmac_int_tx_clk: clk@3 {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <125000000>;
+			clock-output-names = "gmac_int_tx";
+		};
+
+		gmac_tx_clk: clk@01c20164 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun7i-a20-gmac-clk";
+			reg = <0x01c20164 0x4>;
+			clocks = <&mii_phy_tx_clk>, <&gmac_int_tx_clk>;
+			clock-output-names = "gmac_tx";
+		};
+
+		/*
+		 * Dummy clock used by output clocks
+		 */
+		osc24M_32k: clk@1 {
+			#clock-cells = <0>;
+			compatible = "fixed-factor-clock";
+			clock-div = <750>;
+			clock-mult = <1>;
+			clocks = <&osc24M>;
+			clock-output-names = "osc24M_32k";
+		};
+
+		clk_out_a: clk@01c201f0 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun7i-a20-out-clk";
+			reg = <0x01c201f0 0x4>;
+			clocks = <&osc24M_32k>, <&osc32k>, <&osc24M>;
+			clock-output-names = "clk_out_a";
+		};
+
+		clk_out_b: clk@01c201f4 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun7i-a20-out-clk";
+			reg = <0x01c201f4 0x4>;
+			clocks = <&osc24M_32k>, <&osc32k>, <&osc24M>;
+			clock-output-names = "clk_out_b";
+		};
+	};
+
+	soc@01c00000 {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		nmi_intc: interrupt-controller@01c00030 {
+			compatible = "allwinner,sun7i-a20-sc-nmi";
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			reg = <0x01c00030 0x0c>;
+			interrupts = <0 0 4>;
+		};
+
+		spi0: spi@01c05000 {
+			compatible = "allwinner,sun4i-a10-spi";
+			reg = <0x01c05000 0x1000>;
+			interrupts = <0 10 4>;
+			clocks = <&ahb_gates 20>, <&spi0_clk>;
+			clock-names = "ahb", "mod";
+			status = "disabled";
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		spi1: spi@01c06000 {
+			compatible = "allwinner,sun4i-a10-spi";
+			reg = <0x01c06000 0x1000>;
+			interrupts = <0 11 4>;
+			clocks = <&ahb_gates 21>, <&spi1_clk>;
+			clock-names = "ahb", "mod";
+			status = "disabled";
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		emac: ethernet@01c0b000 {
+			compatible = "allwinner,sun4i-a10-emac";
+			reg = <0x01c0b000 0x1000>;
+			interrupts = <0 55 4>;
+			clocks = <&ahb_gates 17>;
+			status = "disabled";
+		};
+
+		mdio@01c0b080 {
+			compatible = "allwinner,sun4i-a10-mdio";
+			reg = <0x01c0b080 0x14>;
+			status = "disabled";
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		mmc0: mmc@01c0f000 {
+			compatible = "allwinner,sun5i-a13-mmc";
+			reg = <0x01c0f000 0x1000>;
+			clocks = <&ahb_gates 8>, <&mmc0_clk>;
+			clock-names = "ahb", "mmc";
+			interrupts = <0 32 4>;
+			status = "disabled";
+		};
+
+		mmc1: mmc@01c10000 {
+			compatible = "allwinner,sun5i-a13-mmc";
+			reg = <0x01c10000 0x1000>;
+			clocks = <&ahb_gates 9>, <&mmc1_clk>;
+			clock-names = "ahb", "mmc";
+			interrupts = <0 33 4>;
+			status = "disabled";
+		};
+
+		mmc2: mmc@01c11000 {
+			compatible = "allwinner,sun5i-a13-mmc";
+			reg = <0x01c11000 0x1000>;
+			clocks = <&ahb_gates 10>, <&mmc2_clk>;
+			clock-names = "ahb", "mmc";
+			interrupts = <0 34 4>;
+			status = "disabled";
+		};
+
+		mmc3: mmc@01c12000 {
+			compatible = "allwinner,sun5i-a13-mmc";
+			reg = <0x01c12000 0x1000>;
+			clocks = <&ahb_gates 11>, <&mmc3_clk>;
+			clock-names = "ahb", "mmc";
+			interrupts = <0 35 4>;
+			status = "disabled";
+		};
+
+		usbphy: phy@01c13400 {
+			#phy-cells = <1>;
+			compatible = "allwinner,sun7i-a20-usb-phy";
+			reg = <0x01c13400 0x10 0x01c14800 0x4 0x01c1c800 0x4>;
+			reg-names = "phy_ctrl", "pmu1", "pmu2";
+			clocks = <&usb_clk 8>;
+			clock-names = "usb_phy";
+			resets = <&usb_clk 1>, <&usb_clk 2>;
+			reset-names = "usb1_reset", "usb2_reset";
+			status = "disabled";
+		};
+
+		ehci0: usb@01c14000 {
+			compatible = "allwinner,sun7i-a20-ehci", "generic-ehci";
+			reg = <0x01c14000 0x100>;
+			interrupts = <0 39 4>;
+			clocks = <&ahb_gates 1>;
+			phys = <&usbphy 1>;
+			phy-names = "usb";
+			status = "disabled";
+		};
+
+		ohci0: usb@01c14400 {
+			compatible = "allwinner,sun7i-a20-ohci", "generic-ohci";
+			reg = <0x01c14400 0x100>;
+			interrupts = <0 64 4>;
+			clocks = <&usb_clk 6>, <&ahb_gates 2>;
+			phys = <&usbphy 1>;
+			phy-names = "usb";
+			status = "disabled";
+		};
+
+		spi2: spi@01c17000 {
+			compatible = "allwinner,sun4i-a10-spi";
+			reg = <0x01c17000 0x1000>;
+			interrupts = <0 12 4>;
+			clocks = <&ahb_gates 22>, <&spi2_clk>;
+			clock-names = "ahb", "mod";
+			status = "disabled";
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		ahci: sata@01c18000 {
+			compatible = "allwinner,sun4i-a10-ahci";
+			reg = <0x01c18000 0x1000>;
+			interrupts = <0 56 4>;
+			clocks = <&pll6 0>, <&ahb_gates 25>;
+			status = "disabled";
+		};
+
+		ehci1: usb@01c1c000 {
+			compatible = "allwinner,sun7i-a20-ehci", "generic-ehci";
+			reg = <0x01c1c000 0x100>;
+			interrupts = <0 40 4>;
+			clocks = <&ahb_gates 3>;
+			phys = <&usbphy 2>;
+			phy-names = "usb";
+			status = "disabled";
+		};
+
+		ohci1: usb@01c1c400 {
+			compatible = "allwinner,sun7i-a20-ohci", "generic-ohci";
+			reg = <0x01c1c400 0x100>;
+			interrupts = <0 65 4>;
+			clocks = <&usb_clk 7>, <&ahb_gates 4>;
+			phys = <&usbphy 2>;
+			phy-names = "usb";
+			status = "disabled";
+		};
+
+		spi3: spi@01c1f000 {
+			compatible = "allwinner,sun4i-a10-spi";
+			reg = <0x01c1f000 0x1000>;
+			interrupts = <0 50 4>;
+			clocks = <&ahb_gates 23>, <&spi3_clk>;
+			clock-names = "ahb", "mod";
+			status = "disabled";
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		pio: pinctrl@01c20800 {
+			compatible = "allwinner,sun7i-a20-pinctrl";
+			reg = <0x01c20800 0x400>;
+			interrupts = <0 28 4>;
+			clocks = <&apb0_gates 5>;
+			gpio-controller;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			#size-cells = <0>;
+			#gpio-cells = <3>;
+
+			pwm0_pins_a: pwm0@0 {
+				allwinner,pins = "PB2";
+				allwinner,function = "pwm";
+				allwinner,drive = <0>;
+				allwinner,pull = <0>;
+			};
+
+			pwm1_pins_a: pwm1@0 {
+				allwinner,pins = "PI3";
+				allwinner,function = "pwm";
+				allwinner,drive = <0>;
+				allwinner,pull = <0>;
+			};
+
+			uart0_pins_a: uart0@0 {
+				allwinner,pins = "PB22", "PB23";
+				allwinner,function = "uart0";
+				allwinner,drive = <0>;
+				allwinner,pull = <0>;
+			};
+
+			uart2_pins_a: uart2@0 {
+				allwinner,pins = "PI16", "PI17", "PI18", "PI19";
+				allwinner,function = "uart2";
+				allwinner,drive = <0>;
+				allwinner,pull = <0>;
+			};
+
+			uart6_pins_a: uart6@0 {
+				allwinner,pins = "PI12", "PI13";
+				allwinner,function = "uart6";
+				allwinner,drive = <0>;
+				allwinner,pull = <0>;
+			};
+
+			uart7_pins_a: uart7@0 {
+				allwinner,pins = "PI20", "PI21";
+				allwinner,function = "uart7";
+				allwinner,drive = <0>;
+				allwinner,pull = <0>;
+			};
+
+			i2c0_pins_a: i2c0@0 {
+				allwinner,pins = "PB0", "PB1";
+				allwinner,function = "i2c0";
+				allwinner,drive = <0>;
+				allwinner,pull = <0>;
+			};
+
+			i2c1_pins_a: i2c1@0 {
+				allwinner,pins = "PB18", "PB19";
+				allwinner,function = "i2c1";
+				allwinner,drive = <0>;
+				allwinner,pull = <0>;
+			};
+
+			i2c2_pins_a: i2c2@0 {
+				allwinner,pins = "PB20", "PB21";
+				allwinner,function = "i2c2";
+				allwinner,drive = <0>;
+				allwinner,pull = <0>;
+			};
+
+			emac_pins_a: emac0@0 {
+				allwinner,pins = "PA0", "PA1", "PA2",
+						"PA3", "PA4", "PA5", "PA6",
+						"PA7", "PA8", "PA9", "PA10",
+						"PA11", "PA12", "PA13", "PA14",
+						"PA15", "PA16";
+				allwinner,function = "emac";
+				allwinner,drive = <0>;
+				allwinner,pull = <0>;
+			};
+
+			clk_out_a_pins_a: clk_out_a@0 {
+				allwinner,pins = "PI12";
+				allwinner,function = "clk_out_a";
+				allwinner,drive = <0>;
+				allwinner,pull = <0>;
+			};
+
+			clk_out_b_pins_a: clk_out_b@0 {
+				allwinner,pins = "PI13";
+				allwinner,function = "clk_out_b";
+				allwinner,drive = <0>;
+				allwinner,pull = <0>;
+			};
+
+			gmac_pins_mii_a: gmac_mii@0 {
+				allwinner,pins = "PA0", "PA1", "PA2",
+						"PA3", "PA4", "PA5", "PA6",
+						"PA7", "PA8", "PA9", "PA10",
+						"PA11", "PA12", "PA13", "PA14",
+						"PA15", "PA16";
+				allwinner,function = "gmac";
+				allwinner,drive = <0>;
+				allwinner,pull = <0>;
+			};
+
+			gmac_pins_rgmii_a: gmac_rgmii@0 {
+				allwinner,pins = "PA0", "PA1", "PA2",
+						"PA3", "PA4", "PA5", "PA6",
+						"PA7", "PA8", "PA10",
+						"PA11", "PA12", "PA13",
+						"PA15", "PA16";
+				allwinner,function = "gmac";
+				/*
+				 * data lines in RGMII mode use DDR mode
+				 * and need a higher signal drive strength
+				 */
+				allwinner,drive = <3>;
+				allwinner,pull = <0>;
+			};
+
+			spi1_pins_a: spi1@0 {
+				allwinner,pins = "PI16", "PI17", "PI18", "PI19";
+				allwinner,function = "spi1";
+				allwinner,drive = <0>;
+				allwinner,pull = <0>;
+			};
+
+			spi2_pins_a: spi2@0 {
+				allwinner,pins = "PC19", "PC20", "PC21", "PC22";
+				allwinner,function = "spi2";
+				allwinner,drive = <0>;
+				allwinner,pull = <0>;
+			};
+
+			mmc0_pins_a: mmc0@0 {
+				allwinner,pins = "PF0","PF1","PF2","PF3","PF4","PF5";
+				allwinner,function = "mmc0";
+				allwinner,drive = <2>;
+				allwinner,pull = <0>;
+			};
+
+			mmc0_cd_pin_reference_design: mmc0_cd_pin@0 {
+				allwinner,pins = "PH1";
+				allwinner,function = "gpio_in";
+				allwinner,drive = <0>;
+				allwinner,pull = <1>;
+			};
+
+			mmc3_pins_a: mmc3@0 {
+				allwinner,pins = "PI4","PI5","PI6","PI7","PI8","PI9";
+				allwinner,function = "mmc3";
+				allwinner,drive = <2>;
+				allwinner,pull = <0>;
+			};
+
+			ir0_pins_a: ir0@0 {
+				    allwinner,pins = "PB3","PB4";
+				    allwinner,function = "ir0";
+				    allwinner,drive = <0>;
+				    allwinner,pull = <0>;
+			};
+
+			ir1_pins_a: ir1@0 {
+				    allwinner,pins = "PB22","PB23";
+				    allwinner,function = "ir1";
+				    allwinner,drive = <0>;
+				    allwinner,pull = <0>;
+			};
+		};
+
+		timer@01c20c00 {
+			compatible = "allwinner,sun4i-a10-timer";
+			reg = <0x01c20c00 0x90>;
+			interrupts = <0 22 4>,
+				     <0 23 4>,
+				     <0 24 4>,
+				     <0 25 4>,
+				     <0 67 4>,
+				     <0 68 4>;
+			clocks = <&osc24M>;
+		};
+
+		wdt: watchdog@01c20c90 {
+			compatible = "allwinner,sun4i-a10-wdt";
+			reg = <0x01c20c90 0x10>;
+		};
+
+		rtc: rtc@01c20d00 {
+			compatible = "allwinner,sun7i-a20-rtc";
+			reg = <0x01c20d00 0x20>;
+			interrupts = <0 24 4>;
+		};
+
+		pwm: pwm@01c20e00 {
+			compatible = "allwinner,sun7i-a20-pwm";
+			reg = <0x01c20e00 0xc>;
+			clocks = <&osc24M>;
+			#pwm-cells = <3>;
+			status = "disabled";
+		};
+
+		ir0: ir@01c21800 {
+			compatible = "allwinner,sun4i-a10-ir";
+			clocks = <&apb0_gates 6>, <&ir0_clk>;
+			clock-names = "apb", "ir";
+			interrupts = <0 5 4>;
+			reg = <0x01c21800 0x40>;
+			status = "disabled";
+		};
+
+		ir1: ir@01c21c00 {
+			compatible = "allwinner,sun4i-a10-ir";
+			clocks = <&apb0_gates 7>, <&ir1_clk>;
+			clock-names = "apb", "ir";
+			interrupts = <0 6 4>;
+			reg = <0x01c21c00 0x40>;
+			status = "disabled";
+		};
+
+		sid: eeprom@01c23800 {
+			compatible = "allwinner,sun7i-a20-sid";
+			reg = <0x01c23800 0x200>;
+		};
+
+		rtp: rtp@01c25000 {
+			compatible = "allwinner,sun4i-a10-ts";
+			reg = <0x01c25000 0x100>;
+			interrupts = <0 29 4>;
+		};
+
+		uart0: serial@01c28000 {
+			compatible = "snps,dw-apb-uart";
+			reg = <0x01c28000 0x400>;
+			interrupts = <0 1 4>;
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			clocks = <&apb1_gates 16>;
+			status = "disabled";
+		};
+
+		uart1: serial@01c28400 {
+			compatible = "snps,dw-apb-uart";
+			reg = <0x01c28400 0x400>;
+			interrupts = <0 2 4>;
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			clocks = <&apb1_gates 17>;
+			status = "disabled";
+		};
+
+		uart2: serial@01c28800 {
+			compatible = "snps,dw-apb-uart";
+			reg = <0x01c28800 0x400>;
+			interrupts = <0 3 4>;
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			clocks = <&apb1_gates 18>;
+			status = "disabled";
+		};
+
+		uart3: serial@01c28c00 {
+			compatible = "snps,dw-apb-uart";
+			reg = <0x01c28c00 0x400>;
+			interrupts = <0 4 4>;
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			clocks = <&apb1_gates 19>;
+			status = "disabled";
+		};
+
+		uart4: serial@01c29000 {
+			compatible = "snps,dw-apb-uart";
+			reg = <0x01c29000 0x400>;
+			interrupts = <0 17 4>;
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			clocks = <&apb1_gates 20>;
+			status = "disabled";
+		};
+
+		uart5: serial@01c29400 {
+			compatible = "snps,dw-apb-uart";
+			reg = <0x01c29400 0x400>;
+			interrupts = <0 18 4>;
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			clocks = <&apb1_gates 21>;
+			status = "disabled";
+		};
+
+		uart6: serial@01c29800 {
+			compatible = "snps,dw-apb-uart";
+			reg = <0x01c29800 0x400>;
+			interrupts = <0 19 4>;
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			clocks = <&apb1_gates 22>;
+			status = "disabled";
+		};
+
+		uart7: serial@01c29c00 {
+			compatible = "snps,dw-apb-uart";
+			reg = <0x01c29c00 0x400>;
+			interrupts = <0 20 4>;
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			clocks = <&apb1_gates 23>;
+			status = "disabled";
+		};
+
+		i2c0: i2c@01c2ac00 {
+			compatible = "allwinner,sun7i-a20-i2c", "allwinner,sun4i-a10-i2c";
+			reg = <0x01c2ac00 0x400>;
+			interrupts = <0 7 4>;
+			clocks = <&apb1_gates 0>;
+			clock-frequency = <100000>;
+			status = "disabled";
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		i2c1: i2c@01c2b000 {
+			compatible = "allwinner,sun7i-a20-i2c", "allwinner,sun4i-a10-i2c";
+			reg = <0x01c2b000 0x400>;
+			interrupts = <0 8 4>;
+			clocks = <&apb1_gates 1>;
+			clock-frequency = <100000>;
+			status = "disabled";
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		i2c2: i2c@01c2b400 {
+			compatible = "allwinner,sun7i-a20-i2c", "allwinner,sun4i-a10-i2c";
+			reg = <0x01c2b400 0x400>;
+			interrupts = <0 9 4>;
+			clocks = <&apb1_gates 2>;
+			clock-frequency = <100000>;
+			status = "disabled";
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		i2c3: i2c@01c2b800 {
+			compatible = "allwinner,sun7i-a20-i2c", "allwinner,sun4i-a10-i2c";
+			reg = <0x01c2b800 0x400>;
+			interrupts = <0 88 4>;
+			clocks = <&apb1_gates 3>;
+			clock-frequency = <100000>;
+			status = "disabled";
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		i2c4: i2c@01c2c000 {
+			compatible = "allwinner,sun7i-a20-i2c", "allwinner,sun4i-a10-i2c";
+			reg = <0x01c2c000 0x400>;
+			interrupts = <0 89 4>;
+			clocks = <&apb1_gates 15>;
+			clock-frequency = <100000>;
+			status = "disabled";
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		gmac: ethernet@01c50000 {
+			compatible = "allwinner,sun7i-a20-gmac";
+			reg = <0x01c50000 0x10000>;
+			interrupts = <0 85 4>;
+			interrupt-names = "macirq";
+			clocks = <&ahb_gates 49>, <&gmac_tx_clk>;
+			clock-names = "stmmaceth", "allwinner_gmac_tx";
+			snps,pbl = <2>;
+			snps,fixed-burst;
+			snps,force_sf_dma_mode;
+			status = "disabled";
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		hstimer@01c60000 {
+			compatible = "allwinner,sun7i-a20-hstimer";
+			reg = <0x01c60000 0x1000>;
+			interrupts = <0 81 4>,
+				     <0 82 4>,
+				     <0 83 4>,
+				     <0 84 4>;
+			clocks = <&ahb_gates 28>;
+		};
+
+		gic: interrupt-controller@01c81000 {
+			compatible = "arm,cortex-a7-gic", "arm,cortex-a15-gic";
+			reg = <0x01c81000 0x1000>,
+			      <0x01c82000 0x1000>,
+			      <0x01c84000 0x2000>,
+			      <0x01c86000 0x2000>;
+			interrupt-controller;
+			#interrupt-cells = <3>;
+			interrupts = <1 9 0xf04>;
+		};
+	};
+};
diff --git a/arch/arm/dts/sunxi-common-regulators.dtsi b/arch/arm/dts/sunxi-common-regulators.dtsi
new file mode 100644
index 0000000000000000000000000000000000000000..3d021efd1a38f6ae4f00087daef44dfd7bb85ec6
--- /dev/null
+++ b/arch/arm/dts/sunxi-common-regulators.dtsi
@@ -0,0 +1,89 @@
+/*
+ * sunxi boards common regulator (ahci target power supply, usb-vbus) code
+ *
+ * Copyright 2014 - Hans de Goede <hdegoede@redhat.com>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/ {
+	soc@01c00000 {
+		pio: pinctrl@01c20800 {
+			ahci_pwr_pin_a: ahci_pwr_pin@0 {
+				allwinner,pins = "PB8";
+				allwinner,function = "gpio_out";
+				allwinner,drive = <0>;
+				allwinner,pull = <0>;
+			};
+
+			usb1_vbus_pin_a: usb1_vbus_pin@0 {
+				allwinner,pins = "PH6";
+				allwinner,function = "gpio_out";
+				allwinner,drive = <0>;
+				allwinner,pull = <0>;
+			};
+
+			usb2_vbus_pin_a: usb2_vbus_pin@0 {
+				allwinner,pins = "PH3";
+				allwinner,function = "gpio_out";
+				allwinner,drive = <0>;
+				allwinner,pull = <0>;
+			};
+		};
+	};
+
+	reg_ahci_5v: ahci-5v {
+		compatible = "regulator-fixed";
+		pinctrl-names = "default";
+		pinctrl-0 = <&ahci_pwr_pin_a>;
+		regulator-name = "ahci-5v";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		enable-active-high;
+		gpio = <&pio 1 8 0>;
+		status = "disabled";
+	};
+
+	reg_usb1_vbus: usb1-vbus {
+		compatible = "regulator-fixed";
+		pinctrl-names = "default";
+		pinctrl-0 = <&usb1_vbus_pin_a>;
+		regulator-name = "usb1-vbus";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		enable-active-high;
+		gpio = <&pio 7 6 0>;
+		status = "disabled";
+	};
+
+	reg_usb2_vbus: usb2-vbus {
+		compatible = "regulator-fixed";
+		pinctrl-names = "default";
+		pinctrl-0 = <&usb2_vbus_pin_a>;
+		regulator-name = "usb2-vbus";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		enable-active-high;
+		gpio = <&pio 7 3 0>;
+		status = "disabled";
+	};
+
+	reg_vcc3v0: vcc3v0 {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc3v0";
+		regulator-min-microvolt = <3000000>;
+		regulator-max-microvolt = <3000000>;
+	};
+
+	reg_vcc3v3: vcc3v3 {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc3v3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+	};
+};
diff --git a/arch/arm/include/asm/arch-sunxi/clock.h b/arch/arm/include/asm/arch-sunxi/clock.h
index c562f621c22624ddf8589afb3e2cc3090eac8b1c..42382a8ae2ff365694bf7a37a1618733fbabaf73 100644
--- a/arch/arm/include/asm/arch-sunxi/clock.h
+++ b/arch/arm/include/asm/arch-sunxi/clock.h
@@ -15,7 +15,7 @@
 #define CLK_GATE_CLOSE			0x0
 
 /* clock control module regs definition */
-#if defined(CONFIG_SUN6I) || defined(CONFIG_SUN8I)
+#if defined(CONFIG_MACH_SUN6I) || defined(CONFIG_MACH_SUN8I)
 #include <asm/arch/clock_sun6i.h>
 #else
 #include <asm/arch/clock_sun4i.h>
diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h
index 7bb649950a982d19d9ea293352a35e82414e06ad..437dd35b68d47844b8c7d05cad65ed13478ddb0c 100644
--- a/arch/arm/include/asm/arch-sunxi/gpio.h
+++ b/arch/arm/include/asm/arch-sunxi/gpio.h
@@ -155,7 +155,7 @@ enum sunxi_gpio_number {
 
 #define SUNXI_GPF2_SDC0		2
 
-#ifdef CONFIG_SUN8I
+#ifdef CONFIG_MACH_SUN8I
 #define SUNXI_GPF2_UART0_TX	3
 #define SUNXI_GPF4_UART0_RX	3
 #else
@@ -180,7 +180,9 @@ enum sunxi_gpio_number {
 #define SUNXI_GPIO_PULL_UP	1
 #define SUNXI_GPIO_PULL_DOWN	2
 
-int sunxi_gpio_set_cfgpin(u32 pin, u32 val);
+void sunxi_gpio_set_cfgbank(struct sunxi_gpio *pio, int bank_offset, u32 val);
+void sunxi_gpio_set_cfgpin(u32 pin, u32 val);
+int sunxi_gpio_get_cfgbank(struct sunxi_gpio *pio, int bank_offset);
 int sunxi_gpio_get_cfgpin(u32 pin);
 int sunxi_gpio_set_drv(u32 pin, u32 val);
 int sunxi_gpio_set_pull(u32 pin, u32 val);
diff --git a/arch/arm/include/asm/arch-sunxi/mmc.h b/arch/arm/include/asm/arch-sunxi/mmc.h
index 8a216740a722e4471f4f39680634fe9db861b354..537f1455643cc5ffae3d998599f3b941d2244568 100644
--- a/arch/arm/include/asm/arch-sunxi/mmc.h
+++ b/arch/arm/include/asm/arch-sunxi/mmc.h
@@ -43,7 +43,7 @@ struct sunxi_mmc {
 	u32 chda;		/* 0x90 */
 	u32 cbda;		/* 0x94 */
 	u32 res1[26];
-#if defined(CONFIG_SUN6I) || defined(CONFIG_SUN8I)
+#if defined(CONFIG_MACH_SUN6I) || defined(CONFIG_MACH_SUN8I)
 	u32 res2[64];
 #endif
 	u32 fifo;		/* 0x100 (0x200 on sun6i) FIFO access address */
diff --git a/arch/arm/include/asm/arch-sunxi/timer.h b/arch/arm/include/asm/arch-sunxi/timer.h
index 03a0684c797a3c28179886a283ca2382d249b17b..9a5e488a38080f489494fd1f45a987c68142d1b6 100644
--- a/arch/arm/include/asm/arch-sunxi/timer.h
+++ b/arch/arm/include/asm/arch-sunxi/timer.h
@@ -67,7 +67,7 @@ struct sunxi_timer_reg {
 	struct sunxi_timer timer[6];	/* We have 6 timers */
 	u8 res2[16];
 	struct sunxi_avs avs;
-#if defined(CONFIG_SUN4I) || defined(CONFIG_SUN5I) || defined(CONFIG_SUN7I)
+#if defined(CONFIG_MACH_SUN4I) || defined(CONFIG_MACH_SUN5I) || defined(CONFIG_MACH_SUN7I)
 	struct sunxi_wdog wdog;	/* 0x90 */
 	/* XXX the following is not accurate for sun5i/sun7i */
 	struct sunxi_64cnt cnt64;	/* 0xa0 */
@@ -77,7 +77,7 @@ struct sunxi_timer_reg {
 	struct sunxi_tgp tgp[4];
 	u8 res5[8];
 	u32 cpu_cfg;
-#else /* CONFIG_SUN6I || CONFIG_SUN8I || ... */
+#else /* CONFIG_MACH_SUN6I || CONFIG_MACH_SUN8I || ... */
 	u8 res3[16];
 	struct sunxi_wdog wdog[5];	/* We have 5 watchdogs */
 #endif
diff --git a/arch/arm/include/asm/arch-sunxi/watchdog.h b/arch/arm/include/asm/arch-sunxi/watchdog.h
index ccc8fa32c49df2244e7d6ff67b994824722ec3f4..8108be97bab08ec75128853ca07e4c65253d98f6 100644
--- a/arch/arm/include/asm/arch-sunxi/watchdog.h
+++ b/arch/arm/include/asm/arch-sunxi/watchdog.h
@@ -13,7 +13,7 @@
 #define WDT_CTRL_RESTART	(0x1 << 0)
 #define WDT_CTRL_KEY		(0x0a57 << 1)
 
-#if defined(CONFIG_SUN4I) || defined(CONFIG_SUN5I) || defined(CONFIG_SUN7I)
+#if defined(CONFIG_MACH_SUN4I) || defined(CONFIG_MACH_SUN5I) || defined(CONFIG_MACH_SUN7I)
 
 #define WDT_MODE_EN		(0x1 << 0)
 #define WDT_MODE_RESET_EN	(0x1 << 1)
diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig
index 28df18784042e2b5f6e133b8502afa402dfa90dc..5b2d091122de11143313c1124fd1175c3117fed8 100644
--- a/board/sunxi/Kconfig
+++ b/board/sunxi/Kconfig
@@ -1,12 +1,141 @@
-if TARGET_SUN4I || TARGET_SUN5I || TARGET_SUN6I || TARGET_SUN7I || TARGET_SUN8I
+if ARCH_SUNXI
+
+choice
+	prompt "Sunxi SoC Variant"
+
+config MACH_SUN4I
+	bool "sun4i (Allwinner A10)"
+	select CPU_V7
+	select SUPPORT_SPL
+
+config MACH_SUN5I
+	bool "sun5i (Allwinner A13)"
+	select CPU_V7
+	select SUPPORT_SPL
+
+config MACH_SUN6I
+	bool "sun6i (Allwinner A31)"
+	select CPU_V7
+
+config MACH_SUN7I
+	bool "sun7i (Allwinner A20)"
+	select CPU_V7
+	select SUPPORT_SPL
+
+config MACH_SUN8I
+	bool "sun8i (Allwinner A23)"
+	select CPU_V7
+
+endchoice
 
 config SYS_CONFIG_NAME
 	string
-	default "sun4i" if TARGET_SUN4I
-	default "sun5i" if TARGET_SUN5I
-	default "sun6i" if TARGET_SUN6I
-	default "sun7i" if TARGET_SUN7I
-	default "sun8i" if TARGET_SUN8I
+	default "sun4i" if MACH_SUN4I
+	default "sun5i" if MACH_SUN5I
+	default "sun6i" if MACH_SUN6I
+	default "sun7i" if MACH_SUN7I
+	default "sun8i" if MACH_SUN8I
+
+choice
+	prompt "Board"
+
+config TARGET_A10_OLINUXINO_L
+	bool "A10_OLINUXINO_L"
+	depends on MACH_SUN4I
+
+config TARGET_A10S_OLINUXINO_M
+	bool "A10S_OLINUXINO_M"
+	depends on MACH_SUN5I
+
+config TARGET_A13_OLINUXINOM
+	bool "A13_OLINUXINOM"
+	depends on MACH_SUN5I
+
+config TARGET_A13_OLINUXINO
+	bool "A13_OLINUXINO"
+	depends on MACH_SUN5I
+
+config TARGET_A20_OLINUXINO_L2
+	bool "A20_OLINUXINO_L2"
+	depends on MACH_SUN7I
+
+config TARGET_A20_OLINUXINO_L
+	bool "A20_OLINUXINO_L"
+	depends on MACH_SUN7I
+
+config TARGET_A20_OLINUXINO_M
+	bool "A20_OLINUXINO_M"
+	depends on MACH_SUN7I
+
+config TARGET_AUXTEK_T004
+	bool "AUXTEK_T004"
+	depends on MACH_SUN5I
+
+config TARGET_BANANAPI
+	bool "BANANAPI"
+	depends on MACH_SUN7I
+
+config TARGET_COLOMBUS
+	bool "COLOMBUS"
+	depends on MACH_SUN6I
+
+config TARGET_CUBIEBOARD2
+	bool "CUBIEBOARD2"
+	depends on MACH_SUN7I
+
+config TARGET_CUBIEBOARD
+	bool "CUBIEBOARD"
+	depends on MACH_SUN4I
+
+config TARGET_CUBIETRUCK
+	bool "CUBIETRUCK"
+	depends on MACH_SUN7I
+
+config TARGET_IPPO_Q8H_V5
+	bool "IPPO_Q8H_V5"
+	depends on MACH_SUN8I
+
+config TARGET_PCDUINO3
+	bool "PCDUINO3"
+	depends on MACH_SUN7I
+
+config TARGET_MELE_A1000G
+	bool "MELE_A1000G"
+	depends on MACH_SUN4I
+
+config TARGET_MELE_A1000
+	bool "MELE_A1000"
+	depends on MACH_SUN4I
+
+config TARGET_MELE_M3
+	bool "MELE_M3"
+	depends on MACH_SUN7I
+
+config TARGET_MINI_X_1GB
+	bool "MINI_X_1GB"
+	depends on MACH_SUN4I
+
+config TARGET_MINI_X
+	bool "MINI_X"
+	depends on MACH_SUN4I
+
+config TARGET_BA10_TV_BOX
+	bool "BA10_TV_BOX"
+	depends on MACH_SUN4I
+
+config TARGET_I12_TVBOX
+	bool "I12_TVBOX"
+	depends on MACH_SUN7I
+
+config TARGET_QT840A
+	bool "QT840A"
+	depends on MACH_SUN7I
+
+config TARGET_R7DONGLE
+	bool "R7DONGLE"
+	depends on MACH_SUN5I
+
+endchoice
 
 config SYS_BOARD
 	default "sunxi"
@@ -14,6 +143,11 @@ config SYS_BOARD
 config SYS_SOC
 	default "sunxi"
 
+config SPL_FEL
+	bool "SPL/FEL mode support"
+	depends on SPL
+	default n
+
 config FDTFILE
 	string "Default fdtfile env setting for this board"
 
diff --git a/board/sunxi/MAINTAINERS b/board/sunxi/MAINTAINERS
index febd126cb83bb15518515422ac35e25cba071dfa..b3c77a83cb7191e04e29029ba2d96eca0997353d 100644
--- a/board/sunxi/MAINTAINERS
+++ b/board/sunxi/MAINTAINERS
@@ -22,6 +22,7 @@ F:	configs/A20-OLinuXino_MICRO_defconfig
 F:	configs/Bananapi_defconfig
 F:	configs/i12-tvbox_defconfig
 F:	configs/Linksprite_pcDuino3_defconfig
+F:	configs/Linksprite_pcDuino3_fdt_defconfig
 F:	configs/qt840a_defconfig
 
 CUBIEBOARD2 BOARD
@@ -52,6 +53,6 @@ S:	Maintained
 F:	configs/Colombus_defconfig
 
 IPPO-Q8H-V5 BOARD
-M:	CHen-Yu Tsai <wens@csie.org>
+M:	Chen-Yu Tsai <wens@csie.org>
 S:	Maintained
 F:	configs/Ippo_q8h_v5_defconfig
diff --git a/board/sunxi/Makefile b/board/sunxi/Makefile
index 6a2e4c9d5b5553d52a6325277109a201d10a1ca3..b84ff9b8ef81fa481ffd0a06ebe4a3c36067aa7b 100644
--- a/board/sunxi/Makefile
+++ b/board/sunxi/Makefile
@@ -11,26 +11,26 @@
 obj-y	+= board.o
 obj-$(CONFIG_SUNXI_GMAC)	+= gmac.o
 obj-$(CONFIG_SUNXI_AHCI)	+= ahci.o
-obj-$(CONFIG_A10_OLINUXINO_L)	+= dram_a10_olinuxino_l.o
-obj-$(CONFIG_A10S_OLINUXINO_M)	+= dram_a10s_olinuxino_m.o
-obj-$(CONFIG_A13_OLINUXINO)	+= dram_a13_olinuxino.o
-obj-$(CONFIG_A13_OLINUXINOM)	+= dram_a13_oli_micro.o
-obj-$(CONFIG_A20_OLINUXINO_L)	+= dram_a20_olinuxino_l.o
-obj-$(CONFIG_A20_OLINUXINO_L2)	+= dram_a20_olinuxino_l2.o
-obj-$(CONFIG_A20_OLINUXINO_M)	+= dram_sun7i_384_1024_iow16.o
+obj-$(CONFIG_TARGET_A10_OLINUXINO_L)	+= dram_a10_olinuxino_l.o
+obj-$(CONFIG_TARGET_A10S_OLINUXINO_M)	+= dram_a10s_olinuxino_m.o
+obj-$(CONFIG_TARGET_A13_OLINUXINO)	+= dram_a13_olinuxino.o
+obj-$(CONFIG_TARGET_A13_OLINUXINOM)	+= dram_a13_oli_micro.o
+obj-$(CONFIG_TARGET_A20_OLINUXINO_L)	+= dram_a20_olinuxino_l.o
+obj-$(CONFIG_TARGET_A20_OLINUXINO_L2)	+= dram_a20_olinuxino_l2.o
+obj-$(CONFIG_TARGET_A20_OLINUXINO_M)	+= dram_sun7i_384_1024_iow16.o
 # This is not a typo, uses the same mem settings as the a10s-olinuxino-m
-obj-$(CONFIG_AUXTEK_T004)	+= dram_a10s_olinuxino_m.o
-obj-$(CONFIG_BA10_TV_BOX)	+= dram_sun4i_384_1024_iow8.o
-obj-$(CONFIG_BANANAPI)		+= dram_bananapi.o
-obj-$(CONFIG_CUBIEBOARD)	+= dram_cubieboard.o
-obj-$(CONFIG_CUBIEBOARD2)	+= dram_cubieboard2.o
-obj-$(CONFIG_CUBIETRUCK)	+= dram_cubietruck.o
-obj-$(CONFIG_I12_TVBOX)		+= dram_sun7i_384_1024_iow16.o
-obj-$(CONFIG_MELE_A1000)	+= dram_sun4i_360_512.o
-obj-$(CONFIG_MELE_A1000G)	+= dram_sun4i_360_1024_iow8.o
-obj-$(CONFIG_MELE_M3)		+= dram_sun7i_384_1024_iow16.o
-obj-$(CONFIG_MINI_X)		+= dram_sun4i_360_512.o
-obj-$(CONFIG_MINI_X_1GB)	+= dram_sun4i_360_1024_iow16.o
-obj-$(CONFIG_PCDUINO3)		+= dram_linksprite_pcduino3.o
-obj-$(CONFIG_QT840A)		+= dram_sun7i_384_512_busw16_iow16.o
-obj-$(CONFIG_R7DONGLE)		+= dram_r7dongle.o
+obj-$(CONFIG_TARGET_AUXTEK_T004)	+= dram_a10s_olinuxino_m.o
+obj-$(CONFIG_TARGET_BA10_TV_BOX)	+= dram_sun4i_384_1024_iow8.o
+obj-$(CONFIG_TARGET_BANANAPI)		+= dram_bananapi.o
+obj-$(CONFIG_TARGET_CUBIEBOARD)		+= dram_cubieboard.o
+obj-$(CONFIG_TARGET_CUBIEBOARD2)	+= dram_cubieboard2.o
+obj-$(CONFIG_TARGET_CUBIETRUCK)		+= dram_cubietruck.o
+obj-$(CONFIG_TARGET_I12_TVBOX)		+= dram_sun7i_384_1024_iow16.o
+obj-$(CONFIG_TARGET_MELE_A1000)		+= dram_sun4i_360_512.o
+obj-$(CONFIG_TARGET_MELE_A1000G)	+= dram_sun4i_360_1024_iow8.o
+obj-$(CONFIG_TARGET_MELE_M3)		+= dram_sun7i_384_1024_iow16.o
+obj-$(CONFIG_TARGET_MINI_X)		+= dram_sun4i_360_512.o
+obj-$(CONFIG_TARGET_MINI_X_1GB)		+= dram_sun4i_360_1024_iow16.o
+obj-$(CONFIG_TARGET_PCDUINO3)		+= dram_linksprite_pcduino3.o
+obj-$(CONFIG_TARGET_QT840A)		+= dram_sun7i_384_512_busw16_iow16.o
+obj-$(CONFIG_TARGET_R7DONGLE)		+= dram_r7dongle.o
diff --git a/board/sunxi/ahci.c b/board/sunxi/ahci.c
index 0c262eabb754785ca4a53064e47af53feee1d820..5e123285b03d2d8a8fb29b6c2712d11bf4fa1df5 100644
--- a/board/sunxi/ahci.c
+++ b/board/sunxi/ahci.c
@@ -74,6 +74,7 @@ void scsi_init(void)
 {
 	printf("SUNXI SCSI INIT\n");
 #ifdef CONFIG_SATAPWR
+	gpio_request(CONFIG_SATAPWR, "satapwr");
 	gpio_direction_output(CONFIG_SATAPWR, 1);
 #endif
 
diff --git a/configs/A10-OLinuXino-Lime_defconfig b/configs/A10-OLinuXino-Lime_defconfig
index f9922936ab17e724dab24db292d5b76b36fb9889..f0cbf21025afefaecc05eb2af5527dfae1b0e61d 100644
--- a/configs/A10-OLinuXino-Lime_defconfig
+++ b/configs/A10-OLinuXino-Lime_defconfig
@@ -1,5 +1,7 @@
 CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="A10_OLINUXINO_L,AXP209_POWER,SUNXI_EMAC,AHCI,SATAPWR=SUNXI_GPC(3),USB_EHCI"
+CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_EMAC,AHCI,SATAPWR=SUNXI_GPC(3),USB_EHCI"
 CONFIG_FDTFILE="sun4i-a10-olinuxino-lime.dtb"
 +S:CONFIG_ARM=y
-+S:CONFIG_TARGET_SUN4I=y
++S:CONFIG_ARCH_SUNXI=y
++S:CONFIG_MACH_SUN4I=y
++S:CONFIG_TARGET_A10_OLINUXINO_L=y
diff --git a/configs/A10s-OLinuXino-M_defconfig b/configs/A10s-OLinuXino-M_defconfig
index 2aad834fa840c5b1390c3621442e9ab444240349..64756755bf9f2e234c353895e2e54d2db43bf389 100644
--- a/configs/A10s-OLinuXino-M_defconfig
+++ b/configs/A10s-OLinuXino-M_defconfig
@@ -1,8 +1,10 @@
 CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="A10S_OLINUXINO_M,AXP152_POWER,SUNXI_EMAC,USB_EHCI,SUNXI_USB_VBUS0_GPIO=SUNXI_GPB(10)"
+CONFIG_SYS_EXTRA_OPTIONS="AXP152_POWER,SUNXI_EMAC,USB_EHCI,SUNXI_USB_VBUS0_GPIO=SUNXI_GPB(10)"
 CONFIG_FDTFILE="sun5i-a10s-olinuxino-micro.dtb"
 CONFIG_MMC_SUNXI_SLOT_EXTRA=1
 +S:CONFIG_MMC0_CD_PIN="PG1"
 +S:CONFIG_MMC1_CD_PIN="PG13"
 +S:CONFIG_ARM=y
-+S:CONFIG_TARGET_SUN5I=y
++S:CONFIG_ARCH_SUNXI=y
++S:CONFIG_MACH_SUN5I=y
++S:CONFIG_TARGET_A10S_OLINUXINO_M=y
diff --git a/configs/A13-OLinuXinoM_defconfig b/configs/A13-OLinuXinoM_defconfig
index 9ae7b128517b1cfc3339c189f8216a97b1b7b49c..d8b12391d86bbca666e202284e9d4625bc993e49 100644
--- a/configs/A13-OLinuXinoM_defconfig
+++ b/configs/A13-OLinuXinoM_defconfig
@@ -1,5 +1,7 @@
 CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="A13_OLINUXINOM,CONS_INDEX=2,USB_EHCI,SUNXI_USB_VBUS0_GPIO=SUNXI_GPG(11)"
+CONFIG_SYS_EXTRA_OPTIONS="CONS_INDEX=2,USB_EHCI,SUNXI_USB_VBUS0_GPIO=SUNXI_GPG(11)"
 CONFIG_FDTFILE="sun5i-a13-olinuxino-micro.dtb"
 +S:CONFIG_ARM=y
-+S:CONFIG_TARGET_SUN5I=y
++S:CONFIG_ARCH_SUNXI=y
++S:CONFIG_MACH_SUN5I=y
++S:CONFIG_TARGET_A13_OLINUXINOM=y
diff --git a/configs/A13-OLinuXino_defconfig b/configs/A13-OLinuXino_defconfig
index 2c726f308a2b67d9ec2403acebcefec83426a89a..91039dfc9691cc65d065bff557e1255294b7b542 100644
--- a/configs/A13-OLinuXino_defconfig
+++ b/configs/A13-OLinuXino_defconfig
@@ -1,5 +1,7 @@
 CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="A13_OLINUXINO,CONS_INDEX=2,AXP209_POWER,USB_EHCI,SUNXI_USB_VBUS0_GPIO=SUNXI_GPG(11)"
+CONFIG_SYS_EXTRA_OPTIONS="CONS_INDEX=2,AXP209_POWER,USB_EHCI,SUNXI_USB_VBUS0_GPIO=SUNXI_GPG(11)"
 CONFIG_FDTFILE="sun5i-a13-olinuxino.dtb"
 +S:CONFIG_ARM=y
-+S:CONFIG_TARGET_SUN5I=y
++S:CONFIG_ARCH_SUNXI=y
++S:CONFIG_MACH_SUN5I=y
++S:CONFIG_TARGET_A13_OLINUXINO=y
diff --git a/configs/A20-OLinuXino-Lime2_defconfig b/configs/A20-OLinuXino-Lime2_defconfig
index 75ef87278026650dae58b97eedc16e153b1e2b28..f80b98ae90a2d37df500d941fc402b4e5f01ca83 100644
--- a/configs/A20-OLinuXino-Lime2_defconfig
+++ b/configs/A20-OLinuXino-Lime2_defconfig
@@ -1,5 +1,7 @@
 CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="A20_OLINUXINO_L2,AXP209_POWER,SUNXI_GMAC,RGMII,AHCI,SATAPWR=SUNXI_GPC(3),USB_EHCI"
+CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_GMAC,RGMII,AHCI,SATAPWR=SUNXI_GPC(3),USB_EHCI"
 CONFIG_FDTFILE="sun7i-a20-olinuxino-lime2.dtb"
 +S:CONFIG_ARM=y
-+S:CONFIG_TARGET_SUN7I=y
++S:CONFIG_ARCH_SUNXI=y
++S:CONFIG_MACH_SUN7I=y
++S:CONFIG_TARGET_A20_OLINUXINO_L2=y
diff --git a/configs/A20-OLinuXino-Lime_defconfig b/configs/A20-OLinuXino-Lime_defconfig
index ca79fd58aa6f8ab3252cc8666ffdcccacbcd7079..d9e66b715514830da86073f7316f2c846482810f 100644
--- a/configs/A20-OLinuXino-Lime_defconfig
+++ b/configs/A20-OLinuXino-Lime_defconfig
@@ -1,5 +1,7 @@
 CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="A20_OLINUXINO_L,AXP209_POWER,SUNXI_GMAC,AHCI,SATAPWR=SUNXI_GPC(3),USB_EHCI"
+CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_GMAC,AHCI,SATAPWR=SUNXI_GPC(3),USB_EHCI"
 CONFIG_FDTFILE="sun7i-a20-olinuxino-lime.dtb"
 +S:CONFIG_ARM=y
-+S:CONFIG_TARGET_SUN7I=y
++S:CONFIG_ARCH_SUNXI=y
++S:CONFIG_MACH_SUN7I=y
++S:CONFIG_TARGET_A20_OLINUXINO_L=y
diff --git a/configs/A20-OLinuXino_MICRO_defconfig b/configs/A20-OLinuXino_MICRO_defconfig
index 0e0a7def2de600f0fc06aaf6898f3644fdd4243e..1b9668d46df9362ddab520e2b32556854896eb96 100644
--- a/configs/A20-OLinuXino_MICRO_defconfig
+++ b/configs/A20-OLinuXino_MICRO_defconfig
@@ -1,8 +1,10 @@
 CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="A20_OLINUXINO_M,AXP209_POWER,SUNXI_GMAC,AHCI,SATAPWR=SUNXI_GPB(8),USB_EHCI"
+CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_GMAC,AHCI,SATAPWR=SUNXI_GPB(8),USB_EHCI"
 CONFIG_FDTFILE="sun7i-a20-olinuxino-micro.dtb"
 CONFIG_MMC_SUNXI_SLOT_EXTRA=3
 +S:CONFIG_MMC0_CD_PIN="PH1"
 +S:CONFIG_MMC3_CD_PIN="PH11"
 +S:CONFIG_ARM=y
-+S:CONFIG_TARGET_SUN7I=y
++S:CONFIG_ARCH_SUNXI=y
++S:CONFIG_MACH_SUN7I=y
++S:CONFIG_TARGET_A20_OLINUXINO_M=y
diff --git a/configs/Auxtek-T004_defconfig b/configs/Auxtek-T004_defconfig
index ed06f5700c36b3bb2cfe2794453bb93812e86554..5b06ea0aeada7f2feaa3092cdce84b3d21071439 100644
--- a/configs/Auxtek-T004_defconfig
+++ b/configs/Auxtek-T004_defconfig
@@ -1,5 +1,7 @@
 CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="AUXTEK_T004,AXP152_POWER,USB_EHCI,SUNXI_USB_VBUS0_GPIO=SUNXI_GPG(13)"
+CONFIG_SYS_EXTRA_OPTIONS="AXP152_POWER,USB_EHCI,SUNXI_USB_VBUS0_GPIO=SUNXI_GPG(13)"
 CONFIG_FDTFILE="sun5i-a10s-auxtek-t004.dtb"
 +S:CONFIG_ARM=y
-+S:CONFIG_TARGET_SUN5I=y
++S:CONFIG_ARCH_SUNXI=y
++S:CONFIG_MACH_SUN5I=y
++S:CONFIG_TARGET_AUXTEK_T004=y
diff --git a/configs/Bananapi_defconfig b/configs/Bananapi_defconfig
index d59cf72eaac604ef4e39fcdeb0100d85ddc4c73e..196f6824cb422c6f43c137fb10baf0fd83fec61a 100644
--- a/configs/Bananapi_defconfig
+++ b/configs/Bananapi_defconfig
@@ -1,5 +1,7 @@
 CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="BANANAPI,AXP209_POWER,SUNXI_GMAC,RGMII,MACPWR=SUNXI_GPH(23),AHCI,USB_EHCI"
+CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_GMAC,RGMII,MACPWR=SUNXI_GPH(23),AHCI,USB_EHCI"
 CONFIG_FDTFILE="sun7i-a20-bananapi.dtb"
 +S:CONFIG_ARM=y
-+S:CONFIG_TARGET_SUN7I=y
++S:CONFIG_ARCH_SUNXI=y
++S:CONFIG_MACH_SUN7I=y
++S:CONFIG_TARGET_BANANAPI=y
diff --git a/configs/Colombus_defconfig b/configs/Colombus_defconfig
index 16800de2bcd3154b320d6761478cf6101e552927..89291f90e970c66f04ba5a82f0fd6e022e9f57e3 100644
--- a/configs/Colombus_defconfig
+++ b/configs/Colombus_defconfig
@@ -1,4 +1,5 @@
-CONFIG_SYS_EXTRA_OPTIONS="COLOMBUS"
 CONFIG_ARM=y
-CONFIG_TARGET_SUN6I=y
+CONFIG_ARCH_SUNXI=y
+CONFIG_MACH_SUN6I=y
+CONFIG_TARGET_COLOMBUS=y
 CONFIG_FDTFILE="sun6i-a31-colombus.dtb"
diff --git a/configs/Cubieboard2_FEL_defconfig b/configs/Cubieboard2_FEL_defconfig
deleted file mode 100644
index 353b04a3b1dd4f313274504f09a6aa04f90f6ca6..0000000000000000000000000000000000000000
--- a/configs/Cubieboard2_FEL_defconfig
+++ /dev/null
@@ -1,5 +0,0 @@
-CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="CUBIEBOARD2,SPL_FEL,AXP209_POWER,SUNXI_GMAC,AHCI,SATAPWR=SUNXI_GPB(8),USB_EHCI"
-CONFIG_FDTFILE="sun7i-a20-cubieboard2.dtb"
-+S:CONFIG_ARM=y
-+S:CONFIG_TARGET_SUN7I=y
diff --git a/configs/Cubieboard2_defconfig b/configs/Cubieboard2_defconfig
index 11a0c5ff376f8747b9d89574f472c1e4ef50648c..7e7a1ca3981cd4edeca132a71a9c1716fc011149 100644
--- a/configs/Cubieboard2_defconfig
+++ b/configs/Cubieboard2_defconfig
@@ -1,5 +1,7 @@
 CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="CUBIEBOARD2,AXP209_POWER,SUNXI_GMAC,AHCI,SATAPWR=SUNXI_GPB(8),USB_EHCI"
+CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_GMAC,AHCI,SATAPWR=SUNXI_GPB(8),USB_EHCI"
 CONFIG_FDTFILE="sun7i-a20-cubieboard2.dtb"
 +S:CONFIG_ARM=y
-+S:CONFIG_TARGET_SUN7I=y
++S:CONFIG_ARCH_SUNXI=y
++S:CONFIG_MACH_SUN7I=y
++S:CONFIG_TARGET_CUBIEBOARD2=y
diff --git a/configs/Cubieboard_defconfig b/configs/Cubieboard_defconfig
index 8c1ff9584eadc5464056f7b534bbd0ff146c5cbc..0bc45fd2cb28af8c559d68371e1e3b82b821be9d 100644
--- a/configs/Cubieboard_defconfig
+++ b/configs/Cubieboard_defconfig
@@ -1,5 +1,7 @@
 CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="CUBIEBOARD,AXP209_POWER,SUNXI_EMAC,AHCI,SATAPWR=SUNXI_GPB(8),USB_EHCI"
+CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_EMAC,AHCI,SATAPWR=SUNXI_GPB(8),USB_EHCI"
 CONFIG_FDTFILE="sun4i-a10-cubieboard.dtb"
 +S:CONFIG_ARM=y
-+S:CONFIG_TARGET_SUN4I=y
++S:CONFIG_ARCH_SUNXI=y
++S:CONFIG_MACH_SUN4I=y
++S:CONFIG_TARGET_CUBIEBOARD=y
diff --git a/configs/Cubietruck_FEL_defconfig b/configs/Cubietruck_FEL_defconfig
deleted file mode 100644
index 23c5efb18abeed9dd2fbefca61d0103448c59c68..0000000000000000000000000000000000000000
--- a/configs/Cubietruck_FEL_defconfig
+++ /dev/null
@@ -1,5 +0,0 @@
-CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="CUBIETRUCK,SPL_FEL,AXP209_POWER,SUNXI_GMAC,RGMII,AHCI,SATAPWR=SUNXI_GPH(12),USB_EHCI"
-CONFIG_FDTFILE="sun7i-a20-cubietruck.dtb"
-+S:CONFIG_ARM=y
-+S:CONFIG_TARGET_SUN7I=y
diff --git a/configs/Cubietruck_defconfig b/configs/Cubietruck_defconfig
index 1389f2138bbd08a3cc817864d22b03f94ed08a2e..b1f9f936fa8ff05d5c8ee9748f7ffae2d6a08961 100644
--- a/configs/Cubietruck_defconfig
+++ b/configs/Cubietruck_defconfig
@@ -1,5 +1,7 @@
 CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="CUBIETRUCK,AXP209_POWER,SUNXI_GMAC,RGMII,AHCI,SATAPWR=SUNXI_GPH(12),USB_EHCI"
+CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_GMAC,RGMII,AHCI,SATAPWR=SUNXI_GPH(12),USB_EHCI"
 CONFIG_FDTFILE="sun7i-a20-cubietruck.dtb"
 +S:CONFIG_ARM=y
-+S:CONFIG_TARGET_SUN7I=y
++S:CONFIG_ARCH_SUNXI=y
++S:CONFIG_MACH_SUN7I=y
++S:CONFIG_TARGET_CUBIETRUCK=y
diff --git a/configs/Ippo_q8h_defconfig b/configs/Ippo_q8h_defconfig
deleted file mode 100644
index 781f13785b24cbbb653bf35faf60a58b16a2dbe3..0000000000000000000000000000000000000000
--- a/configs/Ippo_q8h_defconfig
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG_SYS_EXTRA_OPTIONS="IPPO_Q8H_V5,CONS_INDEX=5"
-CONFIG_ARM=y
-CONFIG_TARGET_SUN8I=y
-CONFIG_DEFAULT_DEVICE_TREE="sun8i-a23-ippo-q8h-v5.dtb"
diff --git a/configs/Ippo_q8h_v5_defconfig b/configs/Ippo_q8h_v5_defconfig
new file mode 100644
index 0000000000000000000000000000000000000000..fc67bd9d56cec113477818eccb1c2af3943c8436
--- /dev/null
+++ b/configs/Ippo_q8h_v5_defconfig
@@ -0,0 +1,6 @@
+CONFIG_SYS_EXTRA_OPTIONS="CONS_INDEX=5"
+CONFIG_ARM=y
+CONFIG_ARCH_SUNXI=y
+CONFIG_MACH_SUN8I=y
+CONFIG_TARGET_IPPO_Q8H_V5=y
+CONFIG_DEFAULT_DEVICE_TREE="sun8i-a23-ippo-q8h-v5.dtb"
diff --git a/configs/Linksprite_pcDuino3_defconfig b/configs/Linksprite_pcDuino3_defconfig
index efc53017897970912ff7a282dbec9b4aa83d7242..a26ff0a70f40efcb2fc9cdac035d49465c0f90c9 100644
--- a/configs/Linksprite_pcDuino3_defconfig
+++ b/configs/Linksprite_pcDuino3_defconfig
@@ -1,5 +1,7 @@
 CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="PCDUINO3,AXP209_POWER,SUNXI_GMAC,AHCI,SATAPWR=SUNXI_GPH(2),USB_EHCI"
+CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_GMAC,AHCI,SATAPWR=SUNXI_GPH(2),USB_EHCI"
 CONFIG_FDTFILE="sun7i-a20-pcduino3.dtb"
 +S:CONFIG_ARM=y
-+S:CONFIG_TARGET_SUN7I=y
++S:CONFIG_ARCH_SUNXI=y
++S:CONFIG_MACH_SUN7I=y
++S:CONFIG_TARGET_PCDUINO3=y
diff --git a/configs/Linksprite_pcDuino3_fdt_defconfig b/configs/Linksprite_pcDuino3_fdt_defconfig
new file mode 100644
index 0000000000000000000000000000000000000000..a33f3a7981faa8723989d4b88ee0eda21bf84265
--- /dev/null
+++ b/configs/Linksprite_pcDuino3_fdt_defconfig
@@ -0,0 +1,11 @@
+CONFIG_SPL=y
+CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_GMAC,AHCI,SATAPWR=SUNXI_GPH(2),USB_EHCI"
+CONFIG_FDTFILE="sun7i-a20-pcduino3.dtb"
+CONFIG_DM=y
+CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-pcduino3"
+CONFIG_OF_CONTROL=y
+CONFIG_OF_SEPARATE=y
++S:CONFIG_ARM=y
++S:CONFIG_ARCH_SUNXI=y
++S:CONFIG_MACH_SUN7I=y
++S:CONFIG_TARGET_PCDUINO3=y
diff --git a/configs/Mele_A1000G_defconfig b/configs/Mele_A1000G_defconfig
index 06c4cacc53b0b5cbb14fe5f549dac25a134df5e2..2f4bf72c934d8a67301b7a057fa7b4c8135a98bc 100644
--- a/configs/Mele_A1000G_defconfig
+++ b/configs/Mele_A1000G_defconfig
@@ -1,5 +1,7 @@
 CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="MELE_A1000G,AXP209_POWER,SUNXI_EMAC,MACPWR=SUNXI_GPH(15),AHCI,USB_EHCI"
+CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_EMAC,MACPWR=SUNXI_GPH(15),AHCI,USB_EHCI"
 CONFIG_FDTFILE="sun4i-a10-a1000.dtb"
 +S:CONFIG_ARM=y
-+S:CONFIG_TARGET_SUN4I=y
++S:CONFIG_ARCH_SUNXI=y
++S:CONFIG_MACH_SUN4I=y
++S:CONFIG_TARGET_MELE_A1000G=y
diff --git a/configs/Mele_A1000_defconfig b/configs/Mele_A1000_defconfig
index d386c79e04870c12947644d35c8d759738a0f28f..e2912b0afdb1e4e48098df5f82f392945ca9a28d 100644
--- a/configs/Mele_A1000_defconfig
+++ b/configs/Mele_A1000_defconfig
@@ -1,5 +1,7 @@
 CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="MELE_A1000,AXP209_POWER,SUNXI_EMAC,MACPWR=SUNXI_GPH(15),AHCI,USB_EHCI"
+CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_EMAC,MACPWR=SUNXI_GPH(15),AHCI,USB_EHCI"
 CONFIG_FDTFILE="sun4i-a10-a1000.dtb"
 +S:CONFIG_ARM=y
-+S:CONFIG_TARGET_SUN4I=y
++S:CONFIG_ARCH_SUNXI=y
++S:CONFIG_MACH_SUN4I=y
++S:CONFIG_TARGET_MELE_A1000=y
diff --git a/configs/Mele_M3_defconfig b/configs/Mele_M3_defconfig
index a043ad277d79efd5546e223b57664dc8413958bb..fe9ba11c3928163b30bb78ed1208e796f8f37499 100644
--- a/configs/Mele_M3_defconfig
+++ b/configs/Mele_M3_defconfig
@@ -1,7 +1,9 @@
 CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="MELE_M3,AXP209_POWER,SUNXI_GMAC,USB_EHCI"
+CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_GMAC,USB_EHCI"
 CONFIG_FDTFILE="sun7i-a20-m3.dtb"
 +S:CONFIG_MMC_SUNXI_SLOT_EXTRA=2
 +S:CONFIG_MMC0_CD_PIN="PH1"
 +S:CONFIG_ARM=y
-+S:CONFIG_TARGET_SUN7I=y
++S:CONFIG_ARCH_SUNXI=y
++S:CONFIG_MACH_SUN7I=y
++S:CONFIG_TARGET_MELE_M3=y
diff --git a/configs/Mini-X-1Gb_defconfig b/configs/Mini-X-1Gb_defconfig
index 5db4aa3a1478077d0ec52ad17d4535a9943ce8da..b8fea0124572a7aafd878e7200e641d1570e0032 100644
--- a/configs/Mini-X-1Gb_defconfig
+++ b/configs/Mini-X-1Gb_defconfig
@@ -1,5 +1,7 @@
 CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="MINI_X_1GB,AXP209_POWER,USB_EHCI"
+CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,USB_EHCI"
 CONFIG_FDTFILE="sun4i-a10-mini-xplus.dtb"
 +S:CONFIG_ARM=y
-+S:CONFIG_TARGET_SUN4I=y
++S:CONFIG_ARCH_SUNXI=y
++S:CONFIG_MACH_SUN4I=y
++S:CONFIG_TARGET_MINI_X_1GB=y
diff --git a/configs/Mini-X_defconfig b/configs/Mini-X_defconfig
index 6718dcb68cf588ad27d11c84b5ef5b81f96cc8a5..0f6bbe06b2c5d09585a334403b3dd97e91594dd3 100644
--- a/configs/Mini-X_defconfig
+++ b/configs/Mini-X_defconfig
@@ -1,5 +1,7 @@
 CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="MINI_X,AXP209_POWER,USB_EHCI"
+CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,USB_EHCI"
 CONFIG_FDTFILE="sun4i-a10-mini-xplus.dtb"
 +S:CONFIG_ARM=y
-+S:CONFIG_TARGET_SUN4I=y
++S:CONFIG_ARCH_SUNXI=y
++S:CONFIG_MACH_SUN4I=y
++S:CONFIG_TARGET_MINI_X=y
diff --git a/configs/ba10_tv_box_defconfig b/configs/ba10_tv_box_defconfig
index 6f64875b4a2021bf3f6963b48cfb1dc37bbb1f7e..0a1abea0a8d434fd4ab05ce8b9b3e0c3d5bbf3d1 100644
--- a/configs/ba10_tv_box_defconfig
+++ b/configs/ba10_tv_box_defconfig
@@ -1,5 +1,7 @@
 CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="BA10_TV_BOX,AXP209_POWER,SUNXI_EMAC,USB_EHCI,SUNXI_USB_VBUS1_GPIO=SUNXI_GPH(12)"
+CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_EMAC,USB_EHCI,SUNXI_USB_VBUS1_GPIO=SUNXI_GPH(12)"
 CONFIG_FDTFILE="sun4i-a10-ba10-tvbox.dtb"
 +S:CONFIG_ARM=y
-+S:CONFIG_TARGET_SUN4I=y
++S:CONFIG_ARCH_SUNXI=y
++S:CONFIG_MACH_SUN4I=y
++S:CONFIG_TARGET_BA10_TV_BOX=y
diff --git a/configs/i12-tvbox_defconfig b/configs/i12-tvbox_defconfig
index 2ef0f9182871542210e8e832683e6a20d4ba9a5f..5f5037e6982e8a095e2fe1b8e4702ed10ff7a0bb 100644
--- a/configs/i12-tvbox_defconfig
+++ b/configs/i12-tvbox_defconfig
@@ -1,5 +1,7 @@
 CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="I12_TVBOX,AXP209_POWER,SUNXI_GMAC,MACPWR=SUNXI_GPH(21),USB_EHCI"
+CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_GMAC,MACPWR=SUNXI_GPH(21),USB_EHCI"
 CONFIG_FDTFILE="sun7i-a20-i12-tvbox.dtb"
 +S:CONFIG_ARM=y
-+S:CONFIG_TARGET_SUN7I=y
++S:CONFIG_ARCH_SUNXI=y
++S:CONFIG_MACH_SUN7I=y
++S:CONFIG_TARGET_I12_TVBOX=y
diff --git a/configs/qt840a_defconfig b/configs/qt840a_defconfig
index a8d4bb8845f882810643adac4027f1700b0428a7..70f8159b39cfc8e2b4841e4dc88545ae6fcc7619 100644
--- a/configs/qt840a_defconfig
+++ b/configs/qt840a_defconfig
@@ -1,5 +1,7 @@
 CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="QT840A,AXP209_POWER,SUNXI_GMAC,MACPWR=SUNXI_GPH(21),USB_EHCI"
+CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_GMAC,MACPWR=SUNXI_GPH(21),USB_EHCI"
 CONFIG_FDTFILE="sun7i-a20-i12-tvbox.dtb"
 +S:CONFIG_ARM=y
-+S:CONFIG_TARGET_SUN7I=y
++S:CONFIG_ARCH_SUNXI=y
++S:CONFIG_MACH_SUN7I=y
++S:CONFIG_TARGET_QT840A=y
diff --git a/configs/r7-tv-dongle_defconfig b/configs/r7-tv-dongle_defconfig
index 6aba94201e836619c7bfe04dcebe1d14e2cfc42c..7dbff40b508c776f3db7f32aa1fe2fe50c1f651e 100644
--- a/configs/r7-tv-dongle_defconfig
+++ b/configs/r7-tv-dongle_defconfig
@@ -1,5 +1,7 @@
 CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="R7DONGLE,AXP152_POWER,USB_EHCI,SUNXI_USB_VBUS0_GPIO=SUNXI_GPG(13)"
+CONFIG_SYS_EXTRA_OPTIONS="AXP152_POWER,USB_EHCI,SUNXI_USB_VBUS0_GPIO=SUNXI_GPG(13)"
 CONFIG_FDTFILE="sun5i-a10s-r7-tv-dongle.dtb"
 +S:CONFIG_ARM=y
-+S:CONFIG_TARGET_SUN5I=y
++S:CONFIG_ARCH_SUNXI=y
++S:CONFIG_MACH_SUN5I=y
++S:CONFIG_TARGET_R7DONGLE=y
diff --git a/drivers/gpio/sunxi_gpio.c b/drivers/gpio/sunxi_gpio.c
index 0c50a8f332684b27194a9985ab2a180780bdab2b..44135e5bb746b38b987128605d3619050eef9f41 100644
--- a/drivers/gpio/sunxi_gpio.c
+++ b/drivers/gpio/sunxi_gpio.c
@@ -11,9 +11,25 @@
  */
 
 #include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <fdtdec.h>
+#include <malloc.h>
 #include <asm/io.h>
 #include <asm/gpio.h>
+#include <dm/device-internal.h>
 
+DECLARE_GLOBAL_DATA_PTR;
+
+#define SUNXI_GPIOS_PER_BANK	SUNXI_GPIO_A_NR
+
+struct sunxi_gpio_platdata {
+	struct sunxi_gpio *regs;
+	const char *bank_name;	/* Name of bank, e.g. "B" */
+	int gpio_count;
+};
+
+#ifndef CONFIG_DM_GPIO
 static int sunxi_gpio_output(u32 pin, u32 val)
 {
 	u32 dat;
@@ -100,3 +116,157 @@ int sunxi_name_to_gpio(const char *name)
 		return -1;
 	return group * 32 + pin;
 }
+#endif
+
+#ifdef CONFIG_DM_GPIO
+static int sunxi_gpio_direction_input(struct udevice *dev, unsigned offset)
+{
+	struct sunxi_gpio_platdata *plat = dev_get_platdata(dev);
+
+	sunxi_gpio_set_cfgbank(plat->regs, offset, SUNXI_GPIO_INPUT);
+
+	return 0;
+}
+
+static int sunxi_gpio_direction_output(struct udevice *dev, unsigned offset,
+				       int value)
+{
+	struct sunxi_gpio_platdata *plat = dev_get_platdata(dev);
+	u32 num = GPIO_NUM(offset);
+
+	sunxi_gpio_set_cfgbank(plat->regs, offset, SUNXI_GPIO_OUTPUT);
+	clrsetbits_le32(&plat->regs->dat, 1 << num, value ? (1 << num) : 0);
+
+	return 0;
+}
+
+static int sunxi_gpio_get_value(struct udevice *dev, unsigned offset)
+{
+	struct sunxi_gpio_platdata *plat = dev_get_platdata(dev);
+	u32 num = GPIO_NUM(offset);
+	unsigned dat;
+
+	dat = readl(&plat->regs->dat);
+	dat >>= num;
+
+	return dat & 0x1;
+}
+
+static int sunxi_gpio_set_value(struct udevice *dev, unsigned offset,
+				int value)
+{
+	struct sunxi_gpio_platdata *plat = dev_get_platdata(dev);
+	u32 num = GPIO_NUM(offset);
+
+	clrsetbits_le32(&plat->regs->dat, 1 << num, value ? (1 << num) : 0);
+	return 0;
+}
+
+static int sunxi_gpio_get_function(struct udevice *dev, unsigned offset)
+{
+	struct sunxi_gpio_platdata *plat = dev_get_platdata(dev);
+	int func;
+
+	func = sunxi_gpio_get_cfgbank(plat->regs, offset);
+	if (func == SUNXI_GPIO_OUTPUT)
+		return GPIOF_OUTPUT;
+	else if (func == SUNXI_GPIO_INPUT)
+		return GPIOF_INPUT;
+	else
+		return GPIOF_FUNC;
+}
+
+static const struct dm_gpio_ops gpio_sunxi_ops = {
+	.direction_input	= sunxi_gpio_direction_input,
+	.direction_output	= sunxi_gpio_direction_output,
+	.get_value		= sunxi_gpio_get_value,
+	.set_value		= sunxi_gpio_set_value,
+	.get_function		= sunxi_gpio_get_function,
+};
+
+/**
+ * Returns the name of a GPIO bank
+ *
+ * GPIO banks are named A, B, C, ...
+ *
+ * @bank:	Bank number (0, 1..n-1)
+ * @return allocated string containing the name
+ */
+static char *gpio_bank_name(int bank)
+{
+	char *name;
+
+	name = malloc(2);
+	if (name) {
+		name[0] = 'A' + bank;
+		name[1] = '\0';
+	}
+
+	return name;
+}
+
+static int gpio_sunxi_probe(struct udevice *dev)
+{
+	struct sunxi_gpio_platdata *plat = dev_get_platdata(dev);
+	struct gpio_dev_priv *uc_priv = dev->uclass_priv;
+
+	/* Tell the uclass how many GPIOs we have */
+	if (plat) {
+		uc_priv->gpio_count = plat->gpio_count;
+		uc_priv->bank_name = plat->bank_name;
+	}
+
+	return 0;
+}
+/**
+ * We have a top-level GPIO device with no actual GPIOs. It has a child
+ * device for each Sunxi bank.
+ */
+static int gpio_sunxi_bind(struct udevice *parent)
+{
+	struct sunxi_gpio_platdata *plat = parent->platdata;
+	struct sunxi_gpio_reg *ctlr;
+	int bank;
+	int ret;
+
+	/* If this is a child device, there is nothing to do here */
+	if (plat)
+		return 0;
+
+	ctlr = (struct sunxi_gpio_reg *)fdtdec_get_addr(gd->fdt_blob,
+						   parent->of_offset, "reg");
+	for (bank = 0; bank < SUNXI_GPIO_BANKS; bank++) {
+		struct sunxi_gpio_platdata *plat;
+		struct udevice *dev;
+
+		plat = calloc(1, sizeof(*plat));
+		if (!plat)
+			return -ENOMEM;
+		plat->regs = &ctlr->gpio_bank[bank];
+		plat->bank_name = gpio_bank_name(bank);
+		plat->gpio_count = SUNXI_GPIOS_PER_BANK;
+
+		ret = device_bind(parent, parent->driver,
+					plat->bank_name, plat, -1, &dev);
+		if (ret)
+			return ret;
+		dev->of_offset = parent->of_offset;
+	}
+
+	return 0;
+}
+
+static const struct udevice_id sunxi_gpio_ids[] = {
+	{ .compatible = "allwinner,sun7i-a20-pinctrl" },
+	{ }
+};
+
+U_BOOT_DRIVER(gpio_sunxi) = {
+	.name	= "gpio_sunxi",
+	.id	= UCLASS_GPIO,
+	.ops	= &gpio_sunxi_ops,
+	.of_match = sunxi_gpio_ids,
+	.bind	= gpio_sunxi_bind,
+	.probe	= gpio_sunxi_probe,
+};
+#endif
diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c
index 16592e3d7cf2454e00013181576dcb0ea437822e..231f0a0315dc4f22194079ed9928caa270f44999 100644
--- a/drivers/mmc/sunxi_mmc.c
+++ b/drivers/mmc/sunxi_mmc.c
@@ -30,10 +30,22 @@ struct sunxi_mmc_host {
 /* support 4 mmc hosts */
 struct sunxi_mmc_host mmc_host[4];
 
+static int sunxi_mmc_getcd_gpio(int sdc_no)
+{
+	switch (sdc_no) {
+	case 0: return sunxi_name_to_gpio(CONFIG_MMC0_CD_PIN);
+	case 1: return sunxi_name_to_gpio(CONFIG_MMC1_CD_PIN);
+	case 2: return sunxi_name_to_gpio(CONFIG_MMC2_CD_PIN);
+	case 3: return sunxi_name_to_gpio(CONFIG_MMC3_CD_PIN);
+	}
+	return -1;
+}
+
 static int mmc_resource_init(int sdc_no)
 {
 	struct sunxi_mmc_host *mmchost = &mmc_host[sdc_no];
 	struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
+	int cd_pin, ret = 0;
 
 	debug("init mmc %d resource\n", sdc_no);
 
@@ -60,7 +72,11 @@ static int mmc_resource_init(int sdc_no)
 	}
 	mmchost->mmc_no = sdc_no;
 
-	return 0;
+	cd_pin = sunxi_mmc_getcd_gpio(sdc_no);
+	if (cd_pin != -1)
+		ret = gpio_request(cd_pin, "mmc_cd");
+
+	return ret;
 }
 
 static int mmc_clk_io_on(int sdc_no)
@@ -75,7 +91,7 @@ static int mmc_clk_io_on(int sdc_no)
 	/* config ahb clock */
 	setbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_MMC(sdc_no));
 
-#if defined(CONFIG_SUN6I) || defined(CONFIG_SUN8I)
+#if defined(CONFIG_MACH_SUN6I) || defined(CONFIG_MACH_SUN8I)
 	/* unassert reset */
 	setbits_le32(&ccm->ahb_reset0_cfg, 1 << AHB_RESET_OFFSET_MMC(sdc_no));
 #endif
@@ -351,15 +367,9 @@ out:
 static int sunxi_mmc_getcd(struct mmc *mmc)
 {
 	struct sunxi_mmc_host *mmchost = mmc->priv;
-	int cd_pin = -1;
-
-	switch (mmchost->mmc_no) {
-	case 0: cd_pin = sunxi_name_to_gpio(CONFIG_MMC0_CD_PIN); break;
-	case 1: cd_pin = sunxi_name_to_gpio(CONFIG_MMC1_CD_PIN); break;
-	case 2: cd_pin = sunxi_name_to_gpio(CONFIG_MMC2_CD_PIN); break;
-	case 3: cd_pin = sunxi_name_to_gpio(CONFIG_MMC3_CD_PIN); break;
-	}
+	int cd_pin;
 
+	cd_pin = sunxi_mmc_getcd_gpio(mmchost->mmc_no);
 	if (cd_pin == -1)
 		return 1;
 
@@ -385,7 +395,7 @@ struct mmc *sunxi_mmc_init(int sdc_no)
 	cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
 	cfg->host_caps = MMC_MODE_4BIT;
 	cfg->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
-#if defined(CONFIG_SUN6I) || defined(CONFIG_SUN7I) || defined(CONFIG_SUN8I)
+#if defined(CONFIG_MACH_SUN6I) || defined(CONFIG_MACH_SUN7I) || defined(CONFIG_MACH_SUN8I)
 	cfg->host_caps |= MMC_MODE_HC;
 #endif
 	cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
@@ -393,7 +403,9 @@ struct mmc *sunxi_mmc_init(int sdc_no)
 	cfg->f_min = 400000;
 	cfg->f_max = 52000000;
 
-	mmc_resource_init(sdc_no);
+	if (mmc_resource_init(sdc_no) != 0)
+		return NULL;
+
 	mmc_clk_io_on(sdc_no);
 
 	return mmc_create(cfg, &mmc_host[sdc_no]);
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index 2c19ebc2885e90c77b58302e989527a162d9c517..8c8494276116360d5340d669c7e7e7130a6e1549 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -19,6 +19,7 @@ obj-$(CONFIG_ALTERA_UART) += altera_uart.o
 obj-$(CONFIG_ALTERA_JTAG_UART) += altera_jtag_uart.o
 obj-$(CONFIG_ARM_DCC) += arm_dcc.o
 obj-$(CONFIG_ATMEL_USART) += atmel_usart.o
+obj-$(CONFIG_DW_SERIAL) += serial_dw.o
 obj-$(CONFIG_LPC32XX_HSUART) += lpc32xx_hsuart.o
 obj-$(CONFIG_MCFUART) += mcfuart.o
 obj-$(CONFIG_OPENCORES_YANU) += opencores_yanu.o
diff --git a/drivers/serial/serial_dw.c b/drivers/serial/serial_dw.c
new file mode 100644
index 0000000000000000000000000000000000000000..a348f2956acbd96c5b099eb2dc1df36539823f66
--- /dev/null
+++ b/drivers/serial/serial_dw.c
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2014 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <ns16550.h>
+#include <serial.h>
+
+static const struct udevice_id dw_serial_ids[] = {
+	{ .compatible = "snps,dw-apb-uart" },
+	{ }
+};
+
+static int dw_serial_ofdata_to_platdata(struct udevice *dev)
+{
+	struct ns16550_platdata *plat = dev_get_platdata(dev);
+	int ret;
+
+	ret = ns16550_serial_ofdata_to_platdata(dev);
+	if (ret)
+		return ret;
+	plat->clock = CONFIG_SYS_NS16550_CLK;
+
+	return 0;
+}
+
+U_BOOT_DRIVER(serial_ns16550) = {
+	.name	= "serial_dw",
+	.id	= UCLASS_SERIAL,
+	.of_match = dw_serial_ids,
+	.ofdata_to_platdata = dw_serial_ofdata_to_platdata,
+	.platdata_auto_alloc_size = sizeof(struct ns16550_platdata),
+	.priv_auto_alloc_size = sizeof(struct NS16550),
+	.probe = ns16550_serial_probe,
+	.ops	= &ns16550_serial_ops,
+};
diff --git a/drivers/usb/host/ehci-sunxi.c b/drivers/usb/host/ehci-sunxi.c
index 23617b7adc131a8770ba8715bccffc04e261eafa..4befd574541d74ce7ab7651360cb9c654e0bc452 100644
--- a/drivers/usb/host/ehci-sunxi.c
+++ b/drivers/usb/host/ehci-sunxi.c
@@ -105,7 +105,7 @@ static void sunxi_usb_phy_init(struct sunxi_ehci_hcd *sunxi_ehci)
 	usb_phy_write(sunxi_ehci, 0x20, 0x14, 5);
 
 	/* threshold adjustment disconnect */
-#ifdef CONFIG_SUN4I
+#ifdef CONFIG_MACH_SUN4I
 	usb_phy_write(sunxi_ehci, 0x2a, 3, 2);
 #else
 	usb_phy_write(sunxi_ehci, 0x2a, 2, 2);
@@ -163,11 +163,16 @@ int ehci_hcd_init(int index, enum usb_init_type init, struct ehci_hccr **hccr,
 {
 	struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
 	struct sunxi_ehci_hcd *sunxi_ehci = &sunxi_echi_hcd[index];
+	int err;
 
 	/* enable common PHY only once */
 	if (index == 0)
 		setbits_le32(&ccm->usb_clk_cfg, CCM_USB_CTRL_PHYGATE);
 
+	err = gpio_request(sunxi_ehci->gpio_vbus, "ehci_vbus");
+	if (err)
+		return err;
+
 	sunxi_ehci_enable(sunxi_ehci);
 
 	*hccr = get_io_base(sunxi_ehci->id);
@@ -188,9 +193,14 @@ int ehci_hcd_stop(int index)
 {
 	struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
 	struct sunxi_ehci_hcd *sunxi_ehci = &sunxi_echi_hcd[index];
+	int err;
 
 	sunxi_ehci_disable(sunxi_ehci);
 
+	err = gpio_free(sunxi_ehci->gpio_vbus);
+	if (err)
+		return err;
+
 	/* disable common PHY only once, for the last enabled hcd */
 	if (enabled_hcd_count == 1)
 		clrbits_le32(&ccm->usb_clk_cfg, CCM_USB_CTRL_PHYGATE);
diff --git a/include/configs/sun4i.h b/include/configs/sun4i.h
index d0191a32b1a6d99807cf75becf4821f2e6879cfd..e0ec52dcde7fb7c296c5a92acca7a5bc4ab062c4 100644
--- a/include/configs/sun4i.h
+++ b/include/configs/sun4i.h
@@ -11,7 +11,6 @@
 /*
  * A10 specific configuration
  */
-#define CONFIG_SUN4I		/* sun4i SoC generation */
 #define CONFIG_CLK_FULL_SPEED		1008000000
 
 #define CONFIG_SYS_PROMPT		"sun4i# "
diff --git a/include/configs/sun5i.h b/include/configs/sun5i.h
index 7b683e9c8908394e56072d545f873d0e5f798c6a..09f7533575c83518c43c040ecf944a787aab4fba 100644
--- a/include/configs/sun5i.h
+++ b/include/configs/sun5i.h
@@ -11,7 +11,6 @@
 /*
  * High Level Configuration Options
  */
-#define CONFIG_SUN5I		/* sun5i SoC generation */
 #define CONFIG_CLK_FULL_SPEED		1008000000
 
 #define CONFIG_SYS_PROMPT		"sun5i# "
diff --git a/include/configs/sun6i.h b/include/configs/sun6i.h
index 93a1d965ca4e680e27f24ff7fd8efac3f154faf6..b7144745c9204603ffc5be64c041e4c287f13220 100644
--- a/include/configs/sun6i.h
+++ b/include/configs/sun6i.h
@@ -14,7 +14,6 @@
 /*
  * A31 specific configuration
  */
-#define CONFIG_SUN6I		/* sun6i SoC generation */
 
 #define CONFIG_SYS_PROMPT		"sun6i# "
 
diff --git a/include/configs/sun7i.h b/include/configs/sun7i.h
index 966cbd8e83f6cb2659f64798cfeb502a1b5e6aa4..0193826a9dd404938f815487cb982a9f9ac01e8e 100644
--- a/include/configs/sun7i.h
+++ b/include/configs/sun7i.h
@@ -12,7 +12,6 @@
 /*
  * A20 specific configuration
  */
-#define CONFIG_SUN7I		/* sun7i SoC generation */
 #define CONFIG_CLK_FULL_SPEED		912000000
 
 #define CONFIG_SYS_PROMPT		"sun7i# "
diff --git a/include/configs/sun8i.h b/include/configs/sun8i.h
index 1c1a7cde5ec1762d6a1702ed5a295c17c4696459..6f1fc48cf02d08cbbfc5b13f857ad892512c6d4e 100644
--- a/include/configs/sun8i.h
+++ b/include/configs/sun8i.h
@@ -12,7 +12,6 @@
 /*
  * A23 specific configuration
  */
-#define CONFIG_SUN8I		/* sun8i SoC generation */
 #define CONFIG_SYS_PROMPT	"sun8i# "
 
 /*
diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h
index cc450e02e67e041b248a47c84c05aa1a5325c57b..ce038eddf04b1858cc87bf22fc87709301559599 100644
--- a/include/configs/sunxi-common.h
+++ b/include/configs/sunxi-common.h
@@ -27,6 +27,14 @@
 
 #define CONFIG_SYS_TEXT_BASE		0x4a000000
 
+#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_DM)
+# define CONFIG_CMD_DM
+# define CONFIG_DM_GPIO
+# define CONFIG_DM_SERIAL
+# define CONFIG_DW_SERIAL
+# define CONFIG_SYS_MALLOC_F_LEN	(1 << 10)
+#endif
+
 /*
  * Display CPU information
  */
@@ -36,13 +44,15 @@
 #define CONFIG_SYS_NS16550
 #define CONFIG_SYS_NS16550_SERIAL
 /* ns16550 reg in the low bits of cpu reg */
-#define CONFIG_SYS_NS16550_REG_SIZE	-4
 #define CONFIG_SYS_NS16550_CLK		24000000
-#define CONFIG_SYS_NS16550_COM1		SUNXI_UART0_BASE
-#define CONFIG_SYS_NS16550_COM2		SUNXI_UART1_BASE
-#define CONFIG_SYS_NS16550_COM3		SUNXI_UART2_BASE
-#define CONFIG_SYS_NS16550_COM4		SUNXI_UART3_BASE
-#define CONFIG_SYS_NS16550_COM5		SUNXI_R_UART_BASE
+#ifndef CONFIG_DM_SERIAL
+# define CONFIG_SYS_NS16550_REG_SIZE	-4
+# define CONFIG_SYS_NS16550_COM1		SUNXI_UART0_BASE
+# define CONFIG_SYS_NS16550_COM2		SUNXI_UART1_BASE
+# define CONFIG_SYS_NS16550_COM3		SUNXI_UART2_BASE
+# define CONFIG_SYS_NS16550_COM4		SUNXI_UART3_BASE
+# define CONFIG_SYS_NS16550_COM5		SUNXI_R_UART_BASE
+#endif
 
 /* DRAM Base */
 #define CONFIG_SYS_SDRAM_BASE		0x40000000
diff --git a/include/dt-bindings/input/input.h b/include/dt-bindings/input/input.h
new file mode 100644
index 0000000000000000000000000000000000000000..042e7b3b629637d468029cadac9e9419f7ae295e
--- /dev/null
+++ b/include/dt-bindings/input/input.h
@@ -0,0 +1,525 @@
+/*
+ * This header provides constants for most input bindings.
+ *
+ * Most input bindings include key code, matrix key code format.
+ * In most cases, key code and matrix key code format uses
+ * the standard values/macro defined in this header.
+ */
+
+#ifndef _DT_BINDINGS_INPUT_INPUT_H
+#define _DT_BINDINGS_INPUT_INPUT_H
+
+#define KEY_RESERVED		0
+#define KEY_ESC			1
+#define KEY_1			2
+#define KEY_2			3
+#define KEY_3			4
+#define KEY_4			5
+#define KEY_5			6
+#define KEY_6			7
+#define KEY_7			8
+#define KEY_8			9
+#define KEY_9			10
+#define KEY_0			11
+#define KEY_MINUS		12
+#define KEY_EQUAL		13
+#define KEY_BACKSPACE		14
+#define KEY_TAB			15
+#define KEY_Q			16
+#define KEY_W			17
+#define KEY_E			18
+#define KEY_R			19
+#define KEY_T			20
+#define KEY_Y			21
+#define KEY_U			22
+#define KEY_I			23
+#define KEY_O			24
+#define KEY_P			25
+#define KEY_LEFTBRACE		26
+#define KEY_RIGHTBRACE		27
+#define KEY_ENTER		28
+#define KEY_LEFTCTRL		29
+#define KEY_A			30
+#define KEY_S			31
+#define KEY_D			32
+#define KEY_F			33
+#define KEY_G			34
+#define KEY_H			35
+#define KEY_J			36
+#define KEY_K			37
+#define KEY_L			38
+#define KEY_SEMICOLON		39
+#define KEY_APOSTROPHE		40
+#define KEY_GRAVE		41
+#define KEY_LEFTSHIFT		42
+#define KEY_BACKSLASH		43
+#define KEY_Z			44
+#define KEY_X			45
+#define KEY_C			46
+#define KEY_V			47
+#define KEY_B			48
+#define KEY_N			49
+#define KEY_M			50
+#define KEY_COMMA		51
+#define KEY_DOT			52
+#define KEY_SLASH		53
+#define KEY_RIGHTSHIFT		54
+#define KEY_KPASTERISK		55
+#define KEY_LEFTALT		56
+#define KEY_SPACE		57
+#define KEY_CAPSLOCK		58
+#define KEY_F1			59
+#define KEY_F2			60
+#define KEY_F3			61
+#define KEY_F4			62
+#define KEY_F5			63
+#define KEY_F6			64
+#define KEY_F7			65
+#define KEY_F8			66
+#define KEY_F9			67
+#define KEY_F10			68
+#define KEY_NUMLOCK		69
+#define KEY_SCROLLLOCK		70
+#define KEY_KP7			71
+#define KEY_KP8			72
+#define KEY_KP9			73
+#define KEY_KPMINUS		74
+#define KEY_KP4			75
+#define KEY_KP5			76
+#define KEY_KP6			77
+#define KEY_KPPLUS		78
+#define KEY_KP1			79
+#define KEY_KP2			80
+#define KEY_KP3			81
+#define KEY_KP0			82
+#define KEY_KPDOT		83
+
+#define KEY_ZENKAKUHANKAKU	85
+#define KEY_102ND		86
+#define KEY_F11			87
+#define KEY_F12			88
+#define KEY_RO			89
+#define KEY_KATAKANA		90
+#define KEY_HIRAGANA		91
+#define KEY_HENKAN		92
+#define KEY_KATAKANAHIRAGANA	93
+#define KEY_MUHENKAN		94
+#define KEY_KPJPCOMMA		95
+#define KEY_KPENTER		96
+#define KEY_RIGHTCTRL		97
+#define KEY_KPSLASH		98
+#define KEY_SYSRQ		99
+#define KEY_RIGHTALT		100
+#define KEY_LINEFEED		101
+#define KEY_HOME		102
+#define KEY_UP			103
+#define KEY_PAGEUP		104
+#define KEY_LEFT		105
+#define KEY_RIGHT		106
+#define KEY_END			107
+#define KEY_DOWN		108
+#define KEY_PAGEDOWN		109
+#define KEY_INSERT		110
+#define KEY_DELETE		111
+#define KEY_MACRO		112
+#define KEY_MUTE		113
+#define KEY_VOLUMEDOWN		114
+#define KEY_VOLUMEUP		115
+#define KEY_POWER		116	/* SC System Power Down */
+#define KEY_KPEQUAL		117
+#define KEY_KPPLUSMINUS		118
+#define KEY_PAUSE		119
+#define KEY_SCALE		120	/* AL Compiz Scale (Expose) */
+
+#define KEY_KPCOMMA		121
+#define KEY_HANGEUL		122
+#define KEY_HANGUEL		KEY_HANGEUL
+#define KEY_HANJA		123
+#define KEY_YEN			124
+#define KEY_LEFTMETA		125
+#define KEY_RIGHTMETA		126
+#define KEY_COMPOSE		127
+
+#define KEY_STOP		128	/* AC Stop */
+#define KEY_AGAIN		129
+#define KEY_PROPS		130	/* AC Properties */
+#define KEY_UNDO		131	/* AC Undo */
+#define KEY_FRONT		132
+#define KEY_COPY		133	/* AC Copy */
+#define KEY_OPEN		134	/* AC Open */
+#define KEY_PASTE		135	/* AC Paste */
+#define KEY_FIND		136	/* AC Search */
+#define KEY_CUT			137	/* AC Cut */
+#define KEY_HELP		138	/* AL Integrated Help Center */
+#define KEY_MENU		139	/* Menu (show menu) */
+#define KEY_CALC		140	/* AL Calculator */
+#define KEY_SETUP		141
+#define KEY_SLEEP		142	/* SC System Sleep */
+#define KEY_WAKEUP		143	/* System Wake Up */
+#define KEY_FILE		144	/* AL Local Machine Browser */
+#define KEY_SENDFILE		145
+#define KEY_DELETEFILE		146
+#define KEY_XFER		147
+#define KEY_PROG1		148
+#define KEY_PROG2		149
+#define KEY_WWW			150	/* AL Internet Browser */
+#define KEY_MSDOS		151
+#define KEY_COFFEE		152	/* AL Terminal Lock/Screensaver */
+#define KEY_SCREENLOCK		KEY_COFFEE
+#define KEY_DIRECTION		153
+#define KEY_CYCLEWINDOWS	154
+#define KEY_MAIL		155
+#define KEY_BOOKMARKS		156	/* AC Bookmarks */
+#define KEY_COMPUTER		157
+#define KEY_BACK		158	/* AC Back */
+#define KEY_FORWARD		159	/* AC Forward */
+#define KEY_CLOSECD		160
+#define KEY_EJECTCD		161
+#define KEY_EJECTCLOSECD	162
+#define KEY_NEXTSONG		163
+#define KEY_PLAYPAUSE		164
+#define KEY_PREVIOUSSONG	165
+#define KEY_STOPCD		166
+#define KEY_RECORD		167
+#define KEY_REWIND		168
+#define KEY_PHONE		169	/* Media Select Telephone */
+#define KEY_ISO			170
+#define KEY_CONFIG		171	/* AL Consumer Control Configuration */
+#define KEY_HOMEPAGE		172	/* AC Home */
+#define KEY_REFRESH		173	/* AC Refresh */
+#define KEY_EXIT		174	/* AC Exit */
+#define KEY_MOVE		175
+#define KEY_EDIT		176
+#define KEY_SCROLLUP		177
+#define KEY_SCROLLDOWN		178
+#define KEY_KPLEFTPAREN		179
+#define KEY_KPRIGHTPAREN	180
+#define KEY_NEW			181	/* AC New */
+#define KEY_REDO		182	/* AC Redo/Repeat */
+
+#define KEY_F13			183
+#define KEY_F14			184
+#define KEY_F15			185
+#define KEY_F16			186
+#define KEY_F17			187
+#define KEY_F18			188
+#define KEY_F19			189
+#define KEY_F20			190
+#define KEY_F21			191
+#define KEY_F22			192
+#define KEY_F23			193
+#define KEY_F24			194
+
+#define KEY_PLAYCD		200
+#define KEY_PAUSECD		201
+#define KEY_PROG3		202
+#define KEY_PROG4		203
+#define KEY_DASHBOARD		204	/* AL Dashboard */
+#define KEY_SUSPEND		205
+#define KEY_CLOSE		206	/* AC Close */
+#define KEY_PLAY		207
+#define KEY_FASTFORWARD		208
+#define KEY_BASSBOOST		209
+#define KEY_PRINT		210	/* AC Print */
+#define KEY_HP			211
+#define KEY_CAMERA		212
+#define KEY_SOUND		213
+#define KEY_QUESTION		214
+#define KEY_EMAIL		215
+#define KEY_CHAT		216
+#define KEY_SEARCH		217
+#define KEY_CONNECT		218
+#define KEY_FINANCE		219	/* AL Checkbook/Finance */
+#define KEY_SPORT		220
+#define KEY_SHOP		221
+#define KEY_ALTERASE		222
+#define KEY_CANCEL		223	/* AC Cancel */
+#define KEY_BRIGHTNESSDOWN	224
+#define KEY_BRIGHTNESSUP	225
+#define KEY_MEDIA		226
+
+#define KEY_SWITCHVIDEOMODE	227	/* Cycle between available video
+					   outputs (Monitor/LCD/TV-out/etc) */
+#define KEY_KBDILLUMTOGGLE	228
+#define KEY_KBDILLUMDOWN	229
+#define KEY_KBDILLUMUP		230
+
+#define KEY_SEND		231	/* AC Send */
+#define KEY_REPLY		232	/* AC Reply */
+#define KEY_FORWARDMAIL		233	/* AC Forward Msg */
+#define KEY_SAVE		234	/* AC Save */
+#define KEY_DOCUMENTS		235
+
+#define KEY_BATTERY		236
+
+#define KEY_BLUETOOTH		237
+#define KEY_WLAN		238
+#define KEY_UWB			239
+
+#define KEY_UNKNOWN		240
+
+#define KEY_VIDEO_NEXT		241	/* drive next video source */
+#define KEY_VIDEO_PREV		242	/* drive previous video source */
+#define KEY_BRIGHTNESS_CYCLE	243	/* brightness up, after max is min */
+#define KEY_BRIGHTNESS_ZERO	244	/* brightness off, use ambient */
+#define KEY_DISPLAY_OFF		245	/* display device to off state */
+
+#define KEY_WIMAX		246
+#define KEY_RFKILL		247	/* Key that controls all radios */
+
+#define KEY_MICMUTE		248	/* Mute / unmute the microphone */
+
+/* Code 255 is reserved for special needs of AT keyboard driver */
+
+#define BTN_MISC		0x100
+#define BTN_0			0x100
+#define BTN_1			0x101
+#define BTN_2			0x102
+#define BTN_3			0x103
+#define BTN_4			0x104
+#define BTN_5			0x105
+#define BTN_6			0x106
+#define BTN_7			0x107
+#define BTN_8			0x108
+#define BTN_9			0x109
+
+#define BTN_MOUSE		0x110
+#define BTN_LEFT		0x110
+#define BTN_RIGHT		0x111
+#define BTN_MIDDLE		0x112
+#define BTN_SIDE		0x113
+#define BTN_EXTRA		0x114
+#define BTN_FORWARD		0x115
+#define BTN_BACK		0x116
+#define BTN_TASK		0x117
+
+#define BTN_JOYSTICK		0x120
+#define BTN_TRIGGER		0x120
+#define BTN_THUMB		0x121
+#define BTN_THUMB2		0x122
+#define BTN_TOP			0x123
+#define BTN_TOP2		0x124
+#define BTN_PINKIE		0x125
+#define BTN_BASE		0x126
+#define BTN_BASE2		0x127
+#define BTN_BASE3		0x128
+#define BTN_BASE4		0x129
+#define BTN_BASE5		0x12a
+#define BTN_BASE6		0x12b
+#define BTN_DEAD		0x12f
+
+#define BTN_GAMEPAD		0x130
+#define BTN_SOUTH		0x130
+#define BTN_A			BTN_SOUTH
+#define BTN_EAST		0x131
+#define BTN_B			BTN_EAST
+#define BTN_C			0x132
+#define BTN_NORTH		0x133
+#define BTN_X			BTN_NORTH
+#define BTN_WEST		0x134
+#define BTN_Y			BTN_WEST
+#define BTN_Z			0x135
+#define BTN_TL			0x136
+#define BTN_TR			0x137
+#define BTN_TL2			0x138
+#define BTN_TR2			0x139
+#define BTN_SELECT		0x13a
+#define BTN_START		0x13b
+#define BTN_MODE		0x13c
+#define BTN_THUMBL		0x13d
+#define BTN_THUMBR		0x13e
+
+#define BTN_DIGI		0x140
+#define BTN_TOOL_PEN		0x140
+#define BTN_TOOL_RUBBER		0x141
+#define BTN_TOOL_BRUSH		0x142
+#define BTN_TOOL_PENCIL		0x143
+#define BTN_TOOL_AIRBRUSH	0x144
+#define BTN_TOOL_FINGER		0x145
+#define BTN_TOOL_MOUSE		0x146
+#define BTN_TOOL_LENS		0x147
+#define BTN_TOOL_QUINTTAP	0x148	/* Five fingers on trackpad */
+#define BTN_TOUCH		0x14a
+#define BTN_STYLUS		0x14b
+#define BTN_STYLUS2		0x14c
+#define BTN_TOOL_DOUBLETAP	0x14d
+#define BTN_TOOL_TRIPLETAP	0x14e
+#define BTN_TOOL_QUADTAP	0x14f	/* Four fingers on trackpad */
+
+#define BTN_WHEEL		0x150
+#define BTN_GEAR_DOWN		0x150
+#define BTN_GEAR_UP		0x151
+
+#define KEY_OK			0x160
+#define KEY_SELECT		0x161
+#define KEY_GOTO		0x162
+#define KEY_CLEAR		0x163
+#define KEY_POWER2		0x164
+#define KEY_OPTION		0x165
+#define KEY_INFO		0x166	/* AL OEM Features/Tips/Tutorial */
+#define KEY_TIME		0x167
+#define KEY_VENDOR		0x168
+#define KEY_ARCHIVE		0x169
+#define KEY_PROGRAM		0x16a	/* Media Select Program Guide */
+#define KEY_CHANNEL		0x16b
+#define KEY_FAVORITES		0x16c
+#define KEY_EPG			0x16d
+#define KEY_PVR			0x16e	/* Media Select Home */
+#define KEY_MHP			0x16f
+#define KEY_LANGUAGE		0x170
+#define KEY_TITLE		0x171
+#define KEY_SUBTITLE		0x172
+#define KEY_ANGLE		0x173
+#define KEY_ZOOM		0x174
+#define KEY_MODE		0x175
+#define KEY_KEYBOARD		0x176
+#define KEY_SCREEN		0x177
+#define KEY_PC			0x178	/* Media Select Computer */
+#define KEY_TV			0x179	/* Media Select TV */
+#define KEY_TV2			0x17a	/* Media Select Cable */
+#define KEY_VCR			0x17b	/* Media Select VCR */
+#define KEY_VCR2		0x17c	/* VCR Plus */
+#define KEY_SAT			0x17d	/* Media Select Satellite */
+#define KEY_SAT2		0x17e
+#define KEY_CD			0x17f	/* Media Select CD */
+#define KEY_TAPE		0x180	/* Media Select Tape */
+#define KEY_RADIO		0x181
+#define KEY_TUNER		0x182	/* Media Select Tuner */
+#define KEY_PLAYER		0x183
+#define KEY_TEXT		0x184
+#define KEY_DVD			0x185	/* Media Select DVD */
+#define KEY_AUX			0x186
+#define KEY_MP3			0x187
+#define KEY_AUDIO		0x188	/* AL Audio Browser */
+#define KEY_VIDEO		0x189	/* AL Movie Browser */
+#define KEY_DIRECTORY		0x18a
+#define KEY_LIST		0x18b
+#define KEY_MEMO		0x18c	/* Media Select Messages */
+#define KEY_CALENDAR		0x18d
+#define KEY_RED			0x18e
+#define KEY_GREEN		0x18f
+#define KEY_YELLOW		0x190
+#define KEY_BLUE		0x191
+#define KEY_CHANNELUP		0x192	/* Channel Increment */
+#define KEY_CHANNELDOWN		0x193	/* Channel Decrement */
+#define KEY_FIRST		0x194
+#define KEY_LAST		0x195	/* Recall Last */
+#define KEY_AB			0x196
+#define KEY_NEXT		0x197
+#define KEY_RESTART		0x198
+#define KEY_SLOW		0x199
+#define KEY_SHUFFLE		0x19a
+#define KEY_BREAK		0x19b
+#define KEY_PREVIOUS		0x19c
+#define KEY_DIGITS		0x19d
+#define KEY_TEEN		0x19e
+#define KEY_TWEN		0x19f
+#define KEY_VIDEOPHONE		0x1a0	/* Media Select Video Phone */
+#define KEY_GAMES		0x1a1	/* Media Select Games */
+#define KEY_ZOOMIN		0x1a2	/* AC Zoom In */
+#define KEY_ZOOMOUT		0x1a3	/* AC Zoom Out */
+#define KEY_ZOOMRESET		0x1a4	/* AC Zoom */
+#define KEY_WORDPROCESSOR	0x1a5	/* AL Word Processor */
+#define KEY_EDITOR		0x1a6	/* AL Text Editor */
+#define KEY_SPREADSHEET		0x1a7	/* AL Spreadsheet */
+#define KEY_GRAPHICSEDITOR	0x1a8	/* AL Graphics Editor */
+#define KEY_PRESENTATION	0x1a9	/* AL Presentation App */
+#define KEY_DATABASE		0x1aa	/* AL Database App */
+#define KEY_NEWS		0x1ab	/* AL Newsreader */
+#define KEY_VOICEMAIL		0x1ac	/* AL Voicemail */
+#define KEY_ADDRESSBOOK		0x1ad	/* AL Contacts/Address Book */
+#define KEY_MESSENGER		0x1ae	/* AL Instant Messaging */
+#define KEY_DISPLAYTOGGLE	0x1af	/* Turn display (LCD) on and off */
+#define KEY_SPELLCHECK		0x1b0   /* AL Spell Check */
+#define KEY_LOGOFF		0x1b1   /* AL Logoff */
+
+#define KEY_DOLLAR		0x1b2
+#define KEY_EURO		0x1b3
+
+#define KEY_FRAMEBACK		0x1b4	/* Consumer - transport controls */
+#define KEY_FRAMEFORWARD	0x1b5
+#define KEY_CONTEXT_MENU	0x1b6	/* GenDesc - system context menu */
+#define KEY_MEDIA_REPEAT	0x1b7	/* Consumer - transport control */
+#define KEY_10CHANNELSUP	0x1b8	/* 10 channels up (10+) */
+#define KEY_10CHANNELSDOWN	0x1b9	/* 10 channels down (10-) */
+#define KEY_IMAGES		0x1ba	/* AL Image Browser */
+
+#define KEY_DEL_EOL		0x1c0
+#define KEY_DEL_EOS		0x1c1
+#define KEY_INS_LINE		0x1c2
+#define KEY_DEL_LINE		0x1c3
+
+#define KEY_FN			0x1d0
+#define KEY_FN_ESC		0x1d1
+#define KEY_FN_F1		0x1d2
+#define KEY_FN_F2		0x1d3
+#define KEY_FN_F3		0x1d4
+#define KEY_FN_F4		0x1d5
+#define KEY_FN_F5		0x1d6
+#define KEY_FN_F6		0x1d7
+#define KEY_FN_F7		0x1d8
+#define KEY_FN_F8		0x1d9
+#define KEY_FN_F9		0x1da
+#define KEY_FN_F10		0x1db
+#define KEY_FN_F11		0x1dc
+#define KEY_FN_F12		0x1dd
+#define KEY_FN_1		0x1de
+#define KEY_FN_2		0x1df
+#define KEY_FN_D		0x1e0
+#define KEY_FN_E		0x1e1
+#define KEY_FN_F		0x1e2
+#define KEY_FN_S		0x1e3
+#define KEY_FN_B		0x1e4
+
+#define KEY_BRL_DOT1		0x1f1
+#define KEY_BRL_DOT2		0x1f2
+#define KEY_BRL_DOT3		0x1f3
+#define KEY_BRL_DOT4		0x1f4
+#define KEY_BRL_DOT5		0x1f5
+#define KEY_BRL_DOT6		0x1f6
+#define KEY_BRL_DOT7		0x1f7
+#define KEY_BRL_DOT8		0x1f8
+#define KEY_BRL_DOT9		0x1f9
+#define KEY_BRL_DOT10		0x1fa
+
+#define KEY_NUMERIC_0		0x200	/* used by phones, remote controls, */
+#define KEY_NUMERIC_1		0x201	/* and other keypads */
+#define KEY_NUMERIC_2		0x202
+#define KEY_NUMERIC_3		0x203
+#define KEY_NUMERIC_4		0x204
+#define KEY_NUMERIC_5		0x205
+#define KEY_NUMERIC_6		0x206
+#define KEY_NUMERIC_7		0x207
+#define KEY_NUMERIC_8		0x208
+#define KEY_NUMERIC_9		0x209
+#define KEY_NUMERIC_STAR	0x20a
+#define KEY_NUMERIC_POUND	0x20b
+
+#define KEY_CAMERA_FOCUS	0x210
+#define KEY_WPS_BUTTON		0x211	/* WiFi Protected Setup key */
+
+#define KEY_TOUCHPAD_TOGGLE	0x212	/* Request switch touchpad on or off */
+#define KEY_TOUCHPAD_ON		0x213
+#define KEY_TOUCHPAD_OFF	0x214
+
+#define KEY_CAMERA_ZOOMIN	0x215
+#define KEY_CAMERA_ZOOMOUT	0x216
+#define KEY_CAMERA_UP		0x217
+#define KEY_CAMERA_DOWN		0x218
+#define KEY_CAMERA_LEFT		0x219
+#define KEY_CAMERA_RIGHT	0x21a
+
+#define KEY_ATTENDANT_ON	0x21b
+#define KEY_ATTENDANT_OFF	0x21c
+#define KEY_ATTENDANT_TOGGLE	0x21d	/* Attendant call on or off */
+#define KEY_LIGHTS_TOGGLE	0x21e	/* Reading light on or off */
+
+#define BTN_DPAD_UP		0x220
+#define BTN_DPAD_DOWN		0x221
+#define BTN_DPAD_LEFT		0x222
+#define BTN_DPAD_RIGHT		0x223
+
+#define MATRIX_KEY(row, col, code)	\
+	((((row) & 0xFF) << 24) | (((col) & 0xFF) << 16) | ((code) & 0xFFFF))
+
+#endif /* _DT_BINDINGS_INPUT_INPUT_H */
diff --git a/scripts/multiconfig.sh b/scripts/multiconfig.sh
index 3e3040b2e2ab9210ebef73859b93e158d2875ecc..70f3a5df6f711081d9808cb67bd807a843164df9 100644
--- a/scripts/multiconfig.sh
+++ b/scripts/multiconfig.sh
@@ -162,6 +162,16 @@ do_defconfig () {
 	fi
 }
 
+do_board_felconfig () {
+    do_board_defconfig ${1%%_felconfig}_defconfig
+    if ! grep -q CONFIG_ARCH_SUNXI=y .config || ! grep -q CONFIG_SPL=y .config ; then
+	echo "$progname: Cannot felconfig a non-sunxi or non-SPL platform" >&2
+	exit 1
+    fi
+    sed -i -e 's/\# CONFIG_SPL_FEL is not set/CONFIG_SPL_FEL=y/g' \
+	.config spl/.config
+}
+
 do_savedefconfig () {
 	if [ -r "$KCONFIG_CONFIG" ]; then
 		subimages=$(get_enabled_subimages)
@@ -323,6 +333,8 @@ target=$1
 case $target in
 *_defconfig)
 	do_board_defconfig $target;;
+*_felconfig)
+	do_board_felconfig $target;;
 *_config)
 	# backward compatibility
 	do_board_defconfig ${target%_config}_defconfig;;