Merge branch 'master' of git://git.denx.de/u-boot-arm
diff --git a/Licenses/README b/Licenses/README
index 4196125..9f61192 100644
--- a/Licenses/README
+++ b/Licenses/README
@@ -52,5 +52,5 @@
 eCos license version 2.0			eCos-2.0			eCos-2.0.txt		http://www.gnu.org/licenses/ecos-license.html
 BSD 2-Clause License				BSD-2-Clause	Y		bsd-2-clause.txt	http://spdx.org/licenses/BSD-2-Clause
 BSD 3-clause "New" or "Revised" License		BSD-3-Clause	Y		bsd-3-clause.txt	http://spdx.org/licenses/BSD-3-Clause#licenseText
-IBM PIBS (PowerPC Initialization and		ibm-pibs			ibm-pibs.txt
+IBM PIBS (PowerPC Initialization and		IBM-pibs			ibm-pibs.txt
 	Boot Software) license
diff --git a/Makefile b/Makefile
index 1365db6..b09bfcc 100644
--- a/Makefile
+++ b/Makefile
@@ -8,7 +8,7 @@
 VERSION = 2013
 PATCHLEVEL = 10
 SUBLEVEL =
-EXTRAVERSION = -rc2
+EXTRAVERSION = -rc4
 ifneq "$(SUBLEVEL)" ""
 U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 else
@@ -45,13 +45,13 @@
 
 #########################################################################
 #
-# U-boot build supports producing a object files to the separate external
+# U-boot build supports generating object files in a separate external
 # directory. Two use cases are supported:
 #
 # 1) Add O= to the make command line
 # 'make O=/tmp/build all'
 #
-# 2) Set environement variable BUILD_DIR to point to the desired location
+# 2) Set environment variable BUILD_DIR to point to the desired location
 # 'export BUILD_DIR=/tmp/build'
 # 'make'
 #
@@ -59,7 +59,7 @@
 # 'export BUILD_DIR=/tmp/build'
 # './MAKEALL'
 #
-# Command line 'O=' setting overrides BUILD_DIR environent variable.
+# Command line 'O=' setting overrides BUILD_DIR environment variable.
 #
 # When none of the above methods is used the local build is performed and
 # the object files are placed in the source directory.
@@ -838,7 +838,7 @@
 
 sinclude $(obj).boards.depend
 $(obj).boards.depend:	boards.cfg
-	@awk '(NF && $$1 !~ /^#/) { print $$7 ": " $$7 "_config; $$(MAKE) -d" }' $< > $@
+	@awk '(NF && $$1 !~ /^#/) { print $$7 ": " $$7 "_config; $$(MAKE)" }' $< > $@
 
 #
 # Functions to generate common board directory names
diff --git a/README b/README
index 2fcad7f..b99a444 100644
--- a/README
+++ b/README
@@ -152,9 +152,6 @@
   /blackfin		Files generic to Analog Devices Blackfin architecture
     /cpu		CPU specific files
     /lib		Architecture specific library files
-  /x86			Files generic to x86 architecture
-    /cpu		CPU specific files
-    /lib		Architecture specific library files
   /m68k			Files generic to m68k architecture
     /cpu		CPU specific files
       /mcf52x2		Files specific to Freescale ColdFire MCF52x2 CPUs
@@ -178,6 +175,9 @@
   /nios2		Files generic to Altera NIOS2 architecture
     /cpu		CPU specific files
     /lib		Architecture specific library files
+  /openrisc		Files generic to OpenRISC architecture
+    /cpu		CPU specific files
+    /lib		Architecture specific library files
   /powerpc		Files generic to PowerPC architecture
     /cpu		CPU specific files
       /74xx_7xx		Files specific to Freescale MPC74xx and 7xx CPUs
@@ -200,12 +200,16 @@
       /leon2		Files specific to Gaisler LEON2 SPARC CPU
       /leon3		Files specific to Gaisler LEON3 SPARC CPU
     /lib		Architecture specific library files
+  /x86			Files generic to x86 architecture
+    /cpu		CPU specific files
+    /lib		Architecture specific library files
 /api			Machine/arch independent API for external apps
 /board			Board dependent files
 /common			Misc architecture independent functions
 /disk			Code for disk drive partition handling
 /doc			Documentation (don't expect too much)
 /drivers		Commonly used device drivers
+/dts			Contains Makefile for building internal U-Boot fdt.
 /examples		Example code for standalone applications, etc.
 /fs			Filesystem code (cramfs, ext2, jffs2, etc.)
 /include		Header Files
@@ -215,7 +219,7 @@
   /lzo			Library files to support LZO decompression
 /net			Networking code
 /post			Power On Self Test
-/rtc			Real Time Clock drivers
+/spl			Secondary Program Loader framework
 /tools			Tools to build S-Record or U-Boot images, etc.
 
 Software Configuration:
@@ -1404,6 +1408,12 @@
 		CONFIG_DFU_NAND
 		This enables support for exposing NAND devices via DFU.
 
+		CONFIG_DFU_RAM
+		This enables support for exposing RAM via DFU.
+		Note: DFU spec refer to non-volatile memory usage, but
+		allow usages beyond the scope of spec - here RAM usage,
+		one that would help mostly the developer.
+
 		CONFIG_SYS_DFU_DATA_BUF_SIZE
 		Dfu transfer uses a buffer before writing data to the
 		raw storage device. Make the size (in bytes) of this buffer
@@ -3359,7 +3369,7 @@
 		the Linux kernel; all data that must be processed by
 		the Linux kernel (bd_info, boot arguments, FDT blob if
 		used) must be put below this limit, unless "bootm_low"
-		enviroment variable is defined and non-zero. In such case
+		environment variable is defined and non-zero. In such case
 		all data for the Linux kernel must be between "bootm_low"
 		and "bootm_low" + CONFIG_SYS_BOOTMAPSZ.	 The environment
 		variable "bootm_mapsize" will override the value of
@@ -3472,7 +3482,7 @@
 
 - CONFIG_ENV_FLAGS_LIST_DEFAULT
 - CONFIG_ENV_FLAGS_LIST_STATIC
-	Enable validation of the values given to enviroment variables when
+	Enable validation of the values given to environment variables when
 	calling env set.  Variables can be restricted to only decimal,
 	hexadecimal, or boolean.  If CONFIG_CMD_NET is also defined,
 	the variables can also be restricted to IP address or MAC address.
diff --git a/arch/arm/cpu/arm926ejs/at91/eflash.c b/arch/arm/cpu/arm926ejs/at91/eflash.c
index 3e21cdb..3f39264 100644
--- a/arch/arm/cpu/arm926ejs/at91/eflash.c
+++ b/arch/arm/cpu/arm926ejs/at91/eflash.c
@@ -28,7 +28,7 @@
  * by u-Boot commands.
  *
  * Note: Redundant environment will not work in this flash since
- * it does use partial page writes. Make sure the environent spans
+ * it does use partial page writes. Make sure the environment spans
  * whole pages!
  */
 
diff --git a/arch/arm/cpu/arm926ejs/kirkwood/cpu.c b/arch/arm/cpu/arm926ejs/kirkwood/cpu.c
index cde3172..d4711c0 100644
--- a/arch/arm/cpu/arm926ejs/kirkwood/cpu.c
+++ b/arch/arm/cpu/arm926ejs/kirkwood/cpu.c
@@ -302,7 +302,7 @@
 	/*
 	 * Configures the I/O voltage of the pads connected to Egigabit
 	 * Ethernet interface to 1.8V
-	 * By defult it is set to 3.3V
+	 * By default it is set to 3.3V
 	 */
 	reg = readl(KW_REG_MPP_OUT_DRV_REG);
 	reg |= (1 << 7);
diff --git a/arch/arm/cpu/armv7/at91/sama5d3_devices.c b/arch/arm/cpu/armv7/at91/sama5d3_devices.c
index e55e1c6..51f0a6d 100644
--- a/arch/arm/cpu/armv7/at91/sama5d3_devices.c
+++ b/arch/arm/cpu/armv7/at91/sama5d3_devices.c
@@ -202,3 +202,15 @@
 	at91_periph_clk_enable(ATMEL_ID_LCDC);
 }
 #endif
+
+#ifdef CONFIG_USB_GADGET_ATMEL_USBA
+void at91_udp_hw_init(void)
+{
+	struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
+
+	/* Enable UPLL clock */
+	writel(AT91_PMC_UPLLEN | AT91_PMC_BIASEN, &pmc->uckr);
+	/* Enable UDPHS clock */
+	at91_periph_clk_enable(ATMEL_ID_UDPHS);
+}
+#endif
diff --git a/arch/arm/cpu/armv7/exynos/clock.c b/arch/arm/cpu/armv7/exynos/clock.c
index 0cb1a61..36fedd6 100644
--- a/arch/arm/cpu/armv7/exynos/clock.c
+++ b/arch/arm/cpu/armv7/exynos/clock.c
@@ -282,6 +282,9 @@
 		src = readl(&clk->src_peric0);
 		div = readl(&clk->div_peric3);
 		break;
+	case PERIPH_ID_I2S0:
+		src = readl(&clk->src_mau);
+		div = readl(&clk->div_mau);
 	case PERIPH_ID_SPI0:
 	case PERIPH_ID_SPI1:
 		src = readl(&clk->src_peric1);
@@ -1146,17 +1149,29 @@
 	return 0;
 }
 
-void exynos5_set_i2s_clk_source(void)
+int exynos5_set_i2s_clk_source(unsigned int i2s_id)
 {
 	struct exynos5_clock *clk =
 		(struct exynos5_clock *)samsung_get_base_clock();
+	unsigned int *audio_ass = (unsigned int *)samsung_get_base_audio_ass();
 
-	clrsetbits_le32(&clk->src_peric1, AUDIO1_SEL_MASK,
-			(CLK_SRC_SCLK_EPLL));
+	if (i2s_id == 0) {
+		setbits_le32(&clk->src_top2, CLK_SRC_MOUT_EPLL);
+		clrsetbits_le32(&clk->src_mau, AUDIO0_SEL_MASK,
+				(CLK_SRC_SCLK_EPLL));
+		setbits_le32(audio_ass, AUDIO_CLKMUX_ASS);
+	} else if (i2s_id == 1) {
+		clrsetbits_le32(&clk->src_peric1, AUDIO1_SEL_MASK,
+				(CLK_SRC_SCLK_EPLL));
+	} else {
+		return -1;
+	}
+	return 0;
 }
 
 int exynos5_set_i2s_clk_prescaler(unsigned int src_frq,
-					unsigned int dst_frq)
+				  unsigned int dst_frq,
+				  unsigned int i2s_id)
 {
 	struct exynos5_clock *clk =
 		(struct exynos5_clock *)samsung_get_base_clock();
@@ -1169,13 +1184,27 @@
 	}
 
 	div = (src_frq / dst_frq);
-	if (div > AUDIO_1_RATIO_MASK) {
-		debug("%s: Frequency ratio is out of range\n", __func__);
-		debug("src frq = %d des frq = %d ", src_frq, dst_frq);
+	if (i2s_id == 0) {
+		if (div > AUDIO_0_RATIO_MASK) {
+			debug("%s: Frequency ratio is out of range\n",
+			      __func__);
+			debug("src frq = %d des frq = %d ", src_frq, dst_frq);
+			return -1;
+		}
+		clrsetbits_le32(&clk->div_mau, AUDIO_0_RATIO_MASK,
+				(div & AUDIO_0_RATIO_MASK));
+	} else if(i2s_id == 1) {
+		if (div > AUDIO_1_RATIO_MASK) {
+			debug("%s: Frequency ratio is out of range\n",
+			      __func__);
+			debug("src frq = %d des frq = %d ", src_frq, dst_frq);
+			return -1;
+		}
+		clrsetbits_le32(&clk->div_peric4, AUDIO_1_RATIO_MASK,
+				(div & AUDIO_1_RATIO_MASK));
+	} else {
 		return -1;
 	}
-	clrsetbits_le32(&clk->div_peric4, AUDIO_1_RATIO_MASK,
-				(div & AUDIO_1_RATIO_MASK));
 	return 0;
 }
 
@@ -1415,19 +1444,21 @@
 		return 0;
 }
 
-int set_i2s_clk_prescaler(unsigned int src_frq, unsigned int dst_frq)
+int set_i2s_clk_prescaler(unsigned int src_frq, unsigned int dst_frq,
+			  unsigned int i2s_id)
 {
-
 	if (cpu_is_exynos5())
-		return exynos5_set_i2s_clk_prescaler(src_frq, dst_frq);
+		return exynos5_set_i2s_clk_prescaler(src_frq, dst_frq, i2s_id);
 	else
 		return 0;
 }
 
-void set_i2s_clk_source(void)
+int set_i2s_clk_source(unsigned int i2s_id)
 {
 	if (cpu_is_exynos5())
-		exynos5_set_i2s_clk_source();
+		return exynos5_set_i2s_clk_source(i2s_id);
+	else
+		return 0;
 }
 
 int set_epll_clk(unsigned long rate)
diff --git a/arch/arm/cpu/armv7/exynos/pinmux.c b/arch/arm/cpu/armv7/exynos/pinmux.c
index 1b05ebf..8002bce 100644
--- a/arch/arm/cpu/armv7/exynos/pinmux.c
+++ b/arch/arm/cpu/armv7/exynos/pinmux.c
@@ -220,10 +220,20 @@
 {
 	int i;
 	struct exynos5_gpio_part1 *gpio1 =
-		(struct exynos5_gpio_part1 *) samsung_get_base_gpio_part1();
+		(struct exynos5_gpio_part1 *)samsung_get_base_gpio_part1();
+	struct exynos5_gpio_part4 *gpio4 =
+		(struct exynos5_gpio_part4 *)samsung_get_base_gpio_part4();
 
-	for (i = 0; i < 5; i++)
-		s5p_gpio_cfg_pin(&gpio1->b0, i, GPIO_FUNC(0x02));
+	switch (peripheral) {
+	case PERIPH_ID_I2S0:
+		for (i = 0; i < 5; i++)
+			s5p_gpio_cfg_pin(&gpio4->z, i, GPIO_FUNC(0x02));
+		break;
+	case PERIPH_ID_I2S1:
+		for (i = 0; i < 5; i++)
+			s5p_gpio_cfg_pin(&gpio1->b0, i, GPIO_FUNC(0x02));
+		break;
+	}
 }
 
 void exynos5_spi_config(int peripheral)
@@ -296,6 +306,7 @@
 	case PERIPH_ID_I2C7:
 		exynos5_i2c_config(peripheral, flags);
 		break;
+	case PERIPH_ID_I2S0:
 	case PERIPH_ID_I2S1:
 		exynos5_i2s_config(peripheral);
 		break;
@@ -463,11 +474,11 @@
 
 int exynos_pinmux_config(int peripheral, int flags)
 {
-	if (cpu_is_exynos5())
+	if (cpu_is_exynos5()) {
 		return exynos5_pinmux_config(peripheral, flags);
-	else if (cpu_is_exynos4())
+	} else if (cpu_is_exynos4()) {
 		return exynos4_pinmux_config(peripheral, flags);
-	else {
+	} else {
 		debug("pinmux functionality not supported\n");
 		return -1;
 	}
diff --git a/arch/arm/dts/exynos5250.dtsi b/arch/arm/dts/exynos5250.dtsi
index 4fff5e3..1c5474f 100644
--- a/arch/arm/dts/exynos5250.dtsi
+++ b/arch/arm/dts/exynos5250.dtsi
@@ -93,9 +93,28 @@
 		interrupts = <0 63 0>;
 	};
 
+	sound@3830000 {
+		compatible = "samsung,exynos-sound";
+		reg = <0x3830000 0x50>;
+		samsung,i2s-epll-clock-frequency = <192000000>;
+		samsung,i2s-sampling-rate = <48000>;
+		samsung,i2s-bits-per-sample = <16>;
+		samsung,i2s-channels = <2>;
+		samsung,i2s-lr-clk-framesize = <256>;
+		samsung,i2s-bit-clk-framesize = <32>;
+		samsung,i2s-id = <0>;
+	};
+
 	sound@12d60000 {
 		compatible = "samsung,exynos-sound";
 		reg = <0x12d60000 0x20>;
+		samsung,i2s-epll-clock-frequency = <192000000>;
+		samsung,i2s-sampling-rate = <48000>;
+		samsung,i2s-bits-per-sample = <16>;
+		samsung,i2s-channels = <2>;
+		samsung,i2s-lr-clk-framesize = <256>;
+		samsung,i2s-bit-clk-framesize = <32>;
+		samsung,i2s-id = <1>;
 	};
 
 	spi@12d20000 {
diff --git a/arch/arm/include/asm/arch-at91/at91_common.h b/arch/arm/include/asm/arch-at91/at91_common.h
index 9f54fdd..abcb97d 100644
--- a/arch/arm/include/asm/arch-at91/at91_common.h
+++ b/arch/arm/include/asm/arch-at91/at91_common.h
@@ -19,6 +19,7 @@
 void at91_seriald_hw_init(void);
 void at91_spi0_hw_init(unsigned long cs_mask);
 void at91_spi1_hw_init(unsigned long cs_mask);
+void at91_udp_hw_init(void);
 void at91_uhp_hw_init(void);
 void at91_lcd_hw_init(void);
 
diff --git a/arch/arm/include/asm/arch-at91/atmel_usba_udc.h b/arch/arm/include/asm/arch-at91/atmel_usba_udc.h
new file mode 100644
index 0000000..6f540d2
--- /dev/null
+++ b/arch/arm/include/asm/arch-at91/atmel_usba_udc.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2005-2013 Atmel Corporation
+ *			   Bo Shen <voice.shen@atmel.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __ATMEL_USBA_UDC_H__
+#define __ATMEL_USBA_UDC_H__
+
+#include <linux/usb/atmel_usba_udc.h>
+
+#define EP(nam, idx, maxpkt, maxbk, dma, isoc)		\
+	[idx] = {					\
+		.name	= nam,				\
+		.index	= idx,				\
+		.fifo_size	= maxpkt,		\
+		.nr_banks	= maxbk,		\
+		.can_dma	= dma,			\
+		.can_isoc	= isoc,			\
+	}
+
+#if defined(CONFIG_AT91SAM9G45) || defined(CONFIG_AT91SAM9M10G45) || \
+	defined(CONFIG_AT91SAM9X5)
+static struct usba_ep_data usba_udc_ep[] = {
+	EP("ep0", 0, 64, 1, 0, 0),
+	EP("ep1", 1, 1024, 2, 1, 1),
+	EP("ep2", 2, 1024, 2, 1, 1),
+	EP("ep3", 3, 1024, 3, 1, 0),
+	EP("ep4", 4, 1024, 3, 1, 0),
+	EP("ep5", 5, 1024, 3, 1, 1),
+	EP("ep6", 6, 1024, 3, 1, 1),
+};
+#elif defined(CONFIG_SAMA5D3)
+static struct usba_ep_data usba_udc_ep[] = {
+	EP("ep0", 0, 64, 1, 0, 0),
+	EP("ep1", 1, 1024, 3, 1, 0),
+	EP("ep2", 2, 1024, 3, 1, 0),
+	EP("ep3", 3, 1024, 2, 1, 0),
+	EP("ep4", 4, 1024, 2, 1, 0),
+	EP("ep5", 5, 1024, 2, 1, 0),
+	EP("ep6", 6, 1024, 2, 1, 0),
+	EP("ep7", 7, 1024, 2, 1, 0),
+	EP("ep8", 8, 1024, 2, 0, 0),
+	EP("ep9", 9, 1024, 2, 0, 0),
+	EP("ep10", 10, 1024, 2, 0, 0),
+	EP("ep11", 11, 1024, 2, 0, 0),
+	EP("ep12", 12, 1024, 2, 0, 0),
+	EP("ep13", 13, 1024, 2, 0, 0),
+	EP("ep14", 14, 1024, 2, 0, 0),
+	EP("ep15", 15, 1024, 2, 0, 0),
+};
+#else
+# error "NO usba_udc_ep defined"
+#endif
+
+#undef EP
+
+struct usba_platform_data pdata = {
+	.num_ep	= ARRAY_SIZE(usba_udc_ep),
+	.ep	= usba_udc_ep,
+};
+
+#endif
diff --git a/arch/arm/include/asm/arch-at91/sama5d3.h b/arch/arm/include/asm/arch-at91/sama5d3.h
index fefee5e..123a627 100644
--- a/arch/arm/include/asm/arch-at91/sama5d3.h
+++ b/arch/arm/include/asm/arch-at91/sama5d3.h
@@ -120,7 +120,7 @@
 #define ATMEL_BASE_USART3	0xf8024000
 #define ATMEL_BASE_UART1	0xf8028000
 #define ATMEL_BASE_EMAC		0xf802c000
-#define ATMEL_BASE_UDHPS	0xf8030000
+#define ATMEL_BASE_UDPHS	0xf8030000
 #define ATMEL_BASE_SHA		0xf8034000
 #define ATMEL_BASE_AES		0xf8038000
 #define ATMEL_BASE_TDES		0xf803c000
diff --git a/arch/arm/include/asm/arch-exynos/clk.h b/arch/arm/include/asm/arch-exynos/clk.h
index 71075bd..1d6fa93 100644
--- a/arch/arm/include/asm/arch-exynos/clk.h
+++ b/arch/arm/include/asm/arch-exynos/clk.h
@@ -31,8 +31,9 @@
 unsigned long get_lcd_clk(void);
 void set_lcd_clk(void);
 void set_mipi_clk(void);
-void set_i2s_clk_source(void);
-int set_i2s_clk_prescaler(unsigned int src_frq, unsigned int dst_frq);
+int set_i2s_clk_source(unsigned int i2s_id);
+int set_i2s_clk_prescaler(unsigned int src_frq, unsigned int dst_frq,
+				unsigned int i2s_id);
 int set_epll_clk(unsigned long rate);
 int set_spi_clk(int periph_id, unsigned int rate);
 
diff --git a/arch/arm/include/asm/arch-exynos/clock.h b/arch/arm/include/asm/arch-exynos/clock.h
index 2b97b9a..cf26eef 100644
--- a/arch/arm/include/asm/arch-exynos/clock.h
+++ b/arch/arm/include/asm/arch-exynos/clock.h
@@ -876,8 +876,12 @@
 #define AUDIO_0_RATIO_MASK		0x0f
 #define AUDIO_1_RATIO_MASK		0x0f
 
+#define AUDIO0_SEL_MASK			0xf
 #define AUDIO1_SEL_MASK			0xf
+
 #define CLK_SRC_SCLK_EPLL		0x7
+#define CLK_SRC_MOUT_EPLL		(1<<12)
+#define AUDIO_CLKMUX_ASS		(1<<0)
 
 /* CON0 bit-fields */
 #define EPLL_CON0_MDIV_MASK		0x1ff
diff --git a/arch/arm/include/asm/arch-exynos/cpu.h b/arch/arm/include/asm/arch-exynos/cpu.h
index cb924fb..4b67191 100644
--- a/arch/arm/include/asm/arch-exynos/cpu.h
+++ b/arch/arm/include/asm/arch-exynos/cpu.h
@@ -50,6 +50,7 @@
 #define EXYNOS4_SPI_ISP_BASE		DEVICE_NOT_AVAILABLE
 #define EXYNOS4_ACE_SFR_BASE		DEVICE_NOT_AVAILABLE
 #define EXYNOS4_DMC_PHY_BASE		DEVICE_NOT_AVAILABLE
+#define EXYNOS4_AUDIOSS_BASE		DEVICE_NOT_AVAILABLE
 
 /* EXYNOS4X12 */
 #define EXYNOS4X12_GPIO_PART3_BASE	0x03860000
@@ -85,10 +86,12 @@
 #define EXYNOS4X12_SPI_ISP_BASE		DEVICE_NOT_AVAILABLE
 #define EXYNOS4X12_ACE_SFR_BASE		DEVICE_NOT_AVAILABLE
 #define EXYNOS4X12_DMC_PHY_BASE		DEVICE_NOT_AVAILABLE
+#define EXYNOS4X12_AUDIOSS_BASE		DEVICE_NOT_AVAILABLE
 
 /* EXYNOS5 Common*/
 #define EXYNOS5_I2C_SPACING		0x10000
 
+#define EXYNOS5_AUDIOSS_BASE		0x03810000
 #define EXYNOS5_GPIO_PART4_BASE		0x03860000
 #define EXYNOS5_PRO_ID			0x10000000
 #define EXYNOS5_CLOCK_BASE		0x10010000
@@ -226,6 +229,7 @@
 SAMSUNG_BASE(tzpc, TZPC_BASE)
 SAMSUNG_BASE(dmc_ctrl, DMC_CTRL_BASE)
 SAMSUNG_BASE(dmc_phy, DMC_PHY_BASE)
+SAMSUNG_BASE(audio_ass, AUDIOSS_BASE)
 #endif
 
 #endif	/* _EXYNOS4_CPU_H */
diff --git a/arch/arm/include/asm/arch-exynos/i2s-regs.h b/arch/arm/include/asm/arch-exynos/i2s-regs.h
index 613b9b7..4a4a7a0 100644
--- a/arch/arm/include/asm/arch-exynos/i2s-regs.h
+++ b/arch/arm/include/asm/arch-exynos/i2s-regs.h
@@ -8,10 +8,12 @@
 #ifndef __I2S_REGS_H__
 #define __I2S_REGS_H__
 
+#define CON_RESET		(1 << 31)
 #define CON_TXFIFO_FULL		(1 << 8)
 #define CON_TXCH_PAUSE		(1 << 4)
 #define CON_ACTIVE		(1 << 0)
 
+#define MOD_OP_CLK		(3 << 30)
 #define MOD_BLCP_SHIFT		24
 #define MOD_BLCP_16BIT		(0 << MOD_BLCP_SHIFT)
 #define MOD_BLCP_8BIT		(1 << MOD_BLCP_SHIFT)
@@ -24,6 +26,7 @@
 #define MOD_BLC_MASK		(3 << 13)
 
 #define MOD_SLAVE		(1 << 11)
+#define MOD_RCLKSRC		(0 << 10)
 #define MOD_MASK		(3 << 8)
 #define MOD_LR_LLOW		(0 << 7)
 #define MOD_LR_RLOW		(1 << 7)
@@ -47,4 +50,7 @@
 #define FIC_TXFLUSH		(1 << 15)
 #define FIC_RXFLUSH		(1 << 7)
 
+#define PSREN			(1 << 15)
+#define PSVAL			(3 << 8)
+
 #endif /* __I2S_REGS_H__ */
diff --git a/arch/arm/include/asm/arch-exynos/periph.h b/arch/arm/include/asm/arch-exynos/periph.h
index 9952155..64bd8b7 100644
--- a/arch/arm/include/asm/arch-exynos/periph.h
+++ b/arch/arm/include/asm/arch-exynos/periph.h
@@ -34,6 +34,7 @@
 	PERIPH_ID_SDMMC1,
 	PERIPH_ID_SDMMC2,
 	PERIPH_ID_SDMMC3,
+	PERIPH_ID_I2S0 = 98,
 	PERIPH_ID_I2S1 = 99,
 
 	/* Since following peripherals do
diff --git a/arch/arm/include/asm/arch-omap5/ehci.h b/arch/arm/include/asm/arch-omap5/ehci.h
index 3921e4a..63aaa02 100644
--- a/arch/arm/include/asm/arch-omap5/ehci.h
+++ b/arch/arm/include/asm/arch-omap5/ehci.h
@@ -2,20 +2,7 @@
  * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com*
  * Author: Govindraj R <govindraj.raja@ti.com>
  *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
+ * SPDX-License-Identifier: GPL-2.0+
  */
 
 #ifndef _EHCI_H
diff --git a/arch/powerpc/cpu/mpc85xx/cmd_errata.c b/arch/powerpc/cpu/mpc85xx/cmd_errata.c
index eea264b..c441bd2 100644
--- a/arch/powerpc/cpu/mpc85xx/cmd_errata.c
+++ b/arch/powerpc/cpu/mpc85xx/cmd_errata.c
@@ -252,6 +252,9 @@
 #ifdef CONFIG_SYS_FSL_ERRATUM_A005812
 	puts("Work-around for Erratum A-005812 enabled\n");
 #endif
+#ifdef CONFIG_SYS_FSL_ERRATUM_A005125
+	puts("Work-around for Erratum A005125 enabled\n");
+#endif
 #ifdef CONFIG_SYS_FSL_ERRATUM_I2C_A004447
 	if ((SVR_SOC_VER(svr) == SVR_8548 && IS_SVR_REV(svr, 3, 1)) ||
 	    (SVR_REV(svr) <= CONFIG_SYS_FSL_A004447_SVR_REV))
diff --git a/arch/powerpc/cpu/mpc85xx/start.S b/arch/powerpc/cpu/mpc85xx/start.S
index ad57a9c..be4f4ae 100644
--- a/arch/powerpc/cpu/mpc85xx/start.S
+++ b/arch/powerpc/cpu/mpc85xx/start.S
@@ -108,6 +108,14 @@
 	isync
 2:
 #endif
+#ifdef CONFIG_SYS_FSL_ERRATUM_A005125
+	msync
+	isync
+	mfspr	r3, SPRN_HDBCR0
+	oris	r3, r3, 0x0080
+	mtspr	SPRN_HDBCR0, r3
+#endif
+
 
 #if defined(CONFIG_SECURE_BOOT) && defined(CONFIG_E500MC)
 	/* ISBC uses L2 as stack.
diff --git a/arch/powerpc/cpu/ppc4xx/4xx_pci.c b/arch/powerpc/cpu/ppc4xx/4xx_pci.c
index 5584e0f..08781a1 100644
--- a/arch/powerpc/cpu/ppc4xx/4xx_pci.c
+++ b/arch/powerpc/cpu/ppc4xx/4xx_pci.c
@@ -1,5 +1,5 @@
 /*
- * SPDX-License-Identifier:	GPL-2.0	ibm-pibs
+ * SPDX-License-Identifier:	GPL-2.0	IBM-pibs
  *
  *  File Name:   405gp_pci.c
  *
diff --git a/arch/powerpc/cpu/ppc4xx/4xx_uart.c b/arch/powerpc/cpu/ppc4xx/4xx_uart.c
index 50c28a0..c02058f 100644
--- a/arch/powerpc/cpu/ppc4xx/4xx_uart.c
+++ b/arch/powerpc/cpu/ppc4xx/4xx_uart.c
@@ -5,7 +5,7 @@
  * (C) Copyright 2010
  * Stefan Roese, DENX Software Engineering, sr@denx.de.
  *
- * SPDX-License-Identifier:	GPL-2.0	ibm-pibs
+ * SPDX-License-Identifier:	GPL-2.0	IBM-pibs
  */
 
 #include <common.h>
diff --git a/arch/powerpc/cpu/ppc4xx/miiphy.c b/arch/powerpc/cpu/ppc4xx/miiphy.c
index e4a9db6..10147de 100644
--- a/arch/powerpc/cpu/ppc4xx/miiphy.c
+++ b/arch/powerpc/cpu/ppc4xx/miiphy.c
@@ -1,5 +1,5 @@
 /*
- * SPDX-License-Identifier:	GPL-2.0	ibm-pibs
+ * SPDX-License-Identifier:	GPL-2.0	IBM-pibs
  */
 /*-----------------------------------------------------------------------------+
   |
diff --git a/arch/powerpc/cpu/ppc4xx/start.S b/arch/powerpc/cpu/ppc4xx/start.S
index d9d8cbf..38bbc5a 100644
--- a/arch/powerpc/cpu/ppc4xx/start.S
+++ b/arch/powerpc/cpu/ppc4xx/start.S
@@ -6,7 +6,7 @@
  *  Copyright (c) 2008 Nuovation System Designs, LLC
  *    Grant Erickson <gerickson@nuovations.com>
  *
- * SPDX-License-Identifier:	GPL-2.0	ibm-pibs
+ * SPDX-License-Identifier:	GPL-2.0	IBM-pibs
  */
 
 /*
diff --git a/arch/powerpc/include/asm/config_mpc85xx.h b/arch/powerpc/include/asm/config_mpc85xx.h
index 15e44de..bec8966 100644
--- a/arch/powerpc/include/asm/config_mpc85xx.h
+++ b/arch/powerpc/include/asm/config_mpc85xx.h
@@ -34,6 +34,7 @@
 #define CONFIG_SYS_PPC_E500_DEBUG_TLB	1
 #define CONFIG_SYS_FSL_SEC_COMPAT	2
 #define CONFIG_SYS_CCSRBAR_DEFAULT	0xff700000
+#define CONFIG_SYS_FSL_ERRATUM_A005125
 
 #elif defined(CONFIG_MPC8540)
 #define CONFIG_MAX_CPUS			1
@@ -52,6 +53,7 @@
 #define CONFIG_SYS_PPC_E500_DEBUG_TLB	0
 #define CONFIG_SYS_FSL_SEC_COMPAT	2
 #define CONFIG_SYS_CCSRBAR_DEFAULT	0xff700000
+#define CONFIG_SYS_FSL_ERRATUM_A005125
 
 #elif defined(CONFIG_MPC8548)
 #define CONFIG_MAX_CPUS			1
@@ -67,6 +69,7 @@
 #define CONFIG_SYS_FSL_SRIO_IB_WIN_NUM	5
 #define CONFIG_SYS_FSL_RMU
 #define CONFIG_SYS_FSL_SRIO_MSG_UNIT_NUM	2
+#define CONFIG_SYS_FSL_ERRATUM_A005125
 #define CONFIG_SYS_FSL_ERRATUM_I2C_A004447
 #define CONFIG_SYS_FSL_A004447_SVR_REV	0x00
 
@@ -108,6 +111,7 @@
 #define CONFIG_SYS_FSL_SRIO_IB_WIN_NUM	5
 #define CONFIG_SYS_FSL_RMU
 #define CONFIG_SYS_FSL_SRIO_MSG_UNIT_NUM	2
+#define CONFIG_SYS_FSL_ERRATUM_A005125
 
 #elif defined(CONFIG_MPC8572)
 #define CONFIG_MAX_CPUS			2
@@ -117,6 +121,7 @@
 #define CONFIG_SYS_CCSRBAR_DEFAULT	0xff700000
 #define CONFIG_SYS_FSL_ERRATUM_DDR_115
 #define CONFIG_SYS_FSL_ERRATUM_DDR111_DDR134
+#define CONFIG_SYS_FSL_ERRATUM_A005125
 
 #elif defined(CONFIG_P1010)
 #define CONFIG_MAX_CPUS			1
@@ -135,6 +140,7 @@
 #define CONFIG_SYS_FSL_ERRATUM_P1010_A003549
 #define CONFIG_SYS_FSL_ERRATUM_SEC_A003571
 #define CONFIG_SYS_FSL_ERRATUM_IFC_A003399
+#define CONFIG_SYS_FSL_ERRATUM_A005125
 #define CONFIG_SYS_FSL_ERRATUM_I2C_A004447
 #define CONFIG_SYS_FSL_A004447_SVR_REV	0x10
 
@@ -149,6 +155,7 @@
 #define CONFIG_SYS_CCSRBAR_DEFAULT	0xff700000
 #define CONFIG_SYS_FSL_ERRATUM_ELBC_A001
 #define CONFIG_SYS_FSL_ERRATUM_ESDHC111
+#define CONFIG_SYS_FSL_ERRATUM_A005125
 
 /* P1012 is single core version of P1021 */
 #elif defined(CONFIG_P1012)
@@ -164,6 +171,7 @@
 #define QE_MURAM_SIZE			0x6000UL
 #define MAX_QE_RISC			1
 #define QE_NUM_OF_SNUM			28
+#define CONFIG_SYS_FSL_ERRATUM_A005125
 
 /* P1013 is single core version of P1022 */
 #elif defined(CONFIG_P1013)
@@ -176,6 +184,7 @@
 #define CONFIG_SYS_FSL_ERRATUM_ELBC_A001
 #define CONFIG_SYS_FSL_ERRATUM_ESDHC111
 #define CONFIG_FSL_SATA_ERRATUM_A001
+#define CONFIG_SYS_FSL_ERRATUM_A005125
 
 #elif defined(CONFIG_P1014)
 #define CONFIG_MAX_CPUS			1
@@ -205,6 +214,7 @@
 #define CONFIG_SYS_FM_MURAM_SIZE	0x10000
 #define CONFIG_SYS_FSL_PCIE_COMPAT	"fsl,qoriq-pcie-v2.2"
 #define CONFIG_SYS_CCSRBAR_DEFAULT	0xff600000
+#define CONFIG_SYS_FSL_ERRATUM_A005125
 
 #elif defined(CONFIG_P1020)
 #define CONFIG_MAX_CPUS			2
@@ -216,6 +226,7 @@
 #define CONFIG_SYS_CCSRBAR_DEFAULT	0xff700000
 #define CONFIG_SYS_FSL_ERRATUM_ELBC_A001
 #define CONFIG_SYS_FSL_ERRATUM_ESDHC111
+#define CONFIG_SYS_FSL_ERRATUM_A005125
 
 #elif defined(CONFIG_P1021)
 #define CONFIG_MAX_CPUS			2
@@ -230,6 +241,7 @@
 #define QE_MURAM_SIZE			0x6000UL
 #define MAX_QE_RISC			1
 #define QE_NUM_OF_SNUM			28
+#define CONFIG_SYS_FSL_ERRATUM_A005125
 
 #elif defined(CONFIG_P1022)
 #define CONFIG_MAX_CPUS			2
@@ -241,6 +253,7 @@
 #define CONFIG_SYS_FSL_ERRATUM_ELBC_A001
 #define CONFIG_SYS_FSL_ERRATUM_ESDHC111
 #define CONFIG_FSL_SATA_ERRATUM_A001
+#define CONFIG_SYS_FSL_ERRATUM_A005125
 
 #elif defined(CONFIG_P1023)
 #define CONFIG_MAX_CPUS			2
@@ -254,6 +267,7 @@
 #define CONFIG_SYS_FM_MURAM_SIZE	0x10000
 #define CONFIG_SYS_FSL_PCIE_COMPAT	"fsl,qoriq-pcie-v2.2"
 #define CONFIG_SYS_CCSRBAR_DEFAULT	0xff600000
+#define CONFIG_SYS_FSL_ERRATUM_A005125
 #define CONFIG_SYS_FSL_ERRATUM_I2C_A004447
 #define CONFIG_SYS_FSL_A004447_SVR_REV	0x11
 
@@ -268,6 +282,7 @@
 #define CONFIG_SYS_CCSRBAR_DEFAULT	0xff700000
 #define CONFIG_SYS_FSL_ERRATUM_ELBC_A001
 #define CONFIG_SYS_FSL_ERRATUM_ESDHC111
+#define CONFIG_SYS_FSL_ERRATUM_A005125
 
 /* P1025 is lower end variant of P1021 */
 #elif defined(CONFIG_P1025)
@@ -283,6 +298,7 @@
 #define QE_MURAM_SIZE			0x6000UL
 #define MAX_QE_RISC			1
 #define QE_NUM_OF_SNUM			28
+#define CONFIG_SYS_FSL_ERRATUM_A005125
 
 /* P2010 is single core version of P2020 */
 #elif defined(CONFIG_P2010)
@@ -293,6 +309,7 @@
 #define CONFIG_SYS_CCSRBAR_DEFAULT	0xff700000
 #define CONFIG_SYS_FSL_ERRATUM_ESDHC111
 #define CONFIG_SYS_FSL_ERRATUM_ESDHC_A001
+#define CONFIG_SYS_FSL_ERRATUM_A005125
 
 #elif defined(CONFIG_P2020)
 #define CONFIG_MAX_CPUS			2
@@ -307,6 +324,7 @@
 #define CONFIG_SYS_FSL_SRIO_IB_WIN_NUM	5
 #define CONFIG_SYS_FSL_RMU
 #define CONFIG_SYS_FSL_SRIO_MSG_UNIT_NUM	2
+#define CONFIG_SYS_FSL_ERRATUM_A005125
 
 #elif defined(CONFIG_PPC_P2041) /* also supports P2040 */
 #define CONFIG_SYS_FSL_QORIQ_CHASSIS1
@@ -506,6 +524,7 @@
 #define CONFIG_SYS_CCSRBAR_DEFAULT	0xff700000
 #define CONFIG_NAND_FSL_IFC
 #define CONFIG_SYS_FSL_ERRATUM_ESDHC111
+#define CONFIG_SYS_FSL_ERRATUM_A005125
 
 #elif defined(CONFIG_BSC9132)
 #define CONFIG_MAX_CPUS			2
@@ -525,6 +544,7 @@
 #define CONFIG_SYS_FSL_ERRATUM_ESDHC111
 #define CONFIG_SYS_FSL_ESDHC_P1010_BROKEN_SDCLK
 #define CONFIG_SYS_FSL_PCIE_COMPAT	"fsl,qoriq-pcie-v2.2"
+#define CONFIG_SYS_FSL_ERRATUM_A005125
 #define CONFIG_SYS_FSL_ERRATUM_I2C_A004447
 #define CONFIG_SYS_FSL_A004447_SVR_REV	0x11
 
@@ -658,6 +678,7 @@
 #define CONFIG_NUM_DDR_CONTROLLERS	1
 #define CONFIG_SYS_FSL_IFC_BANK_COUNT	8
 #define CONFIG_SYS_CCSRBAR_DEFAULT	0xff700000
+#define CONFIG_SYS_FSL_ERRATUM_A005125
 
 #else
 #error Processor type not defined for this platform
diff --git a/arch/powerpc/include/asm/ppc405.h b/arch/powerpc/include/asm/ppc405.h
index 8bb342b..f2ed16a 100644
--- a/arch/powerpc/include/asm/ppc405.h
+++ b/arch/powerpc/include/asm/ppc405.h
@@ -1,5 +1,5 @@
 /*
- * SPDX-License-Identifier:	GPL-2.0	ibm-pibs
+ * SPDX-License-Identifier:	GPL-2.0	IBM-pibs
  */
 
 #ifndef	__PPC405_H__
diff --git a/arch/powerpc/include/asm/ppc440.h b/arch/powerpc/include/asm/ppc440.h
index 0f5bc8d..0cfa88b 100644
--- a/arch/powerpc/include/asm/ppc440.h
+++ b/arch/powerpc/include/asm/ppc440.h
@@ -9,7 +9,7 @@
  * (C) Copyright 2010
  * Stefan Roese, DENX Software Engineering, sr@denx.de.
  *
- * SPDX-License-Identifier:	GPL-2.0	ibm-pibs
+ * SPDX-License-Identifier:	GPL-2.0	IBM-pibs
  */
 
 #ifndef __PPC440_H__
diff --git a/arch/powerpc/include/asm/ppc4xx-emac.h b/arch/powerpc/include/asm/ppc4xx-emac.h
index e6eb332..76fa95c 100644
--- a/arch/powerpc/include/asm/ppc4xx-emac.h
+++ b/arch/powerpc/include/asm/ppc4xx-emac.h
@@ -1,5 +1,5 @@
 /*
- * SPDX-License-Identifier:	GPL-2.0	ibm-pibs
+ * SPDX-License-Identifier:	GPL-2.0	IBM-pibs
  */
 /*----------------------------------------------------------------------------+
 |
diff --git a/arch/powerpc/include/asm/ppc4xx-mal.h b/arch/powerpc/include/asm/ppc4xx-mal.h
index d15290d..ef8b174 100644
--- a/arch/powerpc/include/asm/ppc4xx-mal.h
+++ b/arch/powerpc/include/asm/ppc4xx-mal.h
@@ -1,6 +1,6 @@
 /* include/mal.h, openbios_walnut, walnut_bios 8/6/99 08:48:40 */
 /*
- * SPDX-License-Identifier:	GPL-2.0	ibm-pibs
+ * SPDX-License-Identifier:	GPL-2.0	IBM-pibs
  */
 /*----------------------------------------------------------------------------+
 |
diff --git a/arch/powerpc/include/asm/ppc4xx.h b/arch/powerpc/include/asm/ppc4xx.h
index 8d703c6..e6a3bff 100644
--- a/arch/powerpc/include/asm/ppc4xx.h
+++ b/arch/powerpc/include/asm/ppc4xx.h
@@ -1,5 +1,5 @@
 /*
- * SPDX-License-Identifier:	GPL-2.0	ibm-pibs
+ * SPDX-License-Identifier:	GPL-2.0	IBM-pibs
  */
 
 #ifndef	__PPC4XX_H__
diff --git a/board/RPXlite_dw/README b/board/RPXlite_dw/README
index 14296b2..9e2d0f4 100644
--- a/board/RPXlite_dw/README
+++ b/board/RPXlite_dw/README
@@ -87,9 +87,9 @@
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-A word on the U-Boot enviroment variable setting and usage :
+A word on the U-Boot environment variable setting and usage :
 
-In the beginning, you could just need very simple defult environment variable setting,
+In the beginning, you could just need very simple default environment variable setting,
 like[include/configs/RPXlite.h] :
 
 #define CONFIG_BOOTCOMMAND                                                      \
diff --git a/board/atmel/sama5d3xek/sama5d3xek.c b/board/atmel/sama5d3xek/sama5d3xek.c
index 97caf64..b0965ef 100644
--- a/board/atmel/sama5d3xek/sama5d3xek.c
+++ b/board/atmel/sama5d3xek/sama5d3xek.c
@@ -21,6 +21,10 @@
 #include <net.h>
 #include <netdev.h>
 
+#ifdef CONFIG_USB_GADGET_ATMEL_USBA
+#include <asm/arch/atmel_usba_udc.h>
+#endif
+
 DECLARE_GLOBAL_DATA_PTR;
 
 /* ------------------------------------------------------------------------- */
@@ -170,6 +174,9 @@
 #ifdef CONFIG_CMD_USB
 	sama5d3xek_usb_hw_init();
 #endif
+#ifdef CONFIG_USB_GADGET_ATMEL_USBA
+	at91_udp_hw_init();
+#endif
 #ifdef CONFIG_GENERIC_ATMEL_MCI
 	sama5d3xek_mci_hw_init();
 #endif
@@ -221,6 +228,12 @@
 	if (has_gmac())
 		rc = macb_eth_initialize(0, (void *)ATMEL_BASE_GMAC, 0x00);
 #endif
+#ifdef CONFIG_USB_GADGET_ATMEL_USBA
+	usba_udc_probe(&pdata);
+#ifdef CONFIG_USB_ETH_RNDIS
+	usb_eth_initialize(bis);
+#endif
+#endif
 
 	return rc;
 }
diff --git a/board/cray/L1/init.S b/board/cray/L1/init.S
index 82f21b0..44c688d 100644
--- a/board/cray/L1/init.S
+++ b/board/cray/L1/init.S
@@ -1,5 +1,5 @@
 /*
- * SPDX-License-Identifier:	GPL-2.0	ibm-pibs
+ * SPDX-License-Identifier:	GPL-2.0	IBM-pibs
  */
 
 /*----------------------------------------------------------------------------- */
diff --git a/board/csb272/init.S b/board/csb272/init.S
index b1283aa..5961978 100644
--- a/board/csb272/init.S
+++ b/board/csb272/init.S
@@ -1,5 +1,5 @@
 /*
- * SPDX-License-Identifier:	GPL-2.0	ibm-pibs
+ * SPDX-License-Identifier:	GPL-2.0	IBM-pibs
  */
 #include <config.h>
 #include <asm/ppc4xx.h>
diff --git a/board/csb472/init.S b/board/csb472/init.S
index f5805b7..1ebc9ea 100644
--- a/board/csb472/init.S
+++ b/board/csb472/init.S
@@ -1,5 +1,5 @@
 /*
- * SPDX-License-Identifier:	GPL-2.0	ibm-pibs
+ * SPDX-License-Identifier:	GPL-2.0	IBM-pibs
  */
 #include <config.h>
 #include <asm/ppc4xx.h>
diff --git a/board/esd/pci405/writeibm.S b/board/esd/pci405/writeibm.S
index 38acca1..03eaf97 100644
--- a/board/esd/pci405/writeibm.S
+++ b/board/esd/pci405/writeibm.S
@@ -1,5 +1,5 @@
 /*
- * SPDX-License-Identifier:	GPL-2.0	ibm-pibs
+ * SPDX-License-Identifier:	GPL-2.0	IBM-pibs
  */
 /*----------------------------------------------------------------------------- */
 /* Function:     ext_bus_cntlr_init */
diff --git a/board/freescale/mx28evk/README b/board/freescale/mx28evk/README
index 524f3fc..0389a1d 100644
--- a/board/freescale/mx28evk/README
+++ b/board/freescale/mx28evk/README
@@ -29,11 +29,11 @@
 
 There are two targets for mx28evk:
 
-"make mx28evk_config"		- store enviroment variables into MMC
+"make mx28evk_config"		- store environment variables into MMC
 
 or
 
-"make mx28evk_nand_config"	- store enviroment variables into NAND flash
+"make mx28evk_nand_config"	- store environment variables into NAND flash
 
 Choose the target accordingly.
 
diff --git a/board/jse/init.S b/board/jse/init.S
index 7b918b5..4e449fe 100644
--- a/board/jse/init.S
+++ b/board/jse/init.S
@@ -1,5 +1,5 @@
 /*
- * SPDX-License-Identifier:	GPL-2.0	ibm-pibs
+ * SPDX-License-Identifier:	GPL-2.0	IBM-pibs
  */
 /*------------------------------------------------------------------------- */
 /* Function:     ext_bus_cntlr_init */
diff --git a/board/mpl/common/pci.c b/board/mpl/common/pci.c
index 6ab263a..cd969cb 100644
--- a/board/mpl/common/pci.c
+++ b/board/mpl/common/pci.c
@@ -1,5 +1,5 @@
 /*
- * SPDX-License-Identifier:	GPL-2.0	ibm-pibs
+ * SPDX-License-Identifier:	GPL-2.0	IBM-pibs
  */
 /*
  * Adapted for PIP405 03.07.01
diff --git a/board/mpl/mip405/init.S b/board/mpl/mip405/init.S
index bf886c0..642f17c 100644
--- a/board/mpl/mip405/init.S
+++ b/board/mpl/mip405/init.S
@@ -1,5 +1,5 @@
 /*
- * SPDX-License-Identifier:	GPL-2.0	ibm-pibs
+ * SPDX-License-Identifier:	GPL-2.0	IBM-pibs
  */
 /*-----------------------------------------------------------------------------
  * Function:     ext_bus_cntlr_init
diff --git a/board/mpl/pip405/init.S b/board/mpl/pip405/init.S
index 9ed2799..95fed34 100644
--- a/board/mpl/pip405/init.S
+++ b/board/mpl/pip405/init.S
@@ -1,5 +1,5 @@
 /*
- * SPDX-License-Identifier:	GPL-2.0	ibm-pibs
+ * SPDX-License-Identifier:	GPL-2.0	IBM-pibs
  */
 /*-----------------------------------------------------------------------------
  * Function:     ext_bus_cntlr_init
diff --git a/board/samsung/dts/exynos5250-smdk5250.dts b/board/samsung/dts/exynos5250-smdk5250.dts
index 1e94c7f..b1bba96 100644
--- a/board/samsung/dts/exynos5250-smdk5250.dts
+++ b/board/samsung/dts/exynos5250-smdk5250.dts
@@ -36,6 +36,7 @@
 		mmc3 = "/mmc@12230000";
 		serial0 = "/serial@12C30000";
 		console = "/serial@12C30000";
+		i2s = "/sound@3830000";
 	};
 
 	sromc@12250000 {
@@ -49,16 +50,14 @@
 		};
 	};
 
-	sound@12d60000 {
-		samsung,i2s-epll-clock-frequency = <192000000>;
-		samsung,i2s-sampling-rate = <48000>;
-		samsung,i2s-bits-per-sample = <16>;
-		samsung,i2s-channels = <2>;
-		samsung,i2s-lr-clk-framesize = <256>;
-		samsung,i2s-bit-clk-framesize = <32>;
+	sound@3830000 {
 		samsung,codec-type = "wm8994";
 	};
 
+	sound@12d60000 {
+		status = "disabled";
+	};
+
 	i2c@12c70000 {
 		soundcodec@1a {
 			reg = <0x1a>;
diff --git a/board/samsung/dts/exynos5250-snow.dts b/board/samsung/dts/exynos5250-snow.dts
index 7832e4e..9b7e57e 100644
--- a/board/samsung/dts/exynos5250-snow.dts
+++ b/board/samsung/dts/exynos5250-snow.dts
@@ -36,6 +36,7 @@
 		mmc3 = "/mmc@12230000";
 		serial0 = "/serial@12C30000";
 		console = "/serial@12C30000";
+		i2s = "/sound@3830000";
 	};
 
 	i2c4: i2c@12ca0000 {
@@ -65,16 +66,15 @@
 		};
 	};
 
-	sound@12d60000 {
-		samsung,i2s-epll-clock-frequency = <192000000>;
-		samsung,i2s-sampling-rate = <48000>;
-		samsung,i2s-bits-per-sample = <16>;
-		samsung,i2s-channels = <2>;
-		samsung,i2s-lr-clk-framesize = <256>;
-		samsung,i2s-bit-clk-framesize = <32>;
+	sound@3830000 {
 		samsung,codec-type = "max98095";
+		codec-enable-gpio = <&gpio 0xb7 0>;
 	};
 
+        sound@12d60000 {
+                status = "disabled";
+        };
+
 	i2c@12cd0000 {
 		soundcodec@22 {
 			reg = <0x22>;
diff --git a/board/sbc8349/README b/board/sbc8349/README
index 2c35919..e2d60cc 100644
--- a/board/sbc8349/README
+++ b/board/sbc8349/README
@@ -50,7 +50,7 @@
     trying to preserve your old environment settings and user flash).
   - Set the start address of the erase/flash process to FF80_0000
   - Set the target RAM required to 64kB.
-  - Select sectors for erasing (see note on enviroment below)
+  - Select sectors for erasing (see note on environment below)
   - Select Erase and Reprogram.
 
 Note that some versions of the register files used with Workbench
diff --git a/board/sc3/init.S b/board/sc3/init.S
index 9921f8f..46323d2 100644
--- a/board/sc3/init.S
+++ b/board/sc3/init.S
@@ -1,5 +1,5 @@
 /*
- * SPDX-License-Identifier:	GPL-2.0	ibm-pibs
+ * SPDX-License-Identifier:	GPL-2.0	IBM-pibs
  */
 #include <config.h>
 #include <asm/ppc4xx.h>
diff --git a/board/w7o/init.S b/board/w7o/init.S
index 490411e..54eda32 100644
--- a/board/w7o/init.S
+++ b/board/w7o/init.S
@@ -1,5 +1,5 @@
 /*
- * SPDX-License-Identifier:	GPL-2.0	ibm-pibs
+ * SPDX-License-Identifier:	GPL-2.0	IBM-pibs
  */
 #include <config.h>
 #include <asm/ppc4xx.h>
diff --git a/boards.cfg b/boards.cfg
index 80846c9..c90dddd 100644
--- a/boards.cfg
+++ b/boards.cfg
@@ -38,7 +38,7 @@
 # It can be used from a shell:
 #	tools/reformat.py -i -d '-' -s 8 <boards.cfg >boards0.cfg && mv boards0.cfg boards.cfg
 # It can directly be invoked from vim:
-#	:%tools/reformat.py -i -d '-' -s 8
+#	:%!tools/reformat.py -i -d '-' -s 8
 #
 # Status, Arch, CPU:SPLCPU, SoC, Vendor, Board name, Target, Options, Maintainers
 ###########################################################################################################
diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c
index b07b0f4..166b901 100644
--- a/common/cmd_bootm.c
+++ b/common/cmd_bootm.c
@@ -558,6 +558,7 @@
 #ifdef CONFIG_NETCONSOLE
 	/* Stop the ethernet stack if NetConsole could have left it up */
 	eth_halt();
+	eth_unregister(eth_get_dev());
 #endif
 
 #if defined(CONFIG_CMD_USB)
@@ -799,8 +800,12 @@
 
 	return do_bootm_states(cmdtp, flag, argc, argv, BOOTM_STATE_START |
 		BOOTM_STATE_FINDOS | BOOTM_STATE_FINDOTHER |
-		BOOTM_STATE_LOADOS | BOOTM_STATE_OS_PREP |
-		BOOTM_STATE_OS_FAKE_GO | BOOTM_STATE_OS_GO, &images, 1);
+		BOOTM_STATE_LOADOS |
+#if defined(CONFIG_PPC) || defined(CONFIG_MIPS)
+		BOOTM_STATE_OS_CMDLINE |
+#endif
+		BOOTM_STATE_OS_PREP | BOOTM_STATE_OS_FAKE_GO |
+		BOOTM_STATE_OS_GO, &images, 1);
 }
 
 int bootm_maybe_autostart(cmd_tbl_t *cmdtp, const char *cmd)
diff --git a/common/cmd_dfu.c b/common/cmd_dfu.c
index 793c422..7ce92ce 100644
--- a/common/cmd_dfu.c
+++ b/common/cmd_dfu.c
@@ -9,34 +9,20 @@
  */
 
 #include <common.h>
-#include <command.h>
-#include <malloc.h>
 #include <dfu.h>
-#include <asm/errno.h>
 #include <g_dnl.h>
 
 static int do_dfu(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
-	const char *str_env;
 	char *s = "dfu";
 	int ret, i = 0;
-	char *env_bkp;
 
 	if (argc < 3)
 		return CMD_RET_USAGE;
 
-	str_env = getenv("dfu_alt_info");
-	if (str_env == NULL) {
-		printf("%s: \"dfu_alt_info\" env variable not defined!\n",
-		       __func__);
-		return CMD_RET_FAILURE;
-	}
-
-	env_bkp = strdup(str_env);
-	ret = dfu_config_entities(env_bkp, argv[1],
-			    (int)simple_strtoul(argv[2], NULL, 10));
+	ret = dfu_init_env_entities(argv[1], simple_strtoul(argv[2], NULL, 10));
 	if (ret)
-		return CMD_RET_FAILURE;
+		return ret;
 
 	if (argc > 3 && strcmp(argv[3], "list") == 0) {
 		dfu_show_entities();
@@ -67,7 +53,6 @@
 	g_dnl_unregister();
 done:
 	dfu_free_entities();
-	free(env_bkp);
 
 	if (dfu_reset())
 		run_command("reset", 0);
diff --git a/common/cmd_gpt.c b/common/cmd_gpt.c
index 06767aa..a46f5cc 100644
--- a/common/cmd_gpt.c
+++ b/common/cmd_gpt.c
@@ -161,7 +161,7 @@
 	/* allocate memory for partitions */
 	parts = calloc(sizeof(disk_partition_t), p_count);
 
-	/* retrive partions data from string */
+	/* retrieve partitions data from string */
 	for (i = 0; i < p_count; i++) {
 		tok = strsep(&s, ";");
 
@@ -316,7 +316,7 @@
 
 U_BOOT_CMD(gpt, CONFIG_SYS_MAXARGS, 1, do_gpt,
 	"GUID Partition Table",
-	"<command> <interface> <dev> <partions_list>\n"
+	"<command> <interface> <dev> <partitions_list>\n"
 	" - GUID partition table restoration\n"
 	" Restore GPT information on a device connected\n"
 	" to interface\n"
diff --git a/common/cmd_mmc.c b/common/cmd_mmc.c
index 1cdeb44..67a94a7 100644
--- a/common/cmd_mmc.c
+++ b/common/cmd_mmc.c
@@ -260,7 +260,7 @@
 				if (!ret)
 					mmc->part_num = part;
 
-				printf("switch to partions #%d, %s\n",
+				printf("switch to partitions #%d, %s\n",
 						part, (!ret) ? "OK" : "ERROR");
 			}
 		}
@@ -421,7 +421,7 @@
 	"mmc close <dev> <boot_partition>\n"
 	" - Enable boot_part for booting and disable access to boot_part\n"
 	"mmc bootpart <device num> <boot part size MB> <RPMB part size MB>\n"
-	" - change sizes of boot and RPMB partions of specified device\n"
+	" - change sizes of boot and RPMB partitions of specified device\n"
 #endif
 	);
 #endif /* !CONFIG_GENERIC_MMC */
diff --git a/common/cmd_mtdparts.c b/common/cmd_mtdparts.c
index 3023479..38a6e6d 100644
--- a/common/cmd_mtdparts.c
+++ b/common/cmd_mtdparts.c
@@ -420,7 +420,7 @@
 }
 
 /**
- * Delete selected partition from the partion list of the specified device.
+ * Delete selected partition from the partition list of the specified device.
  *
  * @param dev device to delete partition from
  * @param part partition to delete
diff --git a/common/cmd_pxe.c b/common/cmd_pxe.c
index a2fb50a..c5f4a22 100644
--- a/common/cmd_pxe.c
+++ b/common/cmd_pxe.c
@@ -572,7 +572,7 @@
  * If the label specifies an 'append' line, its contents will overwrite that
  * of the 'bootargs' environment variable.
  */
-static int label_boot(struct pxe_label *label)
+static int label_boot(cmd_tbl_t *cmdtp, struct pxe_label *label)
 {
 	char *bootm_argv[] = { "bootm", NULL, NULL, NULL, NULL };
 	char initrd_str[22];
@@ -684,11 +684,11 @@
 	if (bootm_argv[3])
 		bootm_argc = 4;
 
-	do_bootm(NULL, 0, bootm_argc, bootm_argv);
+	do_bootm(cmdtp, 0, bootm_argc, bootm_argv);
 
 #ifdef CONFIG_CMD_BOOTZ
 	/* Try booting a zImage if do_bootm returns */
-	do_bootz(NULL, 0, bootm_argc, bootm_argv);
+	do_bootz(cmdtp, 0, bootm_argc, bootm_argv);
 #endif
 	return 1;
 }
@@ -1355,7 +1355,7 @@
 /*
  * Try to boot any labels we have yet to attempt to boot.
  */
-static void boot_unattempted_labels(struct pxe_menu *cfg)
+static void boot_unattempted_labels(cmd_tbl_t *cmdtp, struct pxe_menu *cfg)
 {
 	struct list_head *pos;
 	struct pxe_label *label;
@@ -1364,7 +1364,7 @@
 		label = list_entry(pos, struct pxe_label, list);
 
 		if (!label->attempted)
-			label_boot(label);
+			label_boot(cmdtp, label);
 	}
 }
 
@@ -1380,7 +1380,7 @@
  * If this function returns, there weren't any labels that successfully
  * booted, or the user interrupted the menu selection via ctrl+c.
  */
-static void handle_pxe_menu(struct pxe_menu *cfg)
+static void handle_pxe_menu(cmd_tbl_t *cmdtp, struct pxe_menu *cfg)
 {
 	void *choice;
 	struct menu *m;
@@ -1406,14 +1406,14 @@
 	 */
 
 	if (err == 1) {
-		err = label_boot(choice);
+		err = label_boot(cmdtp, choice);
 		if (!err)
 			return;
 	} else if (err != -ENOENT) {
 		return;
 	}
 
-	boot_unattempted_labels(cfg);
+	boot_unattempted_labels(cmdtp, cfg);
 }
 
 /*
@@ -1453,7 +1453,7 @@
 		return 1;
 	}
 
-	handle_pxe_menu(cfg);
+	handle_pxe_menu(cmdtp, cfg);
 
 	destroy_pxe_menu(cfg);
 
@@ -1559,7 +1559,7 @@
 	if (prompt)
 		cfg->prompt = 1;
 
-	handle_pxe_menu(cfg);
+	handle_pxe_menu(cmdtp, cfg);
 
 	destroy_pxe_menu(cfg);
 
diff --git a/common/cmd_sf.c b/common/cmd_sf.c
index 4af0f0a..3f60979 100644
--- a/common/cmd_sf.c
+++ b/common/cmd_sf.c
@@ -152,8 +152,10 @@
 {
 	debug("offset=%#x, sector_size=%#x, len=%#zx\n",
 	      offset, flash->sector_size, len);
-	if (spi_flash_read(flash, offset, len, cmp_buf))
+	/* Read the entire sector so to allow for rewriting */
+	if (spi_flash_read(flash, offset, flash->sector_size, cmp_buf))
 		return "read";
+	/* Compare only what is meaningful (len) */
 	if (memcmp(cmp_buf, buf, len) == 0) {
 		debug("Skip region %x size %zx: no change\n",
 		      offset, len);
@@ -163,8 +165,17 @@
 	/* Erase the entire sector */
 	if (spi_flash_erase(flash, offset, flash->sector_size))
 		return "erase";
+	/* Write the initial part of the block from the source */
 	if (spi_flash_write(flash, offset, len, buf))
 		return "write";
+	/* If it's a partial sector, rewrite the existing part */
+	if (len != flash->sector_size) {
+		/* Rewrite the original data to the end of the sector */
+		if (spi_flash_write(flash, offset + len,
+				    flash->sector_size - len, &cmp_buf[len]))
+			return "write";
+	}
+
 	return NULL;
 }
 
diff --git a/common/cmd_usb_mass_storage.c b/common/cmd_usb_mass_storage.c
index 33a4715..ccf7195 100644
--- a/common/cmd_usb_mass_storage.c
+++ b/common/cmd_usb_mass_storage.c
@@ -5,7 +5,6 @@
  * SPDX-License-Identifier:	GPL-2.0+
  */
 
-#include <errno.h>
 #include <common.h>
 #include <command.h>
 #include <g_dnl.h>
diff --git a/common/image-fdt.c b/common/image-fdt.c
index 2e22cca..6f9ce7d 100644
--- a/common/image-fdt.c
+++ b/common/image-fdt.c
@@ -55,7 +55,7 @@
 		fdt_error("uImage is compressed");
 		return NULL;
 	}
-	if (fdt_check_header((char *)image_get_data(fdt_hdr)) != 0) {
+	if (fdt_check_header((void *)image_get_data(fdt_hdr)) != 0) {
 		fdt_error("uImage data is not a fdt");
 		return NULL;
 	}
diff --git a/common/image-fit.c b/common/image-fit.c
index 199b4ed..cf4b67e 100644
--- a/common/image-fit.c
+++ b/common/image-fit.c
@@ -58,7 +58,7 @@
  * @conf_name double pointer to a char, will hold pointer to a configuration
  * unit name
  *
- * fit_parse_conf() expects configuration spec in the for of [<addr>]#<conf>,
+ * fit_parse_conf() expects configuration spec in the form of [<addr>]#<conf>,
  * where <addr> is a FIT image address that contains configuration
  * with a <conf> unit name.
  *
@@ -84,7 +84,7 @@
  * subimage
  * @image_name: double pointer to a char, will hold pointer to a subimage name
  *
- * fit_parse_subimage() expects subimage spec in the for of
+ * fit_parse_subimage() expects subimage spec in the form of
  * [<addr>]:<subimage>, where <addr> is a FIT image address that contains
  * subimage with a <subimg> unit name.
  *
@@ -1331,7 +1331,7 @@
  *
  * When NULL is provided in second argument fit_conf_get_node() will search
  * for a default configuration node instead. Default configuration node unit
- * name is retrived from FIT_DEFAULT_PROP property of the '/configurations'
+ * name is retrieved from FIT_DEFAULT_PROP property of the '/configurations'
  * node.
  *
  * returns:
@@ -1596,7 +1596,7 @@
 	len = (ulong)size;
 
 	/* verify that image data is a proper FDT blob */
-	if (image_type == IH_TYPE_FLATDT && fdt_check_header((char *)buf)) {
+	if (image_type == IH_TYPE_FLATDT && fdt_check_header(buf)) {
 		puts("Subimage data is not a FDT");
 		return -ENOEXEC;
 	}
diff --git a/common/image.c b/common/image.c
index 2c88091..b0ae58f 100644
--- a/common/image.c
+++ b/common/image.c
@@ -652,17 +652,13 @@
 {
 	ulong format = IMAGE_FORMAT_INVALID;
 	const image_header_t *hdr;
-#if defined(CONFIG_FIT) || defined(CONFIG_OF_LIBFDT)
-	char *fit_hdr;
-#endif
 
 	hdr = (const image_header_t *)img_addr;
 	if (image_check_magic(hdr))
 		format = IMAGE_FORMAT_LEGACY;
 #if defined(CONFIG_FIT) || defined(CONFIG_OF_LIBFDT)
 	else {
-		fit_hdr = (char *)img_addr;
-		if (fdt_check_header(fit_hdr) == 0)
+		if (fdt_check_header(img_addr) == 0)
 			format = IMAGE_FORMAT_FIT;
 	}
 #endif
@@ -965,7 +961,7 @@
  * @initrd_end: pointer to a ulong variable, will hold final init ramdisk
  *      end address (after possible relocation)
  *
- * boot_ramdisk_high() takes a relocation hint from "initrd_high" environement
+ * boot_ramdisk_high() takes a relocation hint from "initrd_high" environment
  * variable and if requested ramdisk data is moved to a specified location.
  *
  * Initrd_start and initrd_end are set to final (after relocation) ramdisk
diff --git a/common/spl/spl_mmc.c b/common/spl/spl_mmc.c
index f27b4c2..fc2f226 100644
--- a/common/spl/spl_mmc.c
+++ b/common/spl/spl_mmc.c
@@ -9,7 +9,6 @@
 #include <common.h>
 #include <spl.h>
 #include <asm/u-boot.h>
-#include <asm/utils.h>
 #include <mmc.h>
 #include <fat.h>
 #include <version.h>
@@ -45,8 +44,10 @@
 					(void *)spl_image.load_addr);
 
 end:
+#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
 	if (err == 0)
 		printf("spl: mmc blk read err - %lu\n", err);
+#endif
 
 	return (err == 0);
 }
@@ -58,7 +59,9 @@
 				       CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTOR,
 				       CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTORS,
 				       (void *)CONFIG_SYS_SPL_ARGS_ADDR)) {
+#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
 		printf("mmc args blk read error\n");
+#endif
 		return -1;
 	}
 
@@ -84,9 +87,11 @@
 	err = file_fat_read(filename, (u8 *)spl_image.load_addr, 0);
 
 end:
+#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
 	if (err <= 0)
 		printf("spl: error reading image %s, err - %d\n",
 		       filename, err);
+#endif
 
 	return (err <= 0);
 }
@@ -99,8 +104,10 @@
 	err = file_fat_read(CONFIG_SPL_FAT_LOAD_ARGS_NAME,
 			    (void *)CONFIG_SYS_SPL_ARGS_ADDR, 0);
 	if (err <= 0) {
+#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
 		printf("spl: error reading image %s, err - %d\n",
 		       CONFIG_SPL_FAT_LOAD_ARGS_NAME, err);
+#endif
 		return -1;
 	}
 
@@ -120,13 +127,17 @@
 	/* We register only one device. So, the dev id is always 0 */
 	mmc = find_mmc_device(0);
 	if (!mmc) {
+#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
 		puts("spl: mmc device not found!!\n");
+#endif
 		hang();
 	}
 
 	err = mmc_init(mmc);
 	if (err) {
+#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
 		printf("spl: mmc init failed: err - %d\n", err);
+#endif
 		hang();
 	}
 
@@ -145,7 +156,9 @@
 		err = fat_register_device(&mmc->block_dev,
 					  CONFIG_SYS_MMC_SD_FAT_BOOT_PARTITION);
 		if (err) {
+#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
 			printf("spl: fat register err - %d\n", err);
+#endif
 			hang();
 		}
 
@@ -155,7 +168,9 @@
 		err = mmc_load_image_fat(mmc, CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME);
 #endif
 	} else {
+#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
 		puts("spl: wrong MMC boot mode\n");
+#endif
 		hang();
 	}
 
diff --git a/disk/part_efi.c b/disk/part_efi.c
index b7524d6..9c33ae7 100644
--- a/disk/part_efi.c
+++ b/disk/part_efi.c
@@ -164,8 +164,9 @@
 
 	if (part > le32_to_cpu(gpt_head->num_partition_entries) ||
 	    !is_pte_valid(&gpt_pte[part - 1])) {
-		printf("%s: *** ERROR: Invalid partition number %d ***\n",
+		debug("%s: *** ERROR: Invalid partition number %d ***\n",
 			__func__, part);
+		free(gpt_pte);
 		return -1;
 	}
 
diff --git a/doc/README.hwconfig b/doc/README.hwconfig
index cf54965..b6ddb43 100644
--- a/doc/README.hwconfig
+++ b/doc/README.hwconfig
@@ -18,7 +18,7 @@
    U-Boot. But I haven't bothered yet.
 
 2. Since we don't implement a hwconfig command, i.e. we're working
-   with the environement directly, there is no way to tell that
+   with the environment directly, there is no way to tell that
    toggling a particular option will need a reboot to take
    effect. So, for now it's advised to always reboot the
    target after modifying the hwconfig variable.
diff --git a/doc/git-mailrc b/doc/git-mailrc
index 2cacaa0..251586e 100644
--- a/doc/git-mailrc
+++ b/doc/git-mailrc
@@ -18,6 +18,7 @@
 alias gruss          Graeme Russ <graeme.russ@gmail.com>
 alias hs             Heiko Schocher <hs@denx.de>
 alias iwamatsu       Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
+alias jagan	     Jagannadha Sutradharudu Teki <jagannadh.teki@gmail.com>
 alias jasonjin       Jason Jin <jason.jin@freescale.com>
 alias jhersh         Joe Hershberger <joe.hershberger@gmail.com>
 alias kimphill       Kim Phillips <kim.phillips@freescale.com>
@@ -106,5 +107,6 @@
 alias mmc            uboot, panto
 alias nand           uboot, scottwood
 alias net            uboot, jhersh
+alias spi	     uboot, jagan
 alias usb            uboot, marex
 alias video          uboot, ag
diff --git a/doc/uImage.FIT/command_syntax_extensions.txt b/doc/uImage.FIT/command_syntax_extensions.txt
index 002818c..6c99b1c 100644
--- a/doc/uImage.FIT/command_syntax_extensions.txt
+++ b/doc/uImage.FIT/command_syntax_extensions.txt
@@ -170,7 +170,7 @@
 
 In case of the new uImage argument syntax, the address portion of any argument
 can be omitted. If <addr3> is omitted, then it is assumed that image at
-<addr2> should be used. Similarly, when <addr2> is omitted, is is assumed that
+<addr2> should be used. Similarly, when <addr2> is omitted, it is assumed that
 image at <addr1> should be used. If <addr1> is omitted, it is assumed that the
 current image address is to be used. For example, consider the following
 commands:
diff --git a/doc/uImage.FIT/source_file_format.txt b/doc/uImage.FIT/source_file_format.txt
index 6d20707..160b2d0 100644
--- a/doc/uImage.FIT/source_file_format.txt
+++ b/doc/uImage.FIT/source_file_format.txt
@@ -62,7 +62,7 @@
 The following picture shows how the new uImage is prepared. Input consists of
 image source file (.its) and a set of data files. Image is created with the
 help of standard U-boot mkimage tool which in turn uses dtc (device tree
-compiler) to produce image tree blob (.itb).  Resulting .itb file is is the
+compiler) to produce image tree blob (.itb).  Resulting .itb file is the
 actual binary of a new uImage.
 
 
diff --git a/drivers/block/sym53c8xx.c b/drivers/block/sym53c8xx.c
index c538e37..6f1ac85 100644
--- a/drivers/block/sym53c8xx.c
+++ b/drivers/block/sym53c8xx.c
@@ -248,7 +248,7 @@
 
 /******************************************************************************
  * sets-up the SCSI controller
- * the base memory address is retrived via the pci_read_config_dword
+ * the base memory address is retrieved via the pci_read_config_dword
  */
 void scsi_low_level_init(int busdevfunc)
 {
diff --git a/drivers/dfu/Makefile b/drivers/dfu/Makefile
index fca370a..de9e44e 100644
--- a/drivers/dfu/Makefile
+++ b/drivers/dfu/Makefile
@@ -12,6 +12,7 @@
 COBJS-$(CONFIG_DFU_FUNCTION) += dfu.o
 COBJS-$(CONFIG_DFU_MMC) += dfu_mmc.o
 COBJS-$(CONFIG_DFU_NAND) += dfu_nand.o
+COBJS-$(CONFIG_DFU_RAM) += dfu_ram.o
 
 SRCS    := $(COBJS-y:.o=.c)
 OBJS	:= $(addprefix $(obj),$(COBJS-y))
diff --git a/drivers/dfu/dfu.c b/drivers/dfu/dfu.c
index d73d510..56b21c7 100644
--- a/drivers/dfu/dfu.c
+++ b/drivers/dfu/dfu.c
@@ -41,6 +41,29 @@
 	return ++i;
 }
 
+int dfu_init_env_entities(char *interface, int dev)
+{
+	const char *str_env;
+	char *env_bkp;
+	int ret;
+
+	str_env = getenv("dfu_alt_info");
+	if (!str_env) {
+		error("\"dfu_alt_info\" env variable not defined!\n");
+		return -EINVAL;
+	}
+
+	env_bkp = strdup(str_env);
+	ret = dfu_config_entities(env_bkp, interface, dev);
+	if (ret) {
+		error("DFU entities configuration failed!\n");
+		return ret;
+	}
+
+	free(env_bkp);
+	return 0;
+}
+
 static unsigned char *dfu_buf;
 static unsigned long dfu_buf_size = CONFIG_SYS_DFU_DATA_BUF_SIZE;
 
@@ -153,8 +176,8 @@
 
 	/* we should be in buffer now (if not then size too large) */
 	if ((dfu->i_buf + size) > dfu->i_buf_end) {
-		printf("%s: Wrong size! [%d] [%d] - %d\n",
-		       __func__, dfu->i_blk_seq_num, blk_seq_num, size);
+		error("Buffer overflow! (0x%p + 0x%x > 0x%p)\n", dfu->i_buf,
+		      size, dfu->i_buf_end);
 		return -1;
 	}
 
@@ -325,6 +348,9 @@
 	} else if (strcmp(interface, "nand") == 0) {
 		if (dfu_fill_entity_nand(dfu, s))
 			return -1;
+	} else if (strcmp(interface, "ram") == 0) {
+		if (dfu_fill_entity_ram(dfu, s))
+			return -1;
 	} else {
 		printf("%s: Device %s not (yet) supported!\n",
 		       __func__,  interface);
@@ -374,14 +400,14 @@
 
 const char *dfu_get_dev_type(enum dfu_device_type t)
 {
-	const char *dev_t[] = {NULL, "eMMC", "OneNAND", "NAND" };
+	const char *dev_t[] = {NULL, "eMMC", "OneNAND", "NAND", "RAM" };
 	return dev_t[t];
 }
 
 const char *dfu_get_layout(enum dfu_layout l)
 {
 	const char *dfu_layout[] = {NULL, "RAW_ADDR", "FAT", "EXT2",
-					   "EXT3", "EXT4" };
+					   "EXT3", "EXT4", "RAM_ADDR" };
 	return dfu_layout[l];
 }
 
diff --git a/drivers/dfu/dfu_mmc.c b/drivers/dfu/dfu_mmc.c
index 0871a77..f942758 100644
--- a/drivers/dfu/dfu_mmc.c
+++ b/drivers/dfu/dfu_mmc.c
@@ -13,16 +13,11 @@
 #include <div64.h>
 #include <dfu.h>
 
-enum dfu_mmc_op {
-	DFU_OP_READ = 1,
-	DFU_OP_WRITE,
-};
-
 static unsigned char __aligned(CONFIG_SYS_CACHELINE_SIZE)
 				dfu_file_buf[CONFIG_SYS_DFU_MAX_FILE_SIZE];
 static long dfu_file_buf_len;
 
-static int mmc_block_op(enum dfu_mmc_op op, struct dfu_entity *dfu,
+static int mmc_block_op(enum dfu_op op, struct dfu_entity *dfu,
 			u64 offset, void *buf, long *len)
 {
 	char cmd_buf[DFU_CMD_BUF_SIZE];
@@ -65,7 +60,7 @@
 	return 0;
 }
 
-static int mmc_file_op(enum dfu_mmc_op op, struct dfu_entity *dfu,
+static int mmc_file_op(enum dfu_op op, struct dfu_entity *dfu,
 			void *buf, long *len)
 {
 	char cmd_buf[DFU_CMD_BUF_SIZE];
diff --git a/drivers/dfu/dfu_nand.c b/drivers/dfu/dfu_nand.c
index 0ec12cf..edbf5a9 100644
--- a/drivers/dfu/dfu_nand.c
+++ b/drivers/dfu/dfu_nand.c
@@ -19,12 +19,7 @@
 #include <jffs2/load_kernel.h>
 #include <nand.h>
 
-enum dfu_nand_op {
-	DFU_OP_READ = 1,
-	DFU_OP_WRITE,
-};
-
-static int nand_block_op(enum dfu_nand_op op, struct dfu_entity *dfu,
+static int nand_block_op(enum dfu_op op, struct dfu_entity *dfu,
 			u64 offset, void *buf, long *len)
 {
 	loff_t start, lim;
diff --git a/drivers/dfu/dfu_ram.c b/drivers/dfu/dfu_ram.c
new file mode 100644
index 0000000..335a8e1
--- /dev/null
+++ b/drivers/dfu/dfu_ram.c
@@ -0,0 +1,77 @@
+/*
+ * (C) Copyright 2013
+ * Afzal Mohammed <afzal.mohd.ma@gmail.com>
+ *
+ * Reference: dfu_mmc.c
+ * Copyright (C) 2012 Samsung Electronics
+ * author: Lukasz Majewski <l.majewski@samsung.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <errno.h>
+#include <dfu.h>
+
+static int dfu_transfer_medium_ram(enum dfu_op op, struct dfu_entity *dfu,
+				   u64 offset, void *buf, long *len)
+{
+	if (dfu->layout != DFU_RAM_ADDR) {
+		error("unsupported layout: %s\n", dfu_get_layout(dfu->layout));
+		return  -EINVAL;
+	}
+
+	if (offset > dfu->data.ram.size) {
+		error("request exceeds allowed area\n");
+		return -EINVAL;
+	}
+
+	if (op == DFU_OP_WRITE)
+		memcpy(dfu->data.ram.start + offset, buf, *len);
+	else
+		memcpy(buf, dfu->data.ram.start + offset, *len);
+
+	return 0;
+}
+
+static int dfu_write_medium_ram(struct dfu_entity *dfu, u64 offset,
+				void *buf, long *len)
+{
+	return dfu_transfer_medium_ram(DFU_OP_WRITE, dfu, offset, buf, len);
+}
+
+static int dfu_read_medium_ram(struct dfu_entity *dfu, u64 offset,
+			       void *buf, long *len)
+{
+	if (!*len) {
+		*len = dfu->data.ram.size;
+		return 0;
+	}
+
+	return dfu_transfer_medium_ram(DFU_OP_READ, dfu, offset, buf, len);
+}
+
+int dfu_fill_entity_ram(struct dfu_entity *dfu, char *s)
+{
+	char *st;
+
+	dfu->dev_type = DFU_DEV_RAM;
+	st = strsep(&s, " ");
+	if (strcmp(st, "ram")) {
+		error("unsupported device: %s\n", st);
+		return -ENODEV;
+	}
+
+	dfu->layout = DFU_RAM_ADDR;
+	dfu->data.ram.start = (void *)simple_strtoul(s, &s, 16);
+	s++;
+	dfu->data.ram.size = simple_strtoul(s, &s, 16);
+
+	dfu->write_medium = dfu_write_medium_ram;
+	dfu->read_medium = dfu_read_medium_ram;
+
+	dfu->inited = 0;
+
+	return 0;
+}
diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
index bedf833..06280d1 100644
--- a/drivers/mmc/Makefile
+++ b/drivers/mmc/Makefile
@@ -34,6 +34,8 @@
 COBJS-$(CONFIG_ZYNQ_SDHCI) += zynq_sdhci.o
 ifdef CONFIG_SPL_BUILD
 COBJS-$(CONFIG_SPL_MMC_BOOT) += fsl_esdhc_spl.o
+else
+COBJS-$(CONFIG_GENERIC_MMC) += mmc_write.o
 endif
 
 COBJS	:= $(COBJS-y)
diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c
index a82ee17..9a803a0 100644
--- a/drivers/mmc/dw_mmc.c
+++ b/drivers/mmc/dw_mmc.c
@@ -41,12 +41,11 @@
 }
 
 static void dwmci_prepare_data(struct dwmci_host *host,
-		struct mmc_data *data)
+		struct mmc_data *data, struct dwmci_idmac *cur_idmac)
 {
 	unsigned long ctrl;
 	unsigned int i = 0, flags, cnt, blk_cnt;
 	ulong data_start, data_end, start_addr;
-	ALLOC_CACHE_ALIGN_BUFFER(struct dwmci_idmac, cur_idmac, data->blocks);
 
 
 	blk_cnt = data->blocks;
@@ -73,7 +72,7 @@
 		dwmci_set_idma_desc(cur_idmac, flags, cnt,
 				start_addr + (i * PAGE_SIZE));
 
-		if(blk_cnt < 8)
+		if (blk_cnt <= 8)
 			break;
 		blk_cnt -= 8;
 		cur_idmac++;
@@ -111,6 +110,8 @@
 		struct mmc_data *data)
 {
 	struct dwmci_host *host = (struct dwmci_host *)mmc->priv;
+	ALLOC_CACHE_ALIGN_BUFFER(struct dwmci_idmac, cur_idmac,
+				 data ? DIV_ROUND_UP(data->blocks, 8) : 0);
 	int flags = 0, i;
 	unsigned int timeout = 100000;
 	u32 retry = 10000;
@@ -127,7 +128,7 @@
 	dwmci_writel(host, DWMCI_RINTSTS, DWMCI_INTMSK_ALL);
 
 	if (data)
-		dwmci_prepare_data(host, data);
+		dwmci_prepare_data(host, data, cur_idmac);
 
 	dwmci_writel(host, DWMCI_CMDARG, cmd->cmdarg);
 
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 5502675..84dae4d 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -15,6 +15,7 @@
 #include <malloc.h>
 #include <linux/list.h>
 #include <div64.h>
+#include "mmc_private.h"
 
 /* Set block count limit because of 16 bit register limit on some hardware*/
 #ifndef CONFIG_SYS_MMC_MAX_BLK_COUNT
@@ -52,14 +53,10 @@
 int board_mmc_getcd(struct mmc *mmc)__attribute__((weak,
 	alias("__board_mmc_getcd")));
 
-static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
-			struct mmc_data *data)
+int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
 {
-	struct mmc_data backup;
 	int ret;
 
-	memset(&backup, 0, sizeof(backup));
-
 #ifdef CONFIG_MMC_TRACE
 	int i;
 	u8 *ptr;
@@ -114,7 +111,7 @@
 	return ret;
 }
 
-static int mmc_send_status(struct mmc *mmc, int timeout)
+int mmc_send_status(struct mmc *mmc, int timeout)
 {
 	struct mmc_cmd cmd;
 	int err, retries = 5;
@@ -135,8 +132,10 @@
 			     MMC_STATE_PRG)
 				break;
 			else if (cmd.response[0] & MMC_STATUS_MASK) {
+#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
 				printf("Status Error: 0x%08X\n",
 					cmd.response[0]);
+#endif
 				return COMM_ERR;
 			}
 		} else if (--retries < 0)
@@ -151,14 +150,16 @@
 	printf("CURR STATE:%d\n", status);
 #endif
 	if (timeout <= 0) {
+#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
 		printf("Timeout waiting card ready\n");
+#endif
 		return TIMEOUT;
 	}
 
 	return 0;
 }
 
-static int mmc_set_blocklen(struct mmc *mmc, int len)
+int mmc_set_blocklen(struct mmc *mmc, int len)
 {
 	struct mmc_cmd cmd;
 
@@ -181,179 +182,13 @@
 			return m;
 	}
 
+#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
 	printf("MMC Device %d not found\n", dev_num);
+#endif
 
 	return NULL;
 }
 
-static ulong mmc_erase_t(struct mmc *mmc, ulong start, lbaint_t blkcnt)
-{
-	struct mmc_cmd cmd;
-	ulong end;
-	int err, start_cmd, end_cmd;
-
-	if (mmc->high_capacity)
-		end = start + blkcnt - 1;
-	else {
-		end = (start + blkcnt - 1) * mmc->write_bl_len;
-		start *= mmc->write_bl_len;
-	}
-
-	if (IS_SD(mmc)) {
-		start_cmd = SD_CMD_ERASE_WR_BLK_START;
-		end_cmd = SD_CMD_ERASE_WR_BLK_END;
-	} else {
-		start_cmd = MMC_CMD_ERASE_GROUP_START;
-		end_cmd = MMC_CMD_ERASE_GROUP_END;
-	}
-
-	cmd.cmdidx = start_cmd;
-	cmd.cmdarg = start;
-	cmd.resp_type = MMC_RSP_R1;
-
-	err = mmc_send_cmd(mmc, &cmd, NULL);
-	if (err)
-		goto err_out;
-
-	cmd.cmdidx = end_cmd;
-	cmd.cmdarg = end;
-
-	err = mmc_send_cmd(mmc, &cmd, NULL);
-	if (err)
-		goto err_out;
-
-	cmd.cmdidx = MMC_CMD_ERASE;
-	cmd.cmdarg = SECURE_ERASE;
-	cmd.resp_type = MMC_RSP_R1b;
-
-	err = mmc_send_cmd(mmc, &cmd, NULL);
-	if (err)
-		goto err_out;
-
-	return 0;
-
-err_out:
-	puts("mmc erase failed\n");
-	return err;
-}
-
-static unsigned long
-mmc_berase(int dev_num, lbaint_t start, lbaint_t blkcnt)
-{
-	int err = 0;
-	struct mmc *mmc = find_mmc_device(dev_num);
-	lbaint_t blk = 0, blk_r = 0;
-	int timeout = 1000;
-
-	if (!mmc)
-		return -1;
-
-	if ((start % mmc->erase_grp_size) || (blkcnt % mmc->erase_grp_size))
-		printf("\n\nCaution! Your devices Erase group is 0x%x\n"
-		       "The erase range would be change to "
-		       "0x" LBAF "~0x" LBAF "\n\n",
-		       mmc->erase_grp_size, start & ~(mmc->erase_grp_size - 1),
-		       ((start + blkcnt + mmc->erase_grp_size)
-		       & ~(mmc->erase_grp_size - 1)) - 1);
-
-	while (blk < blkcnt) {
-		blk_r = ((blkcnt - blk) > mmc->erase_grp_size) ?
-			mmc->erase_grp_size : (blkcnt - blk);
-		err = mmc_erase_t(mmc, start + blk, blk_r);
-		if (err)
-			break;
-
-		blk += blk_r;
-
-		/* Waiting for the ready status */
-		if (mmc_send_status(mmc, timeout))
-			return 0;
-	}
-
-	return blk;
-}
-
-static ulong
-mmc_write_blocks(struct mmc *mmc, lbaint_t start, lbaint_t blkcnt, const void*src)
-{
-	struct mmc_cmd cmd;
-	struct mmc_data data;
-	int timeout = 1000;
-
-	if ((start + blkcnt) > mmc->block_dev.lba) {
-		printf("MMC: block number 0x" LBAF " exceeds max(0x" LBAF ")\n",
-			start + blkcnt, mmc->block_dev.lba);
-		return 0;
-	}
-
-	if (blkcnt == 0)
-		return 0;
-	else if (blkcnt == 1)
-		cmd.cmdidx = MMC_CMD_WRITE_SINGLE_BLOCK;
-	else
-		cmd.cmdidx = MMC_CMD_WRITE_MULTIPLE_BLOCK;
-
-	if (mmc->high_capacity)
-		cmd.cmdarg = start;
-	else
-		cmd.cmdarg = start * mmc->write_bl_len;
-
-	cmd.resp_type = MMC_RSP_R1;
-
-	data.src = src;
-	data.blocks = blkcnt;
-	data.blocksize = mmc->write_bl_len;
-	data.flags = MMC_DATA_WRITE;
-
-	if (mmc_send_cmd(mmc, &cmd, &data)) {
-		printf("mmc write failed\n");
-		return 0;
-	}
-
-	/* SPI multiblock writes terminate using a special
-	 * token, not a STOP_TRANSMISSION request.
-	 */
-	if (!mmc_host_is_spi(mmc) && blkcnt > 1) {
-		cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION;
-		cmd.cmdarg = 0;
-		cmd.resp_type = MMC_RSP_R1b;
-		if (mmc_send_cmd(mmc, &cmd, NULL)) {
-			printf("mmc fail to send stop cmd\n");
-			return 0;
-		}
-	}
-
-	/* Waiting for the ready status */
-	if (mmc_send_status(mmc, timeout))
-		return 0;
-
-	return blkcnt;
-}
-
-static ulong
-mmc_bwrite(int dev_num, lbaint_t start, lbaint_t blkcnt, const void*src)
-{
-	lbaint_t cur, blocks_todo = blkcnt;
-
-	struct mmc *mmc = find_mmc_device(dev_num);
-	if (!mmc)
-		return 0;
-
-	if (mmc_set_blocklen(mmc, mmc->write_bl_len))
-		return 0;
-
-	do {
-		cur = (blocks_todo > mmc->b_max) ?  mmc->b_max : blocks_todo;
-		if(mmc_write_blocks(mmc, start, cur, src) != cur)
-			return 0;
-		blocks_todo -= cur;
-		start += cur;
-		src += cur * mmc->write_bl_len;
-	} while (blocks_todo > 0);
-
-	return blkcnt;
-}
-
 static int mmc_read_blocks(struct mmc *mmc, void *dst, lbaint_t start,
 			   lbaint_t blkcnt)
 {
@@ -385,7 +220,9 @@
 		cmd.cmdarg = 0;
 		cmd.resp_type = MMC_RSP_R1b;
 		if (mmc_send_cmd(mmc, &cmd, NULL)) {
+#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
 			printf("mmc fail to send stop cmd\n");
+#endif
 			return 0;
 		}
 	}
@@ -405,8 +242,10 @@
 		return 0;
 
 	if ((start + blkcnt) > mmc->block_dev.lba) {
+#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
 		printf("MMC: block number 0x" LBAF " exceeds max(0x" LBAF ")\n",
 			start + blkcnt, mmc->block_dev.lba);
+#endif
 		return 0;
 	}
 
@@ -1268,6 +1107,7 @@
 	mmc->block_dev.blksz = mmc->read_bl_len;
 	mmc->block_dev.log2blksz = LOG2(mmc->block_dev.blksz);
 	mmc->block_dev.lba = lldiv(mmc->capacity, mmc->read_bl_len);
+#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
 	sprintf(mmc->block_dev.vendor, "Man %06x Snr %04x%04x",
 		mmc->cid[0] >> 24, (mmc->cid[2] & 0xffff),
 		(mmc->cid[3] >> 16) & 0xffff);
@@ -1277,6 +1117,11 @@
 		(mmc->cid[2] >> 24) & 0xff);
 	sprintf(mmc->block_dev.revision, "%d.%d", (mmc->cid[2] >> 20) & 0xf,
 		(mmc->cid[2] >> 16) & 0xf);
+#else
+	mmc->block_dev.vendor[0] = 0;
+	mmc->block_dev.product[0] = 0;
+	mmc->block_dev.revision[0] = 0;
+#endif
 #if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBDISK_SUPPORT)
 	init_part(&mmc->block_dev);
 #endif
@@ -1343,7 +1188,9 @@
 
 	if (mmc_getcd(mmc) == 0) {
 		mmc->has_init = 0;
+#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
 		printf("MMC: no card present\n");
+#endif
 		return NO_CARD_ERR;
 	}
 
@@ -1378,7 +1225,9 @@
 		err = mmc_send_op_cond(mmc);
 
 		if (err && err != IN_PROGRESS) {
+#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
 			printf("Card did not respond to voltage select!\n");
+#endif
 			return UNUSABLE_ERR;
 		}
 	}
@@ -1434,6 +1283,8 @@
 int cpu_mmc_init(bd_t *bis) __attribute__((weak, alias("__def_mmc_init")));
 int board_mmc_init(bd_t *bis) __attribute__((weak, alias("__def_mmc_init")));
 
+#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
+
 void print_mmc_devices(char separator)
 {
 	struct mmc *m;
@@ -1451,6 +1302,10 @@
 	printf("\n");
 }
 
+#else
+void print_mmc_devices(char separator) { }
+#endif
+
 int get_mmc_num(void)
 {
 	return cur_dev_num;
diff --git a/drivers/mmc/mmc_private.h b/drivers/mmc/mmc_private.h
new file mode 100644
index 0000000..16dcf9f
--- /dev/null
+++ b/drivers/mmc/mmc_private.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2008,2010 Freescale Semiconductor, Inc
+ * Andy Fleming
+ *
+ * Based (loosely) on the Linux code
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef _MMC_PRIVATE_H_
+#define _MMC_PRIVATE_H_
+
+#include <mmc.h>
+
+extern int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
+			struct mmc_data *data);
+extern int mmc_send_status(struct mmc *mmc, int timeout);
+extern int mmc_set_blocklen(struct mmc *mmc, int len);
+
+#ifndef CONFIG_SPL_BUILD
+
+extern unsigned long mmc_berase(int dev_num, lbaint_t start, lbaint_t blkcnt);
+
+extern ulong mmc_bwrite(int dev_num, lbaint_t start, lbaint_t blkcnt,
+		const void *src);
+
+#else /* CONFIG_SPL_BUILD */
+
+/* SPL will never write or erase, declare dummies to reduce code size. */
+
+static inline unsigned long mmc_berase(int dev_num, lbaint_t start,
+		lbaint_t blkcnt)
+{
+	return 0;
+}
+
+static inline ulong mmc_bwrite(int dev_num, lbaint_t start, lbaint_t blkcnt,
+		const void *src)
+{
+	return 0;
+}
+
+#endif /* CONFIG_SPL_BUILD */
+
+#endif /* _MMC_PRIVATE_H_ */
diff --git a/drivers/mmc/mmc_write.c b/drivers/mmc/mmc_write.c
new file mode 100644
index 0000000..aa2fdef
--- /dev/null
+++ b/drivers/mmc/mmc_write.c
@@ -0,0 +1,179 @@
+/*
+ * Copyright 2008, Freescale Semiconductor, Inc
+ * Andy Fleming
+ *
+ * Based vaguely on the Linux code
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <config.h>
+#include <common.h>
+#include <part.h>
+#include "mmc_private.h"
+
+static ulong mmc_erase_t(struct mmc *mmc, ulong start, lbaint_t blkcnt)
+{
+	struct mmc_cmd cmd;
+	ulong end;
+	int err, start_cmd, end_cmd;
+
+	if (mmc->high_capacity) {
+		end = start + blkcnt - 1;
+	} else {
+		end = (start + blkcnt - 1) * mmc->write_bl_len;
+		start *= mmc->write_bl_len;
+	}
+
+	if (IS_SD(mmc)) {
+		start_cmd = SD_CMD_ERASE_WR_BLK_START;
+		end_cmd = SD_CMD_ERASE_WR_BLK_END;
+	} else {
+		start_cmd = MMC_CMD_ERASE_GROUP_START;
+		end_cmd = MMC_CMD_ERASE_GROUP_END;
+	}
+
+	cmd.cmdidx = start_cmd;
+	cmd.cmdarg = start;
+	cmd.resp_type = MMC_RSP_R1;
+
+	err = mmc_send_cmd(mmc, &cmd, NULL);
+	if (err)
+		goto err_out;
+
+	cmd.cmdidx = end_cmd;
+	cmd.cmdarg = end;
+
+	err = mmc_send_cmd(mmc, &cmd, NULL);
+	if (err)
+		goto err_out;
+
+	cmd.cmdidx = MMC_CMD_ERASE;
+	cmd.cmdarg = SECURE_ERASE;
+	cmd.resp_type = MMC_RSP_R1b;
+
+	err = mmc_send_cmd(mmc, &cmd, NULL);
+	if (err)
+		goto err_out;
+
+	return 0;
+
+err_out:
+	puts("mmc erase failed\n");
+	return err;
+}
+
+unsigned long mmc_berase(int dev_num, lbaint_t start, lbaint_t blkcnt)
+{
+	int err = 0;
+	struct mmc *mmc = find_mmc_device(dev_num);
+	lbaint_t blk = 0, blk_r = 0;
+	int timeout = 1000;
+
+	if (!mmc)
+		return -1;
+
+	if ((start % mmc->erase_grp_size) || (blkcnt % mmc->erase_grp_size))
+		printf("\n\nCaution! Your devices Erase group is 0x%x\n"
+		       "The erase range would be change to "
+		       "0x" LBAF "~0x" LBAF "\n\n",
+		       mmc->erase_grp_size, start & ~(mmc->erase_grp_size - 1),
+		       ((start + blkcnt + mmc->erase_grp_size)
+		       & ~(mmc->erase_grp_size - 1)) - 1);
+
+	while (blk < blkcnt) {
+		blk_r = ((blkcnt - blk) > mmc->erase_grp_size) ?
+			mmc->erase_grp_size : (blkcnt - blk);
+		err = mmc_erase_t(mmc, start + blk, blk_r);
+		if (err)
+			break;
+
+		blk += blk_r;
+
+		/* Waiting for the ready status */
+		if (mmc_send_status(mmc, timeout))
+			return 0;
+	}
+
+	return blk;
+}
+
+static ulong mmc_write_blocks(struct mmc *mmc, lbaint_t start,
+		lbaint_t blkcnt, const void *src)
+{
+	struct mmc_cmd cmd;
+	struct mmc_data data;
+	int timeout = 1000;
+
+	if ((start + blkcnt) > mmc->block_dev.lba) {
+		printf("MMC: block number 0x" LBAF " exceeds max(0x" LBAF ")\n",
+		       start + blkcnt, mmc->block_dev.lba);
+		return 0;
+	}
+
+	if (blkcnt == 0)
+		return 0;
+	else if (blkcnt == 1)
+		cmd.cmdidx = MMC_CMD_WRITE_SINGLE_BLOCK;
+	else
+		cmd.cmdidx = MMC_CMD_WRITE_MULTIPLE_BLOCK;
+
+	if (mmc->high_capacity)
+		cmd.cmdarg = start;
+	else
+		cmd.cmdarg = start * mmc->write_bl_len;
+
+	cmd.resp_type = MMC_RSP_R1;
+
+	data.src = src;
+	data.blocks = blkcnt;
+	data.blocksize = mmc->write_bl_len;
+	data.flags = MMC_DATA_WRITE;
+
+	if (mmc_send_cmd(mmc, &cmd, &data)) {
+		printf("mmc write failed\n");
+		return 0;
+	}
+
+	/* SPI multiblock writes terminate using a special
+	 * token, not a STOP_TRANSMISSION request.
+	 */
+	if (!mmc_host_is_spi(mmc) && blkcnt > 1) {
+		cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION;
+		cmd.cmdarg = 0;
+		cmd.resp_type = MMC_RSP_R1b;
+		if (mmc_send_cmd(mmc, &cmd, NULL)) {
+			printf("mmc fail to send stop cmd\n");
+			return 0;
+		}
+	}
+
+	/* Waiting for the ready status */
+	if (mmc_send_status(mmc, timeout))
+		return 0;
+
+	return blkcnt;
+}
+
+ulong mmc_bwrite(int dev_num, lbaint_t start, lbaint_t blkcnt, const void *src)
+{
+	lbaint_t cur, blocks_todo = blkcnt;
+
+	struct mmc *mmc = find_mmc_device(dev_num);
+	if (!mmc)
+		return 0;
+
+	if (mmc_set_blocklen(mmc, mmc->write_bl_len))
+		return 0;
+
+	do {
+		cur = (blocks_todo > mmc->b_max) ?  mmc->b_max : blocks_todo;
+		if (mmc_write_blocks(mmc, start, cur, src) != cur)
+			return 0;
+		blocks_todo -= cur;
+		start += cur;
+		src += cur * mmc->write_bl_len;
+	} while (blocks_todo > 0);
+
+	return blkcnt;
+}
diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c
index 975b2c5..d3a8b53 100644
--- a/drivers/mmc/omap_hsmmc.c
+++ b/drivers/mmc/omap_hsmmc.c
@@ -288,6 +288,30 @@
 
 	mmc_reg_out(&mmc_base->sysctl, bit, bit);
 
+	/*
+	 * CMD(DAT) lines reset procedures are slightly different
+	 * for OMAP3 and OMAP4(AM335x,OMAP5,DRA7xx).
+	 * According to OMAP3 TRM:
+	 * Set SRC(SRD) bit in MMCHS_SYSCTL register to 0x1 and wait until it
+	 * returns to 0x0.
+	 * According to OMAP4(AM335x,OMAP5,DRA7xx) TRMs, CMD(DATA) lines reset
+	 * procedure steps must be as follows:
+	 * 1. Initiate CMD(DAT) line reset by writing 0x1 to SRC(SRD) bit in
+	 *    MMCHS_SYSCTL register (SD_SYSCTL for AM335x).
+	 * 2. Poll the SRC(SRD) bit until it is set to 0x1.
+	 * 3. Wait until the SRC (SRD) bit returns to 0x0
+	 *    (reset procedure is completed).
+	 */
+#if defined(CONFIG_OMAP44XX) || defined(CONFIG_OMAP54XX) || \
+	defined(CONFIG_AM33XX)
+	if (!(readl(&mmc_base->sysctl) & bit)) {
+		start = get_timer(0);
+		while (!(readl(&mmc_base->sysctl) & bit)) {
+			if (get_timer(0) - start > MAX_RETRY_MS)
+				return;
+		}
+	}
+#endif
 	start = get_timer(0);
 	while ((readl(&mmc_base->sysctl) & bit) != 0) {
 		if (get_timer(0) - start > MAX_RETRY_MS) {
@@ -376,6 +400,7 @@
 	}
 
 	writel(cmd->cmdarg, &mmc_base->arg);
+	udelay(20);		/* To fix "No status update" error on eMMC */
 	writel((cmd->cmdidx << 24) | flags, &mmc_base->cmd);
 
 	start = get_timer(0);
@@ -480,7 +505,7 @@
 	unsigned int count;
 
 	/*
-	 * Start Polled Read
+	 * Start Polled Write
 	 */
 	count = (size > MMCSD_SECTOR_SIZE) ? MMCSD_SECTOR_SIZE : size;
 	count /= 4;
@@ -586,6 +611,8 @@
 {
 	struct mmc *mmc = &hsmmc_dev[dev_index];
 	struct omap_hsmmc_data *priv_data = &hsmmc_dev_data[dev_index];
+	uint host_caps_val = MMC_MODE_4BIT | MMC_MODE_HS_52MHz | MMC_MODE_HS |
+			     MMC_MODE_HC;
 
 	sprintf(mmc->name, "OMAP SD/MMC");
 	mmc->send_cmd = mmc_send_cmd;
@@ -600,11 +627,20 @@
 #ifdef OMAP_HSMMC2_BASE
 	case 1:
 		priv_data->base_addr = (struct hsmmc *)OMAP_HSMMC2_BASE;
+#if (defined(CONFIG_OMAP44XX) || defined(CONFIG_OMAP54XX) || \
+     defined(CONFIG_DRA7XX)) && defined(CONFIG_HSMMC2_8BIT)
+		/* Enable 8-bit interface for eMMC on OMAP4/5 or DRA7XX */
+		host_caps_val |= MMC_MODE_8BIT;
+#endif
 		break;
 #endif
 #ifdef OMAP_HSMMC3_BASE
 	case 2:
 		priv_data->base_addr = (struct hsmmc *)OMAP_HSMMC3_BASE;
+#if defined(CONFIG_DRA7XX) && defined(CONFIG_HSMMC3_8BIT)
+		/* Enable 8-bit interface for eMMC on DRA7XX */
+		host_caps_val |= MMC_MODE_8BIT;
+#endif
 		break;
 #endif
 	default:
@@ -620,8 +656,7 @@
 		mmc->getwp = omap_mmc_getwp;
 
 	mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
-	mmc->host_caps = (MMC_MODE_4BIT | MMC_MODE_HS_52MHz | MMC_MODE_HS |
-				MMC_MODE_HC) & ~host_caps_mask;
+	mmc->host_caps = host_caps_val & ~host_caps_mask;
 
 	mmc->f_min = 400000;
 
diff --git a/drivers/mmc/s5p_sdhci.c b/drivers/mmc/s5p_sdhci.c
index 7f89403..40ff873 100644
--- a/drivers/mmc/s5p_sdhci.c
+++ b/drivers/mmc/s5p_sdhci.c
@@ -72,7 +72,7 @@
 
 	host->quirks = SDHCI_QUIRK_NO_HISPD_BIT | SDHCI_QUIRK_BROKEN_VOLTAGE |
 		SDHCI_QUIRK_BROKEN_R1B | SDHCI_QUIRK_32BIT_DMA_ADDR |
-		SDHCI_QUIRK_WAIT_SEND_CMD;
+		SDHCI_QUIRK_WAIT_SEND_CMD | SDHCI_QUIRK_USE_WIDE8;
 	host->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
 	host->version = sdhci_readw(host, SDHCI_HOST_VERSION);
 
@@ -81,6 +81,8 @@
 	host->index = index;
 
 	host->host_caps = MMC_MODE_HC;
+	if (bus_width == 8)
+		host->host_caps |= MMC_MODE_8BIT;
 
 	return add_sdhci(host, 52000000, 400000);
 }
diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c
index 4261991..dfb2eee 100644
--- a/drivers/mmc/sdhci.c
+++ b/drivers/mmc/sdhci.c
@@ -68,10 +68,9 @@
 	unsigned int stat, rdy, mask, timeout, block = 0;
 #ifdef CONFIG_MMC_SDMA
 	unsigned char ctrl;
-	ctrl = sdhci_readl(host, SDHCI_HOST_CONTROL);
+	ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
 	ctrl &= ~SDHCI_CTRL_DMA_MASK;
-	ctrl |= SDHCI_CTRL_SDMA;
-	sdhci_writel(host, ctrl, SDHCI_HOST_CONTROL);
+	sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
 #endif
 
 	timeout = 1000000;
@@ -254,7 +253,7 @@
 	if (clock == 0)
 		return 0;
 
-	if ((host->version & SDHCI_SPEC_VER_MASK) >= SDHCI_SPEC_300) {
+	if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300) {
 		/* Version 3.00 divisors must be a multiple of 2. */
 		if (mmc->f_max <= clock)
 			div = 1;
@@ -347,10 +346,11 @@
 	ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
 	if (mmc->bus_width == 8) {
 		ctrl &= ~SDHCI_CTRL_4BITBUS;
-		if ((host->version & SDHCI_SPEC_VER_MASK) >= SDHCI_SPEC_300)
+		if ((SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300) ||
+				(host->quirks & SDHCI_QUIRK_USE_WIDE8))
 			ctrl |= SDHCI_CTRL_8BITBUS;
 	} else {
-		if ((host->version & SDHCI_SPEC_VER_MASK) >= SDHCI_SPEC_300)
+		if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300)
 			ctrl &= ~SDHCI_CTRL_8BITBUS;
 		if (mmc->bus_width == 4)
 			ctrl |= SDHCI_CTRL_4BITBUS;
@@ -437,7 +437,7 @@
 	if (max_clk)
 		mmc->f_max = max_clk;
 	else {
-		if ((host->version & SDHCI_SPEC_VER_MASK) >= SDHCI_SPEC_300)
+		if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300)
 			mmc->f_max = (caps & SDHCI_CLOCK_V3_BASE_MASK)
 				>> SDHCI_CLOCK_BASE_SHIFT;
 		else
@@ -452,7 +452,7 @@
 	if (min_clk)
 		mmc->f_min = min_clk;
 	else {
-		if ((host->version & SDHCI_SPEC_VER_MASK) >= SDHCI_SPEC_300)
+		if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300)
 			mmc->f_min = mmc->f_max / SDHCI_MAX_DIV_SPEC_300;
 		else
 			mmc->f_min = mmc->f_max / SDHCI_MAX_DIV_SPEC_200;
@@ -470,7 +470,7 @@
 		mmc->voltages |= host->voltages;
 
 	mmc->host_caps = MMC_MODE_HS | MMC_MODE_HS_52MHz | MMC_MODE_4BIT;
-	if ((host->version & SDHCI_SPEC_VER_MASK) >= SDHCI_SPEC_300) {
+	if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300) {
 		if (caps & SDHCI_CAN_DO_8BIT)
 			mmc->host_caps |= MMC_MODE_8BIT;
 	}
diff --git a/drivers/net/4xx_enet.c b/drivers/net/4xx_enet.c
index c98867d..381ec42 100644
--- a/drivers/net/4xx_enet.c
+++ b/drivers/net/4xx_enet.c
@@ -1,5 +1,5 @@
 /*
- * SPDX-License-Identifier:	GPL-2.0	ibm-pibs
+ * SPDX-License-Identifier:	GPL-2.0	IBM-pibs
  */
 /*-----------------------------------------------------------------------------+
  *
diff --git a/drivers/net/npe/miiphy.c b/drivers/net/npe/miiphy.c
index 07fcb60..002fb81 100644
--- a/drivers/net/npe/miiphy.c
+++ b/drivers/net/npe/miiphy.c
@@ -1,5 +1,5 @@
 /*
- * SPDX-License-Identifier:	GPL-2.0	ibm-pibs
+ * SPDX-License-Identifier:	GPL-2.0	IBM-pibs
  */
 /*-----------------------------------------------------------------------------+
   |
diff --git a/drivers/net/phy/smsc.c b/drivers/net/phy/smsc.c
index 5936f9b..60ed92d 100644
--- a/drivers/net/phy/smsc.c
+++ b/drivers/net/phy/smsc.c
@@ -7,7 +7,7 @@
  *   Copyright 2010-2011 Freescale Semiconductor, Inc.
  *   author Andy Fleming
  *
- * Some code get from linux kenrel
+ * Some code copied from linux kernel
  * Copyright (c) 2006 Herbert Valerio Riedel <hvr@gnu.org>
  */
 #include <miiphy.h>
diff --git a/drivers/sound/max98095.c b/drivers/sound/max98095.c
index d69db58..febf419 100644
--- a/drivers/sound/max98095.c
+++ b/drivers/sound/max98095.c
@@ -52,7 +52,7 @@
 static int max98095_i2c_write(unsigned int reg, unsigned char data)
 {
 	debug("%s: Write Addr : 0x%02X, Data :  0x%02X\n",
-		__func__, reg, data);
+	      __func__, reg, data);
 	return i2c_write(g_max98095_i2c_dev_addr, reg, 1, &data, 1);
 }
 
@@ -71,7 +71,7 @@
 	ret = i2c_read(g_max98095_i2c_dev_addr, reg, 1, data, 1);
 	if (ret != 0) {
 		debug("%s: Error while reading register %#04x\n",
-			__func__, reg);
+		      __func__, reg);
 		return -1;
 	}
 
@@ -138,43 +138,57 @@
  * @return -1 for error  and 0  Success.
  */
 static int max98095_hw_params(struct max98095_priv *max98095,
-		unsigned int rate, unsigned int bits_per_sample)
+			      enum en_max_audio_interface aif_id,
+			      unsigned int rate, unsigned int bits_per_sample)
 {
 	u8 regval;
 	int error;
+	unsigned short M98095_DAI_CLKMODE;
+	unsigned short M98095_DAI_FORMAT;
+	unsigned short M98095_DAI_FILTERS;
+
+	if (aif_id == AIF1) {
+		M98095_DAI_CLKMODE = M98095_027_DAI1_CLKMODE;
+		M98095_DAI_FORMAT = M98095_02A_DAI1_FORMAT;
+		M98095_DAI_FILTERS = M98095_02E_DAI1_FILTERS;
+	} else {
+		M98095_DAI_CLKMODE = M98095_031_DAI2_CLKMODE;
+		M98095_DAI_FORMAT = M98095_034_DAI2_FORMAT;
+		M98095_DAI_FILTERS = M98095_038_DAI2_FILTERS;
+	}
 
 	switch (bits_per_sample) {
 	case 16:
-		error = max98095_update_bits(M98095_034_DAI2_FORMAT,
-			M98095_DAI_WS, 0);
+		error = max98095_update_bits(M98095_DAI_FORMAT,
+					     M98095_DAI_WS, 0);
 		break;
 	case 24:
-		error = max98095_update_bits(M98095_034_DAI2_FORMAT,
-			M98095_DAI_WS, M98095_DAI_WS);
+		error = max98095_update_bits(M98095_DAI_FORMAT,
+					     M98095_DAI_WS, M98095_DAI_WS);
 		break;
 	default:
 		debug("%s: Illegal bits per sample %d.\n",
-			__func__, bits_per_sample);
+		      __func__, bits_per_sample);
 		return -1;
 	}
 
 	if (rate_value(rate, &regval)) {
 		debug("%s: Failed to set sample rate to %d.\n",
-			__func__, rate);
+		      __func__, rate);
 		return -1;
 	}
 	max98095->rate = rate;
 
-	error |= max98095_update_bits(M98095_031_DAI2_CLKMODE,
-		M98095_CLKMODE_MASK, regval);
+	error |= max98095_update_bits(M98095_DAI_CLKMODE,
+				      M98095_CLKMODE_MASK, regval);
 
 	/* Update sample rate mode */
 	if (rate < 50000)
-		error |= max98095_update_bits(M98095_038_DAI2_FILTERS,
-			M98095_DAI_DHF, 0);
+		error |= max98095_update_bits(M98095_DAI_FILTERS,
+					      M98095_DAI_DHF, 0);
 	else
-		error |= max98095_update_bits(M98095_038_DAI2_FILTERS,
-			M98095_DAI_DHF, M98095_DAI_DHF);
+		error |= max98095_update_bits(M98095_DAI_FILTERS,
+					      M98095_DAI_DHF, M98095_DAI_DHF);
 
 	if (error < 0) {
 		debug("%s: Error setting hardware params.\n", __func__);
@@ -193,7 +207,7 @@
  * @return -1 for error and 0 success.
  */
 static int max98095_set_sysclk(struct max98095_priv *max98095,
-				unsigned int freq)
+			       unsigned int freq)
 {
 	int error = 0;
 
@@ -235,22 +249,39 @@
  *
  * @return -1 for error and 0  Success.
  */
-static int max98095_set_fmt(struct max98095_priv *max98095, int fmt)
+static int max98095_set_fmt(struct max98095_priv *max98095, int fmt,
+			    enum en_max_audio_interface aif_id)
 {
 	u8 regval = 0;
 	int error = 0;
+	unsigned short M98095_DAI_CLKCFG_HI;
+	unsigned short M98095_DAI_CLKCFG_LO;
+	unsigned short M98095_DAI_FORMAT;
+	unsigned short M98095_DAI_CLOCK;
 
 	if (fmt == max98095->fmt)
 		return 0;
 
 	max98095->fmt = fmt;
 
+	if (aif_id == AIF1) {
+		M98095_DAI_CLKCFG_HI = M98095_028_DAI1_CLKCFG_HI;
+		M98095_DAI_CLKCFG_LO = M98095_029_DAI1_CLKCFG_LO;
+		M98095_DAI_FORMAT = M98095_02A_DAI1_FORMAT;
+		M98095_DAI_CLOCK = M98095_02B_DAI1_CLOCK;
+	} else {
+		M98095_DAI_CLKCFG_HI = M98095_032_DAI2_CLKCFG_HI;
+		M98095_DAI_CLKCFG_LO = M98095_033_DAI2_CLKCFG_LO;
+		M98095_DAI_FORMAT = M98095_034_DAI2_FORMAT;
+		M98095_DAI_CLOCK = M98095_035_DAI2_CLOCK;
+	}
+
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 	case SND_SOC_DAIFMT_CBS_CFS:
 		/* Slave mode PLL */
-		error |= max98095_i2c_write(M98095_032_DAI2_CLKCFG_HI,
+		error |= max98095_i2c_write(M98095_DAI_CLKCFG_HI,
 					0x80);
-		error |= max98095_i2c_write(M98095_033_DAI2_CLKCFG_LO,
+		error |= max98095_i2c_write(M98095_DAI_CLKCFG_LO,
 					0x00);
 		break;
 	case SND_SOC_DAIFMT_CBM_CFM:
@@ -292,12 +323,13 @@
 		return -1;
 	}
 
-	error |= max98095_update_bits(M98095_034_DAI2_FORMAT,
-		M98095_DAI_MAS | M98095_DAI_DLY | M98095_DAI_BCI |
-		M98095_DAI_WCI, regval);
+	error |= max98095_update_bits(M98095_DAI_FORMAT,
+				      M98095_DAI_MAS | M98095_DAI_DLY |
+				      M98095_DAI_BCI | M98095_DAI_WCI,
+				      regval);
 
-	error |= max98095_i2c_write(M98095_035_DAI2_CLOCK,
-		M98095_DAI_BSEL64);
+	error |= max98095_i2c_write(M98095_DAI_CLOCK,
+				    M98095_DAI_BSEL64);
 
 	if (error < 0) {
 		debug("%s: Error setting i2s format.\n", __func__);
@@ -354,7 +386,8 @@
  *
  * @returns -1 for error  and 0 Success.
  */
-static int max98095_device_init(struct max98095_priv *max98095)
+static int max98095_device_init(struct max98095_priv *max98095,
+				enum en_max_audio_interface aif_id)
 {
 	unsigned char id;
 	int error = 0;
@@ -374,7 +407,7 @@
 	error = max98095_i2c_read(M98095_0FF_REV_ID, &id);
 	if (error < 0) {
 		debug("%s: Failure reading hardware revision: %d\n",
-			__func__, id);
+		      __func__, id);
 		goto err_access;
 	}
 	debug("%s: Hardware revision: %c\n", __func__, (id - 0x40) + 'A');
@@ -385,26 +418,28 @@
 	 * initialize registers to hardware default configuring audio
 	 * interface2 to DAC
 	 */
-	error |= max98095_i2c_write(M98095_048_MIX_DAC_LR,
-		M98095_DAI2M_TO_DACL|M98095_DAI2M_TO_DACR);
+	if (aif_id == AIF1)
+		error |= max98095_i2c_write(M98095_048_MIX_DAC_LR,
+					    M98095_DAI1L_TO_DACL |
+					    M98095_DAI1R_TO_DACR);
+	else
+		error |= max98095_i2c_write(M98095_048_MIX_DAC_LR,
+					    M98095_DAI2M_TO_DACL |
+					    M98095_DAI2M_TO_DACR);
 
 	error |= max98095_i2c_write(M98095_092_PWR_EN_OUT,
-			M98095_SPK_SPREADSPECTRUM);
-	error |= max98095_i2c_write(M98095_045_CFG_DSP, M98095_DSPNORMAL);
+				    M98095_SPK_SPREADSPECTRUM);
 	error |= max98095_i2c_write(M98095_04E_CFG_HP, M98095_HPNORMAL);
-
-	error |= max98095_i2c_write(M98095_02C_DAI1_IOCFG,
-			M98095_S1NORMAL|M98095_SDATA);
-
-	error |= max98095_i2c_write(M98095_036_DAI2_IOCFG,
-			M98095_S2NORMAL|M98095_SDATA);
-
-	error |= max98095_i2c_write(M98095_040_DAI3_IOCFG,
-			M98095_S3NORMAL|M98095_SDATA);
+	if (aif_id == AIF1)
+		error |= max98095_i2c_write(M98095_02C_DAI1_IOCFG,
+					    M98095_S1NORMAL | M98095_SDATA);
+	else
+		error |= max98095_i2c_write(M98095_036_DAI2_IOCFG,
+					    M98095_S2NORMAL | M98095_SDATA);
 
 	/* take the codec out of the shut down */
 	error |= max98095_update_bits(M98095_097_PWR_SYS, M98095_SHDNRUN,
-			M98095_SHDNRUN);
+				      M98095_SHDNRUN);
 	/* route DACL and DACR output to HO and Spekers */
 	error |= max98095_i2c_write(M98095_050_MIX_SPK_LEFT, 0x01); /* DACL */
 	error |= max98095_i2c_write(M98095_051_MIX_SPK_RIGHT, 0x01);/* DACR */
@@ -422,7 +457,10 @@
 
 	/* Enable DAIs */
 	error |= max98095_i2c_write(M98095_093_BIAS_CTRL, 0x30);
-	error |= max98095_i2c_write(M98095_096_PWR_DAC_CK, 0x07);
+	if (aif_id == AIF1)
+		error |= max98095_i2c_write(M98095_096_PWR_DAC_CK, 0x01);
+	else
+		error |= max98095_i2c_write(M98095_096_PWR_DAC_CK, 0x07);
 
 err_access:
 	if (error < 0)
@@ -432,8 +470,9 @@
 }
 
 static int max98095_do_init(struct sound_codec_info *pcodec_info,
-			int sampling_rate, int mclk_freq,
-			int bits_per_sample)
+			    enum en_max_audio_interface aif_id,
+			    int sampling_rate, int mclk_freq,
+			    int bits_per_sample)
 {
 	int ret = 0;
 
@@ -443,15 +482,15 @@
 	/* shift the device address by 1 for 7 bit addressing */
 	g_max98095_i2c_dev_addr = pcodec_info->i2c_dev_addr >> 1;
 
-	if (pcodec_info->codec_type == CODEC_MAX_98095)
+	if (pcodec_info->codec_type == CODEC_MAX_98095) {
 		g_max98095_info.devtype = MAX98095;
-	else {
+	} else {
 		debug("%s: Codec id [%d] not defined\n", __func__,
-				pcodec_info->codec_type);
+		      pcodec_info->codec_type);
 		return -1;
 	}
 
-	ret = max98095_device_init(&g_max98095_info);
+	ret = max98095_device_init(&g_max98095_info, aif_id);
 	if (ret < 0) {
 		debug("%s: max98095 codec chip init failed\n", __func__);
 		return ret;
@@ -463,14 +502,15 @@
 		return ret;
 	}
 
-	ret = max98095_hw_params(&g_max98095_info, sampling_rate,
-				bits_per_sample);
+	ret = max98095_hw_params(&g_max98095_info, aif_id, sampling_rate,
+				 bits_per_sample);
 
 	if (ret == 0) {
 		ret = max98095_set_fmt(&g_max98095_info,
-					SND_SOC_DAIFMT_I2S |
-					SND_SOC_DAIFMT_NB_NF |
-					SND_SOC_DAIFMT_CBS_CFS);
+				       SND_SOC_DAIFMT_I2S |
+				       SND_SOC_DAIFMT_NB_NF |
+				       SND_SOC_DAIFMT_CBS_CFS,
+				       aif_id);
 	}
 
 	return ret;
@@ -529,8 +569,9 @@
 }
 
 /* max98095 Device Initialisation */
-int max98095_init(const void *blob, int sampling_rate, int mclk_freq,
-			int bits_per_sample)
+int max98095_init(const void *blob, enum en_max_audio_interface aif_id,
+		  int sampling_rate, int mclk_freq,
+		  int bits_per_sample)
 {
 	int ret;
 	int old_bus = i2c_get_bus_num();
@@ -538,12 +579,12 @@
 
 	if (get_max98095_codec_values(pcodec_info, blob) < 0) {
 		debug("FDT Codec values failed\n");
-		 return -1;
+		return -1;
 	}
 
 	i2c_set_bus_num(pcodec_info->i2c_bus);
-	ret = max98095_do_init(pcodec_info, sampling_rate, mclk_freq,
-				bits_per_sample);
+	ret = max98095_do_init(pcodec_info, aif_id, sampling_rate, mclk_freq,
+			       bits_per_sample);
 	i2c_set_bus_num(old_bus);
 
 	return ret;
diff --git a/drivers/sound/max98095.h b/drivers/sound/max98095.h
index ae5eb14..44b1e3a 100644
--- a/drivers/sound/max98095.h
+++ b/drivers/sound/max98095.h
@@ -11,6 +11,12 @@
 #ifndef _MAX98095_H
 #define _MAX98095_H
 
+/*  Available audio interface ports in wm8994 codec */
+enum en_max_audio_interface {
+	AIF1 = 1,
+	AIF2,
+};
+
 /*
  * MAX98095 Registers Definition
  */
@@ -305,7 +311,7 @@
  *
  * @returns -1 for error and 0 Success.
  */
-int max98095_init(const void *blob, int sampling_rate, int mclk_freq,
-			int bits_per_sample);
+int max98095_init(const void *blob, enum en_max_audio_interface aif_id,
+		  int sampling_rate, int mclk_freq, int bits_per_sample);
 
 #endif
diff --git a/drivers/sound/samsung-i2s.c b/drivers/sound/samsung-i2s.c
index 49921e5..47f155f 100644
--- a/drivers/sound/samsung-i2s.c
+++ b/drivers/sound/samsung-i2s.c
@@ -65,9 +65,7 @@
 	if (on) {
 		con |= CON_ACTIVE;
 		con &= ~CON_TXCH_PAUSE;
-
 	} else {
-
 		con |=  CON_TXCH_PAUSE;
 		con &= ~CON_ACTIVE;
 	}
@@ -172,7 +170,7 @@
 		break;
 	default:
 		debug("%s: Invalid format priority [0x%x]\n", __func__,
-			(fmt & SND_SOC_DAIFMT_FORMAT_MASK));
+		      (fmt & SND_SOC_DAIFMT_FORMAT_MASK));
 		return -1;
 	}
 
@@ -191,7 +189,7 @@
 		break;
 	default:
 		debug("%s: Invalid clock ploarity input [0x%x]\n", __func__,
-			(fmt & SND_SOC_DAIFMT_INV_MASK));
+		      (fmt & SND_SOC_DAIFMT_INV_MASK));
 		return -1;
 	}
 
@@ -209,7 +207,7 @@
 		break;
 	default:
 		debug("%s: Invalid master selection [0x%x]\n", __func__,
-			(fmt & SND_SOC_DAIFMT_MASTER_MASK));
+		      (fmt & SND_SOC_DAIFMT_MASTER_MASK));
 		return -1;
 	}
 
@@ -250,7 +248,7 @@
 		break;
 	default:
 		debug("%s: Invalid sample size input [0x%x]\n",
-			__func__, blc);
+		      __func__, blc);
 		return -1;
 	}
 	writel(mod, &i2s_reg->mod);
@@ -301,27 +299,58 @@
 	int ret;
 	struct i2s_reg *i2s_reg =
 				(struct i2s_reg *)pi2s_tx->base_address;
+	if (pi2s_tx->id == 0) {
+		/* Initialize GPIO for I2S-0 */
+		exynos_pinmux_config(PERIPH_ID_I2S0, 0);
 
-	/* Initialize GPIO for I2s */
-	exynos_pinmux_config(PERIPH_ID_I2S1, 0);
+		/* Set EPLL Clock */
+		ret = set_epll_clk(pi2s_tx->samplingrate * pi2s_tx->rfs * 4);
+	} else if (pi2s_tx->id == 1) {
+		/* Initialize GPIO for I2S-1 */
+		exynos_pinmux_config(PERIPH_ID_I2S1, 0);
 
-	/* Set EPLL Clock */
-	ret = set_epll_clk(pi2s_tx->audio_pll_clk);
+		/* Set EPLL Clock */
+		ret = set_epll_clk(pi2s_tx->audio_pll_clk);
+	} else {
+		debug("%s: unsupported i2s-%d bus\n", __func__, pi2s_tx->id);
+		return -1;
+	}
+
 	if (ret != 0) {
-		debug("%s: epll clock set rate falied\n", __func__);
+		debug("%s: epll clock set rate failed\n", __func__);
 		return -1;
 	}
 
-	/* Select Clk Source for Audio1 */
-	set_i2s_clk_source();
+	/* Select Clk Source for Audio 0 or 1 */
+	ret = set_i2s_clk_source(pi2s_tx->id);
+	if (ret == -1) {
+		debug("%s: unsupported clock for i2s-%d\n", __func__,
+		      pi2s_tx->id);
+		return -1;
+	}
+
+	if (pi2s_tx->id == 0) {
+		/*Reset the i2s module */
+		writel(CON_RESET, &i2s_reg->con);
 
-	/* Set Prescaler to get MCLK */
-	set_i2s_clk_prescaler(pi2s_tx->audio_pll_clk,
-				(pi2s_tx->samplingrate * (pi2s_tx->rfs)));
+		writel(MOD_OP_CLK | MOD_RCLKSRC, &i2s_reg->mod);
+		/* set i2s prescaler */
+		writel(PSREN | PSVAL, &i2s_reg->psr);
+	} else {
+		/* Set Prescaler to get MCLK */
+		ret = set_i2s_clk_prescaler(pi2s_tx->audio_pll_clk,
+				(pi2s_tx->samplingrate * (pi2s_tx->rfs)),
+				pi2s_tx->id);
+	}
+	if (ret == -1) {
+		debug("%s: unsupported prescalar for i2s-%d\n", __func__,
+		      pi2s_tx->id);
+		return -1;
+	}
 
 	/* Configure I2s format */
 	ret = i2s_set_fmt(i2s_reg, (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
-				SND_SOC_DAIFMT_CBM_CFM));
+			  SND_SOC_DAIFMT_CBM_CFM));
 	if (ret == 0) {
 		i2s_set_lr_framesize(i2s_reg, pi2s_tx->rfs);
 		ret = i2s_set_samplesize(i2s_reg, pi2s_tx->bitspersample);
diff --git a/drivers/sound/sound.c b/drivers/sound/sound.c
index 6fcc75d..9b8ce5a 100644
--- a/drivers/sound/sound.c
+++ b/drivers/sound/sound.c
@@ -36,8 +36,7 @@
 	int error = 0;
 	int base;
 
-	node = fdtdec_next_compatible(blob, 0,
-					COMPAT_SAMSUNG_EXYNOS5_SOUND);
+	node = fdt_path_offset(blob, "i2s");
 	if (node <= 0) {
 		debug("EXYNOS_SOUND: No node for sound in device tree\n");
 		return -1;
@@ -80,6 +79,11 @@
 				node, "samsung,i2s-bit-clk-framesize", -1);
 	error |= i2s->bfs;
 	debug("bfs = %d\n", i2s->bfs);
+
+	i2s->id = fdtdec_get_int(blob, node, "samsung,i2s-id", -1);
+	error |= i2s->id;
+	debug("id = %d\n", i2s->id);
+
 	if (error == -1) {
 		debug("fail to get sound i2s node properties\n");
 		return -1;
@@ -92,6 +96,7 @@
 	i2s->channels = I2S_CHANNELS;
 	i2s->rfs = I2S_RFS;
 	i2s->bfs = I2S_BFS;
+	i2s->id = 0;
 #endif
 	return 0;
 }
@@ -111,7 +116,7 @@
 	int node;
 
 	/* Get the node from FDT for sound */
-	node = fdtdec_next_compatible(blob, 0, COMPAT_SAMSUNG_EXYNOS5_SOUND);
+	node = fdt_path_offset(blob, "i2s");
 	if (node <= 0) {
 		debug("EXYNOS_SOUND: No node for sound in device tree\n");
 		debug("node = %d\n", node);
@@ -130,14 +135,15 @@
 #endif
 	if (!strcmp(codectype, "wm8994")) {
 		/* Check the codec type and initialise the same */
-		ret = wm8994_init(blob, WM8994_AIF2,
-			pi2s_tx->samplingrate,
-			(pi2s_tx->samplingrate * (pi2s_tx->rfs)),
-			pi2s_tx->bitspersample, pi2s_tx->channels);
+		ret = wm8994_init(blob, pi2s_tx->id + 1,
+				  pi2s_tx->samplingrate,
+				  (pi2s_tx->samplingrate * (pi2s_tx->rfs)),
+				  pi2s_tx->bitspersample, pi2s_tx->channels);
 	} else if (!strcmp(codectype, "max98095")) {
-		ret = max98095_init(blob, pi2s_tx->samplingrate,
-				(pi2s_tx->samplingrate * (pi2s_tx->rfs)),
-				pi2s_tx->bitspersample);
+		ret = max98095_init(blob, pi2s_tx->id + 1,
+				    pi2s_tx->samplingrate,
+				    (pi2s_tx->samplingrate * (pi2s_tx->rfs)),
+				    pi2s_tx->bitspersample);
 	} else {
 		debug("%s: Unknown codec type %s\n", __func__, codectype);
 		return -1;
@@ -230,7 +236,7 @@
 	}
 
 	sound_prepare_buffer((unsigned short *)data,
-				data_size / sizeof(unsigned short), frequency);
+			     data_size / sizeof(unsigned short), frequency);
 
 	while (msec >= 1000) {
 		ret = i2s_transfer_tx_data(&g_i2stx_pri, data,
diff --git a/drivers/sound/wm8994.c b/drivers/sound/wm8994.c
index 37e354c..f8e9a6e 100644
--- a/drivers/sound/wm8994.c
+++ b/drivers/sound/wm8994.c
@@ -432,12 +432,12 @@
 	int ret;
 
 	/* AIF(1/0) register adress offset calculated */
-	if (aif)
+	if (aif-1)
 		offset = 4;
 	else
 		offset = 0;
 
-	switch (wm8994->sysclk[aif]) {
+	switch (wm8994->sysclk[aif-1]) {
 	case WM8994_SYSCLK_MCLK1:
 		reg1 |= SEL_MCLK1;
 		rate = wm8994->mclk[0];
@@ -460,7 +460,7 @@
 
 	default:
 		debug("%s: Invalid input clock selection [%d]\n",
-		      __func__, wm8994->sysclk[aif]);
+		      __func__, wm8994->sysclk[aif-1]);
 		return -1;
 	}
 
@@ -470,13 +470,18 @@
 		reg1 |= WM8994_AIF1CLK_DIV;
 	}
 
-	wm8994->aifclk[aif] = rate;
+	wm8994->aifclk[aif-1] = rate;
 
 	ret = wm8994_update_bits(WM8994_AIF1_CLOCKING_1 + offset,
 				WM8994_AIF1CLK_SRC_MASK | WM8994_AIF1CLK_DIV,
 				reg1);
 
-	ret |= wm8994_update_bits(WM8994_CLOCKING_1,
+	if (aif == WM8994_AIF1)
+		ret |= wm8994_update_bits(WM8994_CLOCKING_1,
+			WM8994_AIF1DSPCLK_ENA_MASK | WM8994_SYSDSPCLK_ENA_MASK,
+			WM8994_AIF1DSPCLK_ENA | WM8994_SYSDSPCLK_ENA);
+	else if (aif == WM8994_AIF2)
+		ret |= wm8994_update_bits(WM8994_CLOCKING_1,
 			WM8994_SYSCLK_SRC | WM8994_AIF2DSPCLK_ENA_MASK |
 			WM8994_SYSDSPCLK_ENA_MASK, WM8994_SYSCLK_SRC |
 			WM8994_AIF2DSPCLK_ENA | WM8994_SYSDSPCLK_ENA);
@@ -536,7 +541,7 @@
 					break;
 			if (i == ARRAY_SIZE(opclk_divs)) {
 				debug("%s frequency divisor not found\n",
-					__func__);
+				      __func__);
 				return -1;
 			}
 			ret = wm8994_update_bits(WM8994_CLOCKING_2,
@@ -554,7 +559,7 @@
 		return -1;
 	}
 
-	ret |= configure_aif_clock(wm8994, aif_id - 1);
+	ret |= configure_aif_clock(wm8994, aif_id);
 
 	if (ret < 0) {
 		debug("%s: codec register access error\n", __func__);
@@ -608,13 +613,46 @@
 }
 
 /*
+ * Initializes Volume for AIF1 to HP path
+ *
+ * @returns -1 for error  and 0 Success.
+ *
+ */
+static int wm8994_init_volume_aif1_dac1(void)
+{
+	int ret = 0;
+
+	/* Unmute AIF1DAC */
+	ret |= wm8994_i2c_write(WM8994_AIF1_DAC_FILTERS_1, 0x0000);
+
+	ret |= wm8994_update_bits(WM8994_DAC1_LEFT_VOLUME,
+			WM8994_DAC1_VU_MASK | WM8994_DAC1L_VOL_MASK |
+			WM8994_DAC1L_MUTE_MASK, WM8994_DAC1_VU | 0xc0);
+
+	ret |= wm8994_update_bits(WM8994_DAC1_RIGHT_VOLUME,
+			WM8994_DAC1_VU_MASK | WM8994_DAC1R_VOL_MASK |
+			WM8994_DAC1R_MUTE_MASK, WM8994_DAC1_VU | 0xc0);
+	/* Head Phone Volume */
+	ret |= wm8994_i2c_write(WM8994_LEFT_OUTPUT_VOLUME, 0x12D);
+	ret |= wm8994_i2c_write(WM8994_RIGHT_OUTPUT_VOLUME, 0x12D);
+
+	if (ret < 0) {
+		debug("%s: codec register access error\n", __func__);
+		return -1;
+	}
+
+	return 0;
+}
+
+/*
  * Intialise wm8994 codec device
  *
  * @param wm8994	wm8994 information
  *
  * @returns -1 for error  and 0 Success.
  */
-static int wm8994_device_init(struct wm8994_priv *wm8994)
+static int wm8994_device_init(struct wm8994_priv *wm8994,
+			      enum en_audio_interface aif_id)
 {
 	const char *devname;
 	unsigned short reg_data;
@@ -661,13 +699,30 @@
 	ret |= wm8994_update_bits(WM8994_POWER_MANAGEMENT_1,
 				WM8994_HPOUT1R_ENA_MASK, WM8994_HPOUT1R_ENA);
 
-	/* Power enable for AIF2 and DAC1 */
-	ret |= wm8994_update_bits(WM8994_POWER_MANAGEMENT_5,
-		WM8994_AIF2DACL_ENA_MASK | WM8994_AIF2DACR_ENA_MASK |
-		WM8994_DAC1L_ENA_MASK | WM8994_DAC1R_ENA_MASK,
-		WM8994_AIF2DACL_ENA | WM8994_AIF2DACR_ENA | WM8994_DAC1L_ENA |
-		WM8994_DAC1R_ENA);
+	if (aif_id == WM8994_AIF1) {
+		ret |= wm8994_i2c_write(WM8994_POWER_MANAGEMENT_2,
+					WM8994_TSHUT_ENA | WM8994_MIXINL_ENA |
+					WM8994_MIXINR_ENA | WM8994_IN2L_ENA |
+					WM8994_IN2R_ENA);
 
+		ret |= wm8994_i2c_write(WM8994_POWER_MANAGEMENT_4,
+					WM8994_ADCL_ENA | WM8994_ADCR_ENA |
+					WM8994_AIF1ADC1R_ENA |
+					WM8994_AIF1ADC1L_ENA);
+
+		/* Power enable for AIF1 and DAC1 */
+		ret |= wm8994_i2c_write(WM8994_POWER_MANAGEMENT_5,
+					WM8994_AIF1DACL_ENA |
+					WM8994_AIF1DACR_ENA |
+					WM8994_DAC1L_ENA | WM8994_DAC1R_ENA);
+	} else if (aif_id == WM8994_AIF2) {
+		/* Power enable for AIF2 and DAC1 */
+		ret |= wm8994_update_bits(WM8994_POWER_MANAGEMENT_5,
+			WM8994_AIF2DACL_ENA_MASK | WM8994_AIF2DACR_ENA_MASK |
+			WM8994_DAC1L_ENA_MASK | WM8994_DAC1R_ENA_MASK,
+			WM8994_AIF2DACL_ENA | WM8994_AIF2DACR_ENA |
+			WM8994_DAC1L_ENA | WM8994_DAC1R_ENA);
+	}
 	/* Head Phone Initialisation */
 	ret |= wm8994_update_bits(WM8994_ANALOGUE_HP_1,
 		WM8994_HPOUT1L_DLY_MASK | WM8994_HPOUT1R_DLY_MASK,
@@ -695,35 +750,49 @@
 	ret |= wm8994_update_bits(WM8994_OUTPUT_MIXER_2,
 			WM8994_DAC1R_TO_HPOUT1R_MASK, WM8994_DAC1R_TO_HPOUT1R);
 
-	/* Routing AIF2 to DAC1 */
-	ret |= wm8994_update_bits(WM8994_DAC1_LEFT_MIXER_ROUTING,
-			WM8994_AIF2DACL_TO_DAC1L_MASK,
-			WM8994_AIF2DACL_TO_DAC1L);
+	if (aif_id == WM8994_AIF1) {
+		/* Routing AIF1 to DAC1 */
+		ret |= wm8994_i2c_write(WM8994_DAC1_LEFT_MIXER_ROUTING,
+				WM8994_AIF1DAC1L_TO_DAC1L);
 
-	ret |= wm8994_update_bits(WM8994_DAC1_RIGHT_MIXER_ROUTING,
-			WM8994_AIF2DACR_TO_DAC1R_MASK,
-			WM8994_AIF2DACR_TO_DAC1R);
+		ret |= wm8994_i2c_write(WM8994_DAC1_RIGHT_MIXER_ROUTING,
+					WM8994_AIF1DAC1R_TO_DAC1R);
 
-	 /* GPIO Settings for AIF2 */
-	 /* B CLK */
-	ret |= wm8994_update_bits(WM8994_GPIO_3, WM8994_GPIO_DIR_MASK |
-				WM8994_GPIO_FUNCTION_MASK ,
-				WM8994_GPIO_DIR_OUTPUT |
-				WM8994_GPIO_FUNCTION_I2S_CLK);
+		/* GPIO Settings for AIF1 */
+		ret |=  wm8994_i2c_write(WM8994_GPIO_1, WM8994_GPIO_DIR_OUTPUT
+					 | WM8994_GPIO_FUNCTION_I2S_CLK
+					 | WM8994_GPIO_INPUT_DEBOUNCE);
 
-	/* LR CLK */
-	ret |= wm8994_update_bits(WM8994_GPIO_4, WM8994_GPIO_DIR_MASK |
-				WM8994_GPIO_FUNCTION_MASK,
-				WM8994_GPIO_DIR_OUTPUT |
-				WM8994_GPIO_FUNCTION_I2S_CLK);
+		ret |= wm8994_init_volume_aif1_dac1();
+	} else if (aif_id == WM8994_AIF2) {
+		/* Routing AIF2 to DAC1 */
+		ret |= wm8994_update_bits(WM8994_DAC1_LEFT_MIXER_ROUTING,
+				WM8994_AIF2DACL_TO_DAC1L_MASK,
+				WM8994_AIF2DACL_TO_DAC1L);
 
-	/* DATA */
-	ret |= wm8994_update_bits(WM8994_GPIO_5, WM8994_GPIO_DIR_MASK |
-				WM8994_GPIO_FUNCTION_MASK,
-				WM8994_GPIO_DIR_OUTPUT |
-				WM8994_GPIO_FUNCTION_I2S_CLK);
+		ret |= wm8994_update_bits(WM8994_DAC1_RIGHT_MIXER_ROUTING,
+				WM8994_AIF2DACR_TO_DAC1R_MASK,
+				WM8994_AIF2DACR_TO_DAC1R);
 
-	ret |= wm8994_init_volume_aif2_dac1();
+		/* GPIO Settings for AIF2 */
+		/* B CLK */
+		ret |= wm8994_update_bits(WM8994_GPIO_3, WM8994_GPIO_DIR_MASK |
+					WM8994_GPIO_FUNCTION_MASK ,
+					WM8994_GPIO_DIR_OUTPUT);
+
+		/* LR CLK */
+		ret |= wm8994_update_bits(WM8994_GPIO_4, WM8994_GPIO_DIR_MASK |
+					WM8994_GPIO_FUNCTION_MASK,
+					WM8994_GPIO_DIR_OUTPUT);
+
+		/* DATA */
+		ret |= wm8994_update_bits(WM8994_GPIO_5, WM8994_GPIO_DIR_MASK |
+					WM8994_GPIO_FUNCTION_MASK,
+					WM8994_GPIO_DIR_OUTPUT);
+
+		ret |= wm8994_init_volume_aif2_dac1();
+	}
+
 	if (ret < 0)
 		goto err;
 
@@ -795,7 +864,7 @@
 	return 0;
 }
 
-/*wm8994 Device Initialisation */
+/* WM8994 Device Initialisation */
 int wm8994_init(const void *blob, enum en_audio_interface aif_id,
 			int sampling_rate, int mclk_freq,
 			int bits_per_sample, unsigned int channels)
@@ -813,15 +882,15 @@
 	g_wm8994_i2c_dev_addr = pcodec_info->i2c_dev_addr;
 	wm8994_i2c_init(pcodec_info->i2c_bus);
 
-	if (pcodec_info->codec_type == CODEC_WM_8994)
+	if (pcodec_info->codec_type == CODEC_WM_8994) {
 		g_wm8994_info.type = WM8994;
-	else {
+	} else {
 		debug("%s: Codec id [%d] not defined\n", __func__,
-				pcodec_info->codec_type);
+		      pcodec_info->codec_type);
 		return -1;
 	}
 
-	ret = wm8994_device_init(&g_wm8994_info);
+	ret = wm8994_device_init(&g_wm8994_info, aif_id);
 	if (ret < 0) {
 		debug("%s: wm8994 codec chip init failed\n", __func__);
 		return ret;
diff --git a/drivers/sound/wm8994_registers.h b/drivers/sound/wm8994_registers.h
index 1e987c2..0aba2fd 100644
--- a/drivers/sound/wm8994_registers.h
+++ b/drivers/sound/wm8994_registers.h
@@ -13,6 +13,7 @@
 #define WM8994_SOFTWARE_RESET                   0x00
 #define WM8994_POWER_MANAGEMENT_1               0x01
 #define WM8994_POWER_MANAGEMENT_2               0x02
+#define WM8994_POWER_MANAGEMENT_4		0x04
 #define WM8994_POWER_MANAGEMENT_5               0x05
 #define WM8994_LEFT_OUTPUT_VOLUME               0x1C
 #define WM8994_RIGHT_OUTPUT_VOLUME              0x1D
@@ -38,6 +39,7 @@
 #define WM8994_AIF2_CONTROL_2                   0x311
 #define WM8994_AIF2_MASTER_SLAVE                0x312
 #define WM8994_AIF2_BCLK                        0x313
+#define WM8994_AIF1_DAC_FILTERS_1		0x420
 #define WM8994_AIF2_DAC_LEFT_VOLUME             0x502
 #define WM8994_AIF2_DAC_RIGHT_VOLUME            0x503
 #define WM8994_AIF2_DAC_FILTERS_1               0x520
@@ -45,6 +47,7 @@
 #define WM8994_DAC1_RIGHT_MIXER_ROUTING         0x602
 #define WM8994_DAC1_LEFT_VOLUME                 0x610
 #define WM8994_DAC1_RIGHT_VOLUME                0x611
+#define WM8994_GPIO_1				0x700
 #define WM8994_GPIO_3                           0x702
 #define WM8994_GPIO_4                           0x703
 #define WM8994_GPIO_5                           0x704
@@ -82,6 +85,20 @@
 /* OPCLK_ENA */
 #define WM8994_OPCLK_ENA                        0x0800
 
+#define WM8994_TSHUT_ENA			0x4000
+#define WM8994_MIXINL_ENA			0x0200
+#define WM8994_MIXINR_ENA			0x0100
+#define WM8994_IN2L_ENA				0x0080
+#define WM8994_IN2R_ENA				0x0020
+
+/*
+ * R5 (0x04) - Power Management (4)
+ */
+#define WM8994_ADCL_ENA				0x0001
+#define WM8994_ADCR_ENA				0x0002
+#define WM8994_AIF1ADC1R_ENA			0x0100
+#define WM8994_AIF1ADC1L_ENA			0x0200
+
 /*
  * R5 (0x05) - Power Management (5)
  */
@@ -91,6 +108,12 @@
 /* AIF2DACR_ENA */
 #define WM8994_AIF2DACR_ENA                     0x1000
 #define WM8994_AIF2DACR_ENA_MASK                0x1000
+/* AIF1DACL_ENA */
+#define WM8994_AIF1DACL_ENA			0x0200
+#define WM8994_AIF1DACL_ENA_MASK		0x0200
+/* AIF1DACR_ENA */
+#define WM8994_AIF1DACR_ENA			0x0100
+#define WM8994_AIF1DACR_ENA_MASK		0x0100
 /* DAC1L_ENA */
 #define WM8994_DAC1L_ENA                        0x0002
 #define WM8994_DAC1L_ENA_MASK                   0x0002
@@ -170,6 +193,9 @@
 /*
  * R520 (0x208) - Clocking (1)
  */
+/* AIF1DSPCLK_ENA */
+#define WM8994_AIF1DSPCLK_ENA			0x0008
+#define WM8994_AIF1DSPCLK_ENA_MASK		0x0008
 /* AIF2DSPCLK_ENA */
 #define WM8994_AIF2DSPCLK_ENA                   0x0004
 #define WM8994_AIF2DSPCLK_ENA_MASK              0x0004
@@ -254,6 +280,8 @@
 /* AIF2DACL_TO_DAC1L */
 #define WM8994_AIF2DACL_TO_DAC1L                0x0004
 #define WM8994_AIF2DACL_TO_DAC1L_MASK           0x0004
+/* AIF1DAC1L_TO_DAC1L */
+#define WM8994_AIF1DAC1L_TO_DAC1L		0x0001
 
 /*
  * R1538 (0x602) - DAC1 Right Mixer Routing
@@ -261,6 +289,8 @@
 /* AIF2DACR_TO_DAC1R */
 #define WM8994_AIF2DACR_TO_DAC1R                0x0004
 #define WM8994_AIF2DACR_TO_DAC1R_MASK           0x0004
+/* AIF1DAC1R_TO_DAC1R */
+#define WM8994_AIF1DAC1R_TO_DAC1R		0x0001
 
 /*
  * R1552 (0x610) - DAC1 Left Volume
@@ -285,11 +315,12 @@
  *  GPIO
  */
 /* OUTPUT PIN */
-#define WM8994_GPIO_DIR_OUTPUT                   0x8000
+#define WM8994_GPIO_DIR_OUTPUT			0x8000
 /* GPIO PIN MASK */
-#define WM8994_GPIO_DIR_MASK                     0xFFE0
+#define WM8994_GPIO_DIR_MASK			0xFFE0
 /* I2S CLK */
-#define WM8994_GPIO_FUNCTION_I2S_CLK             0x0000
+#define WM8994_GPIO_FUNCTION_I2S_CLK		0x0001
+#define WM8994_GPIO_INPUT_DEBOUNCE		0x0100
 /* GPn FN */
-#define WM8994_GPIO_FUNCTION_MASK                0x001F
+#define WM8994_GPIO_FUNCTION_MASK		0x001F
 #endif
diff --git a/drivers/spi/mxs_spi.c b/drivers/spi/mxs_spi.c
index 3cf7142..2b9f395 100644
--- a/drivers/spi/mxs_spi.c
+++ b/drivers/spi/mxs_spi.c
@@ -56,8 +56,6 @@
 				  unsigned int max_hz, unsigned int mode)
 {
 	struct mxs_spi_slave *mxs_slave;
-	struct mxs_ssp_regs *ssp_regs;
-	int reg;
 
 	if (!spi_cs_is_valid(bus, cs)) {
 		printf("mxs_spi: invalid bus %d / chip select %d\n", bus, cs);
@@ -74,13 +72,7 @@
 	mxs_slave->max_khz = max_hz / 1000;
 	mxs_slave->mode = mode;
 	mxs_slave->regs = mxs_ssp_regs_by_bus(bus);
-	ssp_regs = mxs_slave->regs;
 
-	reg = readl(&ssp_regs->hw_ssp_ctrl0);
-	reg &= ~(MXS_SSP_CHIPSELECT_MASK);
-	reg |= cs << MXS_SSP_CHIPSELECT_SHIFT;
-
-	writel(reg, &ssp_regs->hw_ssp_ctrl0);
 	return &mxs_slave->slave;
 
 err_init:
@@ -102,7 +94,9 @@
 
 	mxs_reset_block(&ssp_regs->hw_ssp_ctrl0_reg);
 
-	writel(SSP_CTRL0_BUS_WIDTH_ONE_BIT, &ssp_regs->hw_ssp_ctrl0);
+	writel((slave->cs << MXS_SSP_CHIPSELECT_SHIFT) |
+	       SSP_CTRL0_BUS_WIDTH_ONE_BIT,
+	       &ssp_regs->hw_ssp_ctrl0);
 
 	reg = SSP_CTRL1_SSP_MODE_SPI | SSP_CTRL1_WORD_LENGTH_EIGHT_BITS;
 	reg |= (mxs_slave->mode & SPI_CPOL) ? SSP_CTRL1_POLARITY : 0;
diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
index 4c2a39a..1590c4a 100644
--- a/drivers/usb/gadget/Makefile
+++ b/drivers/usb/gadget/Makefile
@@ -18,10 +18,12 @@
 
 # new USB gadget layer dependencies
 ifdef CONFIG_USB_GADGET
+COBJS-$(CONFIG_USB_GADGET_ATMEL_USBA) += atmel_usba_udc.o
 COBJS-$(CONFIG_USB_GADGET_S3C_UDC_OTG) += s3c_udc_otg.o
 COBJS-$(CONFIG_USB_GADGET_FOTG210) += fotg210.o
 COBJS-$(CONFIG_USBDOWNLOAD_GADGET) += g_dnl.o
 COBJS-$(CONFIG_DFU_FUNCTION) += f_dfu.o
+COBJS-$(CONFIG_USB_GADGET_MASS_STORAGE) += f_mass_storage.o
 endif
 ifdef CONFIG_USB_ETHER
 COBJS-y += ether.o
diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c
new file mode 100644
index 0000000..c99208d
--- /dev/null
+++ b/drivers/usb/gadget/atmel_usba_udc.c
@@ -0,0 +1,1306 @@
+/*
+ * Driver for the Atmel USBA high speed USB device controller
+ * [Original from Linux kernel: drivers/usb/gadget/atmel_usba_udc.c]
+ *
+ * Copyright (C) 2005-2013 Atmel Corporation
+ *			   Bo Shen <voice.shen@atmel.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/errno.h>
+#include <asm/gpio.h>
+#include <asm/hardware.h>
+#include <linux/list.h>
+#include <linux/usb/ch9.h>
+#include <linux/usb/gadget.h>
+#include <linux/usb/atmel_usba_udc.h>
+#include <malloc.h>
+#include <usb/lin_gadget_compat.h>
+
+#include "atmel_usba_udc.h"
+
+static int vbus_is_present(struct usba_udc *udc)
+{
+	/* No Vbus detection: Assume always present */
+	return 1;
+}
+
+static void next_fifo_transaction(struct usba_ep *ep, struct usba_request *req)
+{
+	unsigned int transaction_len;
+
+	transaction_len = req->req.length - req->req.actual;
+	req->last_transaction = 1;
+	if (transaction_len > ep->ep.maxpacket) {
+		transaction_len = ep->ep.maxpacket;
+		req->last_transaction = 0;
+	} else if (transaction_len == ep->ep.maxpacket && req->req.zero) {
+			req->last_transaction = 0;
+	}
+
+	DBG(DBG_QUEUE, "%s: submit_transaction, req %p (length %d)%s\n",
+	    ep->ep.name, req, transaction_len,
+	    req->last_transaction ? ", done" : "");
+
+	memcpy(ep->fifo, req->req.buf + req->req.actual, transaction_len);
+	usba_ep_writel(ep, SET_STA, USBA_TX_PK_RDY);
+	req->req.actual += transaction_len;
+}
+
+static void submit_request(struct usba_ep *ep, struct usba_request *req)
+{
+	DBG(DBG_QUEUE, "%s: submit_request: req %p (length %d), dma: %d\n",
+	    ep->ep.name, req, req->req.length, req->using_dma);
+
+	req->req.actual = 0;
+	req->submitted = 1;
+
+	next_fifo_transaction(ep, req);
+	if (req->last_transaction) {
+		usba_ep_writel(ep, CTL_DIS, USBA_TX_PK_RDY);
+		usba_ep_writel(ep, CTL_ENB, USBA_TX_COMPLETE);
+	} else {
+		usba_ep_writel(ep, CTL_DIS, USBA_TX_COMPLETE);
+		usba_ep_writel(ep, CTL_ENB, USBA_TX_PK_RDY);
+	}
+}
+
+static void submit_next_request(struct usba_ep *ep)
+{
+	struct usba_request *req;
+
+	if (list_empty(&ep->queue)) {
+		usba_ep_writel(ep, CTL_DIS, USBA_TX_PK_RDY | USBA_RX_BK_RDY);
+		return;
+	}
+
+	req = list_entry(ep->queue.next, struct usba_request, queue);
+	if (!req->submitted)
+		submit_request(ep, req);
+}
+
+static void send_status(struct usba_udc *udc, struct usba_ep *ep)
+{
+	ep->state = STATUS_STAGE_IN;
+	usba_ep_writel(ep, SET_STA, USBA_TX_PK_RDY);
+	usba_ep_writel(ep, CTL_ENB, USBA_TX_COMPLETE);
+}
+
+static void receive_data(struct usba_ep *ep)
+{
+	struct usba_udc *udc = ep->udc;
+	struct usba_request *req;
+	unsigned long status;
+	unsigned int bytecount, nr_busy;
+	int is_complete = 0;
+
+	status = usba_ep_readl(ep, STA);
+	nr_busy = USBA_BFEXT(BUSY_BANKS, status);
+
+	DBG(DBG_QUEUE, "receive data: nr_busy=%u\n", nr_busy);
+
+	while (nr_busy > 0) {
+		if (list_empty(&ep->queue)) {
+			usba_ep_writel(ep, CTL_DIS, USBA_RX_BK_RDY);
+			break;
+		}
+		req = list_entry(ep->queue.next,
+				 struct usba_request, queue);
+
+		bytecount = USBA_BFEXT(BYTE_COUNT, status);
+
+		if (status & USBA_SHORT_PACKET)
+			is_complete = 1;
+		if (req->req.actual + bytecount >= req->req.length) {
+			is_complete = 1;
+			bytecount = req->req.length - req->req.actual;
+		}
+
+		memcpy(req->req.buf + req->req.actual, ep->fifo, bytecount);
+		req->req.actual += bytecount;
+
+		usba_ep_writel(ep, CLR_STA, USBA_RX_BK_RDY);
+
+		if (is_complete) {
+			DBG(DBG_QUEUE, "%s: request done\n", ep->ep.name);
+			req->req.status = 0;
+			list_del_init(&req->queue);
+			usba_ep_writel(ep, CTL_DIS, USBA_RX_BK_RDY);
+			spin_lock(&udc->lock);
+			req->req.complete(&ep->ep, &req->req);
+			spin_unlock(&udc->lock);
+		}
+
+		status = usba_ep_readl(ep, STA);
+		nr_busy = USBA_BFEXT(BUSY_BANKS, status);
+
+		if (is_complete && ep_is_control(ep)) {
+			send_status(udc, ep);
+			break;
+		}
+	}
+}
+
+static void
+request_complete(struct usba_ep *ep, struct usba_request *req, int status)
+{
+	if (req->req.status == -EINPROGRESS)
+		req->req.status = status;
+
+	DBG(DBG_GADGET | DBG_REQ, "%s: req %p complete: status %d, actual %u\n",
+	    ep->ep.name, req, req->req.status, req->req.actual);
+
+	req->req.complete(&ep->ep, &req->req);
+}
+
+static void
+request_complete_list(struct usba_ep *ep, struct list_head *list, int status)
+{
+	struct usba_request *req, *tmp_req;
+
+	list_for_each_entry_safe(req, tmp_req, list, queue) {
+		list_del_init(&req->queue);
+		request_complete(ep, req, status);
+	}
+}
+
+static int
+usba_ep_enable(struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc)
+{
+	struct usba_ep *ep = to_usba_ep(_ep);
+	struct usba_udc *udc = ep->udc;
+	unsigned long flags, ept_cfg, maxpacket;
+	unsigned int nr_trans;
+
+	DBG(DBG_GADGET, "%s: ep_enable: desc=%p\n", ep->ep.name, desc);
+
+	maxpacket = usb_endpoint_maxp(desc) & 0x7ff;
+
+	if (((desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK)
+	      != ep->index) ||
+	      ep->index == 0 ||
+	      desc->bDescriptorType != USB_DT_ENDPOINT ||
+	      maxpacket == 0 ||
+	      maxpacket > ep->fifo_size) {
+		DBG(DBG_ERR, "ep_enable: Invalid argument");
+		return -EINVAL;
+	}
+
+	ep->is_isoc = 0;
+	ep->is_in = 0;
+
+	if (maxpacket <= 8)
+		ept_cfg = USBA_BF(EPT_SIZE, USBA_EPT_SIZE_8);
+	else
+		/* LSB is bit 1, not 0 */
+		ept_cfg = USBA_BF(EPT_SIZE, fls(maxpacket - 1) - 3);
+
+	DBG(DBG_HW, "%s: EPT_SIZE = %lu (maxpacket = %lu)\n",
+	    ep->ep.name, ept_cfg, maxpacket);
+
+	if (usb_endpoint_dir_in(desc)) {
+		ep->is_in = 1;
+		ept_cfg |= USBA_EPT_DIR_IN;
+	}
+
+	switch (usb_endpoint_type(desc)) {
+	case USB_ENDPOINT_XFER_CONTROL:
+		ept_cfg |= USBA_BF(EPT_TYPE, USBA_EPT_TYPE_CONTROL);
+		ept_cfg |= USBA_BF(BK_NUMBER, USBA_BK_NUMBER_ONE);
+		break;
+	case USB_ENDPOINT_XFER_ISOC:
+		if (!ep->can_isoc) {
+			DBG(DBG_ERR, "ep_enable: %s is not isoc capable\n",
+			    ep->ep.name);
+			return -EINVAL;
+		}
+
+		/*
+		 * Bits 11:12 specify number of _additional_
+		 * transactions per microframe.
+		 */
+		nr_trans = ((usb_endpoint_maxp(desc) >> 11) & 3) + 1;
+		if (nr_trans > 3)
+			return -EINVAL;
+
+		ep->is_isoc = 1;
+		ept_cfg |= USBA_BF(EPT_TYPE, USBA_EPT_TYPE_ISO);
+
+		/*
+		 * Do triple-buffering on high-bandwidth iso endpoints.
+		 */
+		if (nr_trans > 1 && ep->nr_banks == 3)
+			ept_cfg |= USBA_BF(BK_NUMBER, USBA_BK_NUMBER_TRIPLE);
+		else
+			ept_cfg |= USBA_BF(BK_NUMBER, USBA_BK_NUMBER_DOUBLE);
+		ept_cfg |= USBA_BF(NB_TRANS, nr_trans);
+		break;
+	case USB_ENDPOINT_XFER_BULK:
+		ept_cfg |= USBA_BF(EPT_TYPE, USBA_EPT_TYPE_BULK);
+		ept_cfg |= USBA_BF(BK_NUMBER, USBA_BK_NUMBER_ONE);
+		break;
+	case USB_ENDPOINT_XFER_INT:
+		ept_cfg |= USBA_BF(EPT_TYPE, USBA_EPT_TYPE_INT);
+		ept_cfg |= USBA_BF(BK_NUMBER, USBA_BK_NUMBER_ONE);
+		break;
+	}
+
+	spin_lock_irqsave(&ep->udc->lock, flags);
+
+	ep->desc = desc;
+	ep->ep.maxpacket = maxpacket;
+
+	usba_ep_writel(ep, CFG, ept_cfg);
+	usba_ep_writel(ep, CTL_ENB, USBA_EPT_ENABLE);
+
+	usba_writel(udc, INT_ENB,
+		    (usba_readl(udc, INT_ENB)
+		     | USBA_BF(EPT_INT, 1 << ep->index)));
+
+	spin_unlock_irqrestore(&udc->lock, flags);
+
+	DBG(DBG_HW, "EPT_CFG%d after init: %#08lx\n", ep->index,
+	    (unsigned long)usba_ep_readl(ep, CFG));
+	DBG(DBG_HW, "INT_ENB after init: %#08lx\n",
+	    (unsigned long)usba_readl(udc, INT_ENB));
+
+	return 0;
+}
+
+static int usba_ep_disable(struct usb_ep *_ep)
+{
+	struct usba_ep *ep = to_usba_ep(_ep);
+	struct usba_udc *udc = ep->udc;
+	LIST_HEAD(req_list);
+	unsigned long flags;
+
+	DBG(DBG_GADGET, "ep_disable: %s\n", ep->ep.name);
+
+	spin_lock_irqsave(&udc->lock, flags);
+
+	if (!ep->desc) {
+		spin_unlock_irqrestore(&udc->lock, flags);
+		/* REVISIT because this driver disables endpoints in
+		 * reset_all_endpoints() before calling disconnect(),
+		 * most gadget drivers would trigger this non-error ...
+		 */
+		if (udc->gadget.speed != USB_SPEED_UNKNOWN)
+			DBG(DBG_ERR, "ep_disable: %s not enabled\n",
+			    ep->ep.name);
+		return -EINVAL;
+	}
+	ep->desc = NULL;
+
+	list_splice_init(&ep->queue, &req_list);
+	usba_ep_writel(ep, CFG, 0);
+	usba_ep_writel(ep, CTL_DIS, USBA_EPT_ENABLE);
+	usba_writel(udc, INT_ENB,
+		    usba_readl(udc, INT_ENB) &
+		    ~USBA_BF(EPT_INT, 1 << ep->index));
+
+	request_complete_list(ep, &req_list, -ESHUTDOWN);
+
+	spin_unlock_irqrestore(&udc->lock, flags);
+
+	return 0;
+}
+
+static struct usb_request *
+usba_ep_alloc_request(struct usb_ep *_ep, gfp_t gfp_flags)
+{
+	struct usba_request *req;
+
+	DBG(DBG_GADGET, "ep_alloc_request: %p, 0x%x\n", _ep, gfp_flags);
+
+	req = malloc(sizeof(struct usba_request));
+	if (!req)
+		return NULL;
+
+	INIT_LIST_HEAD(&req->queue);
+
+	return &req->req;
+}
+
+static void
+usba_ep_free_request(struct usb_ep *_ep, struct usb_request *_req)
+{
+	struct usba_request *req = to_usba_req(_req);
+
+	DBG(DBG_GADGET, "ep_free_request: %p, %p\n", _ep, _req);
+
+	free(req);
+}
+
+static int
+usba_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
+{
+	struct usba_request *req = to_usba_req(_req);
+	struct usba_ep *ep = to_usba_ep(_ep);
+	struct usba_udc *udc = ep->udc;
+	unsigned long flags;
+	int ret;
+
+	DBG(DBG_GADGET | DBG_QUEUE | DBG_REQ, "%s: queue req %p, len %u\n",
+	    ep->ep.name, req, _req->length);
+
+	if (!udc->driver || udc->gadget.speed == USB_SPEED_UNKNOWN ||
+	    !ep->desc)
+		return -ESHUTDOWN;
+
+	req->submitted = 0;
+	req->using_dma = 0;
+	req->last_transaction = 0;
+
+	_req->status = -EINPROGRESS;
+	_req->actual = 0;
+
+	/* May have received a reset since last time we checked */
+	ret = -ESHUTDOWN;
+	spin_lock_irqsave(&udc->lock, flags);
+	if (ep->desc) {
+		list_add_tail(&req->queue, &ep->queue);
+
+		if ((!ep_is_control(ep) && ep->is_in) ||
+		    (ep_is_control(ep) && (ep->state == DATA_STAGE_IN ||
+		    ep->state == STATUS_STAGE_IN)))
+			usba_ep_writel(ep, CTL_ENB, USBA_TX_PK_RDY);
+		else
+			usba_ep_writel(ep, CTL_ENB, USBA_RX_BK_RDY);
+
+		ret = 0;
+	}
+	spin_unlock_irqrestore(&udc->lock, flags);
+
+	return ret;
+}
+
+static int usba_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req)
+{
+	struct usba_ep *ep = to_usba_ep(_ep);
+	struct usba_request *req = to_usba_req(_req);
+
+	DBG(DBG_GADGET | DBG_QUEUE, "ep_dequeue: %s, req %p\n",
+	    ep->ep.name, req);
+
+	/*
+	 * Errors should stop the queue from advancing until the
+	 * completion function returns.
+	 */
+	list_del_init(&req->queue);
+
+	request_complete(ep, req, -ECONNRESET);
+
+	/* Process the next request if any */
+	submit_next_request(ep);
+
+	return 0;
+}
+
+static int usba_ep_set_halt(struct usb_ep *_ep, int value)
+{
+	struct usba_ep *ep = to_usba_ep(_ep);
+	unsigned long flags;
+	int ret = 0;
+
+	DBG(DBG_GADGET, "endpoint %s: %s HALT\n", ep->ep.name,
+	    value ? "set" : "clear");
+
+	if (!ep->desc) {
+		DBG(DBG_ERR, "Attempted to halt uninitialized ep %s\n",
+		    ep->ep.name);
+		return -ENODEV;
+	}
+
+	if (ep->is_isoc) {
+		DBG(DBG_ERR, "Attempted to halt isochronous ep %s\n",
+		    ep->ep.name);
+		return -ENOTTY;
+	}
+
+	spin_lock_irqsave(&udc->lock, flags);
+
+	/*
+	 * We can't halt IN endpoints while there are still data to be
+	 * transferred
+	 */
+	if (!list_empty(&ep->queue) ||
+	    ((value && ep->is_in && (usba_ep_readl(ep, STA) &
+	    USBA_BF(BUSY_BANKS, -1L))))) {
+		ret = -EAGAIN;
+	} else {
+		if (value)
+			usba_ep_writel(ep, SET_STA, USBA_FORCE_STALL);
+		else
+			usba_ep_writel(ep, CLR_STA,
+				       USBA_FORCE_STALL | USBA_TOGGLE_CLR);
+		usba_ep_readl(ep, STA);
+	}
+
+	spin_unlock_irqrestore(&udc->lock, flags);
+
+	return ret;
+}
+
+static int usba_ep_fifo_status(struct usb_ep *_ep)
+{
+	struct usba_ep *ep = to_usba_ep(_ep);
+
+	return USBA_BFEXT(BYTE_COUNT, usba_ep_readl(ep, STA));
+}
+
+static void usba_ep_fifo_flush(struct usb_ep *_ep)
+{
+	struct usba_ep *ep = to_usba_ep(_ep);
+	struct usba_udc *udc = ep->udc;
+
+	usba_writel(udc, EPT_RST, 1 << ep->index);
+}
+
+static const struct usb_ep_ops usba_ep_ops = {
+	.enable		= usba_ep_enable,
+	.disable	= usba_ep_disable,
+	.alloc_request	= usba_ep_alloc_request,
+	.free_request	= usba_ep_free_request,
+	.queue		= usba_ep_queue,
+	.dequeue	= usba_ep_dequeue,
+	.set_halt	= usba_ep_set_halt,
+	.fifo_status	= usba_ep_fifo_status,
+	.fifo_flush	= usba_ep_fifo_flush,
+};
+
+static int usba_udc_get_frame(struct usb_gadget *gadget)
+{
+	struct usba_udc *udc = to_usba_udc(gadget);
+
+	return USBA_BFEXT(FRAME_NUMBER, usba_readl(udc, FNUM));
+}
+
+static int usba_udc_wakeup(struct usb_gadget *gadget)
+{
+	struct usba_udc *udc = to_usba_udc(gadget);
+	unsigned long flags;
+	u32 ctrl;
+	int ret = -EINVAL;
+
+	spin_lock_irqsave(&udc->lock, flags);
+	if (udc->devstatus & (1 << USB_DEVICE_REMOTE_WAKEUP)) {
+		ctrl = usba_readl(udc, CTRL);
+		usba_writel(udc, CTRL, ctrl | USBA_REMOTE_WAKE_UP);
+		ret = 0;
+	}
+	spin_unlock_irqrestore(&udc->lock, flags);
+
+	return ret;
+}
+
+static int
+usba_udc_set_selfpowered(struct usb_gadget *gadget, int is_selfpowered)
+{
+	struct usba_udc *udc = to_usba_udc(gadget);
+	unsigned long flags;
+
+	spin_lock_irqsave(&udc->lock, flags);
+	if (is_selfpowered)
+		udc->devstatus |= 1 << USB_DEVICE_SELF_POWERED;
+	else
+		udc->devstatus &= ~(1 << USB_DEVICE_SELF_POWERED);
+	spin_unlock_irqrestore(&udc->lock, flags);
+
+	return 0;
+}
+
+static const struct usb_gadget_ops usba_udc_ops = {
+	.get_frame		= usba_udc_get_frame,
+	.wakeup			= usba_udc_wakeup,
+	.set_selfpowered	= usba_udc_set_selfpowered,
+};
+
+static struct usb_endpoint_descriptor usba_ep0_desc = {
+	.bLength = USB_DT_ENDPOINT_SIZE,
+	.bDescriptorType = USB_DT_ENDPOINT,
+	.bEndpointAddress = 0,
+	.bmAttributes = USB_ENDPOINT_XFER_CONTROL,
+	.wMaxPacketSize = cpu_to_le16(64),
+	/* FIXME: I have no idea what to put here */
+	.bInterval = 1,
+};
+
+/*
+ * Called with interrupts disabled and udc->lock held.
+ */
+static void reset_all_endpoints(struct usba_udc *udc)
+{
+	struct usba_ep *ep;
+	struct usba_request *req, *tmp_req;
+
+	usba_writel(udc, EPT_RST, ~0UL);
+
+	ep = to_usba_ep(udc->gadget.ep0);
+	list_for_each_entry_safe(req, tmp_req, &ep->queue, queue) {
+		list_del_init(&req->queue);
+		request_complete(ep, req, -ECONNRESET);
+	}
+
+	/* NOTE:  normally, the next call to the gadget driver is in
+	 * charge of disabling endpoints... usually disconnect().
+	 * The exception would be entering a high speed test mode.
+	 *
+	 * FIXME remove this code ... and retest thoroughly.
+	 */
+	list_for_each_entry(ep, &udc->gadget.ep_list, ep.ep_list) {
+		if (ep->desc) {
+			spin_unlock(&udc->lock);
+			usba_ep_disable(&ep->ep);
+			spin_lock(&udc->lock);
+		}
+	}
+}
+
+static struct usba_ep *get_ep_by_addr(struct usba_udc *udc, u16 wIndex)
+{
+	struct usba_ep *ep;
+
+	if ((wIndex & USB_ENDPOINT_NUMBER_MASK) == 0)
+		return to_usba_ep(udc->gadget.ep0);
+
+	list_for_each_entry(ep, &udc->gadget.ep_list, ep.ep_list) {
+		u8 bEndpointAddress;
+
+		if (!ep->desc)
+			continue;
+		bEndpointAddress = ep->desc->bEndpointAddress;
+		if ((wIndex ^ bEndpointAddress) & USB_DIR_IN)
+			continue;
+		if ((bEndpointAddress & USB_ENDPOINT_NUMBER_MASK)
+				== (wIndex & USB_ENDPOINT_NUMBER_MASK))
+			return ep;
+	}
+
+	return NULL;
+}
+
+/* Called with interrupts disabled and udc->lock held */
+static inline void set_protocol_stall(struct usba_udc *udc, struct usba_ep *ep)
+{
+	usba_ep_writel(ep, SET_STA, USBA_FORCE_STALL);
+	ep->state = WAIT_FOR_SETUP;
+}
+
+static inline int is_stalled(struct usba_udc *udc, struct usba_ep *ep)
+{
+	if (usba_ep_readl(ep, STA) & USBA_FORCE_STALL)
+		return 1;
+	return 0;
+}
+
+static inline void set_address(struct usba_udc *udc, unsigned int addr)
+{
+	u32 regval;
+
+	DBG(DBG_BUS, "setting address %u...\n", addr);
+	regval = usba_readl(udc, CTRL);
+	regval = USBA_BFINS(DEV_ADDR, addr, regval);
+	usba_writel(udc, CTRL, regval);
+}
+
+static int do_test_mode(struct usba_udc *udc)
+{
+	static const char test_packet_buffer[] = {
+		/* JKJKJKJK * 9 */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		/* JJKKJJKK * 8 */
+		0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+		/* JJKKJJKK * 8 */
+		0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE,
+		/* JJJJJJJKKKKKKK * 8 */
+		0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+		/* JJJJJJJK * 8 */
+		0x7F, 0xBF, 0xDF, 0xEF, 0xF7, 0xFB, 0xFD,
+		/* {JKKKKKKK * 10}, JK */
+		0xFC, 0x7E, 0xBF, 0xDF, 0xEF, 0xF7, 0xFB, 0xFD, 0x7E
+	};
+	struct usba_ep *ep;
+	int test_mode;
+
+	test_mode = udc->test_mode;
+
+	/* Start from a clean slate */
+	reset_all_endpoints(udc);
+
+	switch (test_mode) {
+	case 0x0100:
+		/* Test_J */
+		usba_writel(udc, TST, USBA_TST_J_MODE);
+		DBG(DBG_ALL, "Entering Test_J mode...\n");
+		break;
+	case 0x0200:
+		/* Test_K */
+		usba_writel(udc, TST, USBA_TST_K_MODE);
+		DBG(DBG_ALL, "Entering Test_K mode...\n");
+		break;
+	case 0x0300:
+		/*
+		 * Test_SE0_NAK: Force high-speed mode and set up ep0
+		 * for Bulk IN transfers
+		 */
+		ep = &udc->usba_ep[0];
+		usba_writel(udc, TST,
+			    USBA_BF(SPEED_CFG, USBA_SPEED_CFG_FORCE_HIGH));
+		usba_ep_writel(ep, CFG,
+			       USBA_BF(EPT_SIZE, USBA_EPT_SIZE_64)
+			       | USBA_EPT_DIR_IN
+			       | USBA_BF(EPT_TYPE, USBA_EPT_TYPE_BULK)
+			       | USBA_BF(BK_NUMBER, 1));
+		if (!(usba_ep_readl(ep, CFG) & USBA_EPT_MAPPED)) {
+			set_protocol_stall(udc, ep);
+			DBG(DBG_ALL, "Test_SE0_NAK: ep0 not mapped\n");
+		} else {
+			usba_ep_writel(ep, CTL_ENB, USBA_EPT_ENABLE);
+			DBG(DBG_ALL, "Entering Test_SE0_NAK mode...\n");
+		}
+		break;
+	case 0x0400:
+		/* Test_Packet */
+		ep = &udc->usba_ep[0];
+		usba_ep_writel(ep, CFG,
+			       USBA_BF(EPT_SIZE, USBA_EPT_SIZE_64)
+			       | USBA_EPT_DIR_IN
+			       | USBA_BF(EPT_TYPE, USBA_EPT_TYPE_BULK)
+			       | USBA_BF(BK_NUMBER, 1));
+		if (!(usba_ep_readl(ep, CFG) & USBA_EPT_MAPPED)) {
+			set_protocol_stall(udc, ep);
+			DBG(DBG_ALL, "Test_Packet: ep0 not mapped\n");
+		} else {
+			usba_ep_writel(ep, CTL_ENB, USBA_EPT_ENABLE);
+			usba_writel(udc, TST, USBA_TST_PKT_MODE);
+			memcpy(ep->fifo, test_packet_buffer,
+			       sizeof(test_packet_buffer));
+			usba_ep_writel(ep, SET_STA, USBA_TX_PK_RDY);
+			DBG(DBG_ALL, "Entering Test_Packet mode...\n");
+		}
+		break;
+	default:
+		DBG(DBG_ERR, "Invalid test mode: 0x%04x\n", test_mode);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/* Avoid overly long expressions */
+static inline bool feature_is_dev_remote_wakeup(struct usb_ctrlrequest *crq)
+{
+	if (crq->wValue == cpu_to_le16(USB_DEVICE_REMOTE_WAKEUP))
+		return true;
+	return false;
+}
+
+static inline bool feature_is_dev_test_mode(struct usb_ctrlrequest *crq)
+{
+	if (crq->wValue == cpu_to_le16(USB_DEVICE_TEST_MODE))
+		return true;
+	return false;
+}
+
+static inline bool feature_is_ep_halt(struct usb_ctrlrequest *crq)
+{
+	if (crq->wValue == cpu_to_le16(USB_ENDPOINT_HALT))
+		return true;
+	return false;
+}
+
+static int handle_ep0_setup(struct usba_udc *udc, struct usba_ep *ep,
+		struct usb_ctrlrequest *crq)
+{
+	int retval = 0;
+
+	switch (crq->bRequest) {
+	case USB_REQ_GET_STATUS: {
+		u16 status;
+
+		if (crq->bRequestType == (USB_DIR_IN | USB_RECIP_DEVICE)) {
+			status = cpu_to_le16(udc->devstatus);
+		} else if (crq->bRequestType
+				== (USB_DIR_IN | USB_RECIP_INTERFACE)) {
+			status = cpu_to_le16(0);
+		} else if (crq->bRequestType
+				== (USB_DIR_IN | USB_RECIP_ENDPOINT)) {
+			struct usba_ep *target;
+
+			target = get_ep_by_addr(udc, le16_to_cpu(crq->wIndex));
+			if (!target)
+				goto stall;
+
+			status = 0;
+			if (is_stalled(udc, target))
+				status |= cpu_to_le16(1);
+		} else {
+			goto delegate;
+		}
+
+		/* Write directly to the FIFO. No queueing is done. */
+		if (crq->wLength != cpu_to_le16(sizeof(status)))
+			goto stall;
+		ep->state = DATA_STAGE_IN;
+		__raw_writew(status, ep->fifo);
+		usba_ep_writel(ep, SET_STA, USBA_TX_PK_RDY);
+		break;
+	}
+
+	case USB_REQ_CLEAR_FEATURE: {
+		if (crq->bRequestType == USB_RECIP_DEVICE) {
+			if (feature_is_dev_remote_wakeup(crq))
+				udc->devstatus
+					&= ~(1 << USB_DEVICE_REMOTE_WAKEUP);
+			else
+				/* Can't CLEAR_FEATURE TEST_MODE */
+				goto stall;
+		} else if (crq->bRequestType == USB_RECIP_ENDPOINT) {
+			struct usba_ep *target;
+
+			if (crq->wLength != cpu_to_le16(0) ||
+			    !feature_is_ep_halt(crq))
+				goto stall;
+			target = get_ep_by_addr(udc, le16_to_cpu(crq->wIndex));
+			if (!target)
+				goto stall;
+
+			usba_ep_writel(target, CLR_STA, USBA_FORCE_STALL);
+			if (target->index != 0)
+				usba_ep_writel(target, CLR_STA,
+					       USBA_TOGGLE_CLR);
+		} else {
+			goto delegate;
+		}
+
+		send_status(udc, ep);
+		break;
+	}
+
+	case USB_REQ_SET_FEATURE: {
+		if (crq->bRequestType == USB_RECIP_DEVICE) {
+			if (feature_is_dev_test_mode(crq)) {
+				send_status(udc, ep);
+				ep->state = STATUS_STAGE_TEST;
+				udc->test_mode = le16_to_cpu(crq->wIndex);
+				return 0;
+			} else if (feature_is_dev_remote_wakeup(crq)) {
+				udc->devstatus |= 1 << USB_DEVICE_REMOTE_WAKEUP;
+			} else {
+				goto stall;
+			}
+		} else if (crq->bRequestType == USB_RECIP_ENDPOINT) {
+			struct usba_ep *target;
+
+			if (crq->wLength != cpu_to_le16(0) ||
+			    !feature_is_ep_halt(crq))
+				goto stall;
+
+			target = get_ep_by_addr(udc, le16_to_cpu(crq->wIndex));
+			if (!target)
+				goto stall;
+
+			usba_ep_writel(target, SET_STA, USBA_FORCE_STALL);
+		} else {
+			goto delegate;
+		}
+
+		send_status(udc, ep);
+		break;
+	}
+
+	case USB_REQ_SET_ADDRESS:
+		if (crq->bRequestType != (USB_DIR_OUT | USB_RECIP_DEVICE))
+			goto delegate;
+
+		set_address(udc, le16_to_cpu(crq->wValue));
+		send_status(udc, ep);
+		ep->state = STATUS_STAGE_ADDR;
+		break;
+
+	default:
+delegate:
+		spin_unlock(&udc->lock);
+		retval = udc->driver->setup(&udc->gadget, crq);
+		spin_lock(&udc->lock);
+	}
+
+	return retval;
+
+stall:
+	DBG(DBG_ALL, "%s: Invalid setup request: %02x.%02x v%04x i%04x l%d\n",
+	    ep->ep.name, crq->bRequestType, crq->bRequest,
+	    le16_to_cpu(crq->wValue), le16_to_cpu(crq->wIndex),
+	    le16_to_cpu(crq->wLength));
+	set_protocol_stall(udc, ep);
+
+	return -1;
+}
+
+static void usba_control_irq(struct usba_udc *udc, struct usba_ep *ep)
+{
+	struct usba_request *req;
+	u32 epstatus;
+	u32 epctrl;
+
+restart:
+	epstatus = usba_ep_readl(ep, STA);
+	epctrl = usba_ep_readl(ep, CTL);
+
+	DBG(DBG_INT, "%s [%d]: s/%08x c/%08x\n",
+	    ep->ep.name, ep->state, epstatus, epctrl);
+
+	req = NULL;
+	if (!list_empty(&ep->queue))
+		req = list_entry(ep->queue.next,
+				 struct usba_request, queue);
+
+	if ((epctrl & USBA_TX_PK_RDY) && !(epstatus & USBA_TX_PK_RDY)) {
+		if (req->submitted)
+			next_fifo_transaction(ep, req);
+		else
+			submit_request(ep, req);
+
+		if (req->last_transaction) {
+			usba_ep_writel(ep, CTL_DIS, USBA_TX_PK_RDY);
+			usba_ep_writel(ep, CTL_ENB, USBA_TX_COMPLETE);
+		}
+		goto restart;
+	}
+	if ((epstatus & epctrl) & USBA_TX_COMPLETE) {
+		usba_ep_writel(ep, CLR_STA, USBA_TX_COMPLETE);
+
+		switch (ep->state) {
+		case DATA_STAGE_IN:
+			usba_ep_writel(ep, CTL_ENB, USBA_RX_BK_RDY);
+			usba_ep_writel(ep, CTL_DIS, USBA_TX_COMPLETE);
+			ep->state = STATUS_STAGE_OUT;
+			break;
+		case STATUS_STAGE_ADDR:
+			/* Activate our new address */
+			usba_writel(udc, CTRL, (usba_readl(udc, CTRL)
+						| USBA_FADDR_EN));
+			usba_ep_writel(ep, CTL_DIS, USBA_TX_COMPLETE);
+			ep->state = WAIT_FOR_SETUP;
+			break;
+		case STATUS_STAGE_IN:
+			if (req) {
+				list_del_init(&req->queue);
+				request_complete(ep, req, 0);
+				submit_next_request(ep);
+			}
+			usba_ep_writel(ep, CTL_DIS, USBA_TX_COMPLETE);
+			ep->state = WAIT_FOR_SETUP;
+			break;
+		case STATUS_STAGE_TEST:
+			usba_ep_writel(ep, CTL_DIS, USBA_TX_COMPLETE);
+			ep->state = WAIT_FOR_SETUP;
+			if (do_test_mode(udc))
+				set_protocol_stall(udc, ep);
+			break;
+		default:
+			DBG(DBG_ALL, "%s: TXCOMP: Invalid endpoint state %d\n",
+			    ep->ep.name, ep->state);
+			set_protocol_stall(udc, ep);
+			break;
+		}
+
+		goto restart;
+	}
+	if ((epstatus & epctrl) & USBA_RX_BK_RDY) {
+		switch (ep->state) {
+		case STATUS_STAGE_OUT:
+			usba_ep_writel(ep, CLR_STA, USBA_RX_BK_RDY);
+			usba_ep_writel(ep, CTL_DIS, USBA_RX_BK_RDY);
+
+			if (req) {
+				list_del_init(&req->queue);
+				request_complete(ep, req, 0);
+			}
+			ep->state = WAIT_FOR_SETUP;
+			break;
+
+		case DATA_STAGE_OUT:
+			receive_data(ep);
+			break;
+
+		default:
+			usba_ep_writel(ep, CLR_STA, USBA_RX_BK_RDY);
+			usba_ep_writel(ep, CTL_DIS, USBA_RX_BK_RDY);
+			DBG(DBG_ALL, "%s: RXRDY: Invalid endpoint state %d\n",
+			    ep->ep.name, ep->state);
+			set_protocol_stall(udc, ep);
+			break;
+		}
+
+		goto restart;
+	}
+	if (epstatus & USBA_RX_SETUP) {
+		union {
+			struct usb_ctrlrequest crq;
+			unsigned long data[2];
+		} crq;
+		unsigned int pkt_len;
+		int ret;
+
+		if (ep->state != WAIT_FOR_SETUP) {
+			/*
+			 * Didn't expect a SETUP packet at this
+			 * point. Clean up any pending requests (which
+			 * may be successful).
+			 */
+			int status = -EPROTO;
+
+			/*
+			 * RXRDY and TXCOMP are dropped when SETUP
+			 * packets arrive.  Just pretend we received
+			 * the status packet.
+			 */
+			if (ep->state == STATUS_STAGE_OUT ||
+			    ep->state == STATUS_STAGE_IN) {
+				usba_ep_writel(ep, CTL_DIS, USBA_RX_BK_RDY);
+				status = 0;
+			}
+
+			if (req) {
+				list_del_init(&req->queue);
+				request_complete(ep, req, status);
+			}
+		}
+
+		pkt_len = USBA_BFEXT(BYTE_COUNT, usba_ep_readl(ep, STA));
+		DBG(DBG_HW, "Packet length: %u\n", pkt_len);
+		if (pkt_len != sizeof(crq)) {
+			DBG(DBG_ALL, "udc: Invalid length %u (expected %zu)\n",
+			    pkt_len, sizeof(crq));
+			set_protocol_stall(udc, ep);
+			return;
+		}
+
+		DBG(DBG_FIFO, "Copying ctrl request from 0x%p:\n", ep->fifo);
+		memcpy(crq.data, ep->fifo, sizeof(crq));
+
+		/* Free up one bank in the FIFO so that we can
+		 * generate or receive a reply right away. */
+		usba_ep_writel(ep, CLR_STA, USBA_RX_SETUP);
+
+		if (crq.crq.bRequestType & USB_DIR_IN) {
+			/*
+			 * The USB 2.0 spec states that "if wLength is
+			 * zero, there is no data transfer phase."
+			 * However, testusb #14 seems to actually
+			 * expect a data phase even if wLength = 0...
+			 */
+			ep->state = DATA_STAGE_IN;
+		} else {
+			if (crq.crq.wLength != cpu_to_le16(0))
+				ep->state = DATA_STAGE_OUT;
+			else
+				ep->state = STATUS_STAGE_IN;
+		}
+
+		ret = -1;
+		if (ep->index == 0) {
+			ret = handle_ep0_setup(udc, ep, &crq.crq);
+		} else {
+			spin_unlock(&udc->lock);
+			ret = udc->driver->setup(&udc->gadget, &crq.crq);
+			spin_lock(&udc->lock);
+		}
+
+		DBG(DBG_BUS, "req %02x.%02x, length %d, state %d, ret %d\n",
+		    crq.crq.bRequestType, crq.crq.bRequest,
+		    le16_to_cpu(crq.crq.wLength), ep->state, ret);
+
+		if (ret < 0) {
+			/* Let the host know that we failed */
+			set_protocol_stall(udc, ep);
+		}
+	}
+}
+
+static void usba_ep_irq(struct usba_udc *udc, struct usba_ep *ep)
+{
+	struct usba_request *req;
+	u32 epstatus;
+	u32 epctrl;
+
+	epstatus = usba_ep_readl(ep, STA);
+	epctrl = usba_ep_readl(ep, CTL);
+
+	DBG(DBG_INT, "%s: interrupt, status: 0x%08x\n", ep->ep.name, epstatus);
+
+	while ((epctrl & USBA_TX_PK_RDY) && !(epstatus & USBA_TX_PK_RDY)) {
+		DBG(DBG_BUS, "%s: TX PK ready\n", ep->ep.name);
+
+		if (list_empty(&ep->queue)) {
+			DBG(DBG_INT, "ep_irq: queue empty\n");
+			usba_ep_writel(ep, CTL_DIS, USBA_TX_PK_RDY);
+			return;
+		}
+
+		req = list_entry(ep->queue.next, struct usba_request, queue);
+
+		if (req->submitted)
+			next_fifo_transaction(ep, req);
+		else
+			submit_request(ep, req);
+
+		if (req->last_transaction) {
+			list_del_init(&req->queue);
+			submit_next_request(ep);
+			request_complete(ep, req, 0);
+		}
+
+		epstatus = usba_ep_readl(ep, STA);
+		epctrl = usba_ep_readl(ep, CTL);
+	}
+
+	if ((epstatus & epctrl) & USBA_RX_BK_RDY) {
+		DBG(DBG_BUS, "%s: RX data ready\n", ep->ep.name);
+		receive_data(ep);
+		usba_ep_writel(ep, CLR_STA, USBA_RX_BK_RDY);
+	}
+}
+
+static int usba_udc_irq(struct usba_udc *udc)
+{
+	u32 status, ep_status;
+
+	spin_lock(&udc->lock);
+
+	status = usba_readl(udc, INT_STA);
+	DBG(DBG_INT, "irq, status=%#08x\n", status);
+
+	if (status & USBA_DET_SUSPEND) {
+		usba_writel(udc, INT_CLR, USBA_DET_SUSPEND);
+		DBG(DBG_BUS, "Suspend detected\n");
+		if (udc->gadget.speed != USB_SPEED_UNKNOWN &&
+		    udc->driver && udc->driver->suspend) {
+			spin_unlock(&udc->lock);
+			udc->driver->suspend(&udc->gadget);
+			spin_lock(&udc->lock);
+		}
+	}
+
+	if (status & USBA_WAKE_UP) {
+		usba_writel(udc, INT_CLR, USBA_WAKE_UP);
+		DBG(DBG_BUS, "Wake Up CPU detected\n");
+	}
+
+	if (status & USBA_END_OF_RESUME) {
+		usba_writel(udc, INT_CLR, USBA_END_OF_RESUME);
+		DBG(DBG_BUS, "Resume detected\n");
+		if (udc->gadget.speed != USB_SPEED_UNKNOWN &&
+		    udc->driver && udc->driver->resume) {
+			spin_unlock(&udc->lock);
+			udc->driver->resume(&udc->gadget);
+			spin_lock(&udc->lock);
+		}
+	}
+
+	ep_status = USBA_BFEXT(EPT_INT, status);
+	if (ep_status) {
+		int i;
+
+		for (i = 0; i < USBA_NR_ENDPOINTS; i++)
+			if (ep_status & (1 << i)) {
+				if (ep_is_control(&udc->usba_ep[i]))
+					usba_control_irq(udc, &udc->usba_ep[i]);
+				else
+					usba_ep_irq(udc, &udc->usba_ep[i]);
+			}
+	}
+
+	if (status & USBA_END_OF_RESET) {
+		struct usba_ep *ep0;
+
+		usba_writel(udc, INT_CLR, USBA_END_OF_RESET);
+		reset_all_endpoints(udc);
+
+		if (udc->gadget.speed != USB_SPEED_UNKNOWN &&
+		    udc->driver->disconnect) {
+			udc->gadget.speed = USB_SPEED_UNKNOWN;
+			spin_unlock(&udc->lock);
+			udc->driver->disconnect(&udc->gadget);
+			spin_lock(&udc->lock);
+		}
+
+		if (status & USBA_HIGH_SPEED)
+			udc->gadget.speed = USB_SPEED_HIGH;
+		else
+			udc->gadget.speed = USB_SPEED_FULL;
+
+		ep0 = &udc->usba_ep[0];
+		ep0->desc = &usba_ep0_desc;
+		ep0->state = WAIT_FOR_SETUP;
+		usba_ep_writel(ep0, CFG,
+			       (USBA_BF(EPT_SIZE, EP0_EPT_SIZE)
+				| USBA_BF(EPT_TYPE, USBA_EPT_TYPE_CONTROL)
+				| USBA_BF(BK_NUMBER, USBA_BK_NUMBER_ONE)));
+		usba_ep_writel(ep0, CTL_ENB,
+			       USBA_EPT_ENABLE | USBA_RX_SETUP);
+		usba_writel(udc, INT_ENB,
+			    (usba_readl(udc, INT_ENB)
+			     | USBA_BF(EPT_INT, 1)
+			     | USBA_DET_SUSPEND
+			     | USBA_END_OF_RESUME));
+
+		/*
+		 * Unclear why we hit this irregularly, e.g. in usbtest,
+		 * but it's clearly harmless...
+		 */
+		if (!(usba_ep_readl(ep0, CFG) & USBA_EPT_MAPPED))
+			DBG(DBG_ALL, "ODD: EP0 configuration is invalid!\n");
+	}
+
+	spin_unlock(&udc->lock);
+
+	return 0;
+}
+
+static int atmel_usba_start(struct usba_udc *udc)
+{
+	udc->devstatus = 1 << USB_DEVICE_SELF_POWERED;
+
+	udc->vbus_prev = 0;
+
+	/* If Vbus is present, enable the controller and wait for reset */
+	if (vbus_is_present(udc) && udc->vbus_prev == 0) {
+		usba_writel(udc, CTRL, USBA_ENABLE_MASK);
+		usba_writel(udc, INT_ENB, USBA_END_OF_RESET);
+	}
+
+	return 0;
+}
+
+static int atmel_usba_stop(struct usba_udc *udc)
+{
+	udc->gadget.speed = USB_SPEED_UNKNOWN;
+	reset_all_endpoints(udc);
+
+	/* This will also disable the DP pullup */
+	usba_writel(udc, CTRL, USBA_DISABLE_MASK);
+
+	return 0;
+}
+
+static struct usba_udc controller = {
+	.regs = (unsigned *)ATMEL_BASE_UDPHS,
+	.fifo = (unsigned *)ATMEL_BASE_UDPHS_FIFO,
+	.gadget = {
+		.ops		= &usba_udc_ops,
+		.ep_list	= LIST_HEAD_INIT(controller.gadget.ep_list),
+		.speed		= USB_SPEED_HIGH,
+		.is_dualspeed	= 1,
+		.name		= "atmel_usba_udc",
+	},
+};
+
+int usb_gadget_handle_interrupts(void)
+{
+	struct usba_udc *udc = &controller;
+
+	return usba_udc_irq(udc);
+}
+
+
+int usb_gadget_register_driver(struct usb_gadget_driver *driver)
+{
+	struct usba_udc *udc = &controller;
+	int ret;
+
+	if (!driver || !driver->bind || !driver->setup) {
+		printf("bad paramter\n");
+		return -EINVAL;
+	}
+
+	if (udc->driver) {
+		printf("UDC already has a gadget driver\n");
+		return -EBUSY;
+	}
+
+	atmel_usba_start(udc);
+
+	udc->driver = driver;
+
+	ret = driver->bind(&udc->gadget);
+	if (ret) {
+		error("driver->bind() returned %d\n", ret);
+		udc->driver = NULL;
+	}
+
+	return ret;
+}
+
+int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
+{
+	struct usba_udc *udc = &controller;
+
+	if (!driver || !driver->unbind || !driver->disconnect) {
+		error("bad paramter\n");
+		return -EINVAL;
+	}
+
+	driver->disconnect(&udc->gadget);
+	driver->unbind(&udc->gadget);
+	udc->driver = NULL;
+
+	atmel_usba_stop(udc);
+
+	return 0;
+}
+
+static struct usba_ep *usba_udc_pdata(struct usba_platform_data *pdata,
+				      struct usba_udc *udc)
+{
+	struct usba_ep *eps;
+	int i;
+
+	eps = malloc(sizeof(struct usba_ep) * pdata->num_ep);
+	if (!eps) {
+		error("failed to alloc eps\n");
+		return NULL;
+	}
+
+	udc->gadget.ep0 = &eps[0].ep;
+
+	INIT_LIST_HEAD(&udc->gadget.ep_list);
+	INIT_LIST_HEAD(&eps[0].ep.ep_list);
+
+	for (i = 0; i < pdata->num_ep; i++) {
+		struct usba_ep *ep = &eps[i];
+
+		ep->ep_regs = udc->regs + USBA_EPT_BASE(i);
+		ep->dma_regs = udc->regs + USBA_DMA_BASE(i);
+		ep->fifo = udc->fifo + USBA_FIFO_BASE(i);
+		ep->ep.ops = &usba_ep_ops;
+		ep->ep.name = pdata->ep[i].name;
+		ep->ep.maxpacket = pdata->ep[i].fifo_size;
+		ep->fifo_size = ep->ep.maxpacket;
+		ep->udc = udc;
+		INIT_LIST_HEAD(&ep->queue);
+		ep->nr_banks = pdata->ep[i].nr_banks;
+		ep->index = pdata->ep[i].index;
+		ep->can_dma = pdata->ep[i].can_dma;
+		ep->can_isoc = pdata->ep[i].can_isoc;
+		if (i)
+			list_add_tail(&ep->ep.ep_list, &udc->gadget.ep_list);
+	};
+
+	return eps;
+}
+
+int usba_udc_probe(struct usba_platform_data *pdata)
+{
+	struct usba_udc *udc;
+
+	udc = &controller;
+
+	udc->usba_ep = usba_udc_pdata(pdata, udc);
+
+	return 0;
+}
diff --git a/drivers/usb/gadget/atmel_usba_udc.h b/drivers/usb/gadget/atmel_usba_udc.h
new file mode 100644
index 0000000..92e462d
--- /dev/null
+++ b/drivers/usb/gadget/atmel_usba_udc.h
@@ -0,0 +1,326 @@
+/*
+ * Register definition for Atmel USBA high speed USB device controller
+ * [Original from Linux kernel: drivers/usb/gadget/atmel_usba_udc.h]
+ *
+ * Copyright (C) 2005-2013 Atmel Corporation
+ *			   Bo Shen <voice.shen@atmel.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#ifndef __LINUX_USB_GADGET_USBA_UDC_H__
+#define __LINUX_USB_GADGET_USBA_UDC_H__
+
+/* USB register offsets */
+#define USBA_CTRL				0x0000
+#define USBA_FNUM				0x0004
+#define USBA_INT_ENB				0x0010
+#define USBA_INT_STA				0x0014
+#define USBA_INT_CLR				0x0018
+#define USBA_EPT_RST				0x001c
+#define USBA_TST				0x00e0
+
+/* USB endpoint register offsets */
+#define USBA_EPT_CFG				0x0000
+#define USBA_EPT_CTL_ENB			0x0004
+#define USBA_EPT_CTL_DIS			0x0008
+#define USBA_EPT_CTL				0x000c
+#define USBA_EPT_SET_STA			0x0014
+#define USBA_EPT_CLR_STA			0x0018
+#define USBA_EPT_STA				0x001c
+
+/* USB DMA register offsets */
+#define USBA_DMA_NXT_DSC			0x0000
+#define USBA_DMA_ADDRESS			0x0004
+#define USBA_DMA_CONTROL			0x0008
+#define USBA_DMA_STATUS				0x000c
+
+/* Bitfields in CTRL */
+#define USBA_DEV_ADDR_OFFSET			0
+#define USBA_DEV_ADDR_SIZE			7
+#define USBA_FADDR_EN				(1 <<  7)
+#define USBA_EN_USBA				(1 <<  8)
+#define USBA_DETACH				(1 <<  9)
+#define USBA_REMOTE_WAKE_UP			(1 << 10)
+#define USBA_PULLD_DIS				(1 << 11)
+
+#if defined(CONFIG_AVR32)
+#define USBA_ENABLE_MASK			USBA_EN_USBA
+#define USBA_DISABLE_MASK			0
+#elif defined(CONFIG_AT91FAMILY)
+#define USBA_ENABLE_MASK			(USBA_EN_USBA | USBA_PULLD_DIS)
+#define USBA_DISABLE_MASK			USBA_DETACH
+#endif /* CONFIG_ARCH_AT91 */
+
+/* Bitfields in FNUM */
+#define USBA_MICRO_FRAME_NUM_OFFSET		0
+#define USBA_MICRO_FRAME_NUM_SIZE		3
+#define USBA_FRAME_NUMBER_OFFSET		3
+#define USBA_FRAME_NUMBER_SIZE			11
+#define USBA_FRAME_NUM_ERROR			(1 << 31)
+
+/* Bitfields in INT_ENB/INT_STA/INT_CLR */
+#define USBA_HIGH_SPEED				(1 <<  0)
+#define USBA_DET_SUSPEND			(1 <<  1)
+#define USBA_MICRO_SOF				(1 <<  2)
+#define USBA_SOF				(1 <<  3)
+#define USBA_END_OF_RESET			(1 <<  4)
+#define USBA_WAKE_UP				(1 <<  5)
+#define USBA_END_OF_RESUME			(1 <<  6)
+#define USBA_UPSTREAM_RESUME			(1 <<  7)
+#define USBA_EPT_INT_OFFSET			8
+#define USBA_EPT_INT_SIZE			16
+#define USBA_DMA_INT_OFFSET			24
+#define USBA_DMA_INT_SIZE			8
+
+/* Bitfields in EPT_RST */
+#define USBA_RST_OFFSET				0
+#define USBA_RST_SIZE				16
+
+/* Bitfields in USBA_TST */
+#define USBA_SPEED_CFG_OFFSET			0
+#define USBA_SPEED_CFG_SIZE			2
+#define USBA_TST_J_MODE				(1 <<  2)
+#define USBA_TST_K_MODE				(1 <<  3)
+#define USBA_TST_PKT_MODE			(1 <<  4)
+#define USBA_OPMODE2				(1 <<  5)
+
+/* Bitfields in EPT_CFG */
+#define USBA_EPT_SIZE_OFFSET			0
+#define USBA_EPT_SIZE_SIZE			3
+#define USBA_EPT_DIR_IN				(1 <<  3)
+#define USBA_EPT_TYPE_OFFSET			4
+#define USBA_EPT_TYPE_SIZE			2
+#define USBA_BK_NUMBER_OFFSET			6
+#define USBA_BK_NUMBER_SIZE			2
+#define USBA_NB_TRANS_OFFSET			8
+#define USBA_NB_TRANS_SIZE			2
+#define USBA_EPT_MAPPED				(1 << 31)
+
+/* Bitfields in EPT_CTL/EPT_CTL_ENB/EPT_CTL_DIS */
+#define USBA_EPT_ENABLE				(1 <<  0)
+#define USBA_AUTO_VALID				(1 <<  1)
+#define USBA_INTDIS_DMA				(1 <<  3)
+#define USBA_NYET_DIS				(1 <<  4)
+#define USBA_DATAX_RX				(1 <<  6)
+#define USBA_MDATA_RX				(1 <<  7)
+/* Bits 8-15 and 31 enable interrupts for respective bits in EPT_STA */
+#define USBA_BUSY_BANK_IE			(1 << 18)
+
+/* Bitfields in EPT_SET_STA/EPT_CLR_STA/EPT_STA */
+#define USBA_FORCE_STALL			(1 <<  5)
+#define USBA_TOGGLE_CLR				(1 <<  6)
+#define USBA_TOGGLE_SEQ_OFFSET			6
+#define USBA_TOGGLE_SEQ_SIZE			2
+#define USBA_ERR_OVFLW				(1 <<  8)
+#define USBA_RX_BK_RDY				(1 <<  9)
+#define USBA_KILL_BANK				(1 <<  9)
+#define USBA_TX_COMPLETE			(1 << 10)
+#define USBA_TX_PK_RDY				(1 << 11)
+#define USBA_ISO_ERR_TRANS			(1 << 11)
+#define USBA_RX_SETUP				(1 << 12)
+#define USBA_ISO_ERR_FLOW			(1 << 12)
+#define USBA_STALL_SENT				(1 << 13)
+#define USBA_ISO_ERR_CRC			(1 << 13)
+#define USBA_ISO_ERR_NBTRANS			(1 << 13)
+#define USBA_NAK_IN				(1 << 14)
+#define USBA_ISO_ERR_FLUSH			(1 << 14)
+#define USBA_NAK_OUT				(1 << 15)
+#define USBA_CURRENT_BANK_OFFSET		16
+#define USBA_CURRENT_BANK_SIZE			2
+#define USBA_BUSY_BANKS_OFFSET			18
+#define USBA_BUSY_BANKS_SIZE			2
+#define USBA_BYTE_COUNT_OFFSET			20
+#define USBA_BYTE_COUNT_SIZE			11
+#define USBA_SHORT_PACKET			(1 << 31)
+
+/* Bitfields in DMA_CONTROL */
+#define USBA_DMA_CH_EN				(1 <<  0)
+#define USBA_DMA_LINK				(1 <<  1)
+#define USBA_DMA_END_TR_EN			(1 <<  2)
+#define USBA_DMA_END_BUF_EN			(1 <<  3)
+#define USBA_DMA_END_TR_IE			(1 <<  4)
+#define USBA_DMA_END_BUF_IE			(1 <<  5)
+#define USBA_DMA_DESC_LOAD_IE			(1 <<  6)
+#define USBA_DMA_BURST_LOCK			(1 <<  7)
+#define USBA_DMA_BUF_LEN_OFFSET			16
+#define USBA_DMA_BUF_LEN_SIZE			16
+
+/* Bitfields in DMA_STATUS */
+#define USBA_DMA_CH_ACTIVE			(1 <<  1)
+#define USBA_DMA_END_TR_ST			(1 <<  4)
+#define USBA_DMA_END_BUF_ST			(1 <<  5)
+#define USBA_DMA_DESC_LOAD_ST			(1 <<  6)
+
+/* Constants for SPEED_CFG */
+#define USBA_SPEED_CFG_NORMAL			0
+#define USBA_SPEED_CFG_FORCE_HIGH		2
+#define USBA_SPEED_CFG_FORCE_FULL		3
+
+/* Constants for EPT_SIZE */
+#define USBA_EPT_SIZE_8				0
+#define USBA_EPT_SIZE_16			1
+#define USBA_EPT_SIZE_32			2
+#define USBA_EPT_SIZE_64			3
+#define USBA_EPT_SIZE_128			4
+#define USBA_EPT_SIZE_256			5
+#define USBA_EPT_SIZE_512			6
+#define USBA_EPT_SIZE_1024			7
+
+/* Constants for EPT_TYPE */
+#define USBA_EPT_TYPE_CONTROL			0
+#define USBA_EPT_TYPE_ISO			1
+#define USBA_EPT_TYPE_BULK			2
+#define USBA_EPT_TYPE_INT			3
+
+/* Constants for BK_NUMBER */
+#define USBA_BK_NUMBER_ZERO			0
+#define USBA_BK_NUMBER_ONE			1
+#define USBA_BK_NUMBER_DOUBLE			2
+#define USBA_BK_NUMBER_TRIPLE			3
+
+/* Bit manipulation macros */
+#define USBA_BF(name, value)					\
+	(((value) & ((1 << USBA_##name##_SIZE) - 1))		\
+	 << USBA_##name##_OFFSET)
+#define USBA_BFEXT(name, value)					\
+	(((value) >> USBA_##name##_OFFSET)			\
+	 & ((1 << USBA_##name##_SIZE) - 1))
+#define USBA_BFINS(name, value, old)				\
+	(((old) & ~(((1 << USBA_##name##_SIZE) - 1)		\
+		    << USBA_##name##_OFFSET))			\
+	 | USBA_BF(name, value))
+
+/* Register access macros */
+#define usba_readl(udc, reg)					\
+	__raw_readl((udc)->regs + USBA_##reg)
+#define usba_writel(udc, reg, value)				\
+	__raw_writel((value), (udc)->regs + USBA_##reg)
+#define usba_ep_readl(ep, reg)					\
+	__raw_readl((ep)->ep_regs + USBA_EPT_##reg)
+#define usba_ep_writel(ep, reg, value)				\
+	__raw_writel((value), (ep)->ep_regs + USBA_EPT_##reg)
+#define usba_dma_readl(ep, reg)					\
+	__raw_readl((ep)->dma_regs + USBA_DMA_##reg)
+#define usba_dma_writel(ep, reg, value)				\
+	__raw_writel((value), (ep)->dma_regs + USBA_DMA_##reg)
+
+/* Calculate base address for a given endpoint or DMA controller */
+#define USBA_EPT_BASE(x)	(0x100 + (x) * 0x20)
+#define USBA_DMA_BASE(x)	(0x300 + (x) * 0x10)
+#define USBA_FIFO_BASE(x)	((x) << 16)
+
+/* Synth parameters */
+#define USBA_NR_ENDPOINTS	7
+
+#define EP0_FIFO_SIZE		64
+#define EP0_EPT_SIZE		USBA_EPT_SIZE_64
+#define EP0_NR_BANKS		1
+
+#define DBG_ERR		0x0001	/* report all error returns */
+#define DBG_HW		0x0002	/* debug hardware initialization */
+#define DBG_GADGET	0x0004	/* calls to/from gadget driver */
+#define DBG_INT		0x0008	/* interrupts */
+#define DBG_BUS		0x0010	/* report changes in bus state */
+#define DBG_QUEUE	0x0020  /* debug request queue processing */
+#define DBG_FIFO	0x0040  /* debug FIFO contents */
+#define DBG_DMA		0x0080  /* debug DMA handling */
+#define DBG_REQ		0x0100	/* print out queued request length */
+#define DBG_ALL		0xffff
+#define DBG_NONE	0x0000
+
+#define DEBUG_LEVEL	(DBG_ERR)
+
+#define DBG(level, fmt, ...)					\
+	do {							\
+		if ((level) & DEBUG_LEVEL)			\
+			debug("udc: " fmt, ## __VA_ARGS__);	\
+	} while (0)
+
+enum usba_ctrl_state {
+	WAIT_FOR_SETUP,
+	DATA_STAGE_IN,
+	DATA_STAGE_OUT,
+	STATUS_STAGE_IN,
+	STATUS_STAGE_OUT,
+	STATUS_STAGE_ADDR,
+	STATUS_STAGE_TEST,
+};
+
+struct usba_dma_desc {
+	dma_addr_t next;
+	dma_addr_t addr;
+	u32 ctrl;
+};
+
+struct usba_ep {
+	int					state;
+	void					*ep_regs;
+	void					*dma_regs;
+	void					*fifo;
+	struct usb_ep				ep;
+	struct usba_udc				*udc;
+
+	struct list_head			queue;
+
+	u16					fifo_size;
+	u8					nr_banks;
+	u8					index;
+	unsigned int				can_dma:1;
+	unsigned int				can_isoc:1;
+	unsigned int				is_isoc:1;
+	unsigned int				is_in:1;
+
+	const struct usb_endpoint_descriptor	*desc;
+};
+
+struct usba_request {
+	struct usb_request			req;
+	struct list_head			queue;
+
+	u32					ctrl;
+
+	unsigned int				submitted:1;
+	unsigned int				last_transaction:1;
+	unsigned int				using_dma:1;
+	unsigned int				mapped:1;
+};
+
+struct usba_udc {
+	void *regs;
+	void *fifo;
+
+	struct usb_gadget gadget;
+	struct usb_gadget_driver *driver;
+	struct platform_device *pdev;
+	int irq;
+	int vbus_pin;
+	int vbus_pin_inverted;
+	int num_ep;
+	struct usba_ep *usba_ep;
+
+	u16 devstatus;
+
+	u16 test_mode;
+	int vbus_prev;
+};
+
+static inline struct usba_ep *to_usba_ep(struct usb_ep *ep)
+{
+	return container_of(ep, struct usba_ep, ep);
+}
+
+static inline struct usba_request *to_usba_req(struct usb_request *req)
+{
+	return container_of(req, struct usba_request, req);
+}
+
+static inline struct usba_udc *to_usba_udc(struct usb_gadget *gadget)
+{
+	return container_of(gadget, struct usba_udc, gadget);
+}
+
+#define ep_is_control(ep)	((ep)->index == 0)
+#define ep_is_idle(ep)		((ep)->state == EP_STATE_IDLE)
+
+#endif /* __LINUX_USB_GADGET_USBA_UDC_H */
diff --git a/drivers/usb/gadget/config.c b/drivers/usb/gadget/config.c
index f563afe..014a679 100644
--- a/drivers/usb/gadget/config.c
+++ b/drivers/usb/gadget/config.c
@@ -10,6 +10,7 @@
  */
 
 #include <common.h>
+#include <asm/unaligned.h>
 #include <asm/errno.h>
 #include <linux/list.h>
 #include <linux/string.h>
@@ -86,7 +87,8 @@
 	/* config descriptor first */
 	if (length < USB_DT_CONFIG_SIZE || !desc)
 		return -EINVAL;
-	*cp = *config;
+	/* config need not be aligned */
+	memcpy(cp, config, sizeof(*cp));
 
 	/* then interface/endpoint/class/vendor/... */
 	len = usb_descriptor_fillbuf(USB_DT_CONFIG_SIZE + (u8 *)buf,
@@ -100,7 +102,7 @@
 	/* patch up the config descriptor */
 	cp->bLength = USB_DT_CONFIG_SIZE;
 	cp->bDescriptorType = USB_DT_CONFIG;
-	cp->wTotalLength = cpu_to_le16(len);
+	put_unaligned_le16(len, &cp->wTotalLength);
 	cp->bmAttributes |= USB_CONFIG_ATT_ONE;
 	return len;
 }
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
index 579893c..700d5fb 100644
--- a/drivers/usb/gadget/ether.c
+++ b/drivers/usb/gadget/ether.c
@@ -849,9 +849,10 @@
 };
 
 /*============================================================================*/
-static u8 control_req[USB_BUFSIZ];
+DEFINE_CACHE_ALIGN_BUFFER(u8, control_req, USB_BUFSIZ);
+
 #if defined(CONFIG_USB_ETH_CDC) || defined(CONFIG_USB_ETH_RNDIS)
-static u8 status_req[STATUS_BYTECOUNT] __attribute__ ((aligned(4)));
+DEFINE_CACHE_ALIGN_BUFFER(u8, status_req, STATUS_BYTECOUNT);
 #endif
 
 
diff --git a/drivers/usb/gadget/f_dfu.h b/drivers/usb/gadget/f_dfu.h
index 34a4dde..cc2c455 100644
--- a/drivers/usb/gadget/f_dfu.h
+++ b/drivers/usb/gadget/f_dfu.h
@@ -82,7 +82,4 @@
 	__le16				wTransferSize;
 	__le16				bcdDFUVersion;
 } __packed;
-
-/* configuration-specific linkup */
-int dfu_add(struct usb_configuration *c);
 #endif /* __F_DFU_H_ */
diff --git a/drivers/usb/gadget/g_dnl.c b/drivers/usb/gadget/g_dnl.c
index a3e05a8..40868c0 100644
--- a/drivers/usb/gadget/g_dnl.c
+++ b/drivers/usb/gadget/g_dnl.c
@@ -7,7 +7,6 @@
  * SPDX-License-Identifier:	GPL-2.0+
  */
 
-#include <errno.h>
 #include <common.h>
 #include <malloc.h>
 
@@ -15,11 +14,11 @@
 #include <part.h>
 
 #include <g_dnl.h>
-#include "f_dfu.h"
+#include <usb_mass_storage.h>
+#include <dfu.h>
 
 #include "gadget_chips.h"
 #include "composite.c"
-#include "f_mass_storage.c"
 
 /*
  * One needs to define the following:
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index fdad739..3ae04c0 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -36,6 +36,12 @@
 #define CONFIG_USB_MAX_CONTROLLER_COUNT 1
 #endif
 
+/*
+ * EHCI spec page 20 says that the HC may take up to 16 uFrames (= 4ms) to halt.
+ * Let's time out after 8 to have a little safety margin on top of that.
+ */
+#define HCHALT_TIMEOUT (8 * 1000)
+
 static struct ehci_ctrl ehcic[CONFIG_USB_MAX_CONTROLLER_COUNT];
 
 #define ALIGN_END_ADDR(type, ptr, size)			\
@@ -190,6 +196,36 @@
 	return ret;
 }
 
+static int ehci_shutdown(struct ehci_ctrl *ctrl)
+{
+	int i, ret = 0;
+	uint32_t cmd, reg;
+
+	cmd = ehci_readl(&ctrl->hcor->or_usbcmd);
+	cmd &= ~(CMD_PSE | CMD_ASE);
+	ehci_writel(&ctrl->hcor->or_usbcmd, cmd);
+	ret = handshake(&ctrl->hcor->or_usbsts, STS_ASS | STS_PSS, 0,
+		100 * 1000);
+
+	if (!ret) {
+		for (i = 0; i < CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS; i++) {
+			reg = ehci_readl(&ctrl->hcor->or_portsc[i]);
+			reg |= EHCI_PS_SUSP;
+			ehci_writel(&ctrl->hcor->or_portsc[i], reg);
+		}
+
+		cmd &= ~CMD_RUN;
+		ehci_writel(&ctrl->hcor->or_usbcmd, cmd);
+		ret = handshake(&ctrl->hcor->or_usbsts, STS_HALT, STS_HALT,
+			HCHALT_TIMEOUT);
+	}
+
+	if (ret)
+		puts("EHCI failed to shut down host controller.\n");
+
+	return ret;
+}
+
 static int ehci_td_buffer(struct qTD *td, void *buf, size_t sz)
 {
 	uint32_t delta, next;
@@ -808,6 +844,7 @@
 			}
 			break;
 		case USB_PORT_FEAT_TEST:
+			ehci_shutdown(ctrl);
 			reg &= ~(0xf << 16);
 			reg |= ((le16_to_cpu(req->index) >> 8) & 0xf) << 16;
 			ehci_writel(status_reg, reg);
@@ -878,6 +915,7 @@
 
 int usb_lowlevel_stop(int index)
 {
+	ehci_shutdown(&ehcic[index]);
 	return ehci_hcd_stop(index);
 }
 
diff --git a/examples/standalone/README.smc91111_eeprom b/examples/standalone/README.smc91111_eeprom
index 28e7e69..a2d52e7 100644
--- a/examples/standalone/README.smc91111_eeprom
+++ b/examples/standalone/README.smc91111_eeprom
@@ -154,10 +154,10 @@
 
 -Boot environmental variable in Flash <- can not change, without
 					  re-flashing U-boot.
-U-Boot environental variable	       <- can not change, without
+U-Boot environmental variable	       <- can not change, without
 					  resetting board/U-Boot
-LAN91C111 Registers		       <- volitle
-LAN91C111 EEPROM		       <- Non Volitle
+LAN91C111 Registers		       <- volatile
+LAN91C111 EEPROM		       <- Non-volatile
 
 If you have not activated the network, and do not have a hardcoded
 or pre-assigned MAC address in U-boot, the environmental variables
diff --git a/include/common.h b/include/common.h
index 4d2a56d..f1a590a 100644
--- a/include/common.h
+++ b/include/common.h
@@ -383,7 +383,7 @@
 /**
  * setenv_addr - Set an environment variable to an address in hex
  *
- * @varname:	Environmet variable to set
+ * @varname:	Environment variable to set
  * @addr:	Value to set it to
  * @return 0 if ok, 1 on error
  */
@@ -1017,10 +1017,10 @@
  * of a function scoped static buffer.  It can not be used to create a cache
  * line aligned global buffer.
  */
-#define PAD_COUNT(s, pad) ((s - 1) / pad + 1)
+#define PAD_COUNT(s, pad) (((s) - 1) / (pad) + 1)
 #define PAD_SIZE(s, pad) (PAD_COUNT(s, pad) * pad)
 #define ALLOC_ALIGN_BUFFER_PAD(type, name, size, align, pad)		\
-	char __##name[ROUND(PAD_SIZE(size * sizeof(type), pad), align)  \
+	char __##name[ROUND(PAD_SIZE((size) * sizeof(type), pad), align)  \
 		      + (align - 1)];					\
 									\
 	type *name = (type *) ALIGN((uintptr_t)__##name, align)
diff --git a/include/configs/P2041RDB.h b/include/configs/P2041RDB.h
index 905bacf..862614b 100644
--- a/include/configs/P2041RDB.h
+++ b/include/configs/P2041RDB.h
@@ -354,10 +354,10 @@
 #define CONFIG_SYS_I2C_FSL
 #define CONFIG_SYS_FSL_I2C_SPEED	400000
 #define CONFIG_SYS_FSL_I2C_SLAVE	0x7F
-#define CONFIG_SYS_FSL_I2C_OFFSET	0x3000
+#define CONFIG_SYS_FSL_I2C_OFFSET	0x118000
 #define CONFIG_SYS_FSL_I2C2_SPEED	400000
 #define CONFIG_SYS_FSL_I2C2_SLAVE	0x7F
-#define CONFIG_SYS_FSL_I2C2_OFFSET	0x3100
+#define CONFIG_SYS_FSL_I2C2_OFFSET	0x118100
 
 /*
  * RapidIO
diff --git a/include/configs/am335x_evm.h b/include/configs/am335x_evm.h
index cdf689f..3482470 100644
--- a/include/configs/am335x_evm.h
+++ b/include/configs/am335x_evm.h
@@ -100,6 +100,7 @@
 	"loadbootenv=load mmc ${mmcdev} ${loadaddr} ${bootenv}\0" \
 	"importbootenv=echo Importing environment from mmc ...; " \
 		"env import -t $loadaddr $filesize\0" \
+	"dfu_alt_info_ram=" DFU_ALT_INFO_RAM "\0" \
 	"ramargs=setenv bootargs console=${console} " \
 		"${optargs} " \
 		"root=${ramroot} " \
@@ -327,6 +328,11 @@
 	"kernel part 0 8;" \
 	"rootfs part 0 9"
 #endif
+#define CONFIG_DFU_RAM
+#define DFU_ALT_INFO_RAM \
+	"kernel ram 0x80200000 0xD80000;" \
+	"fdt ram 0x80F80000 0x80000;" \
+	"ramdisk ram 0x81000000 0x4000000"
 
 /*
  * Default to using SPI for environment, etc.
diff --git a/include/configs/eXalion.h b/include/configs/eXalion.h
index c2d04a2..7321b60 100644
--- a/include/configs/eXalion.h
+++ b/include/configs/eXalion.h
@@ -119,7 +119,7 @@
 
 #define CONFIG_ENV_IS_IN_FLASH	1
 #define CONFIG_ENV_SECT_SIZE	0x20000 /* Size of one Flash sector */
-#define CONFIG_ENV_SIZE		CONFIG_ENV_SECT_SIZE	/* Use one Flash sector for enviroment	*/
+#define CONFIG_ENV_SIZE		CONFIG_ENV_SECT_SIZE	/* Use one Flash sector for environment	*/
 #define CONFIG_ENV_ADDR		0xFFFC0000
 #define CONFIG_ENV_OFFSET		0	/* starting right at the beginning  */
 
diff --git a/include/configs/sacsng.h b/include/configs/sacsng.h
index d63d0c4..0feef1e 100644
--- a/include/configs/sacsng.h
+++ b/include/configs/sacsng.h
@@ -305,7 +305,7 @@
 #define CONFIG_ENV_IN_OWN_SECT	1
 
 /* Define this to contain any number of null terminated strings that
- * will be part of the default enviroment compiled into the boot image.
+ * will be part of the default environment compiled into the boot image.
  */
 #define CONFIG_EXTRA_ENV_SETTINGS \
 "quiet=0\0" \
diff --git a/include/configs/sama5d3xek.h b/include/configs/sama5d3xek.h
index 76fa500..79c0068 100644
--- a/include/configs/sama5d3xek.h
+++ b/include/configs/sama5d3xek.h
@@ -162,6 +162,14 @@
 #define CONFIG_USB_STORAGE
 #endif
 
+/* USB device */
+#define CONFIG_USB_GADGET
+#define CONFIG_USB_GADGET_DUALSPEED
+#define CONFIG_USB_GADGET_ATMEL_USBA
+#define CONFIG_USB_ETHER
+#define CONFIG_USB_ETH_RNDIS
+#define CONFIG_USBNET_MANUFACTURER      "Atmel SAMA5D3xEK"
+
 #if defined(CONFIG_CMD_USB) || defined(CONFIG_CMD_MMC)
 #define CONFIG_CMD_FAT
 #endif
diff --git a/include/dfu.h b/include/dfu.h
index 47b9055..b2ecf1b 100644
--- a/include/dfu.h
+++ b/include/dfu.h
@@ -14,11 +14,13 @@
 #include <common.h>
 #include <linux/list.h>
 #include <mmc.h>
+#include <linux/usb/composite.h>
 
 enum dfu_device_type {
 	DFU_DEV_MMC = 1,
 	DFU_DEV_ONENAND,
 	DFU_DEV_NAND,
+	DFU_DEV_RAM,
 };
 
 enum dfu_layout {
@@ -27,8 +29,14 @@
 	DFU_FS_EXT2,
 	DFU_FS_EXT3,
 	DFU_FS_EXT4,
+	DFU_RAM_ADDR,
 };
 
+enum dfu_op {
+	DFU_OP_READ = 1,
+	DFU_OP_WRITE,
+};
+
 struct mmc_internal_data {
 	/* RAW programming */
 	unsigned int lba_start;
@@ -51,6 +59,11 @@
 	unsigned int ubi;
 };
 
+struct ram_internal_data {
+	void		*start;
+	unsigned int	size;
+};
+
 static inline unsigned int get_mmc_blk_size(int dev)
 {
 	return find_mmc_device(dev)->read_bl_len;
@@ -62,7 +75,7 @@
 #define CONFIG_SYS_DFU_DATA_BUF_SIZE		(1024*1024*8)	/* 8 MiB */
 #endif
 #ifndef CONFIG_SYS_DFU_MAX_FILE_SIZE
-#define CONFIG_SYS_DFU_MAX_FILE_SIZE	(4 << 20)	/* 4 MiB */
+#define CONFIG_SYS_DFU_MAX_FILE_SIZE CONFIG_SYS_DFU_DATA_BUF_SIZE
 #endif
 
 struct dfu_entity {
@@ -76,6 +89,7 @@
 	union {
 		struct mmc_internal_data mmc;
 		struct nand_internal_data nand;
+		struct ram_internal_data ram;
 	} data;
 
 	int (*read_medium)(struct dfu_entity *dfu,
@@ -113,6 +127,7 @@
 char *dfu_extract_token(char** e, int *n);
 void dfu_trigger_reset(void);
 bool dfu_reset(void);
+int dfu_init_env_entities(char *interface, int dev);
 
 int dfu_read(struct dfu_entity *de, void *buf, int size, int blk_seq_num);
 int dfu_write(struct dfu_entity *de, void *buf, int size, int blk_seq_num);
@@ -137,4 +152,22 @@
 }
 #endif
 
+#ifdef CONFIG_DFU_RAM
+extern int dfu_fill_entity_ram(struct dfu_entity *dfu, char *s);
+#else
+static inline int dfu_fill_entity_ram(struct dfu_entity *dfu, char *s)
+{
+	puts("RAM support not available!\n");
+	return -1;
+}
+#endif
+
+#ifdef CONFIG_DFU_FUNCTION
+int dfu_add(struct usb_configuration *c);
+#else
+int dfu_add(struct usb_configuration *c)
+{
+	return 0;
+}
+#endif
 #endif /* __DFU_ENTITY_H_ */
diff --git a/include/i2s.h b/include/i2s.h
index aee52e7..8dd2cc3 100644
--- a/include/i2s.h
+++ b/include/i2s.h
@@ -85,6 +85,7 @@
 	unsigned int bitspersample;	/* bits per sample */
 	unsigned int channels;		/* audio channels */
 	unsigned int base_address;	/* I2S Register Base */
+	unsigned int id;		/* I2S controller id */
 };
 
 /*
diff --git a/include/libfdt.h b/include/libfdt.h
index 765d84f..9eefaaf 100644
--- a/include/libfdt.h
+++ b/include/libfdt.h
@@ -596,9 +596,9 @@
 				  const char *name, int namelen);
 
 /**
- * fdt_get_alias - retreive the path referenced by a given alias
+ * fdt_get_alias - retrieve the path referenced by a given alias
  * @fdt: pointer to the device tree blob
- * @name: name of the alias th look up
+ * @name: name of the alias to look up
  *
  * fdt_get_alias() retrieves the value of a given alias.  That is, the
  * value of the property named 'name' in the node /aliases.
diff --git a/include/linux/usb/atmel_usba_udc.h b/include/linux/usb/atmel_usba_udc.h
new file mode 100644
index 0000000..be29ef0
--- /dev/null
+++ b/include/linux/usb/atmel_usba_udc.h
@@ -0,0 +1,26 @@
+/*
+ * Platform data definitions for Atmel USBA gadget driver
+ * [Original from Linux kernel: include/linux/usb/atmel_usba_udc.h]
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+#ifndef __LINUX_USB_USBA_H__
+#define __LINUX_USB_USBA_H__
+
+struct usba_ep_data {
+	char *name;
+	int index;
+	int fifo_size;
+	int nr_banks;
+	int can_dma;
+	int can_isoc;
+};
+
+struct usba_platform_data {
+	int			num_ep;
+	struct usba_ep_data	*ep;
+};
+
+extern int usba_udc_probe(struct usba_platform_data *pdata);
+
+#endif /* __LINUX_USB_USBA_H */
diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
index 220d068..a8a5763 100644
--- a/include/linux/usb/gadget.h
+++ b/include/linux/usb/gadget.h
@@ -18,6 +18,7 @@
 #ifndef __LINUX_USB_GADGET_H
 #define __LINUX_USB_GADGET_H
 
+#include <errno.h>
 #include <linux/list.h>
 
 struct usb_ep;
diff --git a/include/miiphy.h b/include/miiphy.h
index 657b496..088797e 100644
--- a/include/miiphy.h
+++ b/include/miiphy.h
@@ -1,5 +1,5 @@
 /*
- * SPDX-License-Identifier:	GPL-2.0	ibm-pibs
+ * SPDX-License-Identifier:	GPL-2.0	IBM-pibs
  *
  * Additions (C) Copyright 2009 Industrie Dial Face S.p.A.
  */
diff --git a/include/mmc.h b/include/mmc.h
index 228d771..214b9ed 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -335,7 +335,11 @@
 void mmc_set_preinit(struct mmc *mmc, int preinit);
 
 #ifdef CONFIG_GENERIC_MMC
+#ifdef CONFIG_MMC_SPI
 #define mmc_host_is_spi(mmc)	((mmc)->host_caps & MMC_MODE_SPI)
+#else
+#define mmc_host_is_spi(mmc)	0
+#endif
 struct mmc *mmc_spi_init(uint bus, uint cs, uint speed, uint mode);
 #else
 int mmc_legacy_init(int verbose);
diff --git a/include/sdhci.h b/include/sdhci.h
index b18b873..74d06ae 100644
--- a/include/sdhci.h
+++ b/include/sdhci.h
@@ -192,6 +192,8 @@
 #define   SDHCI_SPEC_200	1
 #define   SDHCI_SPEC_300	2
 
+#define SDHCI_GET_VERSION(x) (x->version & SDHCI_SPEC_VER_MASK)
+
 /*
  * End of controller registers.
  */
@@ -210,6 +212,7 @@
 #define SDHCI_QUIRK_NO_CD		(1 << 5)
 #define SDHCI_QUIRK_WAIT_SEND_CMD	(1 << 6)
 #define SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER (1 << 7)
+#define SDHCI_QUIRK_USE_WIDE8		(1 << 8)
 
 /* to make gcc happy */
 struct sdhci_host;
diff --git a/include/usb_mass_storage.h b/include/usb_mass_storage.h
index 35cdcc3..e08deb4 100644
--- a/include/usb_mass_storage.h
+++ b/include/usb_mass_storage.h
@@ -11,6 +11,7 @@
 #define SECTOR_SIZE		0x200
 
 #include <mmc.h>
+#include <linux/usb/composite.h>
 
 struct ums_device {
 	struct mmc *mmc;
@@ -39,4 +40,12 @@
 extern int usb_gadget_handle_interrupts(void);
 extern int fsg_main_thread(void *);
 
+#ifdef CONFIG_USB_GADGET_MASS_STORAGE
+int fsg_add(struct usb_configuration *c);
+#else
+int fsg_add(struct usb_configuration *c)
+{
+	return 0;
+}
+#endif
 #endif /* __USB_MASS_STORAGE_H__ */
diff --git a/lib/hashtable.c b/lib/hashtable.c
index 644330a..c5a2b08 100644
--- a/lib/hashtable.c
+++ b/lib/hashtable.c
@@ -817,7 +817,7 @@
 	 * size of 8 per entry (= safety factor of ~5) should provide enough
 	 * safety margin for any existing environment definitions and still
 	 * allow for more than enough dynamic additions. Note that the
-	 * "size" argument is supposed to give the maximum enviroment size
+	 * "size" argument is supposed to give the maximum environment size
 	 * (CONFIG_ENV_SIZE).  This heuristics will result in
 	 * unreasonably large numbers (and thus memory footprint) for
 	 * big flash environments (>8,000 entries for 64 KB
diff --git a/post/board/lwmon5/sysmon.c b/post/board/lwmon5/sysmon.c
index da37d66..cca1a26 100644
--- a/post/board/lwmon5/sysmon.c
+++ b/post/board/lwmon5/sysmon.c
@@ -22,7 +22,7 @@
  *
  * LCD backlight is not enabled if temperature values are not within
  * allowed ranges (-30 .. + 80). The brightness of backlite can be
- * controlled by setting "brightness" enviroment variable. Default value is 50%
+ * controlled by setting "brightness" environment variable. Default value is 50%
  *
  * See the list of all parameters in the sysmon_table below
  */
diff --git a/tools/buildman/README b/tools/buildman/README
index 734ada6..f63f278 100644
--- a/tools/buildman/README
+++ b/tools/buildman/README
@@ -629,6 +629,28 @@
 increases, and vice versa.
 
 
+Providing 'make' flags
+======================
+
+U-Boot's build system supports a few flags (such as BUILD_TAG) which affect
+the build product. These flags can be specified in the buildman settings
+file. They can also be useful when building U-Boot against other open source
+software.
+
+[make-flags]
+at91-boards=ENABLE_AT91_TEST=1
+snapper9260=${at91-boards} BUILD_TAG=442
+snapper9g45=${at91-boards} BUILD_TAG=443
+
+This will use 'make ENABLE_AT91_TEST=1 BUILD_TAG=442' for snapper9260
+and 'make ENABLE_AT91_TEST=1 BUILD_TAG=442' for snapper9g45. A special
+variable ${target} is available to access the target name (snapper9260 and
+snapper9g20 in this case). Variables are resolved recursively.
+
+It is expected that any variables added are dealt with in U-Boot's
+config.mk file and documented in the README.
+
+
 Other options
 =============
 
diff --git a/tools/buildman/board.py b/tools/buildman/board.py
index a388896..1d3db20 100644
--- a/tools/buildman/board.py
+++ b/tools/buildman/board.py
@@ -5,16 +5,17 @@
 
 class Board:
     """A particular board that we can build"""
-    def __init__(self, target, arch, cpu, board_name, vendor, soc, options):
+    def __init__(self, status, arch, cpu, soc, vendor, board_name, target, options):
         """Create a new board type.
 
         Args:
-            target: Target name (use make <target>_config to configure)
+            status: define whether the board is 'Active' or 'Orphaned'
             arch: Architecture name (e.g. arm)
             cpu: Cpu name (e.g. arm1136)
-            board_name: Name of board (e.g. integrator)
-            vendor: Name of vendor (e.g. armltd)
             soc: Name of SOC, or '' if none (e.g. mx31)
+            vendor: Name of vendor (e.g. armltd)
+            board_name: Name of board (e.g. integrator)
+            target: Target name (use make <target>_config to configure)
             options: board-specific options (e.g. integratorcp:CM1136)
         """
         self.target = target
@@ -63,8 +64,10 @@
                 for upto in range(len(fields)):
                     if fields[upto] == '-':
                         fields[upto] = ''
-                while len(fields) < 9:
+                while len(fields) < 8:
                     fields.append('')
+                if len(fields) > 8:
+                    fields = fields[:8]
 
                 board = Board(*fields)
                 self.AddBoard(board)
diff --git a/tools/buildman/bsettings.py b/tools/buildman/bsettings.py
index c801130..9164798 100644
--- a/tools/buildman/bsettings.py
+++ b/tools/buildman/bsettings.py
@@ -36,9 +36,6 @@
         return settings.items(section)
     except ConfigParser.NoSectionError as e:
         print e
-        print ("Warning: No tool chains - please add a [toolchain] section "
-                "to your buildman config file %s. See README for details" %
-                config_fname)
         return []
     except:
         raise
diff --git a/tools/buildman/builder.py b/tools/buildman/builder.py
index 29da67a..4a2d753 100644
--- a/tools/buildman/builder.py
+++ b/tools/buildman/builder.py
@@ -253,6 +253,7 @@
                     args.extend(['-j', str(self.builder.num_jobs)])
                 config_args = ['%s_config' % brd.target]
                 config_out = ''
+                args.extend(self.builder.toolchains.GetMakeArguments(brd))
 
                 # If we need to reconfigure, do that now
                 if do_config:
diff --git a/tools/buildman/buildman.py b/tools/buildman/buildman.py
index 6fba2f2..43895b8 100755
--- a/tools/buildman/buildman.py
+++ b/tools/buildman/buildman.py
@@ -32,6 +32,19 @@
 
 def RunTests():
     import test
+    import doctest
+
+    result = unittest.TestResult()
+    for module in ['toolchain']:
+        suite = doctest.DocTestSuite(module)
+        suite.run(result)
+
+    # TODO: Surely we can just 'print' result?
+    print result
+    for test, err in result.errors:
+        print err
+    for test, err in result.failures:
+        print err
 
     sys.argv = [sys.argv[0]]
     suite = unittest.TestLoader().loadTestsFromTestCase(test.TestBuild)
diff --git a/tools/buildman/test.py b/tools/buildman/test.py
index bcdedfb..068784a 100644
--- a/tools/buildman/test.py
+++ b/tools/buildman/test.py
@@ -60,11 +60,11 @@
 ]
 
 boards = [
-    ['board0', 'arm', 'armv7', 'ARM Board 1', 'Tester', '', ''],
-    ['board1', 'arm', 'armv7', 'ARM Board 2', 'Tester', '', ''],
-    ['board2', 'powerpc', 'powerpc', 'PowerPC board 1', 'Tester', '', ''],
-    ['board3', 'powerpc', 'mpc5xx', 'PowerPC board 2', 'Tester', '', ''],
-    ['board4', 'sandbox', 'sandbox', 'Sandbox board', 'Tester', '', '']
+    ['Active', 'arm', 'armv7', '', 'Tester', 'ARM Board 1', 'board0',  ''],
+    ['Active', 'arm', 'armv7', '', 'Tester', 'ARM Board 2', 'board1', ''],
+    ['Active', 'powerpc', 'powerpc', '', 'Tester', 'PowerPC board 1', 'board2', ''],
+    ['Active', 'powerpc', 'mpc5xx', '', 'Tester', 'PowerPC board 2', 'board3', ''],
+    ['Active', 'sandbox', 'sandbox', '', 'Tester', 'Sandbox board', 'board4', ''],
 ]
 
 class Options:
diff --git a/tools/buildman/toolchain.py b/tools/buildman/toolchain.py
index dfa1d00..a292338 100644
--- a/tools/buildman/toolchain.py
+++ b/tools/buildman/toolchain.py
@@ -3,6 +3,7 @@
 # SPDX-License-Identifier:	GPL-2.0+
 #
 
+import re
 import glob
 import os
 
@@ -97,12 +98,18 @@
     def __init__(self):
         self.toolchains = {}
         self.paths = []
-        for name, value in bsettings.GetItems('toolchain'):
+        toolchains = bsettings.GetItems('toolchain')
+        if not toolchains:
+            print ("Warning: No tool chains - please add a [toolchain] section"
+                 " to your buildman config file %s. See README for details" %
+                 config_fname)
+
+        for name, value in toolchains:
             if '*' in value:
                 self.paths += glob.glob(value)
             else:
                 self.paths.append(value)
-
+        self._make_flags = dict(bsettings.GetItems('make-flags'))
 
     def Add(self, fname, test=True, verbose=False):
         """Add a toolchain to our list
@@ -167,3 +174,73 @@
         if not arch in self.toolchains:
             raise ValueError, ("No tool chain found for arch '%s'" % arch)
         return self.toolchains[arch]
+
+    def ResolveReferences(self, var_dict, args):
+        """Resolve variable references in a string
+
+        This converts ${blah} within the string to the value of blah.
+        This function works recursively.
+
+        Args:
+            var_dict: Dictionary containing variables and their values
+            args: String containing make arguments
+        Returns:
+            Resolved string
+
+        >>> bsettings.Setup()
+        >>> tcs = Toolchains()
+        >>> tcs.Add('fred', False)
+        >>> var_dict = {'oblique' : 'OBLIQUE', 'first' : 'fi${second}rst', \
+                        'second' : '2nd'}
+        >>> tcs.ResolveReferences(var_dict, 'this=${oblique}_set')
+        'this=OBLIQUE_set'
+        >>> tcs.ResolveReferences(var_dict, 'this=${oblique}_set${first}nd')
+        'this=OBLIQUE_setfi2ndrstnd'
+        """
+        re_var = re.compile('(\$\{[a-z0-9A-Z]{1,}\})')
+
+        while True:
+            m = re_var.search(args)
+            if not m:
+                break
+            lookup = m.group(0)[2:-1]
+            value = var_dict.get(lookup, '')
+            args = args[:m.start(0)] + value + args[m.end(0):]
+        return args
+
+    def GetMakeArguments(self, board):
+        """Returns 'make' arguments for a given board
+
+        The flags are in a section called 'make-flags'. Flags are named
+        after the target they represent, for example snapper9260=TESTING=1
+        will pass TESTING=1 to make when building the snapper9260 board.
+
+        References to other boards can be added in the string also. For
+        example:
+
+        [make-flags]
+        at91-boards=ENABLE_AT91_TEST=1
+        snapper9260=${at91-boards} BUILD_TAG=442
+        snapper9g45=${at91-boards} BUILD_TAG=443
+
+        This will return 'ENABLE_AT91_TEST=1 BUILD_TAG=442' for snapper9260
+        and 'ENABLE_AT91_TEST=1 BUILD_TAG=443' for snapper9g45.
+
+        A special 'target' variable is set to the board target.
+
+        Args:
+            board: Board object for the board to check.
+        Returns:
+            'make' flags for that board, or '' if none
+        """
+        self._make_flags['target'] = board.target
+        arg_str = self.ResolveReferences(self._make_flags,
+                           self._make_flags.get(board.target, ''))
+        args = arg_str.split(' ')
+        i = 0
+        while i < len(args):
+            if not args[i]:
+                del args[i]
+            else:
+                i += 1
+        return args
diff --git a/tools/checkpatch.pl b/tools/checkpatch.pl
index 896e2bc..88c5bc7 100755
--- a/tools/checkpatch.pl
+++ b/tools/checkpatch.pl
@@ -398,7 +398,7 @@
 	my ($root) = @_;
 
 	my @tree_check = (
-		"COPYING", "CREDITS", "Kbuild", "MAINTAINERS", "Makefile",
+		"COPYING", "CREDITS", "Kbuild", "Makefile",
 		"README", "Documentation", "arch", "include", "drivers",
 		"fs", "init", "ipc", "kernel", "lib", "scripts",
 	);
@@ -3701,7 +3701,7 @@
 $vname has style problems, please review.
 
 If any of these errors are false positives, please report
-them to the maintainer, see CHECKPATCH in MAINTAINERS.
+them to the maintainer, see boards.cfg.
 EOM
 	}
 
diff --git a/tools/fit_image.c b/tools/fit_image.c
index 47beaaf..0400a60 100644
--- a/tools/fit_image.c
+++ b/tools/fit_image.c
@@ -23,7 +23,7 @@
 static int fit_verify_header (unsigned char *ptr, int image_size,
 			struct mkimage_params *params)
 {
-	return fdt_check_header ((void *)ptr);
+	return fdt_check_header(ptr);
 }
 
 static int fit_check_image_types (uint8_t type)